about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--COPYRIGHT79
-rw-r--r--Cargo.lock4
-rw-r--r--LICENSES/Unicode-3.0.txt39
-rw-r--r--LICENSES/Unicode-DFS-2016.txt22
-rw-r--r--REUSE.toml5
-rw-r--r--compiler/rustc_abi/src/lib.rs2
-rw-r--r--compiler/rustc_ast/src/ast.rs136
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs35
-rw-r--r--compiler/rustc_ast/src/util/parser.rs115
-rw-r--r--compiler/rustc_ast/src/visit.rs22
-rw-r--r--compiler/rustc_ast_lowering/messages.ftl4
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs76
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs13
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs47
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs18
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs32
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs5
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs4
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/fixup.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs11
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs14
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs25
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs28
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs18
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs18
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/types.rs16
-rw-r--r--compiler/rustc_codegen_cranelift/src/global_asm.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/inline_asm.rs10
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs52
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/base.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs36
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs129
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs124
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs22
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs6
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs74
-rw-r--r--compiler/rustc_const_eval/src/check_consts/ops.rs40
-rw-r--r--compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs57
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs127
-rw-r--r--compiler/rustc_const_eval/src/errors.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/stack.rs2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs112
-rw-r--r--compiler/rustc_expand/src/placeholders.rs3
-rw-r--r--compiler/rustc_feature/src/unstable.rs8
-rw-r--r--compiler/rustc_hir/src/hir.rs161
-rw-r--r--compiler/rustc_hir/src/intravisit.rs14
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl10
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs104
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs38
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs15
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs31
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs23
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs35
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs9
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs85
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs57
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs16
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs9
-rw-r--r--compiler/rustc_incremental/src/lib.rs11
-rw-r--r--compiler/rustc_incremental/src/persist/mod.rs3
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs2
-rw-r--r--compiler/rustc_index_macros/src/newtype.rs2
-rw-r--r--compiler/rustc_infer/src/infer/at.rs42
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs2
-rw-r--r--compiler/rustc_infer/src/infer/context.rs7
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs49
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs6
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs10
-rw-r--r--compiler/rustc_interface/src/passes.rs2
-rw-r--r--compiler/rustc_interface/src/queries.rs32
-rw-r--r--compiler/rustc_interface/src/tests.rs2
-rw-r--r--compiler/rustc_lexer/src/lib.rs8
-rw-r--r--compiler/rustc_lexer/src/tests.rs72
-rw-r--r--compiler/rustc_lint/src/builtin.rs30
-rw-r--r--compiler/rustc_lint/src/context.rs2
-rw-r--r--compiler/rustc_lint/src/dangling.rs4
-rw-r--r--compiler/rustc_lint/src/lints.rs2
-rw-r--r--compiler/rustc_lint/src/unused.rs6
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp19
-rw-r--r--compiler/rustc_metadata/messages.ftl3
-rw-r--r--compiler/rustc_metadata/src/creader.rs20
-rw-r--r--compiler/rustc_metadata/src/errors.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs6
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs7
-rw-r--r--compiler/rustc_middle/messages.ftl3
-rw-r--r--compiler/rustc_middle/src/error.rs11
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs4
-rw-r--r--compiler/rustc_middle/src/hooks/mod.rs13
-rw-r--r--compiler/rustc_middle/src/middle/lang_items.rs11
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs8
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs18
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs4
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs3
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs20
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs6
-rw-r--r--compiler/rustc_middle/src/traits/select.rs18
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs12
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs4
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs6
-rw-r--r--compiler/rustc_middle/src/ty/context.rs31
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs4
-rw-r--r--compiler/rustc_middle/src/ty/error.rs9
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs4
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs161
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs203
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs8
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs1
-rw-r--r--compiler/rustc_middle/src/ty/util.rs45
-rw-r--r--compiler/rustc_mir_build/messages.ftl39
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs107
-rw-r--r--compiler/rustc_mir_build/src/errors.rs91
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs20
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs185
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs10
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/cursor.rs65
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs294
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/fmt.rs13
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/lattice.rs108
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/mod.rs31
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/results.rs39
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/visitor.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs6
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/initialized.rs146
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/mod.rs7
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs29
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs9
-rw-r--r--compiler/rustc_mir_dataflow/src/rustc_peek.rs11
-rw-r--r--compiler/rustc_mir_dataflow/src/storage.rs20
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs16
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs166
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs5
-rw-r--r--compiler/rustc_mir_transform/src/early_otherwise_branch.rs4
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs18
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs4
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs6
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs71
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs6
-rw-r--r--compiler/rustc_mir_transform/src/lint.rs3
-rw-r--r--compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs31
-rw-r--r--compiler/rustc_mir_transform/src/match_branches.rs5
-rw-r--r--compiler/rustc_mir_transform/src/multiple_return_terminators.rs7
-rw-r--r--compiler/rustc_mir_transform/src/nrvo.rs4
-rw-r--r--compiler/rustc_mir_transform/src/post_analysis_normalize.rs (renamed from compiler/rustc_mir_transform/src/reveal_all.rs)16
-rw-r--r--compiler/rustc_mir_transform/src/ref_prop.rs3
-rw-r--r--compiler/rustc_mir_transform/src/remove_unneeded_drops.rs8
-rw-r--r--compiler/rustc_mir_transform/src/remove_zsts.rs12
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs2
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_prop.rs6
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs2
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs74
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs27
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs5
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs4
-rw-r--r--compiler/rustc_parse/messages.ftl2
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs75
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs83
-rw-r--r--compiler/rustc_parse/src/lexer/unicode_chars.rs8
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs62
-rw-r--r--compiler/rustc_parse/src/parser/item.rs22
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs17
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs37
-rw-r--r--compiler/rustc_passes/src/errors.rs11
-rw-r--r--compiler/rustc_passes/src/input_stats.rs11
-rw-r--r--compiler/rustc_passes/src/stability.rs11
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs40
-rw-r--r--compiler/rustc_query_impl/src/lib.rs6
-rw-r--r--compiler/rustc_query_impl/src/profiling_support.rs2
-rw-r--r--compiler/rustc_resolve/messages.ftl8
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs18
-rw-r--r--compiler/rustc_resolve/src/errors.rs16
-rw-r--r--compiler/rustc_resolve/src/late.rs51
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs39
-rw-r--r--compiler/rustc_session/messages.ftl2
-rw-r--r--compiler/rustc_session/src/config.rs8
-rw-r--r--compiler/rustc_session/src/errors.rs6
-rw-r--r--compiler/rustc_session/src/options.rs68
-rw-r--r--compiler/rustc_session/src/session.rs59
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs27
-rw-r--r--compiler/rustc_span/src/edition.rs4
-rw-r--r--compiler/rustc_span/src/lib.rs5
-rw-r--r--compiler/rustc_span/src/source_map.rs11
-rw-r--r--compiler/rustc_span/src/symbol.rs6
-rw-r--r--compiler/rustc_target/src/asm/mod.rs13
-rw-r--r--compiler/rustc_target/src/asm/s390x.rs13
-rw-r--r--compiler/rustc_target/src/callconv/aarch64.rs62
-rw-r--r--compiler/rustc_target/src/callconv/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/mod.rs5
-rw-r--r--compiler/rustc_target/src/spec/tests/tests_impl.rs28
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs17
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs25
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs24
-rw-r--r--compiler/rustc_trait_selection/src/solve/delegate.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs21
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/effects.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs19
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs50
-rw-r--r--compiler/rustc_trait_selection/src/traits/normalize.rs20
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/_match.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs34
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs77
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs191
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs35
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs36
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs8
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs8
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs6
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs17
-rw-r--r--compiler/rustc_type_ir/src/elaborate.rs11
-rw-r--r--compiler/rustc_type_ir/src/error.rs12
-rw-r--r--compiler/rustc_type_ir/src/infer_ctxt.rs36
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs8
-rw-r--r--compiler/rustc_type_ir/src/interner.rs1
-rw-r--r--compiler/rustc_type_ir/src/lang_items.rs1
-rw-r--r--compiler/rustc_type_ir/src/predicate.rs15
-rw-r--r--compiler/rustc_type_ir/src/relate.rs43
-rw-r--r--compiler/rustc_type_ir/src/relate/combine.rs6
-rw-r--r--compiler/rustc_type_ir/src/solve/mod.rs55
-rw-r--r--compiler/rustc_type_ir/src/ty_kind.rs2
-rw-r--r--config.example.toml21
-rw-r--r--library/Cargo.lock6
-rw-r--r--library/alloc/src/alloc.rs8
-rw-r--r--library/alloc/src/collections/btree/map/entry.rs105
-rw-r--r--library/alloc/src/collections/btree/map/tests.rs48
-rw-r--r--library/alloc/src/collections/btree/node.rs20
-rw-r--r--library/core/src/array/mod.rs37
-rw-r--r--library/core/src/fmt/num.rs80
-rw-r--r--library/core/src/intrinsics/mod.rs48
-rw-r--r--library/core/src/io/borrowed_buf.rs20
-rw-r--r--library/core/src/iter/range.rs128
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/core/src/marker.rs3
-rw-r--r--library/core/src/mem/maybe_uninit.rs6
-rw-r--r--library/core/src/net/ip_addr.rs10
-rw-r--r--library/core/src/num/f128.rs16
-rw-r--r--library/core/src/num/f16.rs16
-rw-r--r--library/core/src/num/f32.rs19
-rw-r--r--library/core/src/num/f64.rs19
-rw-r--r--library/core/src/num/int_macros.rs1
-rw-r--r--library/core/src/ops/arith.rs13
-rw-r--r--library/core/src/ops/deref.rs47
-rw-r--r--library/core/src/ops/drop.rs2
-rw-r--r--library/core/src/slice/mod.rs198
-rw-r--r--library/core/tests/fmt/mod.rs7
-rw-r--r--library/core/tests/iter/traits/step.rs35
-rw-r--r--library/core/tests/slice.rs70
-rw-r--r--library/profiler_builtins/Cargo.toml5
-rw-r--r--library/profiler_builtins/src/lib.rs12
-rw-r--r--library/std/src/env.rs15
-rw-r--r--library/std/src/ffi/os_str.rs12
-rw-r--r--library/std/src/fs.rs5
-rw-r--r--library/std/src/io/buffered/bufreader/buffer.rs2
-rw-r--r--library/std/src/io/buffered/bufwriter.rs4
-rw-r--r--library/std/src/io/cursor.rs4
-rw-r--r--library/std/src/io/error.rs67
-rw-r--r--library/std/src/io/error/tests.rs10
-rw-r--r--library/std/src/io/mod.rs7
-rw-r--r--library/std/src/io/tests.rs4
-rw-r--r--library/std/src/lib.rs8
-rw-r--r--library/std/src/net/mod.rs2
-rw-r--r--library/std/src/net/udp.rs4
-rw-r--r--library/std/src/os/fd/owned.rs21
-rw-r--r--library/std/src/os/unix/net/addr.rs8
-rw-r--r--library/std/src/os/wasi/fs.rs5
-rw-r--r--library/std/src/os/windows/io/socket.rs2
-rw-r--r--library/std/src/path.rs3
-rw-r--r--library/std/src/prelude/common.rs3
-rw-r--r--library/std/src/sync/mpmc/array.rs6
-rw-r--r--library/std/src/sync/mpmc/context.rs13
-rw-r--r--library/std/src/sync/mpmc/list.rs3
-rw-r--r--library/std/src/sync/mpmc/zero.rs6
-rw-r--r--library/std/src/sync/rwlock/tests.rs5
-rw-r--r--library/std/src/sys/pal/common/small_c_string.rs2
-rw-r--r--library/std/src/sys/pal/hermit/fs.rs16
-rw-r--r--library/std/src/sys/pal/hermit/mod.rs2
-rw-r--r--library/std/src/sys/pal/hermit/net.rs4
-rw-r--r--library/std/src/sys/pal/hermit/thread.rs2
-rw-r--r--library/std/src/sys/pal/sgx/mod.rs4
-rw-r--r--library/std/src/sys/pal/solid/fs.rs13
-rw-r--r--library/std/src/sys/pal/solid/net.rs2
-rw-r--r--library/std/src/sys/pal/solid/os.rs2
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs30
-rw-r--r--library/std/src/sys/pal/uefi/mod.rs2
-rw-r--r--library/std/src/sys/pal/uefi/os.rs12
-rw-r--r--library/std/src/sys/pal/uefi/process.rs8
-rw-r--r--library/std/src/sys/pal/unix/fs.rs26
-rw-r--r--library/std/src/sys/pal/unix/l4re.rs2
-rw-r--r--library/std/src/sys/pal/unix/net.rs4
-rw-r--r--library/std/src/sys/pal/unix/os.rs101
-rw-r--r--library/std/src/sys/pal/unix/os/tests.rs25
-rw-r--r--library/std/src/sys/pal/unix/process/process_fuchsia.rs8
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs10
-rw-r--r--library/std/src/sys/pal/unix/process/process_vxworks.rs2
-rw-r--r--library/std/src/sys/pal/unix/thread.rs4
-rw-r--r--library/std/src/sys/pal/unix/time.rs2
-rw-r--r--library/std/src/sys/pal/unsupported/os.rs4
-rw-r--r--library/std/src/sys/pal/wasi/fs.rs7
-rw-r--r--library/std/src/sys/pal/wasip2/net.rs2
-rw-r--r--library/std/src/sys/pal/windows/args.rs4
-rw-r--r--library/std/src/sys/pal/windows/fs.rs20
-rw-r--r--library/std/src/sys/pal/windows/mod.rs2
-rw-r--r--library/std/src/sys/pal/windows/net.rs2
-rw-r--r--library/std/src/sys/pal/windows/process.rs13
-rw-r--r--library/std/src/sys/pal/windows/stdio.rs8
-rw-r--r--library/std/src/sys/pal/xous/net/dns.rs5
-rw-r--r--library/std/src/sys/pal/xous/net/tcplistener.rs36
-rw-r--r--library/std/src/sys/pal/xous/net/tcpstream.rs46
-rw-r--r--library/std/src/sys/pal/xous/net/udp.rs50
-rw-r--r--library/std/src/sys/pal/zkvm/os.rs4
-rw-r--r--library/std/src/sys/path/windows.rs2
-rw-r--r--library/std/src/sys/random/arc4random.rs2
-rw-r--r--library/std/src/sys/sync/once/queue.rs9
-rw-r--r--library/std/src/sys/sync/rwlock/queue.rs6
-rw-r--r--library/std/src/sys_common/fs.rs2
-rw-r--r--library/std/src/sys_common/net.rs4
-rw-r--r--library/std/src/thread/current.rs31
-rw-r--r--library/std/src/thread/local.rs30
-rw-r--r--library/std/src/thread/mod.rs15
-rw-r--r--library/std/src/thread/scoped.rs9
-rw-r--r--license-metadata.json269
-rw-r--r--src/bootstrap/Cargo.lock74
-rw-r--r--src/bootstrap/Cargo.toml4
-rw-r--r--src/bootstrap/defaults/config.compiler.toml3
-rw-r--r--src/bootstrap/defaults/config.dist.toml1
-rw-r--r--src/bootstrap/defaults/config.library.toml4
-rw-r--r--src/bootstrap/defaults/config.tools.toml3
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/run.rs9
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs108
-rw-r--r--src/bootstrap/src/core/build_steps/vendor.rs48
-rw-r--r--src/bootstrap/src/core/builder/mod.rs1
-rw-r--r--src/bootstrap/src/core/builder/tests.rs256
-rw-r--r--src/bootstrap/src/core/config/config.rs50
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/helpers.rs14
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile5
-rw-r--r--src/ci/github-actions/jobs.yml22
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/codegen-options/index.md13
-rw-r--r--src/doc/rustc/src/command-line-arguments.md2
-rw-r--r--src/doc/rustdoc/src/write-documentation/documentation-tests.md2
-rw-r--r--src/doc/unstable-book/src/language-features/asm-experimental-reg.md40
-rw-r--r--src/etc/completions/x.py.zsh460
-rw-r--r--src/etc/lldb_providers.py2
-rw-r--r--src/librustdoc/clean/mod.rs18
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/librustdoc/html/highlight.rs13
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_utils.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/neg_multiply.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_slicing.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs7
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs2
-rw-r--r--src/tools/collect-license-metadata/src/main.rs39
-rw-r--r--src/tools/collect-license-metadata/src/reuse.rs4
-rw-r--r--src/tools/compiletest/src/directive-list.rs1
-rw-r--r--src/tools/compiletest/src/header.rs5
-rw-r--r--src/tools/compiletest/src/runtest/pretty.rs16
-rw-r--r--src/tools/generate-copyright/src/cargo_metadata.rs5
-rw-r--r--src/tools/generate-copyright/src/main.rs157
-rw-r--r--src/tools/generate-copyright/templates/COPYRIGHT-library.html53
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/bin/miri.rs83
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs9
-rw-r--r--src/tools/miri/tests/pass/tls/windows-tls.rs18
-rw-r--r--src/tools/rustbook/Cargo.lock4
-rw-r--r--src/tools/rustbook/Cargo.toml2
-rw-r--r--src/tools/rustbook/src/main.rs31
-rw-r--r--src/tools/rustfmt/src/items.rs6
-rw-r--r--src/tools/rustfmt/src/spanned.rs6
-rw-r--r--src/tools/rustfmt/src/types.rs11
-rw-r--r--src/tools/rustfmt/tests/source/unsafe-field.rs16
-rw-r--r--src/tools/rustfmt/tests/target/unsafe-field.rs11
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--src/tools/tidy/src/style.rs22
-rw-r--r--src/version2
-rw-r--r--tests/assembly/asm/s390x-types.rs199
-rw-r--r--tests/auxiliary/minicore.rs1
-rw-r--r--tests/codegen/aarch64-softfloat.rs48
-rw-r--r--tests/codegen/asm/goto.rs38
-rw-r--r--tests/codegen/sanitizer/no-sanitize.rs10
-rw-r--r--tests/coverage/closure.cov-map18
-rw-r--r--tests/coverage/issue-84561.cov-map205
-rw-r--r--tests/coverage/no-core.cov-map9
-rw-r--r--tests/coverage/no-core.coverage13
-rw-r--r--tests/coverage/no-core.rs12
-rw-r--r--tests/crashes/124350.rs17
-rw-r--r--tests/crashes/124751.rs2
-rw-r--r--tests/crashes/125758.rs26
-rw-r--r--tests/crashes/126359.rs9
-rw-r--r--tests/crashes/127351.rs17
-rw-r--r--tests/crashes/127353.rs18
-rw-r--r--tests/crashes/127742.rs11
-rw-r--r--tests/crashes/129444.rs15
-rw-r--r--tests/crashes/130521.rs4
-rw-r--r--tests/crashes/131101.rs12
-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.diff9
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff9
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff9
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff9
-rw-r--r--tests/mir-opt/const_prop/slice_len.rs5
-rw-r--r--tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff12
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff2
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff10
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff10
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.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.dereferences.GVN.panic-abort.diff30
-rw-r--r--tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff30
-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.rs35
-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.subexpression_elimination.GVN.panic-abort.diff50
-rw-r--r--tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff50
-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/inline/issue_78442.bar.PostAnalysisNormalize.panic-abort.diff (renamed from tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff)4
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-unwind.diff (renamed from tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff)4
-rw-r--r--tests/mir-opt/inline/issue_78442.rs2
-rw-r--r--tests/mir-opt/pre-codegen/deref_nested_borrows.rs25
-rw-r--r--tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff42
-rw-r--r--tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff42
-rw-r--r--tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir29
-rw-r--r--tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir29
-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/run-make/avr-rjmp-offset/rmake.rs5
-rw-r--r--tests/run-make/crate-loading/rmake.rs46
-rw-r--r--tests/run-make/diagnostics-traits-from-duplicate-crates/minibevy.rs2
-rw-r--r--tests/run-make/diagnostics-traits-from-duplicate-crates/minirapier.rs1
-rw-r--r--tests/run-make/diagnostics-traits-from-duplicate-crates/repro.rs14
-rw-r--r--tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs45
-rw-r--r--tests/run-make/libstd-no-protected/rmake.rs63
-rw-r--r--tests/run-make/rustc-help/help-v.stdout2
-rw-r--r--tests/run-make/rustc-help/help.stdout2
-rw-r--r--tests/rustdoc-ui/2024-doctests-checks.rs3
-rw-r--r--tests/rustdoc-ui/2024-doctests-checks.stdout4
-rw-r--r--tests/rustdoc-ui/2024-doctests-crate-attribute.rs3
-rw-r--r--tests/rustdoc-ui/2024-doctests-crate-attribute.stdout4
-rw-r--r--tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs1
-rw-r--r--tests/rustdoc-ui/doctest/dead-code-2024.rs3
-rw-r--r--tests/rustdoc-ui/doctest/dead-code-2024.stdout10
-rw-r--r--tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs3
-rw-r--r--tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout6
-rw-r--r--tests/rustdoc-ui/doctest/merged-ignore-no_run.rs3
-rw-r--r--tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout4
-rw-r--r--tests/rustdoc-ui/doctest/standalone-warning-2024.rs3
-rw-r--r--tests/rustdoc-ui/doctest/standalone-warning-2024.stderr36
-rw-r--r--tests/rustdoc-ui/doctest/wrong-ast-2024.rs3
-rw-r--r--tests/rustdoc-ui/doctest/wrong-ast-2024.stdout14
-rw-r--r--tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs20
-rw-r--r--tests/rustdoc-ui/intra-doc/pub-proc-item.rs8
-rw-r--r--tests/rustdoc-ui/unable-fulfill-trait.rs1
-rw-r--r--tests/rustdoc-ui/unable-fulfill-trait.stderr13
-rw-r--r--tests/rustdoc/jump-to-def-prelude-types.rs23
-rw-r--r--tests/ui-fulldeps/obtain-borrowck.rs89
-rw-r--r--tests/ui-fulldeps/stable-mir/check_abi.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_allocation.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_attribute.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_binop.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_crate_defs.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_def_ty.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_defs.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_instance.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_intrinsics.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_item_kind.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_normalization.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_trait_queries.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_transform.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_ty_fold.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/compilation-result.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/projections.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/smir_visitor.rs1
-rw-r--r--tests/ui/abi/anon-extern-mod.rs1
-rw-r--r--tests/ui/abi/c-stack-as-value.rs1
-rw-r--r--tests/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs1
-rw-r--r--tests/ui/abi/cross-crate/duplicated-external-mods.rs1
-rw-r--r--tests/ui/abi/extern/extern-pass-empty.rs1
-rw-r--r--tests/ui/abi/foreign/invoke-external-foreign.rs1
-rw-r--r--tests/ui/alias-uninit-value.rs1
-rw-r--r--tests/ui/array-slice-vec/cast-in-array-size.rs1
-rw-r--r--tests/ui/array-slice-vec/empty-mutable-vec.rs1
-rw-r--r--tests/ui/array-slice-vec/issue-15730.rs1
-rw-r--r--tests/ui/array-slice-vec/issue-18425.rs1
-rw-r--r--tests/ui/array-slice-vec/match_arr_unknown_len.stderr5
-rw-r--r--tests/ui/array-slice-vec/mut-vstore-expr.rs1
-rw-r--r--tests/ui/array-slice-vec/vec-macro-with-brackets.rs1
-rw-r--r--tests/ui/array-slice-vec/vec-repeat-with-cast.rs1
-rw-r--r--tests/ui/array-slice-vec/vector-no-ann-2.rs1
-rw-r--r--tests/ui/asm/s390x/bad-reg.rs78
-rw-r--r--tests/ui/asm/s390x/bad-reg.s390x.stderr192
-rw-r--r--tests/ui/asm/s390x/bad-reg.s390x_vector.stderr328
-rw-r--r--tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr489
-rw-r--r--tests/ui/asm/x86_64/goto.rs64
-rw-r--r--tests/ui/asm/x86_64/goto.stderr4
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs1
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr10
-rw-r--r--tests/ui/associated-types/associated-types-binding-in-where-clause.rs1
-rw-r--r--tests/ui/associated-types/associated-types-conditional-dispatch.rs1
-rw-r--r--tests/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs1
-rw-r--r--tests/ui/associated-types/associated-types-duplicate-binding-in-env.rs1
-rw-r--r--tests/ui/associated-types/associated-types-eq-obj.rs1
-rw-r--r--tests/ui/associated-types/associated-types-issue-20371.rs1
-rw-r--r--tests/ui/associated-types/associated-types-nested-projections.rs1
-rw-r--r--tests/ui/associated-types/associated-types-nested-projections.stderr2
-rw-r--r--tests/ui/associated-types/associated-types-normalize-in-bounds-binding.rs1
-rw-r--r--tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs1
-rw-r--r--tests/ui/associated-types/associated-types-normalize-in-bounds.rs1
-rw-r--r--tests/ui/associated-types/associated-types-projection-in-object-type.rs1
-rw-r--r--tests/ui/associated-types/associated-types-projection-in-where-clause.rs1
-rw-r--r--tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs1
-rw-r--r--tests/ui/associated-types/associated-types-ref-from-struct.rs1
-rw-r--r--tests/ui/associated-types/associated-types-region-erasure-issue-20582.rs1
-rw-r--r--tests/ui/associated-types/associated-types-resolve-lifetime.rs1
-rw-r--r--tests/ui/associated-types/issue-19129-1.rs1
-rw-r--r--tests/ui/associated-types/issue-19129-2.rs1
-rw-r--r--tests/ui/associated-types/issue-20763-1.rs1
-rw-r--r--tests/ui/associated-types/issue-20763-2.rs1
-rw-r--r--tests/ui/associated-types/issue-21363.rs1
-rw-r--r--tests/ui/associated-types/issue-21726.rs1
-rw-r--r--tests/ui/associated-types/issue-22560.rs5
-rw-r--r--tests/ui/associated-types/issue-22560.stderr54
-rw-r--r--tests/ui/associated-types/issue-22828.rs1
-rw-r--r--tests/ui/associated-types/missing-associated-types.rs4
-rw-r--r--tests/ui/associated-types/missing-associated-types.stderr83
-rw-r--r--tests/ui/async-await/async-closures/fn-exception-target-features.stderr4
-rw-r--r--tests/ui/async-await/async-closures/fn-exception.stderr8
-rw-r--r--tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs14
-rw-r--r--tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr17
-rw-r--r--tests/ui/async-await/async-fn/edition-2015.stderr4
-rw-r--r--tests/ui/async-await/coroutine-desc.stderr6
-rw-r--r--tests/ui/async-await/edition-deny-async-fns-2015.stderr18
-rw-r--r--tests/ui/async-await/for-await-passthrough.rs1
-rw-r--r--tests/ui/async-await/suggest-switching-edition-on-await-cargo.rs8
-rw-r--r--tests/ui/async-await/suggest-switching-edition-on-await-cargo.stderr8
-rw-r--r--tests/ui/async-await/suggest-switching-edition-on-await.rs8
-rw-r--r--tests/ui/async-await/suggest-switching-edition-on-await.stderr8
-rw-r--r--tests/ui/attr-start.rs1
-rw-r--r--tests/ui/attributes/attr-before-view-item.rs1
-rw-r--r--tests/ui/attributes/attr-before-view-item2.rs1
-rw-r--r--tests/ui/attributes/attr-mix-new.rs1
-rw-r--r--tests/ui/attributes/method-attributes.rs1
-rw-r--r--tests/ui/attributes/no-sanitize.rs18
-rw-r--r--tests/ui/attributes/no-sanitize.stderr58
-rw-r--r--tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs1
-rw-r--r--tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr20
-rw-r--r--tests/ui/attributes/variant-attributes.rs1
-rw-r--r--tests/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs1
-rw-r--r--tests/ui/auxiliary/unsafe-fields-crate-dep.rs7
-rw-r--r--tests/ui/bench/issue-32062.rs1
-rw-r--r--tests/ui/binding/inconsistent-lifetime-mismatch.rs1
-rw-r--r--tests/ui/binding/match-naked-record-expr.rs1
-rw-r--r--tests/ui/binding/match-naked-record.rs1
-rw-r--r--tests/ui/binding/match-path.rs1
-rw-r--r--tests/ui/binding/match-pattern-simple.rs1
-rw-r--r--tests/ui/binding/match-phi.rs1
-rw-r--r--tests/ui/binding/match-range-static.rs1
-rw-r--r--tests/ui/binding/match-value-binding-in-guard-3291.rs1
-rw-r--r--tests/ui/binding/nil-pattern.rs1
-rw-r--r--tests/ui/binding/simple-generic-match.rs1
-rw-r--r--tests/ui/borrowck/borrowck-assign-to-subfield.rs1
-rw-r--r--tests/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs1
-rw-r--r--tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs1
-rw-r--r--tests/ui/borrowck/borrowck-lend-args.rs1
-rw-r--r--tests/ui/borrowck/borrowck-static-item-in-fn.rs1
-rw-r--r--tests/ui/borrowck/borrowck-trait-lifetime.rs1
-rw-r--r--tests/ui/borrowck/borrowck-uniq-via-ref.rs1
-rw-r--r--tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs1
-rw-r--r--tests/ui/box/new-box-syntax.rs1
-rw-r--r--tests/ui/box/new.rs1
-rw-r--r--tests/ui/box/unit/unique-containing-tag.rs1
-rw-r--r--tests/ui/box/unit/unique-create.rs1
-rw-r--r--tests/ui/box/unit/unique-drop-complex.rs1
-rw-r--r--tests/ui/box/unit/unique-generic-assign.rs1
-rw-r--r--tests/ui/box/unit/unique-init.rs1
-rw-r--r--tests/ui/box/unit/unique-match-discrim.rs1
-rw-r--r--tests/ui/box/unit/unique-object-move.rs1
-rw-r--r--tests/ui/builtin-superkinds/builtin-superkinds-phantom-typaram.rs1
-rw-r--r--tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs1
-rw-r--r--tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs1
-rw-r--r--tests/ui/can-copy-pod.rs1
-rw-r--r--tests/ui/cancel-clean-via-immediate-rvalue-ref.rs1
-rw-r--r--tests/ui/cfg/cfg-attr-cfg.rs1
-rw-r--r--tests/ui/cfg/cfg-attr-crate.rs1
-rw-r--r--tests/ui/cfg/cfg-family.rs1
-rw-r--r--tests/ui/cfg/cfg-match-arm.rs1
-rw-r--r--tests/ui/cfg/cfg-target-family.rs1
-rw-r--r--tests/ui/cfg/cfg_inner_static.rs1
-rw-r--r--tests/ui/cfg/conditional-compile-arch.rs1
-rw-r--r--tests/ui/cleanup-shortcircuit.rs1
-rw-r--r--tests/ui/closures/2229_closure_analysis/bad-pattern.stderr14
-rw-r--r--tests/ui/closures/issue-10682.rs1
-rw-r--r--tests/ui/closures/issue-1460.rs1
-rw-r--r--tests/ui/closures/issue-1460.stderr2
-rw-r--r--tests/ui/closures/issue-868.rs1
-rw-r--r--tests/ui/codegen/init-large-type.rs1
-rw-r--r--tests/ui/codemap_tests/huge_multispan_highlight.rs2
-rw-r--r--tests/ui/coercion/coerce-overloaded-autoderef.rs1
-rw-r--r--tests/ui/coercion/coerce-reborrow-imm-ptr-arg.rs1
-rw-r--r--tests/ui/coercion/coerce-reborrow-imm-vec-arg.rs1
-rw-r--r--tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr2
-rw-r--r--tests/ui/coercion/coerce-reborrow-mut-ptr-arg.rs1
-rw-r--r--tests/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs1
-rw-r--r--tests/ui/coercion/coerce-unify-return.rs1
-rw-r--r--tests/ui/coercion/coerce-unsize-subtype.rs1
-rw-r--r--tests/ui/coercion/issue-14589.rs1
-rw-r--r--tests/ui/coercion/issue-14589.stderr2
-rw-r--r--tests/ui/coherence/coherence-bigint-int.rs1
-rw-r--r--tests/ui/coherence/coherence-bigint-vecint.rs1
-rw-r--r--tests/ui/coherence/coherence-blanket.rs1
-rw-r--r--tests/ui/coherence/coherence-covered-type-parameter.rs1
-rw-r--r--tests/ui/coherence/coherence-iterator-vec-any-elem.rs1
-rw-r--r--tests/ui/coherence/coherence-iterator-vec.rs1
-rw-r--r--tests/ui/coherence/coherence-multidispatch-tuple.rs1
-rw-r--r--tests/ui/coherence/coherence-negative-impls-safe-rpass.rs1
-rw-r--r--tests/ui/coherence/fuzzing/best-obligation-ICE.rs20
-rw-r--r--tests/ui/coherence/fuzzing/best-obligation-ICE.stderr69
-rw-r--r--tests/ui/const-generics/const-arg-in-const-arg.min.stderr62
-rw-r--r--tests/ui/const-generics/const-arg-in-const-arg.rs1
-rw-r--r--tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr4
-rw-r--r--tests/ui/const-generics/generic-param-mismatch.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/bad-multiply.rs18
-rw-r--r--tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr18
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr16
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs18
-rw-r--r--tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr46
-rw-r--r--tests/ui/const-generics/kind_mismatch.rs1
-rw-r--r--tests/ui/const-generics/kind_mismatch.stderr24
-rw-r--r--tests/ui/const-generics/not_wf_param_in_rpitit.rs3
-rw-r--r--tests/ui/const-generics/not_wf_param_in_rpitit.stderr76
-rw-r--r--tests/ui/consts/array-literal-len-mismatch.stderr2
-rw-r--r--tests/ui/consts/bad-array-size-in-type-err.rs10
-rw-r--r--tests/ui/consts/bad-array-size-in-type-err.stderr21
-rw-r--r--tests/ui/consts/const-array-oob-arith.rs4
-rw-r--r--tests/ui/consts/const-array-oob-arith.stderr4
-rw-r--r--tests/ui/consts/const-block-const-bound.rs2
-rw-r--r--tests/ui/consts/const-block-const-bound.stderr28
-rw-r--r--tests/ui/consts/const-bound.rs1
-rw-r--r--tests/ui/consts/const-eval/float_methods.rs1
-rw-r--r--tests/ui/consts/const-expr-in-fixed-length-vec.rs1
-rw-r--r--tests/ui/consts/const-expr-in-vec-repeat.rs1
-rw-r--r--tests/ui/consts/const-match-check.eval1.stderr2
-rw-r--r--tests/ui/consts/const-match-check.eval2.stderr2
-rw-r--r--tests/ui/consts/const-match-check.matchck.stderr8
-rw-r--r--tests/ui/consts/const-pattern-irrefutable.stderr8
-rw-r--r--tests/ui/consts/const-struct-offsets.rs1
-rw-r--r--tests/ui/consts/const-unit-struct.rs1
-rw-r--r--tests/ui/consts/const-vec-of-fns.rs1
-rw-r--r--tests/ui/consts/const-vec-syntax.rs1
-rw-r--r--tests/ui/consts/control-flow/drop-fail.precise.stderr10
-rw-r--r--tests/ui/consts/control-flow/drop-fail.rs1
-rw-r--r--tests/ui/consts/control-flow/drop-fail.stock.stderr8
-rw-r--r--tests/ui/consts/drop_zst.stderr2
-rw-r--r--tests/ui/consts/fn_trait_refs.rs1
-rw-r--r--tests/ui/consts/fn_trait_refs.stderr162
-rw-r--r--tests/ui/consts/issue-13837.rs1
-rw-r--r--tests/ui/consts/promoted-const-drop.rs1
-rw-r--r--tests/ui/consts/promoted-const-drop.stderr15
-rw-r--r--tests/ui/consts/promoted_const_call.stderr34
-rw-r--r--tests/ui/consts/promoted_const_call2.stderr4
-rw-r--r--tests/ui/consts/qualif-indirect-mutation-fail.stderr25
-rw-r--r--tests/ui/consts/too_generic_eval_ice.rs1
-rw-r--r--tests/ui/consts/too_generic_eval_ice.stderr10
-rw-r--r--tests/ui/coroutine/async_gen_fn.none.stderr2
-rw-r--r--tests/ui/coroutine/async_gen_fn.rs2
-rw-r--r--tests/ui/coroutine/async_gen_fn_iter.rs1
-rw-r--r--tests/ui/coroutine/break-inside-coroutine-issue-124495.rs1
-rw-r--r--tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr14
-rw-r--r--tests/ui/coroutine/const_gen_fn.rs1
-rw-r--r--tests/ui/coroutine/const_gen_fn.stderr4
-rw-r--r--tests/ui/coroutine/gen_block.rs2
-rw-r--r--tests/ui/coroutine/gen_block_is_coro.rs3
-rw-r--r--tests/ui/coroutine/gen_block_is_coro.stderr24
-rw-r--r--tests/ui/coroutine/gen_block_is_fused_iter.rs2
-rw-r--r--tests/ui/coroutine/gen_block_is_iter.rs2
-rw-r--r--tests/ui/coroutine/gen_block_is_no_future.rs2
-rw-r--r--tests/ui/coroutine/gen_block_iterate.rs2
-rw-r--r--tests/ui/coroutine/gen_block_move.fixed2
-rw-r--r--tests/ui/coroutine/gen_block_move.rs2
-rw-r--r--tests/ui/coroutine/gen_block_panic.rs2
-rw-r--r--tests/ui/coroutine/gen_fn.rs2
-rw-r--r--tests/ui/coroutine/gen_fn_iter.rs1
-rw-r--r--tests/ui/coroutine/gen_fn_lifetime_capture.rs1
-rw-r--r--tests/ui/coroutine/other-attribute-on-gen.rs1
-rw-r--r--tests/ui/coroutine/return-types-diverge.rs2
-rw-r--r--tests/ui/coroutine/return-types.rs2
-rw-r--r--tests/ui/coroutine/self_referential_gen_block.rs2
-rw-r--r--tests/ui/crate-leading-sep.rs1
-rw-r--r--tests/ui/crate-method-reexport-grrrrrrr.rs1
-rw-r--r--tests/ui/crate-name-attr-used.rs1
-rw-r--r--tests/ui/cross-crate/cci_capture_clause.rs1
-rw-r--r--tests/ui/cross-crate/cross-crate-const-pat.rs1
-rw-r--r--tests/ui/cross-crate/moves-based-on-type-cross-crate.rs1
-rw-r--r--tests/ui/cross-crate/static-addresses.rs1
-rw-r--r--tests/ui/cross-crate/trait-lifetime-param.rs1
-rw-r--r--tests/ui/cross-crate/unit-struct-2.rs1
-rw-r--r--tests/ui/default-method-parsing.rs1
-rw-r--r--tests/ui/deref.rs1
-rw-r--r--tests/ui/deriving/deriving-clone-enum.rs1
-rw-r--r--tests/ui/deriving/deriving-clone-generic-enum.rs1
-rw-r--r--tests/ui/deriving/deriving-clone-generic-struct.rs1
-rw-r--r--tests/ui/deriving/deriving-clone-generic-tuple-struct.rs1
-rw-r--r--tests/ui/deriving/deriving-clone-struct.rs1
-rw-r--r--tests/ui/deriving/deriving-clone-tuple-struct.rs1
-rw-r--r--tests/ui/deriving/deriving-enum-single-variant.rs1
-rw-r--r--tests/ui/deriving/deriving-in-macro.rs1
-rw-r--r--tests/ui/deriving/deriving-meta-multiple.rs1
-rw-r--r--tests/ui/deriving/deriving-meta.rs1
-rw-r--r--tests/ui/deriving/deriving-via-extension-hash-struct.rs1
-rw-r--r--tests/ui/deriving/issue-15689-2.rs1
-rw-r--r--tests/ui/deriving/issue-6341.rs1
-rw-r--r--tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr2
-rw-r--r--tests/ui/diagnostic-width/E0271.rs2
-rw-r--r--tests/ui/diagnostic-width/flag-human.rs2
-rw-r--r--tests/ui/diagnostic-width/long-E0308.rs2
-rw-r--r--tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs2
-rw-r--r--tests/ui/diagnostic-width/non-whitespace-trimming-2.rs2
-rw-r--r--tests/ui/double-ref.rs1
-rw-r--r--tests/ui/drop/auxiliary/edition-2024-macros.rs1
-rw-r--r--tests/ui/drop/drop-on-empty-block-exit.rs1
-rw-r--r--tests/ui/drop/drop-on-ret.rs1
-rw-r--r--tests/ui/drop/drop-uninhabited-enum.rs1
-rw-r--r--tests/ui/drop/drop_order_if_let_rescope.rs2
-rw-r--r--tests/ui/drop/if-let-rescope-borrowck-suggestions.rs2
-rw-r--r--tests/ui/drop/issue-10028.rs1
-rw-r--r--tests/ui/drop/issue-2734.rs1
-rw-r--r--tests/ui/drop/issue-2735.rs1
-rw-r--r--tests/ui/drop/lint-tail-expr-drop-order-gated.rs1
-rw-r--r--tests/ui/drop/nondrop-cycle.rs1
-rw-r--r--tests/ui/drop/tail-expr-drop-order.rs2
-rw-r--r--tests/ui/drop/use_inline_dtor.rs1
-rw-r--r--tests/ui/dropck/cleanup-arm-conditional.rs1
-rw-r--r--tests/ui/dropck/const_drop_is_valid.rs8
-rw-r--r--tests/ui/dropck/const_drop_is_valid.stderr31
-rw-r--r--tests/ui/dupe-first-attr.rs1
-rw-r--r--tests/ui/dynamically-sized-types/dst-coercions.rs1
-rw-r--r--tests/ui/dynamically-sized-types/dst-coercions.stderr2
-rw-r--r--tests/ui/early-ret-binop-add.rs1
-rw-r--r--tests/ui/editions/async-block-2015.rs6
-rw-r--r--tests/ui/editions/async-block-2015.stderr6
-rw-r--r--tests/ui/editions/edition-cstr-2015-2018.rs8
-rw-r--r--tests/ui/editions/edition-cstr-2015-2018.stderr8
-rw-r--r--tests/ui/empty-allocation-rvalue-non-null.rs1
-rw-r--r--tests/ui/empty/empty-never-array.stderr2
-rw-r--r--tests/ui/enum/issue-1821.rs1
-rw-r--r--tests/ui/enum/issue-19340-1.rs1
-rw-r--r--tests/ui/enum/issue-19340-2.rs1
-rw-r--r--tests/ui/error-codes/E0005.stderr2
-rw-r--r--tests/ui/error-codes/E0746.stderr7
-rw-r--r--tests/ui/error-emitter/unicode-output.rs2
-rw-r--r--tests/ui/explicit-i-suffix.rs1
-rw-r--r--tests/ui/expr/if/if-ret.rs1
-rw-r--r--tests/ui/expr/if/if-ret.stderr2
-rw-r--r--tests/ui/expr/scope.rs1
-rw-r--r--tests/ui/extern/extern-1.rs1
-rw-r--r--tests/ui/extern/extern-calling-convention-test.rs1
-rw-r--r--tests/ui/extern/extern-foreign-crate.rs1
-rw-r--r--tests/ui/extern/extern-mod-abi.rs1
-rw-r--r--tests/ui/extern/extern-mod-ordering-exe.rs1
-rw-r--r--tests/ui/extern/extern-pub.rs1
-rw-r--r--tests/ui/extern/extern-rust.rs1
-rw-r--r--tests/ui/extern/issue-10025.rs1
-rw-r--r--tests/ui/extern/issue-10763.rs1
-rw-r--r--tests/ui/extern/issue-10764-rpass.rs1
-rw-r--r--tests/ui/extern/issue-1251.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs23
-rw-r--r--tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr23
-rw-r--r--tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs13
-rw-r--r--tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-coroutines.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-gen_blocks.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-simd.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-simd.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe_fields.rs25
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr11
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr33
-rw-r--r--tests/ui/filter-block-view-items.rs1
-rw-r--r--tests/ui/fn/fn-item-type.stderr10
-rw-r--r--tests/ui/fn/issue-1451.rs1
-rw-r--r--tests/ui/fn/param-mismatch-no-names.rs8
-rw-r--r--tests/ui/fn/param-mismatch-no-names.stderr23
-rw-r--r--tests/ui/for-loop-while/break-value.rs1
-rw-r--r--tests/ui/for-loop-while/issue-1257.rs1
-rw-r--r--tests/ui/for-loop-while/labeled-break.rs1
-rw-r--r--tests/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs1
-rw-r--r--tests/ui/for-loop-while/liveness-move-in-loop.rs1
-rw-r--r--tests/ui/for-loop-while/long-while.rs1
-rw-r--r--tests/ui/for-loop-while/loop-diverges.rs1
-rw-r--r--tests/ui/for-loop-while/loop-label-shadowing.rs1
-rw-r--r--tests/ui/for-loop-while/loop-labeled-break-value.rs1
-rw-r--r--tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs1
-rw-r--r--tests/ui/for-loop-while/while-flow-graph.rs1
-rw-r--r--tests/ui/foreign/foreign-mod-unused-const.rs1
-rw-r--r--tests/ui/foreign/foreign2.rs1
-rw-r--r--tests/ui/foreign/nil-decl-in-foreign.rs1
-rw-r--r--tests/ui/fuel/optimization-fuel-0.rs17
-rw-r--r--tests/ui/fuel/optimization-fuel-0.stderr4
-rw-r--r--tests/ui/fuel/optimization-fuel-1.rs18
-rw-r--r--tests/ui/fuel/optimization-fuel-1.stderr4
-rw-r--r--tests/ui/fuel/print-fuel.rs13
-rw-r--r--tests/ui/fuel/print-fuel.stderr1
-rw-r--r--tests/ui/functions-closures/closure-bounds-can-capture-chan.rs1
-rw-r--r--tests/ui/functions-closures/fn-abi.rs1
-rw-r--r--tests/ui/functions-closures/fn-bare-coerce-to-block.rs1
-rw-r--r--tests/ui/functions-closures/fn-coerce-field.rs1
-rw-r--r--tests/ui/functions-closures/fn-item-type-coerce.rs1
-rw-r--r--tests/ui/functions-closures/fn-lval.rs1
-rw-r--r--tests/ui/functions-closures/fn-type-infer.rs1
-rw-r--r--tests/ui/generic-associated-types/issue-71176.rs4
-rw-r--r--tests/ui/generic-associated-types/issue-71176.stderr19
-rw-r--r--tests/ui/generics/generic-default-type-params-cross-crate.rs1
-rw-r--r--tests/ui/generics/generic-fn-twice.rs1
-rw-r--r--tests/ui/generics/generic-newtype-struct.rs1
-rw-r--r--tests/ui/generics/generic-tag-corruption.rs1
-rw-r--r--tests/ui/generics/generic-tag-local.rs1
-rw-r--r--tests/ui/generics/generic-tag.rs1
-rw-r--r--tests/ui/generics/generic-type-synonym.rs1
-rw-r--r--tests/ui/generics/mid-path-type-params.rs1
-rw-r--r--tests/ui/generics/type-params-in-for-each.rs1
-rw-r--r--tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr2
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr2
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr4
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions1.stderr2
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions2.stderr2
-rw-r--r--tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr2
-rw-r--r--tests/ui/higher-ranked/builtin-closure-like-bounds.rs1
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs1
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs1
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs1
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs1
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs1
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs1
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs1
-rw-r--r--tests/ui/hygiene/issue-15221.rs1
-rw-r--r--tests/ui/impl-privacy-xc-1.rs1
-rw-r--r--tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr14
-rw-r--r--tests/ui/impl-trait/example-calendar.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs2
-rw-r--r--tests/ui/impl-trait/issues/issue-79099.stderr2
-rw-r--r--tests/ui/impl-trait/normalize-tait-in-const.rs2
-rw-r--r--tests/ui/impl-trait/normalize-tait-in-const.stderr29
-rw-r--r--tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr2
-rw-r--r--tests/ui/impl-trait/precise-capturing/auxiliary/foreign.rs1
-rw-r--r--tests/ui/impl-trait/precise-capturing/capturing-implicit.rs1
-rw-r--r--tests/ui/impl-trait/precise-capturing/capturing-implicit.stderr6
-rw-r--r--tests/ui/impl-trait/precise-capturing/external-macro.rs1
-rw-r--r--tests/ui/impl-trait/precise-capturing/foreign-2021.stderr2
-rw-r--r--tests/ui/impl-trait/precise-capturing/migration-note.rs1
-rw-r--r--tests/ui/impl-trait/precise-capturing/migration-note.stderr52
-rw-r--r--tests/ui/impl-trait/precise-capturing/redundant.rs2
-rw-r--r--tests/ui/impl-trait/transmute/in-defining-scope.rs4
-rw-r--r--tests/ui/impl-trait/unsized_coercion.next.stderr30
-rw-r--r--tests/ui/impl-trait/unsized_coercion.rs3
-rw-r--r--tests/ui/impl-trait/unsized_coercion3.next.stderr30
-rw-r--r--tests/ui/impl-trait/unsized_coercion3.old.stderr2
-rw-r--r--tests/ui/impl-trait/unsized_coercion3.rs2
-rw-r--r--tests/ui/imports/export-glob-imports-target.rs1
-rw-r--r--tests/ui/imports/export-multi.rs1
-rw-r--r--tests/ui/imports/import-crate-with-invalid-spans/main.rs1
-rw-r--r--tests/ui/imports/import-from.rs1
-rw-r--r--tests/ui/imports/import-in-block.rs1
-rw-r--r--tests/ui/imports/import-trailing-comma.rs1
-rw-r--r--tests/ui/imports/reexport-star.rs1
-rw-r--r--tests/ui/imports/use-mod.rs1
-rw-r--r--tests/ui/inference/array-len-mismatch.stderr4
-rw-r--r--tests/ui/inference/infer-fn-tail-expr.rs1
-rw-r--r--tests/ui/inference/newlambdas-ret-infer.rs1
-rw-r--r--tests/ui/inference/newlambdas-ret-infer2.rs1
-rw-r--r--tests/ui/invalid-compile-flags/fuel.rs11
-rw-r--r--tests/ui/issue-15924.rs1
-rw-r--r--tests/ui/issues/issue-10228.rs1
-rw-r--r--tests/ui/issues/issue-10456.rs1
-rw-r--r--tests/ui/issues/issue-10638.rs1
-rw-r--r--tests/ui/issues/issue-10683.rs1
-rw-r--r--tests/ui/issues/issue-10718.rs1
-rw-r--r--tests/ui/issues/issue-10767.rs1
-rw-r--r--tests/ui/issues/issue-10806.rs1
-rw-r--r--tests/ui/issues/issue-10853.rs1
-rw-r--r--tests/ui/issues/issue-10902.rs1
-rw-r--r--tests/ui/issues/issue-11085.rs1
-rw-r--r--tests/ui/issues/issue-11205.rs1
-rw-r--r--tests/ui/issues/issue-11224.rs1
-rw-r--r--tests/ui/issues/issue-11384.rs1
-rw-r--r--tests/ui/issues/issue-11529.rs1
-rw-r--r--tests/ui/issues/issue-11820.rs1
-rw-r--r--tests/ui/issues/issue-11869.rs1
-rw-r--r--tests/ui/issues/issue-12612.rs1
-rw-r--r--tests/ui/issues/issue-12660.rs1
-rw-r--r--tests/ui/issues/issue-12729.rs1
-rw-r--r--tests/ui/issues/issue-12909.rs1
-rw-r--r--tests/ui/issues/issue-13105.rs1
-rw-r--r--tests/ui/issues/issue-13167.rs1
-rw-r--r--tests/ui/issues/issue-13214.rs1
-rw-r--r--tests/ui/issues/issue-13405.rs1
-rw-r--r--tests/ui/issues/issue-13620.rs1
-rw-r--r--tests/ui/issues/issue-13665.rs1
-rw-r--r--tests/ui/issues/issue-13703.rs1
-rw-r--r--tests/ui/issues/issue-13763.rs1
-rw-r--r--tests/ui/issues/issue-13775.rs1
-rw-r--r--tests/ui/issues/issue-13808.rs1
-rw-r--r--tests/ui/issues/issue-14082.rs1
-rw-r--r--tests/ui/issues/issue-14254.rs1
-rw-r--r--tests/ui/issues/issue-14330.rs1
-rw-r--r--tests/ui/issues/issue-14393.rs1
-rw-r--r--tests/ui/issues/issue-14399.rs1
-rw-r--r--tests/ui/issues/issue-14399.stderr2
-rw-r--r--tests/ui/issues/issue-14421.rs1
-rw-r--r--tests/ui/issues/issue-14422.rs1
-rw-r--r--tests/ui/issues/issue-14919.rs1
-rw-r--r--tests/ui/issues/issue-14959.rs1
-rw-r--r--tests/ui/issues/issue-15043.rs1
-rw-r--r--tests/ui/issues/issue-15444.rs1
-rw-r--r--tests/ui/issues/issue-15562.rs1
-rw-r--r--tests/ui/issues/issue-15774.rs1
-rw-r--r--tests/ui/issues/issue-16256.rs1
-rw-r--r--tests/ui/issues/issue-16256.stderr2
-rw-r--r--tests/ui/issues/issue-16441.rs1
-rw-r--r--tests/ui/issues/issue-16452.rs1
-rw-r--r--tests/ui/issues/issue-16643.rs1
-rw-r--r--tests/ui/issues/issue-16783.rs1
-rw-r--r--tests/ui/issues/issue-16922-rpass.rs1
-rw-r--r--tests/ui/issues/issue-17121.rs1
-rw-r--r--tests/ui/issues/issue-17322.rs1
-rw-r--r--tests/ui/issues/issue-17351.rs1
-rw-r--r--tests/ui/issues/issue-17351.stderr2
-rw-r--r--tests/ui/issues/issue-17361.rs1
-rw-r--r--tests/ui/issues/issue-17732.rs1
-rw-r--r--tests/ui/issues/issue-17771.rs1
-rw-r--r--tests/ui/issues/issue-17904.rs1
-rw-r--r--tests/ui/issues/issue-18110.rs1
-rw-r--r--tests/ui/issues/issue-18188.rs1
-rw-r--r--tests/ui/issues/issue-18232.rs1
-rw-r--r--tests/ui/issues/issue-18353.rs1
-rw-r--r--tests/ui/issues/issue-18501.rs1
-rw-r--r--tests/ui/issues/issue-18539.rs1
-rw-r--r--tests/ui/issues/issue-18685.rs1
-rw-r--r--tests/ui/issues/issue-18711.rs1
-rw-r--r--tests/ui/issues/issue-18906.rs1
-rw-r--r--tests/ui/issues/issue-19037.rs1
-rw-r--r--tests/ui/issues/issue-19127.rs1
-rw-r--r--tests/ui/issues/issue-19293.rs1
-rw-r--r--tests/ui/issues/issue-19398.rs1
-rw-r--r--tests/ui/issues/issue-19479.rs1
-rw-r--r--tests/ui/issues/issue-19499.rs1
-rw-r--r--tests/ui/issues/issue-19631.rs1
-rw-r--r--tests/ui/issues/issue-19632.rs1
-rw-r--r--tests/ui/issues/issue-19850.rs1
-rw-r--r--tests/ui/issues/issue-20009.rs1
-rw-r--r--tests/ui/issues/issue-20313-rpass.rs1
-rw-r--r--tests/ui/issues/issue-20389.rs1
-rw-r--r--tests/ui/issues/issue-20396.rs1
-rw-r--r--tests/ui/issues/issue-20414.rs1
-rw-r--r--tests/ui/issues/issue-20575.rs1
-rw-r--r--tests/ui/issues/issue-20644.rs1
-rw-r--r--tests/ui/issues/issue-2074.rs1
-rw-r--r--tests/ui/issues/issue-21033.rs1
-rw-r--r--tests/ui/issues/issue-21245.rs1
-rw-r--r--tests/ui/issues/issue-21402.rs1
-rw-r--r--tests/ui/issues/issue-2170-exe.rs1
-rw-r--r--tests/ui/issues/issue-21891.rs1
-rw-r--r--tests/ui/issues/issue-2190-1.rs1
-rw-r--r--tests/ui/issues/issue-21909.rs1
-rw-r--r--tests/ui/issues/issue-22346.rs1
-rw-r--r--tests/ui/issues/issue-22356.rs1
-rw-r--r--tests/ui/issues/issue-22426.rs1
-rw-r--r--tests/ui/issues/issue-22577.rs1
-rw-r--r--tests/ui/issues/issue-22629.rs1
-rw-r--r--tests/ui/issues/issue-22777.rs1
-rw-r--r--tests/ui/issues/issue-2284.rs1
-rw-r--r--tests/ui/issues/issue-23024.rs1
-rw-r--r--tests/ui/issues/issue-23024.stderr10
-rw-r--r--tests/ui/issues/issue-2311.rs1
-rw-r--r--tests/ui/issues/issue-2316-c.rs1
-rw-r--r--tests/ui/issues/issue-2380-b.rs1
-rw-r--r--tests/ui/issues/issue-2383.rs1
-rw-r--r--tests/ui/issues/issue-2414-c.rs1
-rw-r--r--tests/ui/issues/issue-2445-b.rs1
-rw-r--r--tests/ui/issues/issue-2445.rs1
-rw-r--r--tests/ui/issues/issue-2463.rs1
-rw-r--r--tests/ui/issues/issue-2472.rs1
-rw-r--r--tests/ui/issues/issue-2487-a.rs1
-rw-r--r--tests/ui/issues/issue-2502.rs1
-rw-r--r--tests/ui/issues/issue-2526-a.rs1
-rw-r--r--tests/ui/issues/issue-2550.rs1
-rw-r--r--tests/ui/issues/issue-25901.rs2
-rw-r--r--tests/ui/issues/issue-25901.stderr20
-rw-r--r--tests/ui/issues/issue-2642.rs1
-rw-r--r--tests/ui/issues/issue-2708.rs1
-rw-r--r--tests/ui/issues/issue-3012-2.rs1
-rw-r--r--tests/ui/issues/issue-3026.rs1
-rw-r--r--tests/ui/issues/issue-3037.rs1
-rw-r--r--tests/ui/issues/issue-3052.rs1
-rw-r--r--tests/ui/issues/issue-3136-b.rs1
-rw-r--r--tests/ui/issues/issue-3149.rs1
-rw-r--r--tests/ui/issues/issue-3220.rs1
-rw-r--r--tests/ui/issues/issue-3429.rs1
-rw-r--r--tests/ui/issues/issue-34373.rs1
-rw-r--r--tests/ui/issues/issue-34373.stderr30
-rw-r--r--tests/ui/issues/issue-3500.rs1
-rw-r--r--tests/ui/issues/issue-3656.rs1
-rw-r--r--tests/ui/issues/issue-3874.rs1
-rw-r--r--tests/ui/issues/issue-3888-2.rs1
-rw-r--r--tests/ui/issues/issue-39211.rs1
-rw-r--r--tests/ui/issues/issue-39211.stderr10
-rw-r--r--tests/ui/issues/issue-3979-2.rs1
-rw-r--r--tests/ui/issues/issue-3991.rs1
-rw-r--r--tests/ui/issues/issue-4208.rs1
-rw-r--r--tests/ui/issues/issue-4228.rs1
-rw-r--r--tests/ui/issues/issue-4333.rs1
-rw-r--r--tests/ui/issues/issue-4387.rs1
-rw-r--r--tests/ui/issues/issue-4464.rs1
-rw-r--r--tests/ui/issues/issue-4542.rs1
-rw-r--r--tests/ui/issues/issue-4545.rs1
-rw-r--r--tests/ui/issues/issue-4735.rs1
-rw-r--r--tests/ui/issues/issue-4759.rs1
-rw-r--r--tests/ui/issues/issue-48006.rs4
-rw-r--r--tests/ui/issues/issue-4830.rs1
-rw-r--r--tests/ui/issues/issue-4875.rs1
-rw-r--r--tests/ui/issues/issue-5192.rs1
-rw-r--r--tests/ui/issues/issue-5315.rs1
-rw-r--r--tests/ui/issues/issue-5518.rs1
-rw-r--r--tests/ui/issues/issue-5550.rs1
-rw-r--r--tests/ui/issues/issue-5554.rs1
-rw-r--r--tests/ui/issues/issue-55587.stderr2
-rw-r--r--tests/ui/issues/issue-5572.rs1
-rw-r--r--tests/ui/issues/issue-5718.rs1
-rw-r--r--tests/ui/issues/issue-5741.rs1
-rw-r--r--tests/ui/issues/issue-5754.rs1
-rw-r--r--tests/ui/issues/issue-5884.rs1
-rw-r--r--tests/ui/issues/issue-5900.rs1
-rw-r--r--tests/ui/issues/issue-5950.rs1
-rw-r--r--tests/ui/issues/issue-5988.rs1
-rw-r--r--tests/ui/issues/issue-6117.rs1
-rw-r--r--tests/ui/issues/issue-6318.rs1
-rw-r--r--tests/ui/issues/issue-6557.rs1
-rw-r--r--tests/ui/issues/issue-6898.rs1
-rw-r--r--tests/ui/issues/issue-6919.rs1
-rw-r--r--tests/ui/issues/issue-7178.rs1
-rw-r--r--tests/ui/issues/issue-7268.rs1
-rw-r--r--tests/ui/issues/issue-7344.rs1
-rw-r--r--tests/ui/issues/issue-7519-match-unit-in-arg.rs1
-rw-r--r--tests/ui/issues/issue-7660.rs1
-rw-r--r--tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs1
-rw-r--r--tests/ui/issues/issue-7899.rs1
-rw-r--r--tests/ui/issues/issue-8044.rs1
-rw-r--r--tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs1
-rw-r--r--tests/ui/issues/issue-8248.rs1
-rw-r--r--tests/ui/issues/issue-8248.stderr2
-rw-r--r--tests/ui/issues/issue-8249.rs1
-rw-r--r--tests/ui/issues/issue-8259.rs1
-rw-r--r--tests/ui/issues/issue-8398.rs1
-rw-r--r--tests/ui/issues/issue-8401.rs1
-rw-r--r--tests/ui/issues/issue-8506.rs1
-rw-r--r--tests/ui/issues/issue-8578.rs1
-rw-r--r--tests/ui/issues/issue-8783.rs1
-rw-r--r--tests/ui/issues/issue-9110.rs1
-rw-r--r--tests/ui/issues/issue-9123.rs1
-rw-r--r--tests/ui/issues/issue-9155.rs1
-rw-r--r--tests/ui/issues/issue-9249.rs1
-rw-r--r--tests/ui/issues/issue-9382.rs3
-rw-r--r--tests/ui/issues/issue-9719.rs1
-rw-r--r--tests/ui/issues/issue-9906.rs1
-rw-r--r--tests/ui/issues/issue-9942.rs1
-rw-r--r--tests/ui/issues/issue-9951.rs1
-rw-r--r--tests/ui/issues/issue-9951.stderr2
-rw-r--r--tests/ui/issues/issue-9968.rs1
-rw-r--r--tests/ui/item-name-overload.rs1
-rw-r--r--tests/ui/iterators/into-iter-on-boxed-slices-2024.rs1
-rw-r--r--tests/ui/iterators/into-iterator-type-inference-shift.rs1
-rw-r--r--tests/ui/kinds-in-metadata.rs1
-rw-r--r--tests/ui/layout/aggregate-lang/struct-align.rs29
-rw-r--r--tests/ui/layout/aggregate-lang/struct-offsets.rs78
-rw-r--r--tests/ui/layout/aggregate-lang/struct-size.rs50
-rw-r--r--tests/ui/layout/aggregate-lang/union-align.rs29
-rw-r--r--tests/ui/layout/aggregate-lang/union-offsets.rs32
-rw-r--r--tests/ui/layout/aggregate-lang/union-size.rs47
-rw-r--r--tests/ui/layout/ice-type-error-in-tail-124031.rs3
-rw-r--r--tests/ui/layout/ice-type-error-in-tail-124031.stderr16
-rw-r--r--tests/ui/lazy-type-alias/bad-lazy-type-alias.rs18
-rw-r--r--tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr28
-rw-r--r--tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr2
-rw-r--r--tests/ui/lifetimes/tail-expr-in-nested-expr.rs1
-rw-r--r--tests/ui/lifetimes/tail-expr-in-nested-expr.stderr2
-rw-r--r--tests/ui/linkage-attr/issue-12133-1.rs1
-rw-r--r--tests/ui/linkage-attr/issue-12133-2.rs1
-rw-r--r--tests/ui/linkage-attr/issue-12133-3.rs1
-rw-r--r--tests/ui/lint/dead-code/leading-underscore.rs1
-rw-r--r--tests/ui/lint/issue-14837.rs1
-rw-r--r--tests/ui/lint/issue-1866.rs1
-rw-r--r--tests/ui/lint/issue-1866.stderr2
-rw-r--r--tests/ui/lint/issue-20343.rs1
-rw-r--r--tests/ui/lint/issue-79546-fuel-ice.rs8
-rw-r--r--tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs1
-rw-r--r--tests/ui/lint/non-snake-case/lint-non-snake-case-no-lowercase-equivalent.rs1
-rw-r--r--tests/ui/lint/warn-ctypes-inhibit.rs1
-rw-r--r--tests/ui/list.rs1
-rw-r--r--tests/ui/liveness/liveness-assign-imm-local-after-ret.rs1
-rw-r--r--tests/ui/loops/issue-1974.rs1
-rw-r--r--tests/ui/loops/loop-else-break-with-value.stderr2
-rw-r--r--tests/ui/macros/defined-later-issue-121061-2.stderr2
-rw-r--r--tests/ui/macros/defined-later-issue-121061.stderr2
-rw-r--r--tests/ui/macros/expr_2021_implicit_in_2024.rs2
-rw-r--r--tests/ui/macros/expr_2021_inline_const.rs4
-rw-r--r--tests/ui/macros/expr_2024_underscore_expr.rs4
-rw-r--r--tests/ui/macros/issue-8851.rs1
-rw-r--r--tests/ui/macros/log_syntax-trace_macros-macro-locations.rs1
-rw-r--r--tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs1
-rw-r--r--tests/ui/macros/macro-nt-list.rs1
-rw-r--r--tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs9
-rw-r--r--tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr42
-rw-r--r--tests/ui/macros/macro_with_super_2.rs1
-rw-r--r--tests/ui/macros/metavar_cross_edition_recursive_macros.rs2
-rw-r--r--tests/ui/macros/parse-complex-macro-invoc-op.rs1
-rw-r--r--tests/ui/macros/pub-item-inside-macro.rs1
-rw-r--r--tests/ui/macros/pub-method-inside-macro.rs1
-rw-r--r--tests/ui/match/match-fn-call.stderr4
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs1
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr20
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs1
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr32
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr36
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs1
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr34
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs1
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr4
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed1
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs1
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr10
-rw-r--r--tests/ui/methods/method-early-bound-lifetimes-on-self.rs1
-rw-r--r--tests/ui/methods/method-normalize-bounds-issue-20604.rs1
-rw-r--r--tests/ui/methods/method-recursive-blanket-impl.rs1
-rw-r--r--tests/ui/methods/method-recursive-blanket-impl.stderr2
-rw-r--r--tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs1
-rw-r--r--tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr2
-rw-r--r--tests/ui/mir-dataflow/def-inits-1.rs51
-rw-r--r--tests/ui/mir-dataflow/def-inits-1.stderr28
-rw-r--r--tests/ui/mir/issue-112269.stderr4
-rw-r--r--tests/ui/mir/validate/needs-reveal-all.rs4
-rw-r--r--tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr10
-rw-r--r--tests/ui/modules/issue-13872.rs1
-rw-r--r--tests/ui/modules/mod-view-items.rs1
-rw-r--r--tests/ui/moves/move-nullary-fn.rs1
-rw-r--r--tests/ui/multiline-comment.rs1
-rw-r--r--tests/ui/mutual-recursion-group.rs1
-rw-r--r--tests/ui/nested-block-comment.rs1
-rw-r--r--tests/ui/never_type/exhaustive_patterns.stderr2
-rw-r--r--tests/ui/never_type/expr-empty-ret.rs1
-rw-r--r--tests/ui/nll/user-annotations/region-error-ice-109072.rs1
-rw-r--r--tests/ui/nll/user-annotations/region-error-ice-109072.stderr11
-rw-r--r--tests/ui/numbers-arithmetic/int.rs1
-rw-r--r--tests/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs1
-rw-r--r--tests/ui/numbers-arithmetic/integer-literal-suffix-inference.rs1
-rw-r--r--tests/ui/numbers-arithmetic/uint.rs1
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs1
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs1
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs1
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs1
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs1
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs1
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-inferred.rs1
-rw-r--r--tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr2
-rw-r--r--tests/ui/output-slot-variants.rs1
-rw-r--r--tests/ui/overloaded/fixup-deref-mut.rs1
-rw-r--r--tests/ui/overloaded/issue-14958.rs1
-rw-r--r--tests/ui/overloaded/issue-14958.stderr2
-rw-r--r--tests/ui/overloaded/overloaded-calls-param-vtables.rs1
-rw-r--r--tests/ui/panic-handler/weak-lang-item-2.rs1
-rw-r--r--tests/ui/parser/bad-name.stderr2
-rw-r--r--tests/ui/parser/help-set-edition-ice-122130.stderr2
-rw-r--r--tests/ui/parser/issues/issue-21475.rs1
-rw-r--r--tests/ui/parser/issues/issue-24197.stderr2
-rw-r--r--tests/ui/parser/issues/issue-24375.stderr2
-rw-r--r--tests/ui/parser/issues/issue-7222.rs1
-rw-r--r--tests/ui/parser/parse-assoc-type-lt.rs1
-rw-r--r--tests/ui/parser/pat-lt-bracket-5.stderr2
-rw-r--r--tests/ui/parser/pat-lt-bracket-6.stderr2
-rw-r--r--tests/ui/parser/pat-ranges-3.stderr4
-rw-r--r--tests/ui/parser/recover/recover-pat-exprs.stderr66
-rw-r--r--tests/ui/parser/recover/recover-pat-issues.stderr12
-rw-r--r--tests/ui/parser/recover/recover-pat-lets.stderr10
-rw-r--r--tests/ui/parser/recover/recover-pat-ranges.stderr12
-rw-r--r--tests/ui/parser/recover/recover-pat-wildcards.stderr2
-rw-r--r--tests/ui/parser/recover/recover-range-pats.stderr18
-rw-r--r--tests/ui/path.rs1
-rw-r--r--tests/ui/pattern/fn-in-pat.stderr2
-rw-r--r--tests/ui/pattern/issue-106552.stderr4
-rw-r--r--tests/ui/pattern/mut_preserve_binding_mode_2024.rs1
-rw-r--r--tests/ui/pattern/pattern-binding-disambiguation.stderr2
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs1
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs1
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr28
-rw-r--r--tests/ui/pattern/self-ctor-133272.rs21
-rw-r--r--tests/ui/pattern/self-ctor-133272.stderr15
-rw-r--r--tests/ui/pattern/skipped-ref-pats-issue-125058.rs1
-rw-r--r--tests/ui/pattern/skipped-ref-pats-issue-125058.stderr4
-rw-r--r--tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr2
-rw-r--r--tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr2
-rw-r--r--tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr2
-rw-r--r--tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr4
-rw-r--r--tests/ui/pattern/usefulness/empty-types.never_pats.stderr6
-rw-r--r--tests/ui/pattern/usefulness/empty-types.normal.stderr6
-rw-r--r--tests/ui/pattern/usefulness/irrefutable-unit.rs1
-rw-r--r--tests/ui/pattern/usefulness/issue-31561.stderr2
-rw-r--r--tests/ui/pattern/usefulness/nested-exhaustive-match.rs1
-rw-r--r--tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs8
-rw-r--r--tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr8
-rw-r--r--tests/ui/pattern/usefulness/refutable-pattern-errors.stderr2
-rw-r--r--tests/ui/privacy/priv-impl-prim-ty.rs1
-rw-r--r--tests/ui/privacy/privacy-ns.rs1
-rw-r--r--tests/ui/privacy/privacy-reexport.rs1
-rw-r--r--tests/ui/privacy/privacy1-rpass.rs1
-rw-r--r--tests/ui/privacy/private-method-rpass.rs1
-rw-r--r--tests/ui/privacy/pub-extern-privacy.rs1
-rw-r--r--tests/ui/privacy/pub-use-xcrate.rs1
-rw-r--r--tests/ui/privacy/pub_use_mods_xcrate_exe.rs1
-rw-r--r--tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs42
-rw-r--r--tests/ui/proc-macro/macro_rules_edition_from_pm.rs27
-rw-r--r--tests/ui/ptr-coercion-rpass.rs1
-rw-r--r--tests/ui/reachable/issue-11225-1.rs1
-rw-r--r--tests/ui/reachable/issue-11225-2.rs1
-rw-r--r--tests/ui/reachable/issue-11225-3.rs1
-rw-r--r--tests/ui/recursion/instantiable.rs1
-rw-r--r--tests/ui/recursion/recursive-types-are-not-uninhabited.stderr2
-rw-r--r--tests/ui/regions/issue-11612.rs1
-rw-r--r--tests/ui/regions/issue-21520.rs1
-rw-r--r--tests/ui/regions/issue-5243.rs1
-rw-r--r--tests/ui/regions/issue-6157.rs1
-rw-r--r--tests/ui/regions/owned-implies-static.rs1
-rw-r--r--tests/ui/regions/regions-addr-of-interior-of-unique-box.rs1
-rw-r--r--tests/ui/regions/regions-assoc-type-region-bound.rs1
-rw-r--r--tests/ui/regions/regions-assoc-type-static-bound.rs1
-rw-r--r--tests/ui/regions/regions-creating-enums2.rs1
-rw-r--r--tests/ui/regions/regions-creating-enums5.rs1
-rw-r--r--tests/ui/regions/regions-debruijn-of-object.rs1
-rw-r--r--tests/ui/regions/regions-dependent-autofn.rs1
-rw-r--r--tests/ui/regions/regions-dependent-let-ref.rs1
-rw-r--r--tests/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs1
-rw-r--r--tests/ui/regions/regions-expl-self.rs1
-rw-r--r--tests/ui/regions/regions-fn-subtyping-2.rs1
-rw-r--r--tests/ui/regions/regions-fn-subtyping.rs1
-rw-r--r--tests/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs1
-rw-r--r--tests/ui/regions/regions-infer-region-in-fn-but-not-type.rs1
-rw-r--r--tests/ui/regions/regions-infer-static-from-proc.rs1
-rw-r--r--tests/ui/regions/regions-issue-21422.rs1
-rw-r--r--tests/ui/regions/regions-issue-22246.rs1
-rw-r--r--tests/ui/regions/regions-lifetime-nonfree-late-bound.rs1
-rw-r--r--tests/ui/regions/regions-link-fn-args.rs1
-rw-r--r--tests/ui/regions/regions-mock-codegen.rs1
-rw-r--r--tests/ui/regions/regions-no-bound-in-argument-cleanup.rs1
-rw-r--r--tests/ui/regions/regions-nullary-variant.rs1
-rw-r--r--tests/ui/regions/regions-reassign-let-bound-pointer.rs1
-rw-r--r--tests/ui/regions/regions-reassign-match-bound-pointer.rs1
-rw-r--r--tests/ui/regions/regions-scope-chain-example.rs1
-rw-r--r--tests/ui/regions/regions-variance-contravariant-use-contravariant.rs1
-rw-r--r--tests/ui/regions/regions-variance-covariant-use-covariant.rs1
-rw-r--r--tests/ui/regions/wf-bound-region-in-object-type.rs1
-rw-r--r--tests/ui/resolve/blind-item-mixed-crate-use-item.rs1
-rw-r--r--tests/ui/resolve/blind-item-mixed-use-item.rs1
-rw-r--r--tests/ui/resolve/const-with-typo-in-pattern-binding.rs45
-rw-r--r--tests/ui/resolve/const-with-typo-in-pattern-binding.stderr78
-rw-r--r--tests/ui/resolve/issue-10200.stderr2
-rw-r--r--tests/ui/return/return-nil.rs1
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs2
-rw-r--r--tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2024.rs1
-rw-r--r--tests/ui/rust-2024/prelude2024.rs1
-rw-r--r--tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs1
-rw-r--r--tests/ui/rust-2024/reserved-guarded-strings.rs1
-rw-r--r--tests/ui/rust-2024/reserved-guarded-strings.stderr42
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs22
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs17
-rw-r--r--tests/ui/sanitizer/cfi/can-reveal-opaques.rs2
-rw-r--r--tests/ui/sanitizer/cfi/coroutine.rs2
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs-ice.rs2
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs-ice.stderr10
-rw-r--r--tests/ui/self/explicit-self-closures.rs1
-rw-r--r--tests/ui/self/explicit_self_xcrate_exe.rs1
-rw-r--r--tests/ui/self/self-impl-2.rs1
-rw-r--r--tests/ui/self/self-type-param.rs1
-rw-r--r--tests/ui/simd-abi-checks-empty-list.stderr11
-rw-r--r--tests/ui/simd-abi-checks-s390x.z10.stderr164
-rw-r--r--tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr164
-rw-r--r--tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr164
-rw-r--r--tests/ui/simd-abi-checks.rs29
-rw-r--r--tests/ui/simd-abi-checks.stderr172
-rw-r--r--tests/ui/simd/array-trait.rs1
-rw-r--r--tests/ui/simd/array-trait.stderr6
-rw-r--r--tests/ui/simd/array-type.rs1
-rw-r--r--tests/ui/sized-borrowed-pointer.rs1
-rw-r--r--tests/ui/sized-owned-pointer.rs1
-rw-r--r--tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr2
-rw-r--r--tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr2
-rw-r--r--tests/ui/specialization/issue-68830-spurious-diagnostics.rs1
-rw-r--r--tests/ui/specialization/issue-68830-spurious-diagnostics.stderr14
-rw-r--r--tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr12
-rw-r--r--tests/ui/sse-abi-checks.stderr12
-rw-r--r--tests/ui/stability-attribute/missing-const-stability.rs2
-rw-r--r--tests/ui/stability-attribute/missing-const-stability.stderr11
-rw-r--r--tests/ui/static/issue-1660.rs1
-rw-r--r--tests/ui/statics/check-recursion-foreign.rs1
-rw-r--r--tests/ui/statics/issue-15261.rs1
-rw-r--r--tests/ui/statics/issue-15261.stderr2
-rw-r--r--tests/ui/statics/issue-17718-static-unsafe-interior.rs1
-rw-r--r--tests/ui/statics/static-fn-inline-xc.rs1
-rw-r--r--tests/ui/statics/static-fn-trait-xc.rs1
-rw-r--r--tests/ui/statics/static-methods-in-traits2.rs1
-rw-r--r--tests/ui/stats/input-stats.stderr58
-rw-r--r--tests/ui/structs-enums/class-dtor.rs1
-rw-r--r--tests/ui/structs-enums/class-str-field.rs1
-rw-r--r--tests/ui/structs-enums/class-typarams.rs1
-rw-r--r--tests/ui/structs-enums/classes-self-referential.rs1
-rw-r--r--tests/ui/structs-enums/enum-discrim-range-overflow.rs1
-rw-r--r--tests/ui/structs-enums/enum-export-inheritance.rs1
-rw-r--r--tests/ui/structs-enums/enum-variants.rs1
-rw-r--r--tests/ui/structs-enums/enum-vec-initializer.rs1
-rw-r--r--tests/ui/structs-enums/export-abstract-tag.rs1
-rw-r--r--tests/ui/structs-enums/export-tag-variant.rs1
-rw-r--r--tests/ui/structs-enums/foreign-struct.rs1
-rw-r--r--tests/ui/structs-enums/module-qualified-struct-destructure.rs1
-rw-r--r--tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs1
-rw-r--r--tests/ui/structs-enums/namespaced-enum-emulate-flat.rs1
-rw-r--r--tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs1
-rw-r--r--tests/ui/structs-enums/namespaced-enum-glob-import.rs1
-rw-r--r--tests/ui/structs-enums/namespaced-enums-xcrate.rs1
-rw-r--r--tests/ui/structs-enums/namespaced-enums.rs1
-rw-r--r--tests/ui/structs-enums/nested-enum-same-names.rs1
-rw-r--r--tests/ui/structs-enums/newtype-struct-with-dtor.rs1
-rw-r--r--tests/ui/structs-enums/newtype-struct-xc-2.rs1
-rw-r--r--tests/ui/structs-enums/newtype-struct-xc.rs1
-rw-r--r--tests/ui/structs-enums/simple-generic-tag.rs1
-rw-r--r--tests/ui/structs-enums/struct-like-variant-construct.rs1
-rw-r--r--tests/ui/structs-enums/struct-variant-field-visibility.rs1
-rw-r--r--tests/ui/structs-enums/struct_variant_xc.rs1
-rw-r--r--tests/ui/structs-enums/tag-exports.rs1
-rw-r--r--tests/ui/structs-enums/tag-in-block.rs1
-rw-r--r--tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs1
-rw-r--r--tests/ui/structs-enums/tuple-struct-trivial.rs1
-rw-r--r--tests/ui/structs-enums/variant-structs-trivial.rs1
-rw-r--r--tests/ui/structs/large-records.rs1
-rw-r--r--tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr2
-rw-r--r--tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs3
-rw-r--r--tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr17
-rw-r--r--tests/ui/super.rs1
-rw-r--r--tests/ui/svh-add-nothing.rs1
-rw-r--r--tests/ui/swap-overlapping.rs1
-rw-r--r--tests/ui/tail-call-arg-leak.rs1
-rw-r--r--tests/ui/thir-print/thir-tree-match.stdout6
-rw-r--r--tests/ui/threads-sendsync/child-outlives-parent.rs1
-rw-r--r--tests/ui/threads-sendsync/send-resource.rs1
-rw-r--r--tests/ui/threads-sendsync/send-type-inference.rs1
-rw-r--r--tests/ui/threads-sendsync/sendable-class.rs1
-rw-r--r--tests/ui/threads-sendsync/std-sync-right-kind-impls.rs1
-rw-r--r--tests/ui/threads-sendsync/sync-send-atomics.rs1
-rw-r--r--tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs1
-rw-r--r--tests/ui/threads-sendsync/task-comm-11.rs1
-rw-r--r--tests/ui/threads-sendsync/task-comm-15.rs1
-rw-r--r--tests/ui/threads-sendsync/task-comm-17.rs1
-rw-r--r--tests/ui/threads-sendsync/task-life-0.rs1
-rw-r--r--tests/ui/trailing-comma.rs1
-rw-r--r--tests/ui/traits/astconv-cycle-between-and-type.rs1
-rw-r--r--tests/ui/traits/bad-sized.rs3
-rw-r--r--tests/ui/traits/bad-sized.stderr35
-rw-r--r--tests/ui/traits/bound/basic.rs1
-rw-r--r--tests/ui/traits/bound/impl-comparison-duplicates.rs1
-rw-r--r--tests/ui/traits/bound/multiple.rs1
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-rpass.rs1
-rw-r--r--tests/ui/traits/bound/recursion.rs1
-rw-r--r--tests/ui/traits/bug-7295.rs1
-rw-r--r--tests/ui/traits/cache-issue-18209.rs1
-rw-r--r--tests/ui/traits/composition-trivial.rs1
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-pass.stderr19
-rw-r--r--tests/ui/traits/const-traits/const-and-non-const-impl.stderr20
-rw-r--r--tests/ui/traits/const-traits/const-drop-bound.rs2
-rw-r--r--tests/ui/traits/const-traits/const-drop-bound.stderr54
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr33
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.rs13
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.stderr41
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.stock.stderr33
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.precise.stderr67
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.rs8
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail.stock.stderr50
-rw-r--r--tests/ui/traits/const-traits/const-drop.precise.stderr90
-rw-r--r--tests/ui/traits/const-traits/const-drop.rs9
-rw-r--r--tests/ui/traits/const-traits/const-drop.stock.stderr92
-rw-r--r--tests/ui/traits/const-traits/effects/auxiliary/minicore.rs9
-rw-r--r--tests/ui/traits/const-traits/effects/dont-prefer-param-env-for-infer-self-ty.rs16
-rw-r--r--tests/ui/traits/const-traits/effects/minicore-drop-fail.rs37
-rw-r--r--tests/ui/traits/const-traits/effects/minicore-drop-fail.stderr36
-rw-r--r--tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.no.stderr15
-rw-r--r--tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.rs26
-rw-r--r--tests/ui/traits/const-traits/generic-bound.rs3
-rw-r--r--tests/ui/traits/const-traits/generic-bound.stderr20
-rw-r--r--tests/ui/traits/const-traits/issue-92111.rs7
-rw-r--r--tests/ui/traits/const-traits/issue-92111.stderr25
-rw-r--r--tests/ui/traits/cycle-generic-bound.rs1
-rw-r--r--tests/ui/traits/cycle-type-trait.rs1
-rw-r--r--tests/ui/traits/default-method/mut.rs1
-rw-r--r--tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs1
-rw-r--r--tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr16
-rw-r--r--tests/ui/traits/early-vtbl-resolution.rs1
-rw-r--r--tests/ui/traits/false-ambiguity-where-clause-builtin-bound.rs1
-rw-r--r--tests/ui/traits/impl-2.rs1
-rw-r--r--tests/ui/traits/impl-implicit-trait.rs1
-rw-r--r--tests/ui/traits/inheritance/num.rs1
-rw-r--r--tests/ui/traits/inheritance/num0.rs1
-rw-r--r--tests/ui/traits/inheritance/num1.rs1
-rw-r--r--tests/ui/traits/inheritance/num5.rs1
-rw-r--r--tests/ui/traits/issue-22019.rs1
-rw-r--r--tests/ui/traits/issue-22110.rs1
-rw-r--r--tests/ui/traits/issue-22655.rs1
-rw-r--r--tests/ui/traits/issue-23003.rs1
-rw-r--r--tests/ui/traits/issue-32963.rs1
-rw-r--r--tests/ui/traits/issue-32963.stderr17
-rw-r--r--tests/ui/traits/issue-78372.rs1
-rw-r--r--tests/ui/traits/issue-78372.stderr24
-rw-r--r--tests/ui/traits/monomorphized-callees-with-ty-params-3314.rs1
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs6
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr42
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs2
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr14
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.rs1
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.stderr10
-rw-r--r--tests/ui/traits/next-solver/destruct.rs2
-rw-r--r--tests/ui/traits/next-solver/normalization-shadowing/alias-bound-shadowed-by-env.rs19
-rw-r--r--tests/ui/traits/next-solver/normalization-shadowing/ambig-env-no-shadow.rs (renamed from tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs)0
-rw-r--r--tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-1.rs (renamed from tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-1.rs)0
-rw-r--r--tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-2.rs (renamed from tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-2.rs)0
-rw-r--r--tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-3.rs (renamed from tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-3.rs)0
-rw-r--r--tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.rs (renamed from tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.rs)0
-rw-r--r--tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr (renamed from tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.stderr)0
-rw-r--r--tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.rs (renamed from tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs)0
-rw-r--r--tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.stderr (renamed from tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr)0
-rw-r--r--tests/ui/traits/next-solver/normalization-shadowing/param-env-impl-conflict.rs (renamed from tests/ui/traits/next-solver/env-shadows-impls/param-env-impl-conflict.rs)0
-rw-r--r--tests/ui/traits/next-solver/typeck/resolve-before-checking-builtin-ptr.rs20
-rw-r--r--tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs20
-rw-r--r--tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs1
-rw-r--r--tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr25
-rw-r--r--tests/ui/traits/parameterized-with-bounds.rs1
-rw-r--r--tests/ui/traits/solver-cycles/100347-recursive-enum-cow-slice.rs11
-rw-r--r--tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs22
-rw-r--r--tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.stderr10
-rw-r--r--tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs23
-rw-r--r--tests/ui/traits/solver-cycles/129541-recursive-struct.rs19
-rw-r--r--tests/ui/traits/span-bug-issue-121414.rs3
-rw-r--r--tests/ui/traits/span-bug-issue-121414.stderr20
-rw-r--r--tests/ui/traits/syntax-polarity.rs1
-rw-r--r--tests/ui/traits/use-before-def.rs1
-rw-r--r--tests/ui/traits/where-clause-vs-impl.rs1
-rw-r--r--tests/ui/transmute-non-immediate-to-immediate.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs21
-rw-r--r--tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr86
-rw-r--r--tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs22
-rw-r--r--tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs (renamed from tests/crashes/130956.rs)5
-rw-r--r--tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/in-where-clause.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/struct-assignment-validity.rs2
-rw-r--r--tests/ui/type-alias/issue-14933.rs1
-rw-r--r--tests/ui/type-param-constraints.rs1
-rw-r--r--tests/ui/type-param.rs1
-rw-r--r--tests/ui/type-ptr.rs1
-rw-r--r--tests/ui/type-use-i1-versus-i8.rs1
-rw-r--r--tests/ui/type/issue-7607-2.rs1
-rw-r--r--tests/ui/typeck/ufcs-type-params.rs1
-rw-r--r--tests/ui/typeck/unify-return-ty.rs1
-rw-r--r--tests/ui/unboxed-closures/issue-18661.rs1
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs1
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs1
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs1
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs1
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs1
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr4
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-prelude.rs1
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs1
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-zero-args.rs1
-rw-r--r--tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr2
-rw-r--r--tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr2
-rw-r--r--tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr2
-rw-r--r--tests/ui/uninit-empty-types.rs1
-rw-r--r--tests/ui/unit.rs1
-rw-r--r--tests/ui/unnamed_argument_mode.rs1
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.rs2
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.stdout2
-rw-r--r--tests/ui/unsafe-fields-crate.rs62
-rw-r--r--tests/ui/unsafe-fields-crate.stderr47
-rw-r--r--tests/ui/unsafe-fields-parse.rs10
-rw-r--r--tests/ui/unsafe-fields-parse.stderr18
-rw-r--r--tests/ui/unsafe-fields.rs109
-rw-r--r--tests/ui/unsafe-fields.stderr75
-rw-r--r--tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs1
-rw-r--r--tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr4
-rw-r--r--tests/ui/unsafe/new-unsafe-pointers.rs1
-rw-r--r--tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs1
-rw-r--r--tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs1
-rw-r--r--tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.rs1
-rw-r--r--tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr4
-rw-r--r--tests/ui/unused-move-capture.rs1
-rw-r--r--tests/ui/unused-move.rs1
-rw-r--r--tests/ui/use-import-export.rs1
-rw-r--r--tests/ui/use/use.rs1
-rw-r--r--tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs8
-rw-r--r--tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr129
-rw-r--r--tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs1
-rw-r--r--tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr17
-rw-r--r--tests/ui/where-clauses/where-clause-bounds-inconsistency.rs1
-rw-r--r--tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs1
-rw-r--r--tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr2
-rw-r--r--tests/ui/where-clauses/where-clause-method-substituion-rpass.rs1
-rw-r--r--tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr2
-rw-r--r--tests/ui/where-clauses/where-clause-region-outlives.rs1
-rw-r--r--tests/ui/where-clauses/where-clauses-lifetimes.rs1
-rw-r--r--tests/ui/where-clauses/where-clauses-unboxed-closures.rs1
-rw-r--r--triagebot.toml7
1582 files changed, 11784 insertions, 8445 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 703f6e5281d..f6df348b721 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -65,7 +65,7 @@ jobs:
     defaults:
       run:
         shell: ${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}
-    timeout-minutes: 240
+    timeout-minutes: 360
     env:
       CI_JOB_NAME: ${{ matrix.image }}
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
diff --git a/COPYRIGHT b/COPYRIGHT
index 05993830a0f..428a438a086 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -343,49 +343,42 @@ their own copyright notices and license terms:
 * Portions of internationalization code use code or data from Unicode, which
   carry the following license:
 
-      UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
-
-    See Terms of Use <https://www.unicode.org/copyright.html>
-    for definitions of Unicode Inc.’s Data Files and Software.
-
-    NOTICE TO USER: Carefully read the following legal agreement.
-    BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
-    DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
-    YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
-    TERMS AND CONDITIONS OF THIS AGREEMENT.
-    IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
-    THE DATA FILES OR SOFTWARE.
+    UNICODE LICENSE V3
 
     COPYRIGHT AND PERMISSION NOTICE
 
-    Copyright © 1991-2022 Unicode, Inc. All rights reserved.
-    Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
-
-    Permission is hereby granted, free of charge, to any person obtaining
-    a copy of the Unicode data files and any associated documentation
-    (the "Data Files") or Unicode software and any associated documentation
-    (the "Software") to deal in the Data Files or Software
-    without restriction, including without limitation the rights to use,
-    copy, modify, merge, publish, distribute, and/or sell copies of
-    the Data Files or Software, and to permit persons to whom the Data Files
-    or Software are furnished to do so, provided that either
-    (a) this copyright and permission notice appear with all copies
-    of the Data Files or Software, or
-    (b) this copyright and permission notice appear in associated
-    Documentation.
-
-    THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
-    ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-    WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-    NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-    IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
-    NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
-    DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-    DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-    TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-    PERFORMANCE OF THE DATA FILES OR SOFTWARE.
-
-    Except as contained in this notice, the name of a copyright holder
-    shall not be used in advertising or otherwise to promote the sale,
-    use or other dealings in these Data Files or Software without prior
-    written authorization of the copyright holder.
+    Copyright © 1991-2024 Unicode, Inc.
+
+    NOTICE TO USER: Carefully read the following legal agreement. BY
+    DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
+    SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
+    TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
+    DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of data files and any associated documentation (the "Data Files") or
+    software and any associated documentation (the "Software") to deal in the
+    Data Files or Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, and/or sell
+    copies of the Data Files or Software, and to permit persons to whom the
+    Data Files or Software are furnished to do so, provided that either (a)
+    this copyright and permission notice appear with all copies of the Data
+    Files or Software, or (b) this copyright and permission notice appear in
+    associated Documentation.
+
+    THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+    KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+    THIRD PARTY RIGHTS.
+
+    IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
+    BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
+    OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+    WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
+    FILES OR SOFTWARE.
+
+    Except as contained in this notice, the name of a copyright holder shall
+    not be used in advertising or otherwise to promote the sale, use or other
+    dealings in these Data Files or Software without prior written
+    authorization of the copyright holder.
diff --git a/Cargo.lock b/Cargo.lock
index e4dcf13a84b..29176a3ae8e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -411,9 +411,9 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.1.34"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9"
+checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8"
 dependencies = [
  "shlex",
 ]
diff --git a/LICENSES/Unicode-3.0.txt b/LICENSES/Unicode-3.0.txt
new file mode 100644
index 00000000000..ee8e69b2332
--- /dev/null
+++ b/LICENSES/Unicode-3.0.txt
@@ -0,0 +1,39 @@
+UNICODE LICENSE V3
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright © 1991-2024 Unicode, Inc.
+
+NOTICE TO USER: Carefully read the following legal agreement. BY
+DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
+SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
+TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
+DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of data files and any associated documentation (the "Data Files") or
+software and any associated documentation (the "Software") to deal in the
+Data Files or Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, and/or sell
+copies of the Data Files or Software, and to permit persons to whom the
+Data Files or Software are furnished to do so, provided that either (a)
+this copyright and permission notice appear with all copies of the Data
+Files or Software, or (b) this copyright and permission notice appear in
+associated Documentation.
+
+THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+THIRD PARTY RIGHTS.
+
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
+BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
+OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
+FILES OR SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in these Data Files or Software without prior written
+authorization of the copyright holder.
diff --git a/LICENSES/Unicode-DFS-2016.txt b/LICENSES/Unicode-DFS-2016.txt
deleted file mode 100644
index 71fd6ac5e12..00000000000
--- a/LICENSES/Unicode-DFS-2016.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
-
-Unicode Data Files include all data files under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and http://www.unicode.org/utility/trac/browser/.
-
-Unicode Data Files do not include PDF online code charts under the directory http://www.unicode.org/Public/.
-
-Software includes any source code published in the Unicode Standard or under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and http://www.unicode.org/utility/trac/browser/.
-
-NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
-
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright © 1991-2016 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either
-
-     (a) this copyright and permission notice appear with all copies of the Data Files or Software, or
-     (b) this copyright and permission notice appear in associated Documentation.
-
-THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder.
diff --git a/REUSE.toml b/REUSE.toml
index 3005bb56609..6b16d97ed80 100644
--- a/REUSE.toml
+++ b/REUSE.toml
@@ -28,6 +28,7 @@ path = [
     "COPYRIGHT",
     "INSTALL.md",
     "LICENSE-APACHE",
+    "license-metadata.json",
     "LICENSE-MIT",
     "README.md",
     "RELEASES.md",
@@ -63,8 +64,8 @@ SPDX-License-Identifier = "Apache-2.0 WITH LLVM-exception AND (Apache-2.0 OR MIT
 [[annotations]]
 path = "library/core/src/unicode/unicode_data.rs"
 precedence = "override"
-SPDX-FileCopyrightText = "1991-2022 Unicode, Inc. All rights reserved."
-SPDX-License-Identifier = "Unicode-DFS-2016"
+SPDX-FileCopyrightText = "1991-2024 Unicode, Inc."
+SPDX-License-Identifier = "Unicode-3.0"
 
 [[annotations]]
 path = "library/std/src/sync/mpmc/**"
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 7b6abdf1ea9..2e51753ede6 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -638,7 +638,7 @@ impl AddAssign for Size {
 #[cfg(feature = "nightly")]
 impl Step for Size {
     #[inline]
-    fn steps_between(start: &Self, end: &Self) -> Option<usize> {
+    fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
         u64::steps_between(&start.bytes(), &end.bytes())
     }
 
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 5f71fb97d76..ecb6ef5a2a6 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -39,7 +39,9 @@ pub use crate::format::*;
 use crate::ptr::P;
 use crate::token::{self, CommentKind, Delimiter};
 use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
-pub use crate::util::parser::ExprPrecedence;
+use crate::util::parser::{
+    AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_RANGE, PREC_UNAMBIGUOUS,
+};
 
 /// A "Label" is an identifier of some point in sources,
 /// e.g. in the following code:
@@ -428,7 +430,15 @@ impl Default for WhereClause {
 
 /// A single predicate in a where-clause.
 #[derive(Clone, Encodable, Decodable, Debug)]
-pub enum WherePredicate {
+pub struct WherePredicate {
+    pub kind: WherePredicateKind,
+    pub id: NodeId,
+    pub span: Span,
+}
+
+/// Predicate kind in where-clause.
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub enum WherePredicateKind {
     /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate),
     /// A lifetime predicate (e.g., `'a: 'b + 'c`).
@@ -437,22 +447,11 @@ pub enum WherePredicate {
     EqPredicate(WhereEqPredicate),
 }
 
-impl WherePredicate {
-    pub fn span(&self) -> Span {
-        match self {
-            WherePredicate::BoundPredicate(p) => p.span,
-            WherePredicate::RegionPredicate(p) => p.span,
-            WherePredicate::EqPredicate(p) => p.span,
-        }
-    }
-}
-
 /// A type bound.
 ///
 /// E.g., `for<'c> Foo: Send + Clone + 'c`.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct WhereBoundPredicate {
-    pub span: Span,
     /// Any generics from a `for` binding.
     pub bound_generic_params: ThinVec<GenericParam>,
     /// The type being bounded.
@@ -466,7 +465,6 @@ pub struct WhereBoundPredicate {
 /// E.g., `'a: 'b + 'c`.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct WhereRegionPredicate {
-    pub span: Span,
     pub lifetime: Lifetime,
     pub bounds: GenericBounds,
 }
@@ -476,7 +474,6 @@ pub struct WhereRegionPredicate {
 /// E.g., `T = int`.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct WhereEqPredicate {
-    pub span: Span,
     pub lhs_ty: P<Ty>,
     pub rhs_ty: P<Ty>,
 }
@@ -1319,53 +1316,71 @@ impl Expr {
         Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
     }
 
-    pub fn precedence(&self) -> ExprPrecedence {
+    pub fn precedence(&self) -> i8 {
         match self.kind {
-            ExprKind::Array(_) => ExprPrecedence::Array,
-            ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
-            ExprKind::Call(..) => ExprPrecedence::Call,
-            ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
-            ExprKind::Tup(_) => ExprPrecedence::Tup,
-            ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
-            ExprKind::Unary(..) => ExprPrecedence::Unary,
-            ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit,
-            ExprKind::Cast(..) => ExprPrecedence::Cast,
-            ExprKind::Let(..) => ExprPrecedence::Let,
-            ExprKind::If(..) => ExprPrecedence::If,
-            ExprKind::While(..) => ExprPrecedence::While,
-            ExprKind::ForLoop { .. } => ExprPrecedence::ForLoop,
-            ExprKind::Loop(..) => ExprPrecedence::Loop,
-            ExprKind::Match(_, _, MatchKind::Prefix) => ExprPrecedence::Match,
-            ExprKind::Match(_, _, MatchKind::Postfix) => ExprPrecedence::PostfixMatch,
-            ExprKind::Closure(..) => ExprPrecedence::Closure,
-            ExprKind::Block(..) => ExprPrecedence::Block,
-            ExprKind::TryBlock(..) => ExprPrecedence::TryBlock,
-            ExprKind::Gen(..) => ExprPrecedence::Gen,
-            ExprKind::Await(..) => ExprPrecedence::Await,
-            ExprKind::Assign(..) => ExprPrecedence::Assign,
-            ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
-            ExprKind::Field(..) => ExprPrecedence::Field,
-            ExprKind::Index(..) => ExprPrecedence::Index,
-            ExprKind::Range(..) => ExprPrecedence::Range,
-            ExprKind::Underscore => ExprPrecedence::Path,
-            ExprKind::Path(..) => ExprPrecedence::Path,
-            ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
-            ExprKind::Break(..) => ExprPrecedence::Break,
-            ExprKind::Continue(..) => ExprPrecedence::Continue,
-            ExprKind::Ret(..) => ExprPrecedence::Ret,
-            ExprKind::Struct(..) => ExprPrecedence::Struct,
-            ExprKind::Repeat(..) => ExprPrecedence::Repeat,
-            ExprKind::Paren(..) => ExprPrecedence::Paren,
-            ExprKind::Try(..) => ExprPrecedence::Try,
-            ExprKind::Yield(..) => ExprPrecedence::Yield,
-            ExprKind::Yeet(..) => ExprPrecedence::Yeet,
-            ExprKind::Become(..) => ExprPrecedence::Become,
-            ExprKind::InlineAsm(..)
-            | ExprKind::Type(..)
-            | ExprKind::OffsetOf(..)
+            ExprKind::Closure(..) => PREC_CLOSURE,
+
+            ExprKind::Break(..)
+            | ExprKind::Continue(..)
+            | ExprKind::Ret(..)
+            | ExprKind::Yield(..)
+            | ExprKind::Yeet(..)
+            | ExprKind::Become(..) => PREC_JUMP,
+
+            // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
+            // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
+            // ensures that `pprust` will add parentheses in the right places to get the desired
+            // parse.
+            ExprKind::Range(..) => PREC_RANGE,
+
+            // Binop-like expr kinds, handled by `AssocOp`.
+            ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8,
+            ExprKind::Cast(..) => AssocOp::As.precedence() as i8,
+
+            ExprKind::Assign(..) |
+            ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8,
+
+            // Unary, prefix
+            ExprKind::AddrOf(..)
+            // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
+            // However, this is not exactly right. When `let _ = a` is the LHS of a binop we
+            // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
+            // but we need to print `(let _ = a) < b` as-is with parens.
+            | ExprKind::Let(..)
+            | ExprKind::Unary(..) => PREC_PREFIX,
+
+            // Never need parens
+            ExprKind::Array(_)
+            | ExprKind::Await(..)
+            | ExprKind::Block(..)
+            | ExprKind::Call(..)
+            | ExprKind::ConstBlock(_)
+            | ExprKind::Field(..)
+            | ExprKind::ForLoop { .. }
             | ExprKind::FormatArgs(..)
-            | ExprKind::MacCall(..) => ExprPrecedence::Mac,
-            ExprKind::Err(_) | ExprKind::Dummy => ExprPrecedence::Err,
+            | ExprKind::Gen(..)
+            | ExprKind::If(..)
+            | ExprKind::IncludedBytes(..)
+            | ExprKind::Index(..)
+            | ExprKind::InlineAsm(..)
+            | ExprKind::Lit(_)
+            | ExprKind::Loop(..)
+            | ExprKind::MacCall(..)
+            | ExprKind::Match(..)
+            | ExprKind::MethodCall(..)
+            | ExprKind::OffsetOf(..)
+            | ExprKind::Paren(..)
+            | ExprKind::Path(..)
+            | ExprKind::Repeat(..)
+            | ExprKind::Struct(..)
+            | ExprKind::Try(..)
+            | ExprKind::TryBlock(..)
+            | ExprKind::Tup(_)
+            | ExprKind::Type(..)
+            | ExprKind::Underscore
+            | ExprKind::While(..)
+            | ExprKind::Err(_)
+            | ExprKind::Dummy => PREC_UNAMBIGUOUS,
         }
     }
 
@@ -3063,6 +3078,7 @@ pub struct FieldDef {
     pub id: NodeId,
     pub span: Span,
     pub vis: Visibility,
+    pub safety: Safety,
     pub ident: Option<Ident>,
 
     pub ty: P<Ty>,
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 61f2f91635d..0aceed45028 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -332,7 +332,11 @@ pub trait MutVisitor: Sized {
     }
 
     fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) {
-        walk_where_predicate(self, where_predicate);
+        walk_where_predicate(self, where_predicate)
+    }
+
+    fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) {
+        walk_where_predicate_kind(self, kind)
     }
 
     fn visit_vis(&mut self, vis: &mut Visibility) {
@@ -1065,26 +1069,30 @@ fn walk_where_clause<T: MutVisitor>(vis: &mut T, wc: &mut WhereClause) {
     vis.visit_span(span);
 }
 
-fn walk_where_predicate<T: MutVisitor>(vis: &mut T, pred: &mut WherePredicate) {
-    match pred {
-        WherePredicate::BoundPredicate(bp) => {
-            let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp;
+pub fn walk_where_predicate<T: MutVisitor>(vis: &mut T, pred: &mut WherePredicate) {
+    let WherePredicate { kind, id, span } = pred;
+    vis.visit_id(id);
+    vis.visit_where_predicate_kind(kind);
+    vis.visit_span(span);
+}
+
+pub fn walk_where_predicate_kind<T: MutVisitor>(vis: &mut T, kind: &mut WherePredicateKind) {
+    match kind {
+        WherePredicateKind::BoundPredicate(bp) => {
+            let WhereBoundPredicate { bound_generic_params, bounded_ty, bounds } = bp;
             bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
             vis.visit_ty(bounded_ty);
             visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
-            vis.visit_span(span);
         }
-        WherePredicate::RegionPredicate(rp) => {
-            let WhereRegionPredicate { span, lifetime, bounds } = rp;
+        WherePredicateKind::RegionPredicate(rp) => {
+            let WhereRegionPredicate { lifetime, bounds } = rp;
             vis.visit_lifetime(lifetime);
             visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
-            vis.visit_span(span);
         }
-        WherePredicate::EqPredicate(ep) => {
-            let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep;
+        WherePredicateKind::EqPredicate(ep) => {
+            let WhereEqPredicate { lhs_ty, rhs_ty } = ep;
             vis.visit_ty(lhs_ty);
             vis.visit_ty(rhs_ty);
-            vis.visit_span(span);
         }
     }
 }
@@ -1115,10 +1123,11 @@ fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
 }
 
 pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) {
-    let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = fd;
+    let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety } = fd;
     visitor.visit_id(id);
     visit_attrs(visitor, attrs);
     visitor.visit_vis(vis);
+    visit_safety(visitor, safety);
     visit_opt(ident, |ident| visitor.visit_ident(ident));
     visitor.visit_ty(ty);
     visitor.visit_span(span);
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index d8dad4550c0..ed9265d5159 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -237,121 +237,6 @@ pub const PREC_PREFIX: i8 = 50;
 pub const PREC_UNAMBIGUOUS: i8 = 60;
 pub const PREC_FORCE_PAREN: i8 = 100;
 
-#[derive(Debug, Clone, Copy)]
-pub enum ExprPrecedence {
-    Closure,
-    Break,
-    Continue,
-    Ret,
-    Yield,
-    Yeet,
-    Become,
-
-    Range,
-
-    Binary(BinOpKind),
-
-    Cast,
-
-    Assign,
-    AssignOp,
-
-    AddrOf,
-    Let,
-    Unary,
-
-    Call,
-    MethodCall,
-    Field,
-    Index,
-    Try,
-    Mac,
-
-    Array,
-    Repeat,
-    Tup,
-    Lit,
-    Path,
-    Paren,
-    If,
-    While,
-    ForLoop,
-    Loop,
-    Match,
-    PostfixMatch,
-    ConstBlock,
-    Block,
-    TryBlock,
-    Struct,
-    Gen,
-    Await,
-    Err,
-}
-
-impl ExprPrecedence {
-    pub fn order(self) -> i8 {
-        match self {
-            ExprPrecedence::Closure => PREC_CLOSURE,
-
-            ExprPrecedence::Break
-            | ExprPrecedence::Continue
-            | ExprPrecedence::Ret
-            | ExprPrecedence::Yield
-            | ExprPrecedence::Yeet
-            | ExprPrecedence::Become => PREC_JUMP,
-
-            // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
-            // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
-            // ensures that `pprust` will add parentheses in the right places to get the desired
-            // parse.
-            ExprPrecedence::Range => PREC_RANGE,
-
-            // Binop-like expr kinds, handled by `AssocOp`.
-            ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8,
-            ExprPrecedence::Cast => AssocOp::As.precedence() as i8,
-
-            ExprPrecedence::Assign |
-            ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8,
-
-            // Unary, prefix
-            ExprPrecedence::AddrOf
-            // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
-            // However, this is not exactly right. When `let _ = a` is the LHS of a binop we
-            // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
-            // but we need to print `(let _ = a) < b` as-is with parens.
-            | ExprPrecedence::Let
-            | ExprPrecedence::Unary => PREC_PREFIX,
-
-            // Never need parens
-            ExprPrecedence::Array
-            | ExprPrecedence::Await
-            | ExprPrecedence::Block
-            | ExprPrecedence::Call
-            | ExprPrecedence::ConstBlock
-            | ExprPrecedence::Field
-            | ExprPrecedence::ForLoop
-            | ExprPrecedence::Gen
-            | ExprPrecedence::If
-            | ExprPrecedence::Index
-            | ExprPrecedence::Lit
-            | ExprPrecedence::Loop
-            | ExprPrecedence::Mac
-            | ExprPrecedence::Match
-            | ExprPrecedence::MethodCall
-            | ExprPrecedence::Paren
-            | ExprPrecedence::Path
-            | ExprPrecedence::PostfixMatch
-            | ExprPrecedence::Repeat
-            | ExprPrecedence::Struct
-            | ExprPrecedence::Try
-            | ExprPrecedence::TryBlock
-            | ExprPrecedence::Tup
-            | ExprPrecedence::While
-            | ExprPrecedence::Err => PREC_UNAMBIGUOUS,
-        }
-    }
-}
-
 /// In `let p = e`, operators with precedence `<=` this one requires parentheses in `e`.
 pub fn prec_let_scrutinee_needs_par() -> usize {
     AssocOp::LAnd.precedence()
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 0302c9fa7f8..718397e8ca0 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -192,6 +192,9 @@ pub trait Visitor<'ast>: Sized {
     fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result {
         walk_where_predicate(self, p)
     }
+    fn visit_where_predicate_kind(&mut self, k: &'ast WherePredicateKind) -> Self::Result {
+        walk_where_predicate_kind(self, k)
+    }
     fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result {
         walk_fn(self, fk)
     }
@@ -794,22 +797,29 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
     visitor: &mut V,
     predicate: &'a WherePredicate,
 ) -> V::Result {
-    match predicate {
-        WherePredicate::BoundPredicate(WhereBoundPredicate {
+    let WherePredicate { kind, id: _, span: _ } = predicate;
+    visitor.visit_where_predicate_kind(kind)
+}
+
+pub fn walk_where_predicate_kind<'a, V: Visitor<'a>>(
+    visitor: &mut V,
+    kind: &'a WherePredicateKind,
+) -> V::Result {
+    match kind {
+        WherePredicateKind::BoundPredicate(WhereBoundPredicate {
             bounded_ty,
             bounds,
             bound_generic_params,
-            span: _,
         }) => {
             walk_list!(visitor, visit_generic_param, bound_generic_params);
             try_visit!(visitor.visit_ty(bounded_ty));
             walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
         }
-        WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span: _ }) => {
+        WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
             try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound));
             walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
         }
-        WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span: _ }) => {
+        WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
             try_visit!(visitor.visit_ty(lhs_ty));
             try_visit!(visitor.visit_ty(rhs_ty));
         }
@@ -961,7 +971,7 @@ pub fn walk_struct_def<'a, V: Visitor<'a>>(
 }
 
 pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result {
-    let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _ } = field;
+    let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _, safety: _ } = field;
     walk_list!(visitor, visit_attribute, attrs);
     try_visit!(visitor.visit_vis(vis));
     visit_opt!(visitor, visit_ident, ident);
diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
index f704320c71d..a4dbf981115 100644
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ b/compiler/rustc_ast_lowering/messages.ftl
@@ -152,6 +152,8 @@ ast_lowering_register2 = register `{$reg2_name}`
 
 ast_lowering_register_class_only_clobber =
     register class `{$reg_class_name}` can only be used as a clobber, not as an input or output
+ast_lowering_register_class_only_clobber_stable =
+    register class `{$reg_class_name}` can only be used as a clobber in stable
 
 ast_lowering_register_conflict =
     register `{$reg1_name}` conflicts with register `{$reg2_name}`
@@ -181,6 +183,8 @@ ast_lowering_underscore_expr_lhs_assign =
     .label = `_` not allowed here
 
 ast_lowering_unstable_inline_assembly = inline assembly is not stable yet on this architecture
+ast_lowering_unstable_inline_assembly_label_operand_with_outputs =
+    using both label and output operands for inline assembly is unstable
 ast_lowering_unstable_inline_assembly_label_operands =
     label operands for inline assembly are unstable
 ast_lowering_unstable_may_unwind = the `may_unwind` option is unstable
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 215e6d84d0f..ff803e50997 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -17,7 +17,8 @@ use super::errors::{
     InlineAsmUnsupportedTarget, InvalidAbiClobberAbi, InvalidAsmTemplateModifierConst,
     InvalidAsmTemplateModifierLabel, InvalidAsmTemplateModifierRegClass,
     InvalidAsmTemplateModifierRegClassSub, InvalidAsmTemplateModifierSym, InvalidRegister,
-    InvalidRegisterClass, RegisterClassOnlyClobber, RegisterConflict,
+    InvalidRegisterClass, RegisterClassOnlyClobber, RegisterClassOnlyClobberStable,
+    RegisterConflict,
 };
 use crate::{
     AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode,
@@ -61,6 +62,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 .emit();
             }
         }
+        let allow_experimental_reg = self.tcx.features().asm_experimental_reg();
         if asm.options.contains(InlineAsmOptions::ATT_SYNTAX)
             && !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64))
             && !self.tcx.sess.opts.actually_rustdoc
@@ -239,15 +241,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         }
                     }
                     InlineAsmOperand::Label { block } => {
-                        if !self.tcx.features().asm_goto() {
-                            feature_err(
-                                sess,
-                                sym::asm_goto,
-                                *op_sp,
-                                fluent::ast_lowering_unstable_inline_assembly_label_operands,
-                            )
-                            .emit();
-                        }
                         hir::InlineAsmOperand::Label { block: self.lower_block(block, false) }
                     }
                 };
@@ -333,11 +326,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 // means that we disallow passing a value in/out of the asm and
                 // require that the operand name an explicit register, not a
                 // register class.
-                if reg_class.is_clobber_only(asm_arch.unwrap()) && !op.is_clobber() {
-                    self.dcx().emit_err(RegisterClassOnlyClobber {
-                        op_span: op_sp,
-                        reg_class_name: reg_class.name(),
-                    });
+                if reg_class.is_clobber_only(asm_arch.unwrap(), allow_experimental_reg)
+                    && !op.is_clobber()
+                {
+                    if allow_experimental_reg || reg_class.is_clobber_only(asm_arch.unwrap(), true)
+                    {
+                        // always clobber-only
+                        self.dcx().emit_err(RegisterClassOnlyClobber {
+                            op_span: op_sp,
+                            reg_class_name: reg_class.name(),
+                        });
+                    } else {
+                        // clobber-only in stable
+                        self.tcx
+                            .sess
+                            .create_feature_err(
+                                RegisterClassOnlyClobberStable {
+                                    op_span: op_sp,
+                                    reg_class_name: reg_class.name(),
+                                },
+                                sym::asm_experimental_reg,
+                            )
+                            .emit();
+                    }
                     continue;
                 }
 
@@ -466,6 +477,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
         }
 
+        // Feature gate checking for asm goto.
+        if let Some((_, op_sp)) =
+            operands.iter().find(|(op, _)| matches!(op, hir::InlineAsmOperand::Label { .. }))
+        {
+            if !self.tcx.features().asm_goto() {
+                feature_err(
+                    sess,
+                    sym::asm_goto,
+                    *op_sp,
+                    fluent::ast_lowering_unstable_inline_assembly_label_operands,
+                )
+                .emit();
+            }
+
+            // In addition, check if an output operand is used.
+            // This is gated behind an additional feature.
+            let output_operand_used = operands.iter().any(|(op, _)| {
+                matches!(
+                    op,
+                    hir::InlineAsmOperand::Out { expr: Some(_), .. }
+                        | hir::InlineAsmOperand::InOut { .. }
+                        | hir::InlineAsmOperand::SplitInOut { out_expr: Some(_), .. }
+                )
+            });
+            if output_operand_used && !self.tcx.features().asm_goto_with_outputs() {
+                feature_err(
+                    sess,
+                    sym::asm_goto_with_outputs,
+                    *op_sp,
+                    fluent::ast_lowering_unstable_inline_assembly_label_operand_with_outputs,
+                )
+                .emit();
+            }
+        }
+
         let operands = self.arena.alloc_from_iter(operands);
         let template = self.arena.alloc_from_iter(asm.template.iter().cloned());
         let template_strs = self.arena.alloc_from_iter(
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index e6a3f939f2d..447af57354f 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -280,6 +280,14 @@ pub(crate) struct RegisterClassOnlyClobber {
 }
 
 #[derive(Diagnostic)]
+#[diag(ast_lowering_register_class_only_clobber_stable)]
+pub(crate) struct RegisterClassOnlyClobberStable {
+    #[primary_span]
+    pub op_span: Span,
+    pub reg_class_name: Symbol,
+}
+
+#[derive(Diagnostic)]
 #[diag(ast_lowering_register_conflict)]
 pub(crate) struct RegisterConflict<'a> {
     #[primary_span]
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 6289966561f..65e387de800 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -381,15 +381,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) {
-        match predicate {
-            WherePredicate::BoundPredicate(pred) => {
-                self.insert(pred.span, pred.hir_id, Node::WhereBoundPredicate(pred));
-                self.with_parent(pred.hir_id, |this| {
-                    intravisit::walk_where_predicate(this, predicate)
-                })
-            }
-            _ => intravisit::walk_where_predicate(self, predicate),
-        }
+        self.insert(predicate.span, predicate.hir_id, Node::WherePredicate(predicate));
+        self.with_parent(predicate.hir_id, |this| {
+            intravisit::walk_where_predicate(this, predicate)
+        });
     }
 
     fn visit_array_length(&mut self, len: &'hir ArrayLen<'hir>) {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index d7245607501..fb09f1c7fee 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -724,6 +724,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             },
             vis_span: self.lower_span(f.vis.span),
             ty,
+            safety: self.lower_safety(f.safety, hir::Safety::Safe),
         }
     }
 
@@ -1400,7 +1401,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         // keep track of the Span info. Now, `<dyn HirTyLowerer>::add_implicit_sized_bound`
         // checks both param bounds and where clauses for `?Sized`.
         for pred in &generics.where_clause.predicates {
-            let WherePredicate::BoundPredicate(bound_pred) = pred else {
+            let WherePredicateKind::BoundPredicate(bound_pred) = &pred.kind else {
                 continue;
             };
             let compute_is_param = || {
@@ -1537,9 +1538,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
         });
         let span = self.lower_span(span);
-
-        match kind {
-            GenericParamKind::Const { .. } => None,
+        let hir_id = self.next_id();
+        let kind = self.arena.alloc(match kind {
+            GenericParamKind::Const { .. } => return None,
             GenericParamKind::Type { .. } => {
                 let def_id = self.local_def_id(id).to_def_id();
                 let hir_id = self.next_id();
@@ -1554,38 +1555,36 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let ty_id = self.next_id();
                 let bounded_ty =
                     self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path));
-                Some(hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                    hir_id: self.next_id(),
+                hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
                     bounded_ty: self.arena.alloc(bounded_ty),
                     bounds,
-                    span,
                     bound_generic_params: &[],
                     origin,
-                }))
+                })
             }
             GenericParamKind::Lifetime => {
                 let ident = self.lower_ident(ident);
                 let lt_id = self.next_node_id();
                 let lifetime = self.new_named_lifetime(id, lt_id, ident);
-                Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
+                hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
                     lifetime,
-                    span,
                     bounds,
                     in_where_clause: false,
-                }))
+                })
             }
-        }
+        });
+        Some(hir::WherePredicate { hir_id, span, kind })
     }
 
     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
-        match pred {
-            WherePredicate::BoundPredicate(WhereBoundPredicate {
+        let hir_id = self.lower_node_id(pred.id);
+        let span = self.lower_span(pred.span);
+        let kind = self.arena.alloc(match &pred.kind {
+            WherePredicateKind::BoundPredicate(WhereBoundPredicate {
                 bound_generic_params,
                 bounded_ty,
                 bounds,
-                span,
-            }) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                hir_id: self.next_id(),
+            }) => hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
                 bound_generic_params: self
                     .lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
                 bounded_ty: self
@@ -1594,12 +1593,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     bounds,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
                 ),
-                span: self.lower_span(*span),
                 origin: PredicateOrigin::WhereClause,
             }),
-            WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span }) => {
-                hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
-                    span: self.lower_span(*span),
+            WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
+                hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
                     lifetime: self.lower_lifetime(lifetime),
                     bounds: self.lower_param_bounds(
                         bounds,
@@ -1608,15 +1605,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     in_where_clause: true,
                 })
             }
-            WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => {
-                hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
+            WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
+                hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
                     lhs_ty: self
                         .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
                     rhs_ty: self
                         .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
-                    span: self.lower_span(*span),
                 })
             }
-        }
+        });
+        hir::WherePredicate { hir_id, span, kind }
     }
 }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 0b2969a49ba..dae816663e0 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -2117,11 +2117,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             hir::ConstArgKind::Anon(ct)
         };
 
-        self.arena.alloc(hir::ConstArg {
-            hir_id: self.next_id(),
-            kind: ct_kind,
-            is_desugared_from_effects: false,
-        })
+        self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
     }
 
     /// See [`hir::ConstArg`] for when to use this function vs
@@ -2163,19 +2159,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 None,
             );
 
-            return ConstArg {
-                hir_id: self.next_id(),
-                kind: hir::ConstArgKind::Path(qpath),
-                is_desugared_from_effects: false,
-            };
+            return ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath) };
         }
 
         let lowered_anon = self.lower_anon_const_to_anon_const(anon);
-        ConstArg {
-            hir_id: self.next_id(),
-            kind: hir::ConstArgKind::Anon(lowered_anon),
-            is_desugared_from_effects: false,
-        }
+        ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
     }
 
     /// See [`hir::ConstArg`] for when to use this function vs
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 07a6f4e5ee7..64e91c91e2c 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1200,14 +1200,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         validate_generic_param_order(self.dcx(), &generics.params, generics.span);
 
         for predicate in &generics.where_clause.predicates {
-            if let WherePredicate::EqPredicate(predicate) = predicate {
-                deny_equality_constraints(self, predicate, generics);
+            let span = predicate.span;
+            if let WherePredicateKind::EqPredicate(predicate) = &predicate.kind {
+                deny_equality_constraints(self, predicate, span, generics);
             }
         }
         walk_list!(self, visit_generic_param, &generics.params);
         for predicate in &generics.where_clause.predicates {
-            match predicate {
-                WherePredicate::BoundPredicate(bound_pred) => {
+            match &predicate.kind {
+                WherePredicateKind::BoundPredicate(bound_pred) => {
                     // This is slightly complicated. Our representation for poly-trait-refs contains a single
                     // binder and thus we only allow a single level of quantification. However,
                     // the syntax of Rust permits quantification in two places in where clauses,
@@ -1504,9 +1505,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 fn deny_equality_constraints(
     this: &AstValidator<'_>,
     predicate: &WhereEqPredicate,
+    predicate_span: Span,
     generics: &Generics,
 ) {
-    let mut err = errors::EqualityInWhere { span: predicate.span, assoc: None, assoc2: None };
+    let mut err = errors::EqualityInWhere { span: predicate_span, assoc: None, assoc2: None };
 
     // Given `<A as Foo>::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
     if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind
@@ -1550,7 +1552,7 @@ fn deny_equality_constraints(
                     }
                 }
                 err.assoc = Some(errors::AssociatedSuggestion {
-                    span: predicate.span,
+                    span: predicate_span,
                     ident: *ident,
                     param: param.ident,
                     path: pprust::path_to_string(&assoc_path),
@@ -1580,23 +1582,23 @@ fn deny_equality_constraints(
                     // We're removing th eonly where bound left, remove the whole thing.
                     generics.where_clause.span
                 } else {
-                    let mut span = predicate.span;
+                    let mut span = predicate_span;
                     let mut prev: 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() {
-                        if let WherePredicate::EqPredicate(pred) = pred
-                            && pred.span == predicate.span
+                        if let WherePredicateKind::EqPredicate(_) = pred.kind
+                            && pred.span == predicate_span
                         {
                             if let Some(next) = preds.peek() {
                                 // This is the first predicate, remove the trailing comma as well.
-                                span = span.with_hi(next.span().lo());
+                                span = span.with_hi(next.span.lo());
                             } else if let Some(prev) = prev {
                                 // Remove the previous comma as well.
                                 span = span.with_lo(prev.hi());
                             }
                         }
-                        prev = Some(pred.span());
+                        prev = Some(pred.span);
                     }
                     span
                 };
@@ -1613,8 +1615,8 @@ fn deny_equality_constraints(
     if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind {
         // Given `A: Foo, Foo::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
         for bounds in generics.params.iter().map(|p| &p.bounds).chain(
-            generics.where_clause.predicates.iter().filter_map(|pred| match pred {
-                WherePredicate::BoundPredicate(p) => Some(&p.bounds),
+            generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind {
+                WherePredicateKind::BoundPredicate(p) => Some(&p.bounds),
                 _ => None,
             }),
         ) {
@@ -1637,8 +1639,8 @@ fn deny_equality_constraints(
         // Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
         if let [potential_param, potential_assoc] = &full_path.segments[..] {
             for (ident, bounds) in generics.params.iter().map(|p| (p.ident, &p.bounds)).chain(
-                generics.where_clause.predicates.iter().filter_map(|pred| match pred {
-                    WherePredicate::BoundPredicate(p)
+                generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind {
+                    WherePredicateKind::BoundPredicate(p)
                         if let ast::TyKind::Path(None, path) = &p.bounded_ty.kind
                             && let [segment] = &path.segments[..] =>
                     {
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index be6f2c152a4..8cdc7133cc0 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -345,8 +345,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 
     fn visit_generics(&mut self, g: &'a ast::Generics) {
         for predicate in &g.where_clause.predicates {
-            match predicate {
-                ast::WherePredicate::BoundPredicate(bound_pred) => {
+            match &predicate.kind {
+                ast::WherePredicateKind::BoundPredicate(bound_pred) => {
                     // A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
                     self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
                 }
@@ -557,6 +557,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     gate_all!(global_registration, "global registration is experimental");
     gate_all!(return_type_notation, "return type notation is experimental");
     gate_all!(pin_ergonomics, "pinned reference syntax is experimental");
+    gate_all!(unsafe_fields, "`unsafe` fields are experimental");
 
     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 893bfaf8f71..04ec135c428 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -59,7 +59,7 @@ impl<'a> State<'a> {
     }
 
     fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8, fixup: FixupContext) {
-        self.print_expr_cond_paren(expr, expr.precedence().order() < prec, fixup);
+        self.print_expr_cond_paren(expr, expr.precedence() < prec, fixup);
     }
 
     /// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
@@ -615,7 +615,7 @@ impl<'a> State<'a> {
                         expr,
                         // Parenthesize if required by precedence, or in the
                         // case of `break 'inner: loop { break 'inner 1 } + 1`
-                        expr.precedence().order() < parser::PREC_JUMP
+                        expr.precedence() < parser::PREC_JUMP
                             || (opt_label.is_none() && classify::leading_labeled_expr(expr)),
                         fixup.subsequent_subexpression(),
                     );
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
index 50fd12a4e8b..6f5382ce61d 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
@@ -191,6 +191,6 @@ impl FixupContext {
     ///     "let chain".
     pub(crate) fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool {
         self.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr)
-            || parser::needs_par_as_let_scrutinee(expr.precedence().order())
+            || parser::needs_par_as_let_scrutinee(expr.precedence())
     }
 }
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 8279c66836c..1ae765c0130 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -726,11 +726,12 @@ impl<'a> State<'a> {
     }
 
     pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) {
-        match predicate {
-            ast::WherePredicate::BoundPredicate(where_bound_predicate) => {
+        let ast::WherePredicate { kind, id: _, span: _ } = predicate;
+        match kind {
+            ast::WherePredicateKind::BoundPredicate(where_bound_predicate) => {
                 self.print_where_bound_predicate(where_bound_predicate);
             }
-            ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
+            ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
                 lifetime,
                 bounds,
                 ..
@@ -742,7 +743,9 @@ impl<'a> State<'a> {
                     self.print_lifetime_bounds(bounds);
                 }
             }
-            ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
+            ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate {
+                lhs_ty, rhs_ty, ..
+            }) => {
                 self.print_type(lhs_ty);
                 self.space();
                 self.word_space("=");
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index bda96726738..92afad62aa4 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1062,8 +1062,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         && let spans = hir_generics
                             .predicates
                             .iter()
-                            .filter_map(|pred| match pred {
-                                hir::WherePredicate::BoundPredicate(pred) => Some(pred),
+                            .filter_map(|pred| match pred.kind {
+                                hir::WherePredicateKind::BoundPredicate(pred) => Some(pred),
                                 _ => None,
                             })
                             .filter(|pred| {
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index c38747f6675..6ea5c44dc01 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -5,7 +5,7 @@ use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::GenericBound::Trait;
 use rustc_hir::QPath::Resolved;
-use rustc_hir::WherePredicate::BoundPredicate;
+use rustc_hir::WherePredicateKind::BoundPredicate;
 use rustc_hir::def::Res::Def;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
@@ -236,7 +236,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         let mut hrtb_bounds = vec![];
         gat_id_and_generics.iter().flatten().for_each(|(gat_hir_id, generics)| {
             for pred in generics.predicates {
-                let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) = pred
+                let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) =
+                    pred.kind
                 else {
                     continue;
                 };
@@ -267,12 +268,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             };
             debug!(?generics_fn);
             generics_fn.predicates.iter().for_each(|predicate| {
-                let BoundPredicate(WhereBoundPredicate {
-                    span: bounded_span,
-                    bounded_ty,
-                    bounds,
-                    ..
-                }) = predicate
+                let BoundPredicate(WhereBoundPredicate { bounded_ty, bounds, .. }) = predicate.kind
                 else {
                     return;
                 };
@@ -287,7 +283,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                             .rfind(|param| param.def_id.to_def_id() == defid)
                             .is_some()
                     {
-                        suggestions.push((bounded_span.shrink_to_hi(), " + 'static".to_string()));
+                        suggestions.push((predicate.span.shrink_to_hi(), " + 'static".to_string()));
                     }
                 });
             });
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 9ae48024f44..14ac3cd74e8 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -300,7 +300,10 @@ pub fn parse_asm_args<'a>(
     if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output {
         dcx.emit_err(errors::AsmPureNoOutput { spans: args.options_spans.clone() });
     }
-    if args.options.contains(ast::InlineAsmOptions::NORETURN) && !outputs_sp.is_empty() {
+    if args.options.contains(ast::InlineAsmOptions::NORETURN)
+        && !outputs_sp.is_empty()
+        && labels_sp.is_empty()
+    {
         let err = dcx.create_err(errors::AsmNoReturn { outputs_sp });
         // Bail out now since this is likely to confuse MIR
         return Err(err);
diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
index 53e938ee216..8adb9a3f4b0 100644
--- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
@@ -288,19 +288,18 @@ pub(crate) fn expand_deriving_coerce_pointee(
     //
     // We should also write a few new `where` bounds from `#[pointee] T` to `__S`
     // as well as any bound that indirectly involves the `#[pointee] T` type.
-    for bound in &generics.where_clause.predicates {
-        if let ast::WherePredicate::BoundPredicate(bound) = bound {
+    for predicate in &generics.where_clause.predicates {
+        if let ast::WherePredicateKind::BoundPredicate(bound) = &predicate.kind {
             let mut substitution = TypeSubstitution {
                 from_name: pointee_ty_ident.name,
                 to_ty: &s_ty,
                 rewritten: false,
             };
-            let mut predicate = ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                span: bound.span,
-                bound_generic_params: bound.bound_generic_params.clone(),
-                bounded_ty: bound.bounded_ty.clone(),
-                bounds: bound.bounds.clone(),
-            });
+            let mut predicate = ast::WherePredicate {
+                kind: ast::WherePredicateKind::BoundPredicate(bound.clone()),
+                span: predicate.span,
+                id: ast::DUMMY_NODE_ID,
+            };
             substitution.visit_where_predicate(&mut predicate);
             if substitution.rewritten {
                 impl_generics.where_clause.predicates.push(predicate);
@@ -319,7 +318,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
 
 fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee: Symbol) -> bool {
     for bound in predicates {
-        if let ast::WherePredicate::BoundPredicate(bound) = bound
+        if let ast::WherePredicateKind::BoundPredicate(bound) = &bound.kind
             && bound.bounded_ty.kind.is_simple_path().is_some_and(|name| name == pointee)
         {
             for bound in &bound.bounds {
@@ -385,8 +384,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
     }
 
     fn visit_where_predicate(&mut self, where_predicate: &mut ast::WherePredicate) {
-        match where_predicate {
-            rustc_ast::WherePredicate::BoundPredicate(bound) => {
+        match &mut where_predicate.kind {
+            rustc_ast::WherePredicateKind::BoundPredicate(bound) => {
                 bound
                     .bound_generic_params
                     .flat_map_in_place(|param| self.flat_map_generic_param(param));
@@ -395,8 +394,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
                     self.visit_param_bound(bound, BoundKind::Bound)
                 }
             }
-            rustc_ast::WherePredicate::RegionPredicate(_)
-            | rustc_ast::WherePredicate::EqPredicate(_) => {}
+            rustc_ast::WherePredicateKind::RegionPredicate(_)
+            | rustc_ast::WherePredicateKind::EqPredicate(_) => {}
         }
     }
 }
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 79c198ed2d0..f6eea0b21ca 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -690,25 +690,10 @@ impl<'a> TraitDef<'a> {
 
         // and similarly for where clauses
         where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
-            match clause {
-                ast::WherePredicate::BoundPredicate(wb) => {
-                    let span = wb.span.with_ctxt(ctxt);
-                    ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                        span,
-                        ..wb.clone()
-                    })
-                }
-                ast::WherePredicate::RegionPredicate(wr) => {
-                    let span = wr.span.with_ctxt(ctxt);
-                    ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
-                        span,
-                        ..wr.clone()
-                    })
-                }
-                ast::WherePredicate::EqPredicate(we) => {
-                    let span = we.span.with_ctxt(ctxt);
-                    ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { span, ..we.clone() })
-                }
+            ast::WherePredicate {
+                kind: clause.kind.clone(),
+                id: ast::DUMMY_NODE_ID,
+                span: clause.span.with_ctxt(ctxt),
             }
         }));
 
@@ -757,13 +742,14 @@ impl<'a> TraitDef<'a> {
 
                     if !bounds.is_empty() {
                         let predicate = ast::WhereBoundPredicate {
-                            span: self.span,
                             bound_generic_params: field_ty_param.bound_generic_params,
                             bounded_ty: field_ty_param.ty,
                             bounds,
                         };
 
-                        let predicate = ast::WherePredicate::BoundPredicate(predicate);
+                        let kind = ast::WherePredicateKind::BoundPredicate(predicate);
+                        let predicate =
+                            ast::WherePredicate { kind, id: ast::DUMMY_NODE_ID, span: self.span };
                         where_clause.predicates.push(predicate);
                     }
                 }
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 7dd2139cf90..cab5b35c18d 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -80,7 +80,7 @@ pub(crate) fn get_function_sig<'tcx>(
     clif_sig_from_fn_abi(
         tcx,
         default_call_conv,
-        &RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
+        &FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
     )
 }
 
@@ -438,9 +438,9 @@ pub(crate) fn codegen_terminator_call<'tcx>(
         extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.node.ty(fx.mir, fx.tcx))),
     );
     let fn_abi = if let Some(instance) = instance {
-        RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
+        FullyMonomorphizedLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
     } else {
-        RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_sig, extra_args)
+        FullyMonomorphizedLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_sig, extra_args)
     };
 
     let is_cold = if fn_sig.abi() == ExternAbi::RustCold {
@@ -721,8 +721,8 @@ pub(crate) fn codegen_drop<'tcx>(
                     def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0),
                     args: drop_instance.args,
                 };
-                let fn_abi =
-                    RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
+                let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx)
+                    .fn_abi_of_instance(virtual_drop, ty::List::empty());
 
                 let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
                 let sig = fx.bcx.import_signature(sig);
@@ -764,8 +764,8 @@ pub(crate) fn codegen_drop<'tcx>(
                     def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0),
                     args: drop_instance.args,
                 };
-                let fn_abi =
-                    RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
+                let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx)
+                    .fn_abi_of_instance(virtual_drop, ty::List::empty());
 
                 let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
                 let sig = fx.bcx.import_signature(sig);
@@ -774,8 +774,8 @@ pub(crate) fn codegen_drop<'tcx>(
             _ => {
                 assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _)));
 
-                let fn_abi =
-                    RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(drop_instance, ty::List::empty());
+                let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx)
+                    .fn_abi_of_instance(drop_instance, ty::List::empty());
 
                 let arg_value = drop_place.place_ref(
                     fx,
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 70b7d92ce15..06cc5754894 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -103,7 +103,7 @@ pub(crate) fn codegen_fn<'tcx>(
     let block_map: IndexVec<BasicBlock, Block> =
         (0..mir.basic_blocks.len()).map(|_| bcx.create_block()).collect();
 
-    let fn_abi = RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty());
+    let fn_abi = FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty());
 
     // Make FunctionCx
     let target_config = module.target_config();
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index c663fa32965..534557fcd41 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -311,7 +311,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
 impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
-        RevealAllLayoutCx(self.tcx).handle_layout_err(err, span, ty)
+        FullyMonomorphizedLayoutCx(self.tcx).handle_layout_err(err, span, ty)
     }
 }
 
@@ -323,7 +323,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
         span: Span,
         fn_abi_request: FnAbiRequest<'tcx>,
     ) -> ! {
-        RevealAllLayoutCx(self.tcx).handle_fn_abi_err(err, span, fn_abi_request)
+        FullyMonomorphizedLayoutCx(self.tcx).handle_fn_abi_err(err, span, fn_abi_request)
     }
 }
 
@@ -443,9 +443,9 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
     }
 }
 
-pub(crate) struct RevealAllLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>);
+pub(crate) struct FullyMonomorphizedLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>);
 
-impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
+impl<'tcx> LayoutOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> {
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
         if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
@@ -459,7 +459,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
     }
 }
 
-impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
+impl<'tcx> FnAbiOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> {
     #[inline]
     fn handle_fn_abi_err(
         &self,
@@ -485,25 +485,25 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
     }
 }
 
-impl<'tcx> layout::HasTyCtxt<'tcx> for RevealAllLayoutCx<'tcx> {
+impl<'tcx> layout::HasTyCtxt<'tcx> for FullyMonomorphizedLayoutCx<'tcx> {
     fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.0
     }
 }
 
-impl<'tcx> rustc_abi::HasDataLayout for RevealAllLayoutCx<'tcx> {
+impl<'tcx> rustc_abi::HasDataLayout for FullyMonomorphizedLayoutCx<'tcx> {
     fn data_layout(&self) -> &rustc_abi::TargetDataLayout {
         &self.0.data_layout
     }
 }
 
-impl<'tcx> layout::HasTypingEnv<'tcx> for RevealAllLayoutCx<'tcx> {
+impl<'tcx> layout::HasTypingEnv<'tcx> for FullyMonomorphizedLayoutCx<'tcx> {
     fn typing_env(&self) -> ty::TypingEnv<'tcx> {
         ty::TypingEnv::fully_monomorphized()
     }
 }
 
-impl<'tcx> HasTargetSpec for RevealAllLayoutCx<'tcx> {
+impl<'tcx> HasTargetSpec for FullyMonomorphizedLayoutCx<'tcx> {
     fn target_spec(&self) -> &Target {
         &self.0.sess.target
     }
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
index 714742aeaff..a2f6691cdd2 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 
-use crate::{DebugContext, RevealAllLayoutCx, has_ptr_meta};
+use crate::{DebugContext, FullyMonomorphizedLayoutCx, has_ptr_meta};
 
 #[derive(Default)]
 pub(crate) struct TypeDebugContext<'tcx> {
@@ -85,7 +85,7 @@ impl DebugContext {
         type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(encoding));
         type_entry.set(
             gimli::DW_AT_byte_size,
-            AttributeValue::Udata(RevealAllLayoutCx(tcx).layout_of(ty).size.bytes()),
+            AttributeValue::Udata(FullyMonomorphizedLayoutCx(tcx).layout_of(ty).size.bytes()),
         );
 
         type_id
@@ -159,7 +159,7 @@ impl DebugContext {
         return_if_type_created_in_meantime!(type_dbg, tuple_type);
 
         let name = type_names::compute_debuginfo_type_name(tcx, tuple_type, false);
-        let layout = RevealAllLayoutCx(tcx).layout_of(tuple_type);
+        let layout = FullyMonomorphizedLayoutCx(tcx).layout_of(tuple_type);
 
         let tuple_type_id =
             self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_structure_type);
@@ -178,7 +178,9 @@ impl DebugContext {
             member_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty));
             member_entry.set(
                 gimli::DW_AT_alignment,
-                AttributeValue::Udata(RevealAllLayoutCx(tcx).layout_of(ty).align.pref.bytes()),
+                AttributeValue::Udata(
+                    FullyMonomorphizedLayoutCx(tcx).layout_of(ty).align.pref.bytes(),
+                ),
             );
             member_entry.set(
                 gimli::DW_AT_data_member_location,
@@ -198,7 +200,11 @@ impl DebugContext {
         self.debug_type(
             tcx,
             type_dbg,
-            Ty::new_array(tcx, tcx.types.u8, RevealAllLayoutCx(tcx).layout_of(ty).size.bytes()),
+            Ty::new_array(
+                tcx,
+                tcx.types.u8,
+                FullyMonomorphizedLayoutCx(tcx).layout_of(ty).size.bytes(),
+            ),
         )
     }
 }
diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs
index 6f90d17920d..c0a3ce84d52 100644
--- a/compiler/rustc_codegen_cranelift/src/global_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs
@@ -42,7 +42,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
                                         tcx,
                                         op_sp,
                                         const_value,
-                                        RevealAllLayoutCx(tcx).layout_of(ty),
+                                        FullyMonomorphizedLayoutCx(tcx).layout_of(ty),
                                     );
                                     global_asm.push_str(&string);
                                 }
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index 0df1a30fc0a..7bc500b1814 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -238,7 +238,7 @@ pub(crate) fn codegen_naked_asm<'tcx>(
                     tcx,
                     span,
                     const_value,
-                    RevealAllLayoutCx(tcx).layout_of(cv.ty()),
+                    FullyMonomorphizedLayoutCx(tcx).layout_of(cv.ty()),
                 );
                 CInlineAsmOperand::Const { value }
             }
@@ -462,8 +462,12 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
         let mut slots_output = vec![None; self.operands.len()];
 
         let new_slot_fn = |slot_size: &mut Size, reg_class: InlineAsmRegClass| {
-            let reg_size =
-                reg_class.supported_types(self.arch).iter().map(|(ty, _)| ty.size()).max().unwrap();
+            let reg_size = reg_class
+                .supported_types(self.arch, true)
+                .iter()
+                .map(|(ty, _)| ty.size())
+                .max()
+                .unwrap();
             let align = rustc_abi::Align::from_bytes(reg_size.bytes()).unwrap();
             let offset = slot_size.align_to(align);
             *slot_size = offset + reg_size;
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 6b067b35e71..ab4fdb78bb0 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -186,7 +186,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                             // `clobber_abi` can add lots of clobbers that are not supported by the target,
                             // such as AVX-512 registers, so we just ignore unsupported registers
                             let is_target_supported =
-                                reg.reg_class().supported_types(asm_arch).iter().any(
+                                reg.reg_class().supported_types(asm_arch, true).iter().any(
                                     |&(_, feature)| {
                                         if let Some(feature) = feature {
                                             self.tcx
@@ -683,9 +683,8 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
             InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
             InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a",
             InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
-            InlineAsmRegClass::S390x(
-                S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg,
-            ) => {
+            InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => "v",
+            InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => {
                 unreachable!("clobber-only")
             }
             InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => "r",
@@ -766,7 +765,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
             S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr,
         ) => cx.type_i32(),
         InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
-        InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
+        InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i64(), 2),
+        InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => {
             unreachable!("clobber-only")
         }
         InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => cx.type_i32(),
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index bb74dfe1487..6ee80c08d4a 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -45,7 +45,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
             match *op {
                 InlineAsmOperandRef::Out { reg, late, place } => {
                     let is_target_supported = |reg_class: InlineAsmRegClass| {
-                        for &(_, feature) in reg_class.supported_types(asm_arch) {
+                        for &(_, feature) in reg_class.supported_types(asm_arch, true) {
                             if let Some(feature) = feature {
                                 if self
                                     .tcx
@@ -85,7 +85,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                         }
                         continue;
                     } else if !is_target_supported(reg.reg_class())
-                        || reg.reg_class().is_clobber_only(asm_arch)
+                        || reg.reg_class().is_clobber_only(asm_arch, true)
                     {
                         // We turn discarded outputs into clobber constraints
                         // if the target feature needed by the register class is
@@ -342,24 +342,32 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
         }
         attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });
 
-        // Switch to the 'normal' basic block if we did an `invoke` instead of a `call`
-        if let Some(dest) = dest {
-            self.switch_to_block(dest);
-        }
+        // Write results to outputs. We need to do this for all possible control flow.
+        //
+        // Note that `dest` maybe populated with unreachable_block when asm goto with outputs
+        // is used (because we need to codegen callbr which always needs a destination), so
+        // here we use the NORETURN option to determine if `dest` should be used.
+        for block in (if options.contains(InlineAsmOptions::NORETURN) { None } else { Some(dest) })
+            .into_iter()
+            .chain(labels.iter().copied().map(Some))
+        {
+            if let Some(block) = block {
+                self.switch_to_block(block);
+            }
 
-        // Write results to outputs
-        for (idx, op) in operands.iter().enumerate() {
-            if let InlineAsmOperandRef::Out { reg, place: Some(place), .. }
-            | InlineAsmOperandRef::InOut { reg, out_place: Some(place), .. } = *op
-            {
-                let value = if output_types.len() == 1 {
-                    result
-                } else {
-                    self.extract_value(result, op_idx[&idx] as u64)
-                };
-                let value =
-                    llvm_fixup_output(self, value, reg.reg_class(), &place.layout, instance);
-                OperandValue::Immediate(value).store(self, place);
+            for (idx, op) in operands.iter().enumerate() {
+                if let InlineAsmOperandRef::Out { reg, place: Some(place), .. }
+                | InlineAsmOperandRef::InOut { reg, out_place: Some(place), .. } = *op
+                {
+                    let value = if output_types.len() == 1 {
+                        result
+                    } else {
+                        self.extract_value(result, op_idx[&idx] as u64)
+                    };
+                    let value =
+                        llvm_fixup_output(self, value, reg.reg_class(), &place.layout, instance);
+                    OperandValue::Immediate(value).store(self, place);
+                }
             }
         }
     }
@@ -678,7 +686,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
             S390x(S390xInlineAsmRegClass::reg) => "r",
             S390x(S390xInlineAsmRegClass::reg_addr) => "a",
             S390x(S390xInlineAsmRegClass::freg) => "f",
-            S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
+            S390x(S390xInlineAsmRegClass::vreg) => "v",
+            S390x(S390xInlineAsmRegClass::areg) => {
                 unreachable!("clobber-only")
             }
             Sparc(SparcInlineAsmRegClass::reg) => "r",
@@ -844,7 +853,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
         Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(),
         S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(),
         S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
-        S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
+        S390x(S390xInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i64(), 2),
+        S390x(S390xInlineAsmRegClass::areg) => {
             unreachable!("clobber-only")
         }
         Sparc(SparcInlineAsmRegClass::reg) => cx.type_i32(),
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index a65ae4df1e3..00f7b479fa7 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -955,24 +955,7 @@ pub(crate) fn bitcode_section_name(cgcx: &CodegenContext<LlvmCodegenBackend>) ->
     }
 }
 
-/// Embed the bitcode of an LLVM module in the LLVM module itself.
-///
-/// This is done primarily for iOS where it appears to be standard to compile C
-/// code at least with `-fembed-bitcode` which creates two sections in the
-/// executable:
-///
-/// * __LLVM,__bitcode
-/// * __LLVM,__cmdline
-///
-/// It appears *both* of these sections are necessary to get the linker to
-/// recognize what's going on. A suitable cmdline value is taken from the
-/// target spec.
-///
-/// Furthermore debug/O1 builds don't actually embed bitcode but rather just
-/// embed an empty section.
-///
-/// Basically all of this is us attempting to follow in the footsteps of clang
-/// on iOS. See #35968 for lots more info.
+/// Embed the bitcode of an LLVM module for LTO in the LLVM module itself.
 unsafe fn embed_bitcode(
     cgcx: &CodegenContext<LlvmCodegenBackend>,
     llcx: &llvm::Context,
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index 32793894794..f62310bd948 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -172,3 +172,12 @@ pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
         Visibility::Protected => llvm::Visibility::Protected,
     }
 }
+
+pub(crate) fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) {
+    if attrs.no_sanitize.contains(SanitizerSet::ADDRESS) {
+        unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval) };
+    }
+    if attrs.no_sanitize.contains(SanitizerSet::HWADDRESS) {
+        unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval) };
+    }
+}
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 6f5ffbb4b34..c7114480d8b 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -470,6 +470,8 @@ impl<'ll> CodegenCx<'ll, '_> {
                 base::set_link_section(g, attrs);
             }
 
+            base::set_variable_sanitizer_attrs(g, attrs);
+
             if attrs.flags.contains(CodegenFnAttrFlags::USED) {
                 // `USED` and `USED_LINKER` can't be used together.
                 assert!(!attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER));
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
index a6e07ea2a60..19d6726002c 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
@@ -1,6 +1,4 @@
-use rustc_middle::mir::coverage::{CounterId, CovTerm, ExpressionId, SourceRegion};
-
-use crate::coverageinfo::mapgen::LocalFileId;
+use rustc_middle::mir::coverage::{CounterId, CovTerm, ExpressionId};
 
 /// Must match the layout of `LLVMRustCounterKind`.
 #[derive(Copy, Clone, Debug)]
@@ -126,37 +124,23 @@ pub(crate) struct CoverageSpan {
     /// Local index into the function's local-to-global file ID table.
     /// The value at that index is itself an index into the coverage filename
     /// table in the CGU's `__llvm_covmap` section.
-    file_id: u32,
+    pub(crate) file_id: u32,
 
     /// 1-based starting line of the source code span.
-    start_line: u32,
+    pub(crate) start_line: u32,
     /// 1-based starting column of the source code span.
-    start_col: u32,
+    pub(crate) start_col: u32,
     /// 1-based ending line of the source code span.
-    end_line: u32,
+    pub(crate) end_line: u32,
     /// 1-based ending column of the source code span. High bit must be unset.
-    end_col: u32,
-}
-
-impl CoverageSpan {
-    pub(crate) fn from_source_region(
-        local_file_id: LocalFileId,
-        code_region: &SourceRegion,
-    ) -> Self {
-        let file_id = local_file_id.as_u32();
-        let &SourceRegion { start_line, start_col, end_line, end_col } = code_region;
-        // Internally, LLVM uses the high bit of `end_col` to distinguish between
-        // code regions and gap regions, so it can't be used by the column number.
-        assert!(end_col & (1u32 << 31) == 0, "high bit of `end_col` must be unset: {end_col:#X}");
-        Self { file_id, start_line, start_col, end_line, end_col }
-    }
+    pub(crate) end_col: u32,
 }
 
 /// Must match the layout of `LLVMRustCoverageCodeRegion`.
 #[derive(Clone, Debug)]
 #[repr(C)]
 pub(crate) struct CodeRegion {
-    pub(crate) span: CoverageSpan,
+    pub(crate) cov_span: CoverageSpan,
     pub(crate) counter: Counter,
 }
 
@@ -164,7 +148,7 @@ pub(crate) struct CodeRegion {
 #[derive(Clone, Debug)]
 #[repr(C)]
 pub(crate) struct BranchRegion {
-    pub(crate) span: CoverageSpan,
+    pub(crate) cov_span: CoverageSpan,
     pub(crate) true_counter: Counter,
     pub(crate) false_counter: Counter,
 }
@@ -173,7 +157,7 @@ pub(crate) struct BranchRegion {
 #[derive(Clone, Debug)]
 #[repr(C)]
 pub(crate) struct MCDCBranchRegion {
-    pub(crate) span: CoverageSpan,
+    pub(crate) cov_span: CoverageSpan,
     pub(crate) true_counter: Counter,
     pub(crate) false_counter: Counter,
     pub(crate) mcdc_branch_params: mcdc::BranchParameters,
@@ -183,6 +167,6 @@ pub(crate) struct MCDCBranchRegion {
 #[derive(Clone, Debug)]
 #[repr(C)]
 pub(crate) struct MCDCDecisionRegion {
-    pub(crate) span: CoverageSpan,
+    pub(crate) cov_span: CoverageSpan,
     pub(crate) mcdc_decision_params: mcdc::DecisionParameters,
 }
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
index e3c0df27883..95746b88ced 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
@@ -3,9 +3,9 @@ use rustc_data_structures::fx::FxIndexSet;
 use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::coverage::{
     CounterId, CovTerm, Expression, ExpressionId, FunctionCoverageInfo, Mapping, MappingKind, Op,
-    SourceRegion,
 };
 use rustc_middle::ty::Instance;
+use rustc_span::Span;
 use tracing::{debug, instrument};
 
 use crate::coverageinfo::ffi::{Counter, CounterExpression, ExprKind};
@@ -220,16 +220,16 @@ impl<'tcx> FunctionCoverage<'tcx> {
         })
     }
 
-    /// Converts this function's coverage mappings into an intermediate form
-    /// that will be used by `mapgen` when preparing for FFI.
-    pub(crate) fn counter_regions(
+    /// Yields all this function's coverage mappings, after simplifying away
+    /// unused counters and counter expressions.
+    pub(crate) fn mapping_spans(
         &self,
-    ) -> impl Iterator<Item = (MappingKind, &SourceRegion)> + ExactSizeIterator {
+    ) -> impl Iterator<Item = (MappingKind, Span)> + ExactSizeIterator + Captures<'_> {
         self.function_coverage_info.mappings.iter().map(move |mapping| {
-            let Mapping { kind, source_region } = mapping;
+            let &Mapping { ref kind, span } = mapping;
             let kind =
                 kind.map_terms(|term| if self.is_zero_term(term) { CovTerm::Zero } else { term });
-            (kind, source_region)
+            (kind, span)
         })
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index b582dd967a7..ed881418cb0 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -1,12 +1,14 @@
+mod spans;
+
 use std::ffi::CString;
-use std::iter;
+use std::sync::Arc;
 
 use itertools::Itertools as _;
 use rustc_abi::Align;
 use rustc_codegen_ssa::traits::{
     BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
 };
-use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_index::IndexVec;
 use rustc_middle::mir::coverage::MappingKind;
@@ -15,7 +17,7 @@ use rustc_middle::{bug, mir};
 use rustc_session::RemapFileNameExt;
 use rustc_session::config::RemapPathScopeComponents;
 use rustc_span::def_id::DefIdSet;
-use rustc_span::{Span, Symbol};
+use rustc_span::{SourceFile, StableSourceFileId};
 use rustc_target::spec::HasTargetSpec;
 use tracing::debug;
 
@@ -72,11 +74,11 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
         .map(|(instance, function_coverage)| (instance, function_coverage.into_finished()))
         .collect::<Vec<_>>();
 
-    let all_file_names = function_coverage_entries
+    let all_files = function_coverage_entries
         .iter()
         .map(|(_, fn_cov)| fn_cov.function_coverage_info.body_span)
-        .map(|span| span_file_name(tcx, span));
-    let global_file_table = GlobalFileTable::new(all_file_names);
+        .map(|span| tcx.sess.source_map().lookup_source_file(span.lo()));
+    let global_file_table = GlobalFileTable::new(all_files);
 
     // Encode all filenames referenced by coverage mappings in this CGU.
     let filenames_buffer = global_file_table.make_filenames_buffer(tcx);
@@ -103,15 +105,8 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
             encode_mappings_for_function(tcx, &global_file_table, &function_coverage);
 
         if coverage_mapping_buffer.is_empty() {
-            if function_coverage.is_used() {
-                bug!(
-                    "A used function should have had coverage mapping data but did not: {}",
-                    mangled_function_name
-                );
-            } else {
-                debug!("unused function had no coverage mapping data: {}", mangled_function_name);
-                continue;
-            }
+            debug!("function has no mappings to embed; skipping");
+            continue;
         }
 
         if !is_used {
@@ -148,29 +143,34 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
     }
 }
 
-/// Maps "global" (per-CGU) file ID numbers to their underlying filenames.
+/// Maps "global" (per-CGU) file ID numbers to their underlying source files.
 struct GlobalFileTable {
-    /// This "raw" table doesn't include the working dir, so a filename's
+    /// This "raw" table doesn't include the working dir, so a file's
     /// global ID is its index in this set **plus one**.
-    raw_file_table: FxIndexSet<Symbol>,
+    raw_file_table: FxIndexMap<StableSourceFileId, Arc<SourceFile>>,
 }
 
 impl GlobalFileTable {
-    fn new(all_file_names: impl IntoIterator<Item = Symbol>) -> Self {
-        // Collect all of the filenames into a set. Filenames usually come in
-        // contiguous runs, so we can dedup adjacent ones to save work.
-        let mut raw_file_table = all_file_names.into_iter().dedup().collect::<FxIndexSet<Symbol>>();
+    fn new(all_files: impl IntoIterator<Item = Arc<SourceFile>>) -> Self {
+        // Collect all of the files into a set. Files usually come in contiguous
+        // runs, so we can dedup adjacent ones to save work.
+        let mut raw_file_table = all_files
+            .into_iter()
+            .dedup_by(|a, b| a.stable_id == b.stable_id)
+            .map(|f| (f.stable_id, f))
+            .collect::<FxIndexMap<StableSourceFileId, Arc<SourceFile>>>();
 
-        // Sort the file table by its actual string values, not the arbitrary
-        // ordering of its symbols.
-        raw_file_table.sort_unstable_by(|a, b| a.as_str().cmp(b.as_str()));
+        // Sort the file table by its underlying filenames.
+        raw_file_table.sort_unstable_by(|_, a, _, b| {
+            Ord::cmp(&a.name, &b.name).then_with(|| Ord::cmp(&a.stable_id, &b.stable_id))
+        });
 
         Self { raw_file_table }
     }
 
-    fn global_file_id_for_file_name(&self, file_name: Symbol) -> GlobalFileId {
-        let raw_id = self.raw_file_table.get_index_of(&file_name).unwrap_or_else(|| {
-            bug!("file name not found in prepared global file table: {file_name}");
+    fn global_file_id_for_file(&self, file: &SourceFile) -> GlobalFileId {
+        let raw_id = self.raw_file_table.get_index_of(&file.stable_id).unwrap_or_else(|| {
+            bug!("file not found in prepared global file table: {:?}", file.name);
         });
         // The raw file table doesn't include an entry for the working dir
         // (which has ID 0), so add 1 to get the correct ID.
@@ -178,24 +178,27 @@ impl GlobalFileTable {
     }
 
     fn make_filenames_buffer(&self, tcx: TyCtxt<'_>) -> Vec<u8> {
+        let mut table = Vec::with_capacity(self.raw_file_table.len() + 1);
+
         // LLVM Coverage Mapping Format version 6 (zero-based encoded as 5)
         // requires setting the first filename to the compilation directory.
         // Since rustc generates coverage maps with relative paths, the
         // compilation directory can be combined with the relative paths
         // to get absolute paths, if needed.
-        use rustc_session::RemapFileNameExt;
-        use rustc_session::config::RemapPathScopeComponents;
-        let working_dir: &str = &tcx
-            .sess
-            .opts
-            .working_dir
-            .for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
-            .to_string_lossy();
-
-        // Insert the working dir at index 0, before the other filenames.
-        let filenames =
-            iter::once(working_dir).chain(self.raw_file_table.iter().map(Symbol::as_str));
-        llvm_cov::write_filenames_to_buffer(filenames)
+        table.push(
+            tcx.sess
+                .opts
+                .working_dir
+                .for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
+                .to_string_lossy(),
+        );
+
+        // Add the regular entries after the base directory.
+        table.extend(self.raw_file_table.values().map(|file| {
+            file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy()
+        }));
+
+        llvm_cov::write_filenames_to_buffer(table.iter().map(|f| f.as_ref()))
     }
 }
 
@@ -208,7 +211,7 @@ rustc_index::newtype_index! {
     /// An index into a function's list of global file IDs. That underlying list
     /// of local-to-global mappings will be embedded in the function's record in
     /// the `__llvm_covfun` linker section.
-    pub(crate) struct LocalFileId {}
+    struct LocalFileId {}
 }
 
 /// Holds a mapping from "local" (per-function) file IDs to "global" (per-CGU)
@@ -234,13 +237,6 @@ impl VirtualFileMapping {
     }
 }
 
-fn span_file_name(tcx: TyCtxt<'_>, span: Span) -> Symbol {
-    let source_file = tcx.sess.source_map().lookup_source_file(span.lo());
-    let name =
-        source_file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy();
-    Symbol::intern(&name)
-}
-
 /// Using the expressions and counter regions collected for a single function,
 /// generate the variable-sized payload of its corresponding `__llvm_covfun`
 /// entry. The payload is returned as a vector of bytes.
@@ -251,11 +247,13 @@ fn encode_mappings_for_function(
     global_file_table: &GlobalFileTable,
     function_coverage: &FunctionCoverage<'_>,
 ) -> Vec<u8> {
-    let counter_regions = function_coverage.counter_regions();
-    if counter_regions.is_empty() {
+    let mapping_spans = function_coverage.mapping_spans();
+    if mapping_spans.is_empty() {
         return Vec::new();
     }
 
+    let fn_cov_info = function_coverage.function_coverage_info;
+
     let expressions = function_coverage.counter_expressions().collect::<Vec<_>>();
 
     let mut virtual_file_mapping = VirtualFileMapping::default();
@@ -265,34 +263,39 @@ fn encode_mappings_for_function(
     let mut mcdc_decision_regions = vec![];
 
     // Currently a function's mappings must all be in the same file as its body span.
-    let file_name = span_file_name(tcx, function_coverage.function_coverage_info.body_span);
+    let source_map = tcx.sess.source_map();
+    let source_file = source_map.lookup_source_file(fn_cov_info.body_span.lo());
 
-    // Look up the global file ID for that filename.
-    let global_file_id = global_file_table.global_file_id_for_file_name(file_name);
+    // Look up the global file ID for that file.
+    let global_file_id = global_file_table.global_file_id_for_file(&source_file);
 
     // Associate that global file ID with a local file ID for this function.
     let local_file_id = virtual_file_mapping.local_id_for_global(global_file_id);
-    debug!("  file id: {local_file_id:?} => {global_file_id:?} = '{file_name:?}'");
 
-    // For each counter/region pair in this function+file, convert it to a
+    let make_cov_span = |span| {
+        spans::make_coverage_span(local_file_id, source_map, fn_cov_info, &source_file, span)
+    };
+
+    // For each coverage mapping span in this function+file, convert it to a
     // form suitable for FFI.
-    for (mapping_kind, region) in counter_regions {
-        debug!("Adding counter {mapping_kind:?} to map for {region:?}");
-        let span = ffi::CoverageSpan::from_source_region(local_file_id, region);
+    for (mapping_kind, span) in mapping_spans {
+        debug!("Adding counter {mapping_kind:?} to map for {span:?}");
+        let Some(cov_span) = make_cov_span(span) else { continue };
         match mapping_kind {
             MappingKind::Code(term) => {
-                code_regions.push(ffi::CodeRegion { span, counter: ffi::Counter::from_term(term) });
+                code_regions
+                    .push(ffi::CodeRegion { cov_span, counter: ffi::Counter::from_term(term) });
             }
             MappingKind::Branch { true_term, false_term } => {
                 branch_regions.push(ffi::BranchRegion {
-                    span,
+                    cov_span,
                     true_counter: ffi::Counter::from_term(true_term),
                     false_counter: ffi::Counter::from_term(false_term),
                 });
             }
             MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => {
                 mcdc_branch_regions.push(ffi::MCDCBranchRegion {
-                    span,
+                    cov_span,
                     true_counter: ffi::Counter::from_term(true_term),
                     false_counter: ffi::Counter::from_term(false_term),
                     mcdc_branch_params: ffi::mcdc::BranchParameters::from(mcdc_params),
@@ -300,7 +303,7 @@ fn encode_mappings_for_function(
             }
             MappingKind::MCDCDecision(mcdc_decision_params) => {
                 mcdc_decision_regions.push(ffi::MCDCDecisionRegion {
-                    span,
+                    cov_span,
                     mcdc_decision_params: ffi::mcdc::DecisionParameters::from(mcdc_decision_params),
                 });
             }
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs
new file mode 100644
index 00000000000..4a7721879fd
--- /dev/null
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs
@@ -0,0 +1,124 @@
+use rustc_middle::mir::coverage::FunctionCoverageInfo;
+use rustc_span::source_map::SourceMap;
+use rustc_span::{BytePos, Pos, SourceFile, Span};
+use tracing::debug;
+
+use crate::coverageinfo::ffi;
+use crate::coverageinfo::mapgen::LocalFileId;
+
+/// Converts the span into its start line and column, and end line and column.
+///
+/// Line numbers and column numbers are 1-based. Unlike most column numbers emitted by
+/// the compiler, these column numbers are denoted in **bytes**, because that's what
+/// LLVM's `llvm-cov` tool expects to see in coverage maps.
+///
+/// Returns `None` if the conversion failed for some reason. This shouldn't happen,
+/// but it's hard to rule out entirely (especially in the presence of complex macros
+/// or other expansions), and if it does happen then skipping a span or function is
+/// better than an ICE or `llvm-cov` failure that the user might have no way to avoid.
+pub(crate) fn make_coverage_span(
+    file_id: LocalFileId,
+    source_map: &SourceMap,
+    fn_cov_info: &FunctionCoverageInfo,
+    file: &SourceFile,
+    span: Span,
+) -> Option<ffi::CoverageSpan> {
+    let span = ensure_non_empty_span(source_map, fn_cov_info, span)?;
+
+    let lo = span.lo();
+    let hi = span.hi();
+
+    // Column numbers need to be in bytes, so we can't use the more convenient
+    // `SourceMap` methods for looking up file coordinates.
+    let line_and_byte_column = |pos: BytePos| -> Option<(usize, usize)> {
+        let rpos = file.relative_position(pos);
+        let line_index = file.lookup_line(rpos)?;
+        let line_start = file.lines()[line_index];
+        // Line numbers and column numbers are 1-based, so add 1 to each.
+        Some((line_index + 1, (rpos - line_start).to_usize() + 1))
+    };
+
+    let (mut start_line, start_col) = line_and_byte_column(lo)?;
+    let (mut end_line, end_col) = line_and_byte_column(hi)?;
+
+    // Apply an offset so that code in doctests has correct line numbers.
+    // FIXME(#79417): Currently we have no way to offset doctest _columns_.
+    start_line = source_map.doctest_offset_line(&file.name, start_line);
+    end_line = source_map.doctest_offset_line(&file.name, end_line);
+
+    check_coverage_span(ffi::CoverageSpan {
+        file_id: file_id.as_u32(),
+        start_line: start_line as u32,
+        start_col: start_col as u32,
+        end_line: end_line as u32,
+        end_col: end_col as u32,
+    })
+}
+
+fn ensure_non_empty_span(
+    source_map: &SourceMap,
+    fn_cov_info: &FunctionCoverageInfo,
+    span: Span,
+) -> Option<Span> {
+    if !span.is_empty() {
+        return Some(span);
+    }
+
+    let lo = span.lo();
+    let hi = span.hi();
+
+    // The span is empty, so try to expand it to cover an adjacent '{' or '}',
+    // but only within the bounds of the body span.
+    let try_next = hi < fn_cov_info.body_span.hi();
+    let try_prev = fn_cov_info.body_span.lo() < lo;
+    if !(try_next || try_prev) {
+        return None;
+    }
+
+    source_map
+        .span_to_source(span, |src, start, end| try {
+            // We're only checking for specific ASCII characters, so we don't
+            // have to worry about multi-byte code points.
+            if try_next && src.as_bytes()[end] == b'{' {
+                Some(span.with_hi(hi + BytePos(1)))
+            } else if try_prev && src.as_bytes()[start - 1] == b'}' {
+                Some(span.with_lo(lo - BytePos(1)))
+            } else {
+                None
+            }
+        })
+        .ok()?
+}
+
+/// If `llvm-cov` sees a source region that is improperly ordered (end < start),
+/// it will immediately exit with a fatal error. To prevent that from happening,
+/// discard regions that are improperly ordered, or might be interpreted in a
+/// way that makes them improperly ordered.
+fn check_coverage_span(cov_span: ffi::CoverageSpan) -> Option<ffi::CoverageSpan> {
+    let ffi::CoverageSpan { file_id: _, start_line, start_col, end_line, end_col } = cov_span;
+
+    // Line/column coordinates are supposed to be 1-based. If we ever emit
+    // coordinates of 0, `llvm-cov` might misinterpret them.
+    let all_nonzero = [start_line, start_col, end_line, end_col].into_iter().all(|x| x != 0);
+    // Coverage mappings use the high bit of `end_col` to indicate that a
+    // region is actually a "gap" region, so make sure it's unset.
+    let end_col_has_high_bit_unset = (end_col & (1 << 31)) == 0;
+    // If a region is improperly ordered (end < start), `llvm-cov` will exit
+    // with a fatal error, which is inconvenient for users and hard to debug.
+    let is_ordered = (start_line, start_col) <= (end_line, end_col);
+
+    if all_nonzero && end_col_has_high_bit_unset && is_ordered {
+        Some(cov_span)
+    } else {
+        debug!(
+            ?cov_span,
+            ?all_nonzero,
+            ?end_col_has_high_bit_unset,
+            ?is_ordered,
+            "Skipping source region that would be misinterpreted or rejected by LLVM"
+        );
+        // If this happens in a debug build, ICE to make it easier to notice.
+        debug_assert!(false, "Improper source region: {cov_span:?}");
+        None
+    }
+}
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 3dfb86d422d..9f398107fc6 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -17,6 +17,7 @@
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
+#![feature(try_blocks)]
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 7f59264824e..17b0ec4b936 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2460,4 +2460,7 @@ unsafe extern "C" {
     pub fn LLVMRustIs64BitSymbolicFile(buf_ptr: *const u8, buf_len: usize) -> bool;
 
     pub fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool;
+
+    pub fn LLVMRustSetNoSanitizeAddress(Global: &Value);
+    pub fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 5149e3a12f2..651485a1876 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1117,14 +1117,14 @@ fn link_natively(
         let stripcmd = "rust-objcopy";
         match (strip, crate_type) {
             (Strip::Debuginfo, _) => {
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-S"))
+                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-S"])
             }
             // Per the manpage, `-x` is the maximum safe strip level for dynamic libraries. (#93988)
             (Strip::Symbols, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro) => {
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-x"))
+                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-x"])
             }
             (Strip::Symbols, _) => {
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, None)
+                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[])
             }
             (Strip::None, _) => {}
         }
@@ -1141,7 +1141,7 @@ fn link_natively(
         match strip {
             // Always preserve the symbol table (-x).
             Strip::Debuginfo => {
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-x"))
+                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-x"])
             }
             // Strip::Symbols is handled via the --strip-all linker option.
             Strip::Symbols => {}
@@ -1158,11 +1158,15 @@ fn link_natively(
         match strip {
             Strip::Debuginfo => {
                 // FIXME: AIX's strip utility only offers option to strip line number information.
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-l"))
+                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[
+                    "-X32_64", "-l",
+                ])
             }
             Strip::Symbols => {
                 // Must be noted this option might remove symbol __aix_rust_metadata and thus removes .info section which contains metadata.
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-r"))
+                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[
+                    "-X32_64", "-r",
+                ])
             }
             Strip::None => {}
         }
@@ -1181,12 +1185,10 @@ fn strip_symbols_with_external_utility(
     sess: &Session,
     util: &str,
     out_filename: &Path,
-    option: Option<&str>,
+    options: &[&str],
 ) {
     let mut cmd = Command::new(util);
-    if let Some(option) = option {
-        cmd.arg(option);
-    }
+    cmd.args(options);
 
     let mut new_path = sess.get_tools_search_paths(false);
     if let Some(path) = env::var_os("PATH") {
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index a2285bf9204..7c0e9cfd5a7 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -432,11 +432,9 @@ struct CompiledModules {
 
 fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool {
     let sess = tcx.sess;
-    let requested_for_rlib = sess.opts.cg.embed_bitcode
+    sess.opts.cg.embed_bitcode
         && tcx.crate_types().contains(&CrateType::Rlib)
-        && sess.opts.output_types.contains_key(&OutputType::Exe);
-    let forced_by_target = sess.target.forces_embed_bitcode;
-    requested_for_rlib || forced_by_target
+        && sess.opts.output_types.contains_key(&OutputType::Exe)
 }
 
 fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 32e9422e005..a5acd8170ab 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -576,9 +576,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
     // If this closure is marked `#[inline(always)]`, simply skip adding `#[target_feature]`.
     //
     // At this point, `unsafe` has already been checked and `#[target_feature]` only affects codegen.
-    // Emitting both `#[inline(always)]` and `#[target_feature]` can potentially result in an
-    // ICE, because LLVM errors when the function fails to be inlined due to a target feature
-    // mismatch.
+    // Due to LLVM limitations, emitting both `#[inline(always)]` and `#[target_feature]` is *unsound*:
+    // the function may be inlined into a caller with fewer target features. Also see
+    // <https://github.com/rust-lang/rust/issues/116573>.
     //
     // Using `#[inline(always)]` implies that this closure will most likely be inlined into
     // its parent function, which effectively inherits the features anyway. Boxing this closure
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 1129b5caec5..916929b6c0b 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -18,13 +18,12 @@ use rustc_middle::span_bug;
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_mir_dataflow::Analysis;
-use rustc_mir_dataflow::impls::MaybeStorageLive;
-use rustc_mir_dataflow::storage::always_storage_live_locals;
+use rustc_mir_dataflow::impls::{MaybeStorageLive, always_storage_live_locals};
 use rustc_span::{Span, Symbol, sym};
 use rustc_trait_selection::traits::{
     Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt,
 };
-use tracing::{debug, instrument, trace};
+use tracing::{instrument, trace};
 
 use super::ops::{self, NonConstOp, Status};
 use super::qualifs::{self, HasMutInterior, NeedsDrop, NeedsNonConstDrop};
@@ -47,7 +46,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
     /// Returns `true` if `local` is `NeedsDrop` at the given `Location`.
     ///
     /// Only updates the cursor if absolutely necessary
-    fn needs_drop(
+    pub(crate) fn needs_drop(
         &mut self,
         ccx: &'mir ConstCx<'mir, 'tcx>,
         local: Local,
@@ -421,6 +420,43 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
 
         true
     }
+
+    pub fn check_drop_terminator(
+        &mut self,
+        dropped_place: Place<'tcx>,
+        location: Location,
+        terminator_span: Span,
+    ) {
+        let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty;
+
+        let needs_drop = if let Some(local) = dropped_place.as_local() {
+            self.qualifs.needs_drop(self.ccx, local, location)
+        } else {
+            qualifs::NeedsDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place)
+        };
+        // If this type doesn't need a drop at all, then there's nothing to enforce.
+        if !needs_drop {
+            return;
+        }
+
+        let mut err_span = self.span;
+        let needs_non_const_drop = if let Some(local) = dropped_place.as_local() {
+            // Use the span where the local was declared as the span of the drop error.
+            err_span = self.body.local_decls[local].source_info.span;
+            self.qualifs.needs_non_const_drop(self.ccx, local, location)
+        } else {
+            qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place)
+        };
+
+        self.check_op_spanned(
+            ops::LiveDrop {
+                dropped_at: terminator_span,
+                dropped_ty: ty_of_dropped_place,
+                needs_non_const_drop,
+            },
+            err_span,
+        );
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
@@ -866,35 +902,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     return;
                 }
 
-                let mut err_span = self.span;
-                let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty;
-
-                let ty_needs_non_const_drop =
-                    qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place);
-
-                debug!(?ty_of_dropped_place, ?ty_needs_non_const_drop);
-
-                if !ty_needs_non_const_drop {
-                    return;
-                }
-
-                let needs_non_const_drop = if let Some(local) = dropped_place.as_local() {
-                    // Use the span where the local was declared as the span of the drop error.
-                    err_span = self.body.local_decls[local].source_info.span;
-                    self.qualifs.needs_non_const_drop(self.ccx, local, location)
-                } else {
-                    true
-                };
-
-                if needs_non_const_drop {
-                    self.check_op_spanned(
-                        ops::LiveDrop {
-                            dropped_at: Some(terminator.source_info.span),
-                            dropped_ty: ty_of_dropped_place,
-                        },
-                        err_span,
-                    );
-                }
+                self.check_drop_terminator(*dropped_place, location, terminator.source_info.span);
             }
 
             TerminatorKind::InlineAsm { .. } => self.check_op(ops::InlineAsm),
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index 8ba6b89aad4..ab81e60a33f 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -459,17 +459,43 @@ impl<'tcx> NonConstOp<'tcx> for InlineAsm {
 
 #[derive(Debug)]
 pub(crate) struct LiveDrop<'tcx> {
-    pub dropped_at: Option<Span>,
+    pub dropped_at: Span,
     pub dropped_ty: Ty<'tcx>,
+    pub needs_non_const_drop: bool,
 }
 impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> {
+    fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
+        if self.needs_non_const_drop {
+            Status::Forbidden
+        } else {
+            Status::Unstable {
+                gate: sym::const_destruct,
+                gate_already_checked: false,
+                safe_to_expose_on_stable: false,
+                is_function_call: false,
+            }
+        }
+    }
+
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
-        ccx.dcx().create_err(errors::LiveDrop {
-            span,
-            dropped_ty: self.dropped_ty,
-            kind: ccx.const_kind(),
-            dropped_at: self.dropped_at,
-        })
+        if self.needs_non_const_drop {
+            ccx.dcx().create_err(errors::LiveDrop {
+                span,
+                dropped_ty: self.dropped_ty,
+                kind: ccx.const_kind(),
+                dropped_at: self.dropped_at,
+            })
+        } else {
+            ccx.tcx.sess.create_feature_err(
+                errors::LiveDrop {
+                    span,
+                    dropped_ty: self.dropped_ty,
+                    kind: ccx.const_kind(),
+                    dropped_at: self.dropped_at,
+                },
+                sym::const_destruct,
+            )
+        }
     }
 }
 
diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs
index f6eb130fbd3..951e19b470b 100644
--- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs
+++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs
@@ -1,14 +1,11 @@
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::{self, BasicBlock, Location};
-use rustc_middle::ty::{Ty, TyCtxt};
-use rustc_span::Span;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 use tracing::trace;
 
 use super::ConstCx;
-use super::check::Qualifs;
-use super::ops::{self, NonConstOp};
-use super::qualifs::{NeedsNonConstDrop, Qualif};
+use crate::check_consts::check::Checker;
 use crate::check_consts::rustc_allow_const_fn_unstable;
 
 /// Returns `true` if we should use the more precise live drop checker that runs after drop
@@ -45,29 +42,16 @@ pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
         return;
     }
 
-    let mut visitor = CheckLiveDrops { ccx: &ccx, qualifs: Qualifs::default() };
+    // I know it's not great to be creating a new const checker, but I'd
+    // rather use it so we can deduplicate the error emitting logic that
+    // it contains.
+    let mut visitor = CheckLiveDrops { checker: Checker::new(&ccx) };
 
     visitor.visit_body(body);
 }
 
 struct CheckLiveDrops<'mir, 'tcx> {
-    ccx: &'mir ConstCx<'mir, 'tcx>,
-    qualifs: Qualifs<'mir, 'tcx>,
-}
-
-// So we can access `body` and `tcx`.
-impl<'mir, 'tcx> std::ops::Deref for CheckLiveDrops<'mir, 'tcx> {
-    type Target = ConstCx<'mir, 'tcx>;
-
-    fn deref(&self) -> &Self::Target {
-        self.ccx
-    }
-}
-
-impl<'tcx> CheckLiveDrops<'_, 'tcx> {
-    fn check_live_drop(&self, span: Span, dropped_ty: Ty<'tcx>) {
-        ops::LiveDrop { dropped_at: None, dropped_ty }.build_error(self.ccx, span).emit();
-    }
+    checker: Checker<'mir, 'tcx>,
 }
 
 impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
@@ -87,28 +71,11 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
 
         match &terminator.kind {
             mir::TerminatorKind::Drop { place: dropped_place, .. } => {
-                let dropped_ty = dropped_place.ty(self.body, self.tcx).ty;
-
-                if !NeedsNonConstDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
-                    // Instead of throwing a bug, we just return here. This is because we have to
-                    // run custom `const Drop` impls.
-                    return;
-                }
-
-                if dropped_place.is_indirect() {
-                    self.check_live_drop(terminator.source_info.span, dropped_ty);
-                    return;
-                }
-
-                // Drop elaboration is not precise enough to accept code like
-                // `tests/ui/consts/control-flow/drop-pass.rs`; e.g., when an `Option<Vec<T>>` is
-                // initialized with `None` and never changed, it still emits drop glue.
-                // Hence we additionally check the qualifs here to allow more code to pass.
-                if self.qualifs.needs_non_const_drop(self.ccx, dropped_place.local, location) {
-                    // Use the span where the dropped local was declared for the error.
-                    let span = self.body.local_decls[dropped_place.local].source_info.span;
-                    self.check_live_drop(span, dropped_ty);
-                }
+                self.checker.check_drop_terminator(
+                    *dropped_place,
+                    location,
+                    terminator.source_info.span,
+                );
             }
 
             mir::TerminatorKind::UnwindTerminate(_)
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index bc416acc58d..e244b50a4b5 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -2,11 +2,14 @@
 //!
 //! See the `Qualif` trait for more info.
 
+// FIXME(const_trait_impl): This API should be really reworked. It's dangerously general for
+// having basically only two use-cases that act in different ways.
+
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::LangItem;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::mir::*;
-use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty};
+use rustc_middle::ty::{self, AdtDef, Ty};
 use rustc_middle::{bug, mir};
 use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
 use tracing::instrument;
@@ -59,26 +62,12 @@ pub trait Qualif {
     /// It also determines the `Qualif`s for primitive types.
     fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool;
 
-    /// Returns `true` if this `Qualif` is inherent to the given struct or enum.
-    ///
-    /// By default, `Qualif`s propagate into ADTs in a structural way: An ADT only becomes
-    /// qualified if part of it is assigned a value with that `Qualif`. However, some ADTs *always*
-    /// have a certain `Qualif`, regardless of whether their fields have it. For example, a type
-    /// with a custom `Drop` impl is inherently `NeedsDrop`.
-    ///
-    /// Returning `true` for `in_adt_inherently` but `false` for `in_any_value_of_ty` is unsound.
-    fn in_adt_inherently<'tcx>(
-        cx: &ConstCx<'_, 'tcx>,
-        adt: AdtDef<'tcx>,
-        args: GenericArgsRef<'tcx>,
-    ) -> bool;
-
-    /// Returns `true` if this `Qualif` behaves sructurally for pointers and references:
-    /// the pointer/reference qualifies if and only if the pointee qualifies.
+    /// Returns `true` if the `Qualif` is structural in an ADT's fields, i.e. if we may
+    /// recurse into an operand *value* to determine whether it has this `Qualif`.
     ///
-    /// (This is currently `false` for all our instances, but that may change in the future. Also,
-    /// by keeping it abstract, the handling of `Deref` in `in_place` becomes more clear.)
-    fn deref_structural<'tcx>(cx: &ConstCx<'_, 'tcx>) -> bool;
+    /// If this returns false, `in_any_value_of_ty` will be invoked to determine the
+    /// final qualif for this ADT.
+    fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool;
 }
 
 /// Constant containing interior mutability (`UnsafeCell<T>`).
@@ -101,6 +90,11 @@ impl Qualif for HasMutInterior {
             return false;
         }
 
+        // Avoid selecting for `UnsafeCell` either.
+        if ty.ty_adt_def().is_some_and(|adt| adt.is_unsafe_cell()) {
+            return true;
+        }
+
         // We do not use `ty.is_freeze` here, because that requires revealing opaque types, which
         // requires borrowck, which in turn will invoke mir_const_qualifs again, causing a cycle error.
         // Instead we invoke an obligation context manually, and provide the opaque type inference settings
@@ -129,18 +123,10 @@ impl Qualif for HasMutInterior {
         !errors.is_empty()
     }
 
-    fn in_adt_inherently<'tcx>(
-        _cx: &ConstCx<'_, 'tcx>,
-        adt: AdtDef<'tcx>,
-        _: GenericArgsRef<'tcx>,
-    ) -> bool {
+    fn is_structural_in_adt_value<'tcx>(_cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool {
         // Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
         // It arises structurally for all other types.
-        adt.is_unsafe_cell()
-    }
-
-    fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
-        false
+        !adt.is_unsafe_cell()
     }
 }
 
@@ -154,6 +140,7 @@ pub struct NeedsDrop;
 impl Qualif for NeedsDrop {
     const ANALYSIS_NAME: &'static str = "flow_needs_drop";
     const IS_CLEARED_ON_MOVE: bool = true;
+    const ALLOW_PROMOTED: bool = true;
 
     fn in_qualifs(qualifs: &ConstQualifs) -> bool {
         qualifs.needs_drop
@@ -163,16 +150,8 @@ impl Qualif for NeedsDrop {
         ty.needs_drop(cx.tcx, cx.typing_env)
     }
 
-    fn in_adt_inherently<'tcx>(
-        cx: &ConstCx<'_, 'tcx>,
-        adt: AdtDef<'tcx>,
-        _: GenericArgsRef<'tcx>,
-    ) -> bool {
-        adt.has_dtor(cx.tcx)
-    }
-
-    fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
-        false
+    fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool {
+        !adt.has_dtor(cx.tcx)
     }
 }
 
@@ -191,25 +170,46 @@ impl Qualif for NeedsNonConstDrop {
 
     #[instrument(level = "trace", skip(cx), ret)]
     fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
-        // Avoid selecting for simple cases, such as builtin types.
-        if ty::util::is_trivially_const_drop(ty) {
+        // If this doesn't need drop at all, then don't select `~const Destruct`.
+        if !ty.needs_drop(cx.tcx, cx.typing_env) {
             return false;
         }
 
-        // FIXME(const_trait_impl): Reimplement const drop checking.
-        NeedsDrop::in_any_value_of_ty(cx, ty)
-    }
-
-    fn in_adt_inherently<'tcx>(
-        cx: &ConstCx<'_, 'tcx>,
-        adt: AdtDef<'tcx>,
-        _: GenericArgsRef<'tcx>,
-    ) -> bool {
-        adt.has_non_const_dtor(cx.tcx)
+        // We check that the type is `~const Destruct` since that will verify that
+        // the type is both `~const Drop` (if a drop impl exists for the adt), *and*
+        // that the components of this type are also `~const Destruct`. This
+        // amounts to verifying that there are no values in this ADT that may have
+        // a non-const drop.
+        let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span));
+        let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env);
+        let ocx = ObligationCtxt::new(&infcx);
+        ocx.register_obligation(Obligation::new(
+            cx.tcx,
+            ObligationCause::misc(cx.body.span, cx.def_id()),
+            param_env,
+            ty::Binder::dummy(ty::TraitRef::new(cx.tcx, destruct_def_id, [ty]))
+                .to_host_effect_clause(cx.tcx, match cx.const_kind() {
+                    rustc_hir::ConstContext::ConstFn => ty::BoundConstness::Maybe,
+                    rustc_hir::ConstContext::Static(_) | rustc_hir::ConstContext::Const { .. } => {
+                        ty::BoundConstness::Const
+                    }
+                }),
+        ));
+        !ocx.select_all_or_error().is_empty()
     }
 
-    fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
-        false
+    fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool {
+        // As soon as an ADT has a destructor, then the drop becomes non-structural
+        // in its value since:
+        // 1. The destructor may have `~const` bounds which are not present on the type.
+        //   Someone needs to check that those are satisfied.
+        //   While this could be instead satisfied by checking that the `~const Drop`
+        //   impl holds (i.e. replicating part of the `in_any_value_of_ty` logic above),
+        //   even in this case, we have another problem, which is,
+        // 2. The destructor may *modify* the operand being dropped, so even if we
+        //   did recurse on the components of the operand, we may not be even dropping
+        //   the same values that were present before the custom destructor was invoked.
+        !adt.has_dtor(cx.tcx)
     }
 }
 
@@ -261,14 +261,15 @@ where
         Rvalue::Aggregate(kind, operands) => {
             // Return early if we know that the struct or enum being constructed is always
             // qualified.
-            if let AggregateKind::Adt(adt_did, _, args, ..) = **kind {
+            if let AggregateKind::Adt(adt_did, ..) = **kind {
                 let def = cx.tcx.adt_def(adt_did);
-                if Q::in_adt_inherently(cx, def, args) {
-                    return true;
-                }
                 // Don't do any value-based reasoning for unions.
-                if def.is_union() && Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) {
-                    return true;
+                // Also, if the ADT is not structural in its fields,
+                // then we cannot recurse on its fields. Instead,
+                // we fall back to checking the qualif for *any* value
+                // of the ADT.
+                if def.is_union() || !Q::is_structural_in_adt_value(cx, def) {
+                    return Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx));
                 }
             }
 
@@ -305,7 +306,11 @@ where
             return false;
         }
 
-        if matches!(elem, ProjectionElem::Deref) && !Q::deref_structural(cx) {
+        // `Deref` currently unconditionally "qualifies" if `in_any_value_of_ty` returns true,
+        // i.e., we treat all qualifs as non-structural for deref projections. Generally,
+        // we can say very little about `*ptr` even if we know that `ptr` satisfies all
+        // sorts of properties.
+        if matches!(elem, ProjectionElem::Deref) {
             // We have to assume that this qualifies.
             return true;
         }
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 604e5ed61a3..80236ee05b7 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -411,7 +411,7 @@ pub struct LiveDrop<'tcx> {
     pub kind: ConstContext,
     pub dropped_ty: Ty<'tcx>,
     #[label(const_eval_dropped_at_label)]
-    pub dropped_at: Option<Span>,
+    pub dropped_at: Span,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs
index 8ce11c71b8b..a9ebf386617 100644
--- a/compiler/rustc_const_eval/src/interpret/stack.rs
+++ b/compiler/rustc_const_eval/src/interpret/stack.rs
@@ -10,7 +10,7 @@ use rustc_index::IndexVec;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::{bug, mir};
-use rustc_mir_dataflow::storage::always_storage_live_locals;
+use rustc_mir_dataflow::impls::always_storage_live_locals;
 use rustc_span::Span;
 use tracing::{info_span, instrument, trace};
 
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index c270ce16726..005053e4508 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -160,6 +160,9 @@ pub trait Callbacks {
     /// Called after parsing the crate root. Submodules are not yet parsed when
     /// this callback is called. Return value instructs the compiler whether to
     /// continue the compilation afterwards (defaults to `Compilation::Continue`)
+    #[deprecated = "This callback will likely be removed or stop giving access \
+                    to the TyCtxt in the future. Use either the after_expansion \
+                    or the after_analysis callback instead."]
     fn after_crate_root_parsing<'tcx>(
         &mut self,
         _compiler: &interface::Compiler,
@@ -181,7 +184,7 @@ pub trait Callbacks {
     fn after_analysis<'tcx>(
         &mut self,
         _compiler: &interface::Compiler,
-        _queries: &'tcx Queries<'tcx>,
+        _tcx: TyCtxt<'tcx>,
     ) -> Compilation {
         Compilation::Continue
     }
@@ -335,19 +338,12 @@ fn run_compiler(
         expanded_args: args,
     };
 
-    let has_input = match make_input(&default_early_dcx, &matches.free) {
-        Err(reported) => return Err(reported),
-        Ok(Some(input)) => {
+    let has_input = match make_input(&default_early_dcx, &matches.free)? {
+        Some(input) => {
             config.input = input;
             true // has input: normal compilation
         }
-        Ok(None) => match matches.free.as_slice() {
-            [] => false, // no input: we will exit early
-            [_] => panic!("make_input should have provided valid inputs"),
-            [fst, snd, ..] => default_early_dcx.early_fatal(format!(
-                "multiple input filenames provided (first two filenames are `{fst}` and `{snd}`)"
-            )),
-        },
+        None => false, // no input: we will exit early
     };
 
     drop(default_early_dcx);
@@ -405,10 +401,6 @@ fn run_compiler(
                     queries.global_ctxt()?.enter(|tcx| {
                         tcx.ensure().early_lint_checks(());
                         pretty::print(sess, pp_mode, pretty::PrintExtra::NeedsAstMap { tcx });
-                        Ok(())
-                    })?;
-
-                    queries.global_ctxt()?.enter(|tcx| {
                         passes::write_dep_info(tcx);
                     });
                 } else {
@@ -421,6 +413,7 @@ fn run_compiler(
                 return early_exit();
             }
 
+            #[allow(deprecated)]
             if callbacks.after_crate_root_parsing(compiler, queries) == Compilation::Stop {
                 return early_exit();
             }
@@ -442,25 +435,23 @@ fn run_compiler(
 
             queries.global_ctxt()?.enter(|tcx| {
                 passes::write_dep_info(tcx);
-            });
 
-            if sess.opts.output_types.contains_key(&OutputType::DepInfo)
-                && sess.opts.output_types.len() == 1
-            {
-                return early_exit();
-            }
+                if sess.opts.output_types.contains_key(&OutputType::DepInfo)
+                    && sess.opts.output_types.len() == 1
+                {
+                    return early_exit();
+                }
 
-            if sess.opts.unstable_opts.no_analysis {
-                return early_exit();
-            }
+                if sess.opts.unstable_opts.no_analysis {
+                    return early_exit();
+                }
 
-            queries.global_ctxt()?.enter(|tcx| tcx.analysis(()))?;
+                tcx.analysis(())?;
 
-            if callbacks.after_analysis(compiler, queries) == Compilation::Stop {
-                return early_exit();
-            }
+                if callbacks.after_analysis(compiler, tcx) == Compilation::Stop {
+                    return early_exit();
+                }
 
-            queries.global_ctxt()?.enter(|tcx| {
                 Ok(Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend)?))
             })
         })?;
@@ -472,10 +463,6 @@ fn run_compiler(
             linker.link(sess, codegen_backend)?
         }
 
-        if let Some(fuel) = sess.opts.unstable_opts.print_fuel.as_deref() {
-            eprintln!("Fuel used by {}: {}", fuel, sess.print_fuel.load(Ordering::SeqCst));
-        }
-
         Ok(())
     })
 }
@@ -513,37 +500,40 @@ fn make_input(
     early_dcx: &EarlyDiagCtxt,
     free_matches: &[String],
 ) -> Result<Option<Input>, ErrorGuaranteed> {
-    let [input_file] = free_matches else { return Ok(None) };
-
-    if input_file != "-" {
-        // Normal `Input::File`
-        return Ok(Some(Input::File(PathBuf::from(input_file))));
-    }
-
-    // read from stdin as `Input::Str`
-    let mut input = String::new();
-    if io::stdin().read_to_string(&mut input).is_err() {
-        // Immediately stop compilation if there was an issue reading
-        // the input (for example if the input stream is not UTF-8).
-        let reported =
-            early_dcx.early_err("couldn't read from stdin, as it did not contain valid UTF-8");
-        return Err(reported);
-    }
+    match free_matches {
+        [] => Ok(None), // no input: we will exit early,
+        [ifile] if ifile == "-" => {
+            // read from stdin as `Input::Str`
+            let mut input = String::new();
+            if io::stdin().read_to_string(&mut input).is_err() {
+                // Immediately stop compilation if there was an issue reading
+                // the input (for example if the input stream is not UTF-8).
+                let reported = early_dcx
+                    .early_err("couldn't read from stdin, as it did not contain valid UTF-8");
+                return Err(reported);
+            }
 
-    let name = match env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
-        Ok(path) => {
-            let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect(
-                "when UNSTABLE_RUSTDOC_TEST_PATH is set \
+            let name = match env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
+                Ok(path) => {
+                    let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect(
+                        "when UNSTABLE_RUSTDOC_TEST_PATH is set \
                                     UNSTABLE_RUSTDOC_TEST_LINE also needs to be set",
-            );
-            let line = isize::from_str_radix(&line, 10)
-                .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number");
-            FileName::doc_test_source_code(PathBuf::from(path), line)
-        }
-        Err(_) => FileName::anon_source_code(&input),
-    };
+                    );
+                    let line = isize::from_str_radix(&line, 10)
+                        .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number");
+                    FileName::doc_test_source_code(PathBuf::from(path), line)
+                }
+                Err(_) => FileName::anon_source_code(&input),
+            };
 
-    Ok(Some(Input::Str { name, input }))
+            Ok(Some(Input::Str { name, input }))
+        }
+        [ifile] => Ok(Some(Input::File(PathBuf::from(ifile)))),
+        [ifile1, ifile2, ..] => early_dcx.early_fatal(format!(
+            "multiple input filenames provided (first two filenames are `{}` and `{}`)",
+            ifile1, ifile2
+        )),
+    }
 }
 
 /// Whether to stop or continue compilation.
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index bae16a18bcb..f044d964f13 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -2,7 +2,7 @@ use rustc_ast::mut_visit::*;
 use rustc_ast::ptr::P;
 use rustc_ast::token::Delimiter;
 use rustc_ast::visit::AssocCtxt;
-use rustc_ast::{self as ast};
+use rustc_ast::{self as ast, Safety};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_span::DUMMY_SP;
 use rustc_span::symbol::Ident;
@@ -173,6 +173,7 @@ pub(crate) fn placeholder(
             ty: ty(),
             vis,
             is_placeholder: true,
+            safety: Safety::Default,
         }]),
         AstFragmentKind::Variants => AstFragment::Variants(smallvec![ast::Variant {
             attrs: Default::default(),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index e3dc73c1401..aa2e451ef39 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -376,8 +376,12 @@ declare_features! (
     (unstable, arbitrary_self_types_pointers, "1.83.0", Some(44874)),
     /// Enables experimental inline assembly support for additional architectures.
     (unstable, asm_experimental_arch, "1.58.0", Some(93335)),
+    /// Enables experimental register support in inline assembly.
+    (unstable, asm_experimental_reg, "CURRENT_RUSTC_VERSION", Some(133416)),
     /// Allows using `label` operands in inline assembly.
     (unstable, asm_goto, "1.78.0", Some(119364)),
+    /// Allows using `label` operands in inline assembly together with output operands.
+    (unstable, asm_goto_with_outputs, "CURRENT_RUSTC_VERSION", Some(119364)),
     /// Allows the `may_unwind` option in inline assembly.
     (unstable, asm_unwind, "1.58.0", Some(93334)),
     /// Allows users to enforce equality of associated constants `TraitImpl<AssocConst=3>`.
@@ -426,6 +430,8 @@ declare_features! (
     (unstable, const_async_blocks, "1.53.0", Some(85368)),
     /// Allows `const || {}` closures in const contexts.
     (incomplete, const_closures, "1.68.0", Some(106003)),
+    /// Allows using `~const Destruct` bounds and calling drop impls in const contexts.
+    (unstable, const_destruct, "CURRENT_RUSTC_VERSION", Some(133214)),
     /// Allows `for _ in _` loops in const contexts.
     (unstable, const_for, "1.56.0", Some(87575)),
     /// Be more precise when looking for live drops in a const context.
@@ -627,6 +633,8 @@ declare_features! (
     /// Allows creation of instances of a struct by moving fields that have
     /// not changed from prior instances of the same struct (RFC #2528)
     (unstable, type_changing_struct_update, "1.58.0", Some(86555)),
+    /// Allows declaring fields `unsafe`.
+    (incomplete, unsafe_fields, "CURRENT_RUSTC_VERSION", Some(132922)),
     /// Allows const generic parameters to be defined with types that
     /// are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.
     (incomplete, unsized_const_params, "1.82.0", Some(95174)),
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 554097bf115..12dec75e65c 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1,7 +1,7 @@
 use std::fmt;
 
 use rustc_abi::ExternAbi;
-use rustc_ast::util::parser::ExprPrecedence;
+use rustc_ast::util::parser::{AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_UNAMBIGUOUS};
 use rustc_ast::{
     self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label,
     LitKind, TraitObjectSyntax, UintTy,
@@ -261,8 +261,6 @@ pub struct ConstArg<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
     pub kind: ConstArgKind<'hir>,
-    /// Indicates whether this comes from a `~const` desugaring.
-    pub is_desugared_from_effects: bool,
 }
 
 impl<'hir> ConstArg<'hir> {
@@ -462,14 +460,7 @@ impl<'hir> GenericArgs<'hir> {
     /// This function returns the number of type and const generic params.
     /// It should only be used for diagnostics.
     pub fn num_generic_params(&self) -> usize {
-        self.args
-            .iter()
-            .filter(|arg| match arg {
-                GenericArg::Lifetime(_)
-                | GenericArg::Const(ConstArg { is_desugared_from_effects: true, .. }) => false,
-                _ => true,
-            })
-            .count()
+        self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count()
     }
 
     /// The span encompassing the arguments and constraints[^1] inside the surrounding brackets.
@@ -690,8 +681,8 @@ impl<'hir> Generics<'hir> {
         if self.has_where_clause_predicates {
             self.predicates
                 .iter()
-                .rfind(|&p| p.in_where_clause())
-                .map_or(end, |p| p.span())
+                .rfind(|&p| p.kind.in_where_clause())
+                .map_or(end, |p| p.span)
                 .shrink_to_hi()
                 .to(end)
         } else {
@@ -714,8 +705,10 @@ impl<'hir> Generics<'hir> {
         &self,
         param_def_id: LocalDefId,
     ) -> impl Iterator<Item = &WhereBoundPredicate<'hir>> {
-        self.predicates.iter().filter_map(move |pred| match pred {
-            WherePredicate::BoundPredicate(bp) if bp.is_param_bound(param_def_id.to_def_id()) => {
+        self.predicates.iter().filter_map(move |pred| match pred.kind {
+            WherePredicateKind::BoundPredicate(bp)
+                if bp.is_param_bound(param_def_id.to_def_id()) =>
+            {
                 Some(bp)
             }
             _ => None,
@@ -726,8 +719,8 @@ impl<'hir> Generics<'hir> {
         &self,
         param_def_id: LocalDefId,
     ) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
-        self.predicates.iter().filter_map(move |pred| match pred {
-            WherePredicate::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
+        self.predicates.iter().filter_map(move |pred| match pred.kind {
+            WherePredicateKind::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
             _ => None,
         })
     }
@@ -779,9 +772,9 @@ impl<'hir> Generics<'hir> {
 
     pub fn span_for_predicate_removal(&self, pos: usize) -> Span {
         let predicate = &self.predicates[pos];
-        let span = predicate.span();
+        let span = predicate.span;
 
-        if !predicate.in_where_clause() {
+        if !predicate.kind.in_where_clause() {
             // <T: ?Sized, U>
             //   ^^^^^^^^
             return span;
@@ -790,19 +783,19 @@ impl<'hir> Generics<'hir> {
         // We need to find out which comma to remove.
         if pos < self.predicates.len() - 1 {
             let next_pred = &self.predicates[pos + 1];
-            if next_pred.in_where_clause() {
+            if next_pred.kind.in_where_clause() {
                 // where T: ?Sized, Foo: Bar,
                 //       ^^^^^^^^^^^
-                return span.until(next_pred.span());
+                return span.until(next_pred.span);
             }
         }
 
         if pos > 0 {
             let prev_pred = &self.predicates[pos - 1];
-            if prev_pred.in_where_clause() {
+            if prev_pred.kind.in_where_clause() {
                 // where Foo: Bar, T: ?Sized,
                 //               ^^^^^^^^^^^
-                return prev_pred.span().shrink_to_hi().to(span);
+                return prev_pred.span.shrink_to_hi().to(span);
             }
         }
 
@@ -814,7 +807,7 @@ impl<'hir> Generics<'hir> {
 
     pub fn span_for_bound_removal(&self, predicate_pos: usize, bound_pos: usize) -> Span {
         let predicate = &self.predicates[predicate_pos];
-        let bounds = predicate.bounds();
+        let bounds = predicate.kind.bounds();
 
         if bounds.len() == 1 {
             return self.span_for_predicate_removal(predicate_pos);
@@ -841,7 +834,15 @@ impl<'hir> Generics<'hir> {
 
 /// A single predicate in a where-clause.
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
-pub enum WherePredicate<'hir> {
+pub struct WherePredicate<'hir> {
+    pub hir_id: HirId,
+    pub span: Span,
+    pub kind: &'hir WherePredicateKind<'hir>,
+}
+
+/// The kind of a single predicate in a where-clause.
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
+pub enum WherePredicateKind<'hir> {
     /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate<'hir>),
     /// A lifetime predicate (e.g., `'a: 'b + 'c`).
@@ -850,28 +851,20 @@ pub enum WherePredicate<'hir> {
     EqPredicate(WhereEqPredicate<'hir>),
 }
 
-impl<'hir> WherePredicate<'hir> {
-    pub fn span(&self) -> Span {
-        match self {
-            WherePredicate::BoundPredicate(p) => p.span,
-            WherePredicate::RegionPredicate(p) => p.span,
-            WherePredicate::EqPredicate(p) => p.span,
-        }
-    }
-
+impl<'hir> WherePredicateKind<'hir> {
     pub fn in_where_clause(&self) -> bool {
         match self {
-            WherePredicate::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
-            WherePredicate::RegionPredicate(p) => p.in_where_clause,
-            WherePredicate::EqPredicate(_) => false,
+            WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
+            WherePredicateKind::RegionPredicate(p) => p.in_where_clause,
+            WherePredicateKind::EqPredicate(_) => false,
         }
     }
 
     pub fn bounds(&self) -> GenericBounds<'hir> {
         match self {
-            WherePredicate::BoundPredicate(p) => p.bounds,
-            WherePredicate::RegionPredicate(p) => p.bounds,
-            WherePredicate::EqPredicate(_) => &[],
+            WherePredicateKind::BoundPredicate(p) => p.bounds,
+            WherePredicateKind::RegionPredicate(p) => p.bounds,
+            WherePredicateKind::EqPredicate(_) => &[],
         }
     }
 }
@@ -886,8 +879,6 @@ pub enum PredicateOrigin {
 /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct WhereBoundPredicate<'hir> {
-    pub hir_id: HirId,
-    pub span: Span,
     /// Origin of the predicate.
     pub origin: PredicateOrigin,
     /// Any generics from a `for` binding.
@@ -908,7 +899,6 @@ impl<'hir> WhereBoundPredicate<'hir> {
 /// A lifetime predicate (e.g., `'a: 'b + 'c`).
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct WhereRegionPredicate<'hir> {
-    pub span: Span,
     pub in_where_clause: bool,
     pub lifetime: &'hir Lifetime,
     pub bounds: GenericBounds<'hir>,
@@ -924,7 +914,6 @@ impl<'hir> WhereRegionPredicate<'hir> {
 /// An equality predicate (e.g., `T = int`); currently unsupported.
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct WhereEqPredicate<'hir> {
-    pub span: Span,
     pub lhs_ty: &'hir Ty<'hir>,
     pub rhs_ty: &'hir Ty<'hir>,
 }
@@ -1719,41 +1708,54 @@ pub struct Expr<'hir> {
 }
 
 impl Expr<'_> {
-    pub fn precedence(&self) -> ExprPrecedence {
+    pub fn precedence(&self) -> i8 {
         match self.kind {
-            ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
-            ExprKind::Array(_) => ExprPrecedence::Array,
-            ExprKind::Call(..) => ExprPrecedence::Call,
-            ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
-            ExprKind::Tup(_) => ExprPrecedence::Tup,
-            ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
-            ExprKind::Unary(..) => ExprPrecedence::Unary,
-            ExprKind::Lit(_) => ExprPrecedence::Lit,
-            ExprKind::Cast(..) => ExprPrecedence::Cast,
+            ExprKind::Closure { .. } => PREC_CLOSURE,
+
+            ExprKind::Break(..)
+            | ExprKind::Continue(..)
+            | ExprKind::Ret(..)
+            | ExprKind::Yield(..)
+            | ExprKind::Become(..) => PREC_JUMP,
+
+            // Binop-like expr kinds, handled by `AssocOp`.
+            ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8,
+            ExprKind::Cast(..) => AssocOp::As.precedence() as i8,
+
+            ExprKind::Assign(..) |
+            ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8,
+
+            // Unary, prefix
+            ExprKind::AddrOf(..)
+            // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
+            // However, this is not exactly right. When `let _ = a` is the LHS of a binop we
+            // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
+            // but we need to print `(let _ = a) < b` as-is with parens.
+            | ExprKind::Let(..)
+            | ExprKind::Unary(..) => PREC_PREFIX,
+
+            // Never need parens
+            ExprKind::Array(_)
+            | ExprKind::Block(..)
+            | ExprKind::Call(..)
+            | ExprKind::ConstBlock(_)
+            | ExprKind::Field(..)
+            | ExprKind::If(..)
+            | ExprKind::Index(..)
+            | ExprKind::InlineAsm(..)
+            | ExprKind::Lit(_)
+            | ExprKind::Loop(..)
+            | ExprKind::Match(..)
+            | ExprKind::MethodCall(..)
+            | ExprKind::OffsetOf(..)
+            | ExprKind::Path(..)
+            | ExprKind::Repeat(..)
+            | ExprKind::Struct(..)
+            | ExprKind::Tup(_)
+            | ExprKind::Type(..)
+            | ExprKind::Err(_) => PREC_UNAMBIGUOUS,
+
             ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
-            ExprKind::If(..) => ExprPrecedence::If,
-            ExprKind::Let(..) => ExprPrecedence::Let,
-            ExprKind::Loop(..) => ExprPrecedence::Loop,
-            ExprKind::Match(..) => ExprPrecedence::Match,
-            ExprKind::Closure { .. } => ExprPrecedence::Closure,
-            ExprKind::Block(..) => ExprPrecedence::Block,
-            ExprKind::Assign(..) => ExprPrecedence::Assign,
-            ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
-            ExprKind::Field(..) => ExprPrecedence::Field,
-            ExprKind::Index(..) => ExprPrecedence::Index,
-            ExprKind::Path(..) => ExprPrecedence::Path,
-            ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
-            ExprKind::Break(..) => ExprPrecedence::Break,
-            ExprKind::Continue(..) => ExprPrecedence::Continue,
-            ExprKind::Ret(..) => ExprPrecedence::Ret,
-            ExprKind::Become(..) => ExprPrecedence::Become,
-            ExprKind::Struct(..) => ExprPrecedence::Struct,
-            ExprKind::Repeat(..) => ExprPrecedence::Repeat,
-            ExprKind::Yield(..) => ExprPrecedence::Yield,
-            ExprKind::Type(..) | ExprKind::InlineAsm(..) | ExprKind::OffsetOf(..) => {
-                ExprPrecedence::Mac
-            }
-            ExprKind::Err(_) => ExprPrecedence::Err,
         }
     }
 
@@ -3177,6 +3179,7 @@ pub struct FieldDef<'hir> {
     pub hir_id: HirId,
     pub def_id: LocalDefId,
     pub ty: &'hir Ty<'hir>,
+    pub safety: Safety,
 }
 
 impl FieldDef<'_> {
@@ -3797,7 +3800,7 @@ pub enum Node<'hir> {
     GenericParam(&'hir GenericParam<'hir>),
     Crate(&'hir Mod<'hir>),
     Infer(&'hir InferArg),
-    WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
+    WherePredicate(&'hir WherePredicate<'hir>),
     // FIXME: Merge into `Node::Infer`.
     ArrayLenInfer(&'hir InferArg),
     PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
@@ -3852,7 +3855,7 @@ impl<'hir> Node<'hir> {
             | Node::TraitRef(..)
             | Node::OpaqueTy(..)
             | Node::Infer(..)
-            | Node::WhereBoundPredicate(..)
+            | Node::WherePredicate(..)
             | Node::ArrayLenInfer(..)
             | Node::Synthetic
             | Node::Err(..) => None,
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index a453af3f7fd..faaea41047f 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -961,30 +961,28 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
     visitor: &mut V,
     predicate: &'v WherePredicate<'v>,
 ) -> V::Result {
-    match *predicate {
-        WherePredicate::BoundPredicate(WhereBoundPredicate {
-            hir_id,
+    let &WherePredicate { hir_id, kind, span: _ } = predicate;
+    try_visit!(visitor.visit_id(hir_id));
+    match *kind {
+        WherePredicateKind::BoundPredicate(WhereBoundPredicate {
             ref bounded_ty,
             bounds,
             bound_generic_params,
             origin: _,
-            span: _,
         }) => {
-            try_visit!(visitor.visit_id(hir_id));
             try_visit!(visitor.visit_ty(bounded_ty));
             walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_generic_param, bound_generic_params);
         }
-        WherePredicate::RegionPredicate(WhereRegionPredicate {
+        WherePredicateKind::RegionPredicate(WhereRegionPredicate {
             ref lifetime,
             bounds,
-            span: _,
             in_where_clause: _,
         }) => {
             try_visit!(visitor.visit_lifetime(lifetime));
             walk_list!(visitor, visit_param_bound, bounds);
         }
-        WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span: _ }) => {
+        WherePredicateKind::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty }) => {
             try_visit!(visitor.visit_ty(lhs_ty));
             try_visit!(visitor.visit_ty(rhs_ty));
         }
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 64a30e633cf..49b4a1fabec 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -253,6 +253,13 @@ hir_analysis_invalid_union_field =
 hir_analysis_invalid_union_field_sugg =
     wrap the field type in `ManuallyDrop<...>`
 
+hir_analysis_invalid_unsafe_field =
+    field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe
+    .note = unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
+
+hir_analysis_invalid_unsafe_field_sugg =
+    wrap the field type in `ManuallyDrop<...>`
+
 hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
     .label = const parameter declared here
 
@@ -424,6 +431,9 @@ hir_analysis_recursive_generic_parameter = {$param_def_kind} `{$param_name}` is
 hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}`
     .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}`
 
+hir_analysis_register_type_unstable =
+    type `{$ty}` cannot be used with this register class in stable
+
 hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}`
 
 hir_analysis_return_type_notation_equality_bound =
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index cf3f3003bf5..c66572a9377 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_errors::MultiSpan;
 use rustc_errors::codes::*;
 use rustc_hir::def::{CtorKind, DefKind};
-use rustc_hir::{Node, intravisit};
+use rustc_hir::{Node, Safety, intravisit};
 use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
 use rustc_infer::traits::{Obligation, ObligationCauseCode};
 use rustc_lint_defs::builtin::{
@@ -70,6 +70,7 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
     check_transparent(tcx, def);
     check_packed(tcx, span, def);
+    check_unsafe_fields(tcx, def_id);
 }
 
 fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
@@ -81,38 +82,45 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     check_packed(tcx, span, def);
 }
 
+fn allowed_union_or_unsafe_field<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    ty: Ty<'tcx>,
+    typing_env: ty::TypingEnv<'tcx>,
+    span: Span,
+) -> bool {
+    // We don't just accept all !needs_drop fields, due to semver concerns.
+    let allowed = match ty.kind() {
+        ty::Ref(..) => true, // references never drop (even mutable refs, which are non-Copy and hence fail the later check)
+        ty::Tuple(tys) => {
+            // allow tuples of allowed types
+            tys.iter().all(|ty| allowed_union_or_unsafe_field(tcx, ty, typing_env, span))
+        }
+        ty::Array(elem, _len) => {
+            // Like `Copy`, we do *not* special-case length 0.
+            allowed_union_or_unsafe_field(tcx, *elem, typing_env, span)
+        }
+        _ => {
+            // Fallback case: allow `ManuallyDrop` and things that are `Copy`,
+            // also no need to report an error if the type is unresolved.
+            ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop())
+                || ty.is_copy_modulo_regions(tcx, typing_env)
+                || ty.references_error()
+        }
+    };
+    if allowed && ty.needs_drop(tcx, typing_env) {
+        // This should never happen. But we can get here e.g. in case of name resolution errors.
+        tcx.dcx()
+            .span_delayed_bug(span, "we should never accept maybe-dropping union or unsafe fields");
+    }
+    allowed
+}
+
 /// Check that the fields of the `union` do not need dropping.
 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
     let item_type = tcx.type_of(item_def_id).instantiate_identity();
     if let ty::Adt(def, args) = item_type.kind() {
         assert!(def.is_union());
 
-        fn allowed_union_field<'tcx>(
-            ty: Ty<'tcx>,
-            tcx: TyCtxt<'tcx>,
-            typing_env: ty::TypingEnv<'tcx>,
-        ) -> bool {
-            // We don't just accept all !needs_drop fields, due to semver concerns.
-            match ty.kind() {
-                ty::Ref(..) => true, // references never drop (even mutable refs, which are non-Copy and hence fail the later check)
-                ty::Tuple(tys) => {
-                    // allow tuples of allowed types
-                    tys.iter().all(|ty| allowed_union_field(ty, tcx, typing_env))
-                }
-                ty::Array(elem, _len) => {
-                    // Like `Copy`, we do *not* special-case length 0.
-                    allowed_union_field(*elem, tcx, typing_env)
-                }
-                _ => {
-                    // Fallback case: allow `ManuallyDrop` and things that are `Copy`,
-                    // also no need to report an error if the type is unresolved.
-                    ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop())
-                        || ty.is_copy_modulo_regions(tcx, typing_env)
-                        || ty.references_error()
-                }
-            }
-        }
-
         let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
         for field in &def.non_enum_variant().fields {
             let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args))
@@ -121,7 +129,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
                 continue;
             };
 
-            if !allowed_union_field(field_ty, tcx, typing_env) {
+            if !allowed_union_or_unsafe_field(tcx, field_ty, typing_env, span) {
                 let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
                     // We are currently checking the type this field came from, so it must be local.
                     Some(Node::Field(field)) => (field.span, field.ty.span),
@@ -136,10 +144,6 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
                     note: (),
                 });
                 return false;
-            } else if field_ty.needs_drop(tcx, typing_env) {
-                // This should never happen. But we can get here e.g. in case of name resolution errors.
-                tcx.dcx()
-                    .span_delayed_bug(span, "we should never accept maybe-dropping union fields");
             }
         }
     } else {
@@ -148,6 +152,41 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
     true
 }
 
+/// Check that the unsafe fields do not need dropping.
+fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) {
+    let span = tcx.def_span(item_def_id);
+    let item_type = tcx.type_of(item_def_id).instantiate_identity();
+    let ty::Adt(def, args) = item_type.kind() else {
+        span_bug!(span, "structs/enums must be ty::Adt, but got {:?}", item_type.kind());
+    };
+    let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
+    for field in def.all_fields() {
+        if field.safety != Safety::Unsafe {
+            continue;
+        }
+        let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args))
+        else {
+            tcx.dcx().span_delayed_bug(span, "could not normalize field type");
+            continue;
+        };
+
+        if !allowed_union_or_unsafe_field(tcx, field_ty, typing_env, span) {
+            let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.expect_local()) else {
+                unreachable!("field has to correspond to hir field")
+            };
+            let ty_span = field.ty.span;
+            tcx.dcx().emit_err(errors::InvalidUnsafeField {
+                field_span: field.span,
+                sugg: errors::InvalidUnsafeFieldSuggestion {
+                    lo: ty_span.shrink_to_lo(),
+                    hi: ty_span.shrink_to_hi(),
+                },
+                note: (),
+            });
+        }
+    }
+}
+
 /// Check that a `static` is inhabited.
 fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     // Make sure statics are inhabited.
@@ -1464,6 +1503,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
     detect_discriminant_duplicate(tcx, def);
     check_transparent(tcx, def);
+    check_unsafe_fields(tcx, def_id);
 }
 
 /// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal
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 bd0b0ceb92d..2891b48a154 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -26,7 +26,7 @@ use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::regions::InferCtxtRegionExt;
 use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
 use rustc_trait_selection::traits::{
-    self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal,
+    self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt,
 };
 use tracing::{debug, instrument};
 
@@ -223,7 +223,7 @@ fn compare_method_predicate_entailment<'tcx>(
     }
 
     let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
-    let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
+    let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds));
     let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
     debug!(caller_bounds=?param_env.caller_bounds());
 
@@ -508,7 +508,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         .into_iter()
         .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args))
         .map(|(clause, _)| clause);
-    let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
+    let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
     let param_env = traits::normalize_param_env_or_error(
         tcx,
         param_env,
@@ -1100,7 +1100,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
             // FIXME: we could potentially look at the impl's bounds to not point at bounds that
             // *are* present in the impl.
             for p in trait_generics.predicates {
-                if let hir::WherePredicate::BoundPredicate(pred) = p {
+                if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
                     for b in pred.bounds {
                         if let hir::GenericBound::Outlives(lt) = b {
                             bounds_span.push(lt.ident.span);
@@ -1113,7 +1113,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
             {
                 let mut impl_bounds = 0;
                 for p in impl_generics.predicates {
-                    if let hir::WherePredicate::BoundPredicate(pred) = p {
+                    if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
                         for b in pred.bounds {
                             if let hir::GenericBound::Outlives(_) = b {
                                 impl_bounds += 1;
@@ -1793,7 +1793,7 @@ fn compare_const_predicate_entailment<'tcx>(
             .map(|(predicate, _)| predicate),
     );
 
-    let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
+    let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds));
     let param_env = traits::normalize_param_env_or_error(
         tcx,
         param_env,
@@ -1946,7 +1946,7 @@ fn compare_type_predicate_entailment<'tcx>(
         );
     }
 
-    let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
+    let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds));
     let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
     debug!(caller_bounds=?param_env.caller_bounds());
 
@@ -2306,7 +2306,7 @@ fn param_env_with_gat_bounds<'tcx>(
         };
     }
 
-    ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing)
+    ty::ParamEnv::new(tcx.mk_clauses(&predicates))
 }
 
 /// Manually check here that `async fn foo()` wasn't matched against `fn foo()`,
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index 25ba52b4d7b..67cbcc1566a 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -6,7 +6,7 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE};
 use rustc_middle::span_bug;
-use rustc_middle::traits::{ObligationCause, Reveal};
+use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{
     self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable,
     TypeVisitableExt, TypeVisitor, TypingMode,
@@ -134,7 +134,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
         .into_iter()
         .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_m_to_impl_m_args))
         .map(|(clause, _)| clause);
-    let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
+    let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
     let param_env = normalize_param_env_or_error(tcx, param_env, ObligationCause::dummy());
 
     let ref infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index dfddf93a5c2..b96469f503c 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -7,12 +7,14 @@ use rustc_hir::{self as hir, LangItem};
 use rustc_middle::bug;
 use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
 use rustc_session::lint;
-use rustc_span::Symbol;
 use rustc_span::def_id::LocalDefId;
+use rustc_span::{Symbol, sym};
 use rustc_target::asm::{
     InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType, ModifierInfo,
 };
 
+use crate::errors::RegisterTypeUnstable;
+
 pub struct InlineAsmCtxt<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     typing_env: ty::TypingEnv<'tcx>,
@@ -218,17 +220,29 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
         // Check the type against the list of types supported by the selected
         // register class.
         let asm_arch = self.tcx.sess.asm_arch.unwrap();
+        let allow_experimental_reg = self.tcx.features().asm_experimental_reg();
         let reg_class = reg.reg_class();
-        let supported_tys = reg_class.supported_types(asm_arch);
+        let supported_tys = reg_class.supported_types(asm_arch, allow_experimental_reg);
         let Some((_, feature)) = supported_tys.iter().find(|&&(t, _)| t == asm_ty) else {
-            let msg = format!("type `{ty}` cannot be used with this register class");
-            let mut err = self.tcx.dcx().struct_span_err(expr.span, msg);
-            let supported_tys: Vec<_> = supported_tys.iter().map(|(t, _)| t.to_string()).collect();
-            err.note(format!(
-                "register class `{}` supports these types: {}",
-                reg_class.name(),
-                supported_tys.join(", "),
-            ));
+            let mut err = if !allow_experimental_reg
+                && reg_class.supported_types(asm_arch, true).iter().any(|&(t, _)| t == asm_ty)
+            {
+                self.tcx.sess.create_feature_err(
+                    RegisterTypeUnstable { span: expr.span, ty },
+                    sym::asm_experimental_reg,
+                )
+            } else {
+                let msg = format!("type `{ty}` cannot be used with this register class");
+                let mut err = self.tcx.dcx().struct_span_err(expr.span, msg);
+                let supported_tys: Vec<_> =
+                    supported_tys.iter().map(|(t, _)| t.to_string()).collect();
+                err.note(format!(
+                    "register class `{}` supports these types: {}",
+                    reg_class.name(),
+                    supported_tys.join(", "),
+                ));
+                err
+            };
             if let Some(suggest) = reg_class.suggest_class(asm_arch, asm_ty) {
                 err.help(format!("consider using the `{}` register class instead", suggest.name()));
             }
@@ -313,6 +327,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             self.tcx.dcx().delayed_bug("target architecture does not support asm");
             return;
         };
+        let allow_experimental_reg = self.tcx.features().asm_experimental_reg();
         for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
             // Validate register classes against currently enabled target
             // features. We check that at least one type is available for
@@ -352,7 +367,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                     if let InlineAsmRegClass::Err = reg_class {
                         continue;
                     }
-                    for &(_, feature) in reg_class.supported_types(asm_arch) {
+                    for &(_, feature) in reg_class.supported_types(asm_arch, allow_experimental_reg)
+                    {
                         match feature {
                             Some(feature) => {
                                 if target_features.contains(&feature) {
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 20bc34b8c79..8fa797db246 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -604,7 +604,7 @@ fn augment_param_env<'tcx>(
     );
     // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
     // i.e. traits::normalize_param_env_or_error
-    ty::ParamEnv::new(bounds, param_env.reveal())
+    ty::ParamEnv::new(bounds)
 }
 
 /// We use the following trait as an example throughout this function.
@@ -1921,8 +1921,8 @@ fn check_variances_for_type_defn<'tcx>(
         hir_generics
             .predicates
             .iter()
-            .filter_map(|predicate| match predicate {
-                hir::WherePredicate::BoundPredicate(predicate) => {
+            .filter_map(|predicate| match predicate.kind {
+                hir::WherePredicateKind::BoundPredicate(predicate) => {
                     match icx.lower_ty(predicate.bounded_ty).kind() {
                         ty::Param(data) => Some(Parameter(data.index)),
                         _ => None,
@@ -2202,8 +2202,8 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
                     span = predicates
                         .iter()
                         // There seems to be no better way to find out which predicate we are in
-                        .find(|pred| pred.span().contains(obligation_span))
-                        .map(|pred| pred.span())
+                        .find(|pred| pred.span.contains(obligation_span))
+                        .map(|pred| pred.span)
                         .unwrap_or(obligation_span);
                 }
 
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 73b73afb0a5..93be3e06e5d 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1040,6 +1040,7 @@ fn lower_variant(
             did: f.def_id.to_def_id(),
             name: f.ident.name,
             vis: tcx.visibility(f.def_id),
+            safety: f.safety,
         })
         .collect();
     let recovered = match def {
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index b5dee5bd021..bfee5d33598 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -238,11 +238,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     trace!(?predicates);
     // Add inline `<T: Foo>` bounds and bounds in the where clause.
     for predicate in hir_generics.predicates {
-        match predicate {
-            hir::WherePredicate::BoundPredicate(bound_pred) => {
+        match predicate.kind {
+            hir::WherePredicateKind::BoundPredicate(bound_pred) => {
                 let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
 
-                let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
+                let bound_vars = tcx.late_bound_vars(predicate.hir_id);
                 // Keep the type around in a dummy predicate, in case of no bounds.
                 // That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
                 // is still checked for WF.
@@ -275,7 +275,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
                 predicates.extend(bounds.clauses());
             }
 
-            hir::WherePredicate::RegionPredicate(region_pred) => {
+            hir::WherePredicateKind::RegionPredicate(region_pred) => {
                 let r1 = icx
                     .lowerer()
                     .lower_lifetime(region_pred.lifetime, RegionInferReason::RegionPredicate);
@@ -298,7 +298,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
                 }))
             }
 
-            hir::WherePredicate::EqPredicate(..) => {
+            hir::WherePredicateKind::EqPredicate(..) => {
                 // FIXME(#20041)
             }
         }
@@ -881,7 +881,8 @@ impl<'tcx> ItemCtxt<'tcx> {
         let mut bounds = Bounds::default();
 
         for predicate in hir_generics.predicates {
-            let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
+            let hir_id = predicate.hir_id;
+            let hir::WherePredicateKind::BoundPredicate(predicate) = predicate.kind else {
                 continue;
             };
 
@@ -901,7 +902,7 @@ impl<'tcx> ItemCtxt<'tcx> {
 
             let bound_ty = self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty);
 
-            let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
+            let bound_vars = self.tcx.late_bound_vars(hir_id);
             self.lowerer().lower_bounds(
                 bound_ty,
                 predicate.bounds,
@@ -974,10 +975,10 @@ pub(super) fn const_conditions<'tcx>(
     let mut bounds = Bounds::default();
 
     for pred in generics.predicates {
-        match pred {
-            hir::WherePredicate::BoundPredicate(bound_pred) => {
+        match pred.kind {
+            hir::WherePredicateKind::BoundPredicate(bound_pred) => {
                 let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
-                let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
+                let bound_vars = tcx.late_bound_vars(pred.hir_id);
                 icx.lowerer().lower_bounds(
                     ty,
                     bound_pred.bounds.iter(),
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index b4b3ef31f97..74729ebe488 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -936,9 +936,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
     }
 
     fn visit_where_predicate(&mut self, predicate: &'tcx hir::WherePredicate<'tcx>) {
-        match predicate {
-            &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                hir_id,
+        let hir_id = predicate.hir_id;
+        match predicate.kind {
+            &hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
                 bounded_ty,
                 bounds,
                 bound_generic_params,
@@ -979,7 +979,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                     walk_list!(this, visit_param_bound, bounds);
                 })
             }
-            &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
+            &hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
                 lifetime,
                 bounds,
                 ..
@@ -987,7 +987,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 self.visit_lifetime(lifetime);
                 walk_list!(self, visit_param_bound, bounds);
             }
-            &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
+            &hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
+                lhs_ty, rhs_ty, ..
+            }) => {
                 self.visit_ty(lhs_ty);
                 self.visit_ty(rhs_ty);
             }
@@ -2073,7 +2075,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                         // bounds since we'll be emitting a hard error in HIR lowering, so this
                         // is purely speculative.
                         let one_bound = generics.predicates.iter().find_map(|predicate| {
-                            let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
+                            let hir::WherePredicateKind::BoundPredicate(predicate) = predicate.kind
+                            else {
                                 return None;
                             };
                             let hir::TyKind::Path(hir::QPath::Resolved(None, bounded_path)) =
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 07d3273b09c..0b2e9ed6052 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -735,6 +735,17 @@ pub(crate) struct InvalidUnionField {
 }
 
 #[derive(Diagnostic)]
+#[diag(hir_analysis_invalid_unsafe_field, code = E0740)]
+pub(crate) struct InvalidUnsafeField {
+    #[primary_span]
+    pub field_span: Span,
+    #[subdiagnostic]
+    pub sugg: InvalidUnsafeFieldSuggestion,
+    #[note]
+    pub note: (),
+}
+
+#[derive(Diagnostic)]
 #[diag(hir_analysis_return_type_notation_on_non_rpitit)]
 pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> {
     #[primary_span]
@@ -755,6 +766,18 @@ pub(crate) struct InvalidUnionFieldSuggestion {
     pub hi: Span,
 }
 
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(
+    hir_analysis_invalid_unsafe_field_sugg,
+    applicability = "machine-applicable"
+)]
+pub(crate) struct InvalidUnsafeFieldSuggestion {
+    #[suggestion_part(code = "std::mem::ManuallyDrop<")]
+    pub lo: Span,
+    #[suggestion_part(code = ">")]
+    pub hi: Span,
+}
+
 #[derive(Diagnostic)]
 #[diag(hir_analysis_return_type_notation_equality_bound)]
 pub(crate) struct ReturnTypeNotationEqualityBound {
@@ -1685,3 +1708,11 @@ pub(crate) struct CmseEntryGeneric {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_register_type_unstable)]
+pub(crate) struct RegisterTypeUnstable<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub ty: Ty<'a>,
+}
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 6ebe1cedcaf..9d60759ae48 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -69,7 +69,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         search_bounds(hir_bounds);
         if let Some((self_ty, where_clause)) = self_ty_where_predicates {
             for clause in where_clause {
-                if let hir::WherePredicate::BoundPredicate(pred) = clause
+                if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind
                     && pred.is_param_bound(self_ty.to_def_id())
                 {
                     search_bounds(pred.bounds);
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 5e27ace4cbe..cab04ee0987 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
@@ -8,7 +8,8 @@ use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
 use rustc_middle::span_bug;
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::{
-    self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable, Upcast,
+    self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable,
+    TypeVisitableExt, Upcast,
 };
 use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
@@ -92,11 +93,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) =
             expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
+
+        // We don't support >1 principal
         if regular_traits.len() > 1 {
-            let _ = self.report_trait_object_addition_traits_error(&regular_traits);
-        } else if regular_traits.is_empty() && auto_traits.is_empty() {
-            let reported = self.report_trait_object_with_no_traits_error(span, &trait_bounds);
-            return Ty::new_error(tcx, reported);
+            let guar = self.report_trait_object_addition_traits_error(&regular_traits);
+            return Ty::new_error(tcx, guar);
+        }
+        // We  don't support empty trait objects.
+        if regular_traits.is_empty() && auto_traits.is_empty() {
+            let guar = self.report_trait_object_with_no_traits_error(span, &trait_bounds);
+            return Ty::new_error(tcx, guar);
+        }
+        // Don't create a dyn trait if we have errors in the principal.
+        if let Err(guar) = trait_bounds.error_reported() {
+            return Ty::new_error(tcx, guar);
         }
 
         // Check that there are no gross dyn-compatibility violations;
@@ -126,7 +136,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         for (base_trait_ref, original_span) in regular_traits_refs_spans {
             let base_pred: ty::Predicate<'tcx> = base_trait_ref.upcast(tcx);
-            for ClauseWithSupertraitSpan { pred, original_span, supertrait_span } in
+            for ClauseWithSupertraitSpan { pred, supertrait_span } in
                 traits::elaborate(tcx, [ClauseWithSupertraitSpan::new(base_pred, original_span)])
                     .filter_only_self()
             {
@@ -194,7 +204,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         for def_ids in associated_types.values_mut() {
             for (projection_bound, span) in &projection_bounds {
                 let def_id = projection_bound.projection_def_id();
-                // FIXME(#120456) - is `swap_remove` correct?
                 def_ids.swap_remove(&def_id);
                 if tcx.generics_require_sized_self(def_id) {
                     tcx.emit_node_span_lint(
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 4e5a8271e9e..0b58b807090 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -727,7 +727,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let tcx = self.tcx();
         // FIXME: Marked `mut` so that we can replace the spans further below with a more
         // appropriate one, but this should be handled earlier in the span assignment.
-        let mut associated_types: FxIndexMap<Span, Vec<_>> = associated_types
+        let associated_types: FxIndexMap<Span, Vec<_>> = associated_types
             .into_iter()
             .map(|(span, def_ids)| {
                 (span, def_ids.into_iter().map(|did| tcx.associated_item(did)).collect())
@@ -769,39 +769,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 hir::Node::Expr(_) | hir::Node::Pat(_) => true,
                 _ => false,
             };
-            match bound.trait_ref.path.segments {
-                // FIXME: `trait_ref.path.span` can point to a full path with multiple
-                // segments, even though `trait_ref.path.segments` is of length `1`. Work
-                // around that bug here, even though it should be fixed elsewhere.
-                // This would otherwise cause an invalid suggestion. For an example, look at
-                // `tests/ui/issues/issue-28344.rs` where instead of the following:
-                //
-                //   error[E0191]: the value of the associated type `Output`
-                //                 (from trait `std::ops::BitXor`) must be specified
-                //   --> $DIR/issue-28344.rs:4:17
-                //    |
-                // LL |     let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
-                //    |                 ^^^^^^ help: specify the associated type:
-                //    |                              `BitXor<Output = Type>`
-                //
-                // we would output:
-                //
-                //   error[E0191]: the value of the associated type `Output`
-                //                 (from trait `std::ops::BitXor`) must be specified
-                //   --> $DIR/issue-28344.rs:4:17
-                //    |
-                // LL |     let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
-                //    |                 ^^^^^^^^^^^^^ help: specify the associated type:
-                //    |                                     `BitXor::bitor<Output = Type>`
-                [segment] if segment.args.is_none() => {
-                    trait_bound_spans = vec![segment.ident.span];
-                    associated_types = associated_types
-                        .into_values()
-                        .map(|items| (segment.ident.span, items))
-                        .collect();
-                }
-                _ => {}
-            }
         }
 
         // We get all the associated items that _are_ set,
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 34effd199f1..246643d8074 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -70,6 +70,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
+use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::specialization_graph::Node;
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
 use rustc_middle::ty::{
@@ -210,13 +211,7 @@ fn get_impl_args(
         impl1_def_id.to_def_id(),
         impl1_args,
         impl2_node,
-        |_, span| {
-            traits::ObligationCause::new(
-                impl1_span,
-                impl1_def_id,
-                traits::ObligationCauseCode::WhereClause(impl2_node.def_id(), span),
-            )
-        },
+        &ObligationCause::misc(impl1_span, impl1_def_id),
     );
 
     let errors = ocx.select_all_or_error();
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 0a3aa8fec90..64c6969d4b9 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -117,11 +117,7 @@ impl<'a> State<'a> {
             Node::Ctor(..) => panic!("cannot print isolated Ctor"),
             Node::LetStmt(a) => self.print_local_decl(a),
             Node::Crate(..) => panic!("cannot print Crate"),
-            Node::WhereBoundPredicate(pred) => {
-                self.print_formal_generic_params(pred.bound_generic_params);
-                self.print_type(pred.bounded_ty);
-                self.print_bounds(":", pred.bounds);
-            }
+            Node::WherePredicate(pred) => self.print_where_predicate(pred),
             Node::ArrayLenInfer(_) => self.word("_"),
             Node::Synthetic => unreachable!(),
             Node::Err(_) => self.word("/*ERROR*/"),
@@ -1015,7 +1011,7 @@ impl<'a> State<'a> {
     }
 
     fn print_expr_maybe_paren(&mut self, expr: &hir::Expr<'_>, prec: i8) {
-        self.print_expr_cond_paren(expr, expr.precedence().order() < prec)
+        self.print_expr_cond_paren(expr, expr.precedence() < prec)
     }
 
     /// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
@@ -1049,7 +1045,7 @@ impl<'a> State<'a> {
         }
         self.space();
         self.word_space("=");
-        let npals = || parser::needs_par_as_let_scrutinee(init.precedence().order());
+        let npals = || parser::needs_par_as_let_scrutinee(init.precedence());
         self.print_expr_cond_paren(init, Self::cond_needs_par(init) || npals())
     }
 
@@ -2160,47 +2156,50 @@ impl<'a> State<'a> {
             if i != 0 {
                 self.word_space(",");
             }
+            self.print_where_predicate(predicate);
+        }
+    }
 
-            match *predicate {
-                hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                    bound_generic_params,
-                    bounded_ty,
-                    bounds,
-                    ..
-                }) => {
-                    self.print_formal_generic_params(bound_generic_params);
-                    self.print_type(bounded_ty);
-                    self.print_bounds(":", bounds);
-                }
-                hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
-                    lifetime,
-                    bounds,
-                    ..
-                }) => {
-                    self.print_lifetime(lifetime);
-                    self.word(":");
-
-                    for (i, bound) in bounds.iter().enumerate() {
-                        match bound {
-                            GenericBound::Outlives(lt) => {
-                                self.print_lifetime(lt);
-                            }
-                            _ => panic!("unexpected bound on lifetime param: {bound:?}"),
-                        }
+    fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) {
+        match *predicate.kind {
+            hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
+                bound_generic_params,
+                bounded_ty,
+                bounds,
+                ..
+            }) => {
+                self.print_formal_generic_params(bound_generic_params);
+                self.print_type(bounded_ty);
+                self.print_bounds(":", bounds);
+            }
+            hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
+                lifetime,
+                bounds,
+                ..
+            }) => {
+                self.print_lifetime(lifetime);
+                self.word(":");
 
-                        if i != 0 {
-                            self.word(":");
+                for (i, bound) in bounds.iter().enumerate() {
+                    match bound {
+                        GenericBound::Outlives(lt) => {
+                            self.print_lifetime(lt);
                         }
+                        _ => panic!("unexpected bound on lifetime param: {bound:?}"),
+                    }
+
+                    if i != 0 {
+                        self.word(":");
                     }
                 }
-                hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
-                    lhs_ty, rhs_ty, ..
-                }) => {
-                    self.print_type(lhs_ty);
-                    self.space();
-                    self.word_space("=");
-                    self.print_type(rhs_ty);
-                }
+            }
+            hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
+                lhs_ty, rhs_ty, ..
+            }) => {
+                self.print_type(lhs_ty);
+                self.space();
+                self.word_space("=");
+                self.print_type(rhs_ty);
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index e6e0f62b54d..a92482e6a0e 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -606,7 +606,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
 
             if let Ok(rest_snippet) = rest_snippet {
-                let sugg = if callee_expr.precedence().order() >= PREC_UNAMBIGUOUS {
+                let sugg = if callee_expr.precedence() >= PREC_UNAMBIGUOUS {
                     vec![
                         (up_to_rcvr_span, "".to_string()),
                         (rest_span, format!(".{}({rest_snippet}", segment.ident)),
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 483a8d1d9a9..0c3f21d540d 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -1107,7 +1107,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
     }
 
     fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
-        let expr_prec = self.expr.precedence().order();
+        let expr_prec = self.expr.precedence();
         let needs_parens = expr_prec < rustc_ast::util::parser::PREC_UNAMBIGUOUS;
 
         let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize));
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 1610848958e..b4715839cf5 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -68,7 +68,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // While we don't allow *arbitrary* coercions here, we *do* allow
         // coercions from ! to `expected`.
-        if ty.is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) {
+        if self.try_structurally_resolve_type(expr.span, ty).is_never()
+            && self.expr_guaranteed_to_constitute_read_for_never(expr)
+        {
             if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
                 let reported = self.dcx().span_delayed_bug(
                     expr.span,
@@ -274,7 +276,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // unless it's a place expression that isn't being read from, in which case
         // diverging would be unsound since we may never actually read the `!`.
         // e.g. `let _ = *never_ptr;` with `never_ptr: *const !`.
-        if ty.is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) {
+        if self.try_structurally_resolve_type(expr.span, ty).is_never()
+            && self.expr_guaranteed_to_constitute_read_for_never(expr)
+        {
             self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
         }
 
@@ -420,7 +424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             | hir::Node::GenericParam(_)
             | hir::Node::Crate(_)
             | hir::Node::Infer(_)
-            | hir::Node::WhereBoundPredicate(_)
+            | hir::Node::WherePredicate(_)
             | hir::Node::ArrayLenInfer(_)
             | hir::Node::PreciseCapturingNonLifetimeArg(_)
             | hir::Node::OpaqueTy(_) => {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index ce6ce0381a9..47af8c681da 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -269,13 +269,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
                 }
                 Adjust::Deref(None) => {
-                    // FIXME(effects): We *could* enforce `&T: ~const Deref` here.
+                    // FIXME(const_trait_impl): We *could* enforce `&T: ~const Deref` here.
                 }
                 Adjust::Pointer(_pointer_coercion) => {
-                    // FIXME(effects): We should probably enforce these.
+                    // FIXME(const_trait_impl): We should probably enforce these.
                 }
                 Adjust::ReborrowPin(_mutability) => {
-                    // FIXME(effects): We could enforce these; they correspond to
+                    // FIXME(const_trait_impl): We could enforce these; they correspond to
                     // `&mut T: DerefMut` tho, so it's kinda moot.
                 }
                 Adjust::Borrow(_) => {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 961526831fb..f8f6564cf14 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -729,7 +729,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let can_coerce = self.may_coerce(arg_ty, coerced_ty);
             if !can_coerce {
                 return Compatibility::Incompatible(Some(ty::error::TypeError::Sorts(
-                    ty::error::ExpectedFound::new(true, coerced_ty, arg_ty),
+                    ty::error::ExpectedFound::new(coerced_ty, arg_ty),
                 )));
             }
 
@@ -758,7 +758,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             } else {
                 expected_ty
             };
-            TypeTrace::types(&self.misc(span), true, mismatched_ty, provided_ty)
+            TypeTrace::types(&self.misc(span), mismatched_ty, provided_ty)
         };
 
         // The algorithm here is inspired by levenshtein distance and longest common subsequence.
@@ -2347,9 +2347,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 let check_for_matched_generics = || {
                     if matched_inputs.iter().any(|x| x.is_some())
-                        && params_with_generics.iter().any(|x| x.0.is_some())
+                        && params_with_generics.iter().any(|x| x.1.is_some())
                     {
-                        for (idx, (generic, _)) in params_with_generics.iter().enumerate() {
+                        for &(idx, generic, _) in &params_with_generics {
                             // Param has to have a generic and be matched to be relevant
                             if matched_inputs[idx.into()].is_none() {
                                 continue;
@@ -2362,7 +2362,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             for unmatching_idx in idx + 1..params_with_generics.len() {
                                 if matched_inputs[unmatching_idx.into()].is_none()
                                     && let Some(unmatched_idx_param_generic) =
-                                        params_with_generics[unmatching_idx].0
+                                        params_with_generics[unmatching_idx].1
                                     && unmatched_idx_param_generic.name.ident()
                                         == generic.name.ident()
                                 {
@@ -2377,8 +2377,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 let check_for_matched_generics = check_for_matched_generics();
 
-                for (idx, (generic_param, param)) in
-                    params_with_generics.iter().enumerate().filter(|(idx, _)| {
+                for &(idx, generic_param, param) in
+                    params_with_generics.iter().filter(|&(idx, _, _)| {
                         check_for_matched_generics
                             || expected_idx.is_none_or(|expected_idx| expected_idx == *idx)
                     })
@@ -2390,8 +2390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                     let other_params_matched: Vec<(usize, &hir::Param<'_>)> = params_with_generics
                         .iter()
-                        .enumerate()
-                        .filter(|(other_idx, (other_generic_param, _))| {
+                        .filter(|(other_idx, other_generic_param, _)| {
                             if *other_idx == idx {
                                 return false;
                             }
@@ -2410,18 +2409,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             }
                             other_generic_param.name.ident() == generic_param.name.ident()
                         })
-                        .map(|(other_idx, (_, other_param))| (other_idx, *other_param))
+                        .map(|&(other_idx, _, other_param)| (other_idx, other_param))
                         .collect();
 
                     if !other_params_matched.is_empty() {
                         let other_param_matched_names: Vec<String> = other_params_matched
                             .iter()
-                            .map(|(_, other_param)| {
+                            .map(|(idx, other_param)| {
                                 if let hir::PatKind::Binding(_, _, ident, _) = other_param.pat.kind
                                 {
                                     format!("`{ident}`")
                                 } else {
-                                    "{unknown}".to_string()
+                                    format!("parameter #{}", idx + 1)
                                 }
                             })
                             .collect();
@@ -2478,18 +2477,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 {
                     let param_idents_matching: Vec<String> = params_with_generics
                         .iter()
-                        .filter(|(generic, _)| {
+                        .filter(|(_, generic, _)| {
                             if let Some(generic) = generic {
                                 generic.name.ident() == generic_param.name.ident()
                             } else {
                                 false
                             }
                         })
-                        .map(|(_, param)| {
+                        .map(|(idx, _, param)| {
                             if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind {
                                 format!("`{ident}`")
                             } else {
-                                "{unknown}".to_string()
+                                format!("parameter #{}", idx + 1)
                             }
                         })
                         .collect();
@@ -2498,8 +2497,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         spans.push_span_label(
                             generic_param.span,
                             format!(
-                                "{} all reference this parameter {}",
+                                "{} {} reference this parameter `{}`",
                                 display_list_with_comma_and(&param_idents_matching),
+                                if param_idents_matching.len() == 2 { "both" } else { "all" },
                                 generic_param.name.ident().name,
                             ),
                         );
@@ -2580,7 +2580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if let Some(params_with_generics) = self.get_hir_params_with_generics(def_id, is_method) {
             debug_assert_eq!(params_with_generics.len(), matched_inputs.len());
-            for (idx, (generic_param, _)) in params_with_generics.iter().enumerate() {
+            for &(idx, generic_param, _) in &params_with_generics {
                 if matched_inputs[idx.into()].is_none() {
                     continue;
                 }
@@ -2594,20 +2594,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 };
 
                 let mut idxs_matched: Vec<usize> = vec![];
-                for (other_idx, (_, _)) in params_with_generics.iter().enumerate().filter(
-                    |(other_idx, (other_generic_param, _))| {
-                        if *other_idx == idx {
+                for &(other_idx, _, _) in
+                    params_with_generics.iter().filter(|&&(other_idx, other_generic_param, _)| {
+                        if other_idx == idx {
                             return false;
                         }
                         let Some(other_generic_param) = other_generic_param else {
                             return false;
                         };
-                        if matched_inputs[(*other_idx).into()].is_some() {
+                        if matched_inputs[other_idx.into()].is_some() {
                             return false;
                         }
                         other_generic_param.name.ident() == generic_param.name.ident()
-                    },
-                ) {
+                    })
+                {
                     idxs_matched.push(other_idx);
                 }
 
@@ -2642,7 +2642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         def_id: DefId,
         is_method: bool,
-    ) -> Option<Vec<(Option<&hir::GenericParam<'_>>, &hir::Param<'_>)>> {
+    ) -> Option<Vec<(usize, Option<&hir::GenericParam<'_>>, &hir::Param<'_>)>> {
         let fn_node = self.tcx.hir().get_if_local(def_id)?;
         let fn_decl = fn_node.fn_decl()?;
 
@@ -2685,7 +2685,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         debug_assert_eq!(params.len(), generic_params.len());
-        Some(generic_params.into_iter().zip(params).collect())
+        Some(
+            generic_params
+                .into_iter()
+                .zip(params)
+                .enumerate()
+                .map(|(a, (b, c))| (a, b, c))
+                .collect(),
+        )
     }
 }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index c4c4c2f200b..b493a61b9f4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -2,7 +2,7 @@ use core::cmp::min;
 use core::iter;
 
 use hir::def_id::LocalDefId;
-use rustc_ast::util::parser::{ExprPrecedence, PREC_UNAMBIGUOUS};
+use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::{Applicability, Diag, MultiSpan};
 use rustc_hir as hir;
@@ -10,7 +10,7 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{
     Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId,
-    Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
+    Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicateKind,
 };
 use rustc_hir_analysis::collect::suggest_impl_trait;
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
@@ -398,7 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // so we remove the user's `clone` call.
                     {
                         vec![(receiver_method.ident.span, conversion_method.name.to_string())]
-                    } else if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
+                    } else if expr.precedence() < PREC_UNAMBIGUOUS {
                         vec![
                             (expr.span.shrink_to_lo(), "(".to_string()),
                             (expr.span.shrink_to_hi(), format!(").{}()", conversion_method.name)),
@@ -1004,8 +1004,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // get all where BoundPredicates here, because they are used in two cases below
         let where_predicates = predicates
             .iter()
-            .filter_map(|p| match p {
-                WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
+            .filter_map(|p| match p.kind {
+                WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
                     bounds,
                     bounded_ty,
                     ..
@@ -1376,7 +1376,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             let span = expr.span.find_oldest_ancestor_in_same_ctxt();
 
-            let mut sugg = if expr.precedence().order() >= PREC_UNAMBIGUOUS {
+            let mut sugg = if expr.precedence() >= PREC_UNAMBIGUOUS {
                 vec![(span.shrink_to_hi(), ".into()".to_owned())]
             } else {
                 vec![
@@ -3000,7 +3000,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             "change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`",
         );
 
-        let close_paren = if expr.precedence().order() < PREC_UNAMBIGUOUS {
+        let close_paren = if expr.precedence() < PREC_UNAMBIGUOUS {
             sugg.push((expr.span.shrink_to_lo(), "(".to_string()));
             ")"
         } else {
@@ -3025,7 +3025,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let len = src.trim_end_matches(&checked_ty.to_string()).len();
                 expr.span.with_lo(expr.span.lo() + BytePos(len as u32))
             },
-            if expr.precedence().order() < PREC_UNAMBIGUOUS {
+            if expr.precedence() < PREC_UNAMBIGUOUS {
                 // Readd `)`
                 format!("{expected_ty})")
             } else {
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 63dccf8b0ce..91ea34eb54d 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -364,7 +364,7 @@ fn report_unexpected_variant_res(
         .with_code(err_code);
     match res {
         Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == E0164 => {
-            let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html";
+            let patterns_url = "https://doc.rust-lang.org/book/ch19-00-patterns.html";
             err.with_span_label(span, "`fn` calls are not allowed in patterns")
                 .with_help(format!("for more information, visit {patterns_url}"))
         }
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index d50eff0deb0..b0c020dd7cb 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -1802,7 +1802,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut is_mutbl = bm.1;
 
         for pointer_ty in place.deref_tys() {
-            match pointer_ty.kind() {
+            match self.structurally_resolve_type(self.tcx.hir().span(var_hir_id), pointer_ty).kind()
+            {
                 // We don't capture derefs of raw ptrs
                 ty::RawPtr(_, _) => unreachable!(),
 
@@ -1816,7 +1817,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Dereferencing a box doesn't change mutability
                 ty::Adt(def, ..) if def.is_box() => {}
 
-                unexpected_ty => bug!("deref of unexpected pointer type {:?}", unexpected_ty),
+                unexpected_ty => span_bug!(
+                    self.tcx.hir().span(var_hir_id),
+                    "deref of unexpected pointer type {:?}",
+                    unexpected_ty
+                ),
             }
         }
 
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index e8735cba9bd..6dab6468870 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -16,8 +16,15 @@ mod persist;
 
 pub use persist::{
     LoadResult, copy_cgu_workproduct_to_incr_comp_cache_dir, finalize_session_directory,
-    in_incr_comp_dir, in_incr_comp_dir_sess, load_query_result_cache, save_dep_graph,
-    save_work_product_index, setup_dep_graph,
+    in_incr_comp_dir, in_incr_comp_dir_sess, load_query_result_cache, save_work_product_index,
+    setup_dep_graph,
 };
+use rustc_middle::util::Providers;
+
+#[allow(missing_docs)]
+pub fn provide(providers: &mut Providers) {
+    providers.hooks.save_dep_graph =
+        |tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx.tcx));
+}
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_incremental/src/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs
index 186db0a60a3..f5d5167e0e2 100644
--- a/compiler/rustc_incremental/src/persist/mod.rs
+++ b/compiler/rustc_incremental/src/persist/mod.rs
@@ -12,5 +12,6 @@ mod work_product;
 
 pub use fs::{finalize_session_directory, in_incr_comp_dir, in_incr_comp_dir_sess};
 pub use load::{LoadResult, load_query_result_cache, setup_dep_graph};
-pub use save::{save_dep_graph, save_work_product_index};
+pub(crate) use save::save_dep_graph;
+pub use save::save_work_product_index;
 pub use work_product::copy_cgu_workproduct_to_incr_comp_cache_dir;
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index 53726df4597..8fc50ca1b43 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -25,7 +25,7 @@ use crate::errors;
 ///
 /// This function should only run after all queries have completed.
 /// Trying to execute a query afterwards would attempt to read the result cache we just dropped.
-pub fn save_dep_graph(tcx: TyCtxt<'_>) {
+pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) {
     debug!("save_dep_graph()");
     tcx.dep_graph.with_ignore(|| {
         let sess = tcx.sess;
diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs
index 1ac2c44e9dc..67ec7761133 100644
--- a/compiler/rustc_index_macros/src/newtype.rs
+++ b/compiler/rustc_index_macros/src/newtype.rs
@@ -122,7 +122,7 @@ impl Parse for Newtype {
                 #gate_rustc_only
                 impl ::std::iter::Step for #name {
                     #[inline]
-                    fn steps_between(start: &Self, end: &Self) -> Option<usize> {
+                    fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
                         <usize as ::std::iter::Step>::steps_between(
                             &Self::index(*start),
                             &Self::index(*end),
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 3eda3e9c67e..12e2bbc968f 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -308,17 +308,14 @@ impl<'tcx> ToTrace<'tcx> for Ty<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())),
+            values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
-        TypeTrace {
-            cause: cause.clone(),
-            values: ValuePairs::Regions(ExpectedFound::new(true, a, b)),
-        }
+        TypeTrace { cause: cause.clone(), values: ValuePairs::Regions(ExpectedFound::new(a, b)) }
     }
 }
 
@@ -326,7 +323,7 @@ impl<'tcx> ToTrace<'tcx> for Const<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())),
+            values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
         }
     }
 }
@@ -337,13 +334,13 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
             cause: cause.clone(),
             values: match (a.unpack(), b.unpack()) {
                 (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => {
-                    ValuePairs::Regions(ExpectedFound::new(true, a, b))
+                    ValuePairs::Regions(ExpectedFound::new(a, b))
                 }
                 (GenericArgKind::Type(a), GenericArgKind::Type(b)) => {
-                    ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into()))
+                    ValuePairs::Terms(ExpectedFound::new(a.into(), b.into()))
                 }
                 (GenericArgKind::Const(a), GenericArgKind::Const(b)) => {
-                    ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into()))
+                    ValuePairs::Terms(ExpectedFound::new(a.into(), b.into()))
                 }
                 _ => bug!("relating different kinds: {a:?} {b:?}"),
             },
@@ -353,19 +350,13 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
 
 impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
-        TypeTrace {
-            cause: cause.clone(),
-            values: ValuePairs::Terms(ExpectedFound::new(true, a, b)),
-        }
+        TypeTrace { cause: cause.clone(), values: ValuePairs::Terms(ExpectedFound::new(a, b)) }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
-        TypeTrace {
-            cause: cause.clone(),
-            values: ValuePairs::TraitRefs(ExpectedFound::new(true, a, b)),
-        }
+        TypeTrace { cause: cause.clone(), values: ValuePairs::TraitRefs(ExpectedFound::new(a, b)) }
     }
 }
 
@@ -373,17 +364,14 @@ impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Aliases(ExpectedFound::new(true, a.into(), b.into())),
+            values: ValuePairs::Aliases(ExpectedFound::new(a.into(), b.into())),
         }
     }
 }
 
 impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
-        TypeTrace {
-            cause: cause.clone(),
-            values: ValuePairs::Aliases(ExpectedFound::new(true, a, b)),
-        }
+        TypeTrace { cause: cause.clone(), values: ValuePairs::Aliases(ExpectedFound::new(a, b)) }
     }
 }
 
@@ -392,7 +380,6 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
         TypeTrace {
             cause: cause.clone(),
             values: ValuePairs::PolySigs(ExpectedFound::new(
-                true,
                 ty::Binder::dummy(a),
                 ty::Binder::dummy(b),
             )),
@@ -402,10 +389,7 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
 
 impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
-        TypeTrace {
-            cause: cause.clone(),
-            values: ValuePairs::PolySigs(ExpectedFound::new(true, a, b)),
-        }
+        TypeTrace { cause: cause.clone(), values: ValuePairs::PolySigs(ExpectedFound::new(a, b)) }
     }
 }
 
@@ -413,7 +397,7 @@ impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(true, a, b)),
+            values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(a, b)),
         }
     }
 }
@@ -422,7 +406,7 @@ impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::ExistentialProjection(ExpectedFound::new(true, a, b)),
+            values: ValuePairs::ExistentialProjection(ExpectedFound::new(a, b)),
         }
     }
 }
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index f87c43a0ecd..fe66d306ceb 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -72,7 +72,7 @@ impl<'tcx> InferCtxt<'tcx> {
             query_state,
         )
         .unchecked_map(|(param_env, value)| param_env.and(value));
-        CanonicalQueryInput { canonical, typing_mode: self.typing_mode(param_env) }
+        CanonicalQueryInput { canonical, typing_mode: self.typing_mode() }
     }
 
     /// Canonicalizes a query *response* `V`. When we canonicalize a
diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs
index ecda9c6eb00..1968ed34752 100644
--- a/compiler/rustc_infer/src/infer/context.rs
+++ b/compiler/rustc_infer/src/infer/context.rs
@@ -20,11 +20,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
         self.next_trait_solver
     }
 
-    fn typing_mode(
-        &self,
-        param_env_for_debug_assertion: ty::ParamEnv<'tcx>,
-    ) -> ty::TypingMode<'tcx> {
-        self.typing_mode(param_env_for_debug_assertion)
+    fn typing_mode(&self) -> ty::TypingMode<'tcx> {
+        self.typing_mode()
     }
 
     fn universe(&self) -> ty::UniverseIndex {
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index b29dc7f909d..555c1022a8a 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -43,7 +43,6 @@ use rustc_middle::ty::{
 };
 use rustc_span::Span;
 use rustc_span::symbol::Symbol;
-use rustc_type_ir::solve::Reveal;
 use snapshot::undo_log::InferCtxtUndoLogs;
 use tracing::{debug, instrument};
 use type_variable::TypeVariableOrigin;
@@ -265,11 +264,12 @@ pub struct InferCtxt<'tcx> {
     lexical_region_resolutions: RefCell<Option<LexicalRegionResolutions<'tcx>>>,
 
     /// Caches the results of trait selection. This cache is used
-    /// for things that have to do with the parameters in scope.
-    pub selection_cache: select::SelectionCache<'tcx>,
+    /// for things that depends on inference variables or placeholders.
+    pub selection_cache: select::SelectionCache<'tcx, ty::ParamEnv<'tcx>>,
 
-    /// Caches the results of trait evaluation.
-    pub evaluation_cache: select::EvaluationCache<'tcx>,
+    /// Caches the results of trait evaluation. This cache is used
+    /// for things that depends on inference variables or placeholders.
+    pub evaluation_cache: select::EvaluationCache<'tcx, ty::ParamEnv<'tcx>>,
 
     /// The set of predicates on which errors have been reported, to
     /// avoid reporting the same error twice.
@@ -624,22 +624,7 @@ impl<'tcx> InferCtxt<'tcx> {
     }
 
     #[inline(always)]
-    pub fn typing_mode(
-        &self,
-        param_env_for_debug_assertion: ty::ParamEnv<'tcx>,
-    ) -> TypingMode<'tcx> {
-        if cfg!(debug_assertions) {
-            match (param_env_for_debug_assertion.reveal(), self.typing_mode) {
-                (Reveal::All, TypingMode::PostAnalysis)
-                | (Reveal::UserFacing, TypingMode::Coherence | TypingMode::Analysis { .. }) => {}
-                (r, t) => unreachable!("TypingMode x Reveal mismatch: {r:?} {t:?}"),
-            }
-        }
-        self.typing_mode
-    }
-
-    #[inline(always)]
-    pub fn typing_mode_unchecked(&self) -> TypingMode<'tcx> {
+    pub fn typing_mode(&self) -> TypingMode<'tcx> {
         self.typing_mode
     }
 
@@ -1005,7 +990,7 @@ impl<'tcx> InferCtxt<'tcx> {
 
     #[inline(always)]
     pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
-        match self.typing_mode_unchecked() {
+        match self.typing_mode() {
             TypingMode::Analysis { defining_opaque_types } => {
                 id.into().as_local().is_some_and(|def_id| defining_opaque_types.contains(&def_id))
             }
@@ -1290,7 +1275,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// which contains the necessary information to use the trait system without
     /// using canonicalization or carrying this inference context around.
     pub fn typing_env(&self, param_env: ty::ParamEnv<'tcx>) -> ty::TypingEnv<'tcx> {
-        let typing_mode = match self.typing_mode(param_env) {
+        let typing_mode = match self.typing_mode() {
             ty::TypingMode::Coherence => ty::TypingMode::Coherence,
             // FIXME(#132279): This erases the `defining_opaque_types` as it isn't possible
             // to handle them without proper canonicalization. This means we may cause cycle
@@ -1478,39 +1463,29 @@ impl<'tcx> TypeTrace<'tcx> {
         self.cause.span
     }
 
-    pub fn types(
-        cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
-        a: Ty<'tcx>,
-        b: Ty<'tcx>,
-    ) -> TypeTrace<'tcx> {
+    pub fn types(cause: &ObligationCause<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())),
+            values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
         }
     }
 
     pub fn trait_refs(
         cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
         a: ty::TraitRef<'tcx>,
         b: ty::TraitRef<'tcx>,
     ) -> TypeTrace<'tcx> {
-        TypeTrace {
-            cause: cause.clone(),
-            values: ValuePairs::TraitRefs(ExpectedFound::new(a_is_expected, a, b)),
-        }
+        TypeTrace { cause: cause.clone(), values: ValuePairs::TraitRefs(ExpectedFound::new(a, b)) }
     }
 
     pub fn consts(
         cause: &ObligationCause<'tcx>,
-        a_is_expected: bool,
         a: ty::Const<'tcx>,
         b: ty::Const<'tcx>,
     ) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())),
+            values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
         }
     }
 }
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index 0aff4620314..a608ea1ad57 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -101,7 +101,7 @@ impl<'tcx> InferCtxt<'tcx> {
         let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
             ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
                 let def_id = def_id.expect_local();
-                if let ty::TypingMode::Coherence = self.typing_mode(param_env) {
+                if let ty::TypingMode::Coherence = self.typing_mode() {
                     // See comment on `insert_hidden_type` for why this is sufficient in coherence
                     return Some(self.register_hidden_type(
                         OpaqueTypeKey { def_id, args },
@@ -177,7 +177,7 @@ impl<'tcx> InferCtxt<'tcx> {
             res
         } else {
             let (a, b) = self.resolve_vars_if_possible((a, b));
-            Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
+            Err(TypeError::Sorts(ExpectedFound::new(a, b)))
         }
     }
 
@@ -522,7 +522,7 @@ impl<'tcx> InferCtxt<'tcx> {
         // value being folded. In simple cases like `-> impl Foo`,
         // these are the same span, but not in cases like `-> (impl
         // Foo, impl Bar)`.
-        match self.typing_mode(param_env) {
+        match self.typing_mode() {
             ty::TypingMode::Coherence => {
                 // During intercrate we do not define opaque types but instead always
                 // force ambiguity unless the hidden type is known to not implement
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 4c80bf4e07e..21c47967ead 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -520,10 +520,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
                             //
                             // cc trait-system-refactor-initiative#108
                             if self.infcx.next_trait_solver()
-                                && !matches!(
-                                    self.infcx.typing_mode_unchecked(),
-                                    TypingMode::Coherence
-                                )
+                                && !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
                                 && self.in_alias
                             {
                                 inner.type_variables().equate(vid, new_var_id);
@@ -654,10 +651,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
                             // See the comment for type inference variables
                             // for more details.
                             if self.infcx.next_trait_solver()
-                                && !matches!(
-                                    self.infcx.typing_mode_unchecked(),
-                                    TypingMode::Coherence
-                                )
+                                && !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
                                 && self.in_alias
                             {
                                 variable_table.union(vid, new_var_id);
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 43a98782016..2905fe688b5 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -689,10 +689,12 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
     rustc_const_eval::provide(providers);
     rustc_middle::hir::provide(providers);
     rustc_borrowck::provide(providers);
+    rustc_incremental::provide(providers);
     rustc_mir_build::provide(providers);
     rustc_mir_transform::provide(providers);
     rustc_monomorphize::provide(providers);
     rustc_privacy::provide(providers);
+    rustc_query_impl::provide(providers);
     rustc_resolve::provide(providers);
     rustc_hir_analysis::provide(providers);
     rustc_hir_typeck::provide(providers);
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index b6837ec764f..cd3a2fb7049 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -12,13 +12,12 @@ use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::ty::{GlobalCtxt, TyCtxt};
-use rustc_serialize::opaque::FileEncodeResult;
 use rustc_session::Session;
 use rustc_session::config::{self, OutputFilenames, OutputType};
 
 use crate::errors::FailedWritingFile;
 use crate::interface::{Compiler, Result};
-use crate::{errors, passes};
+use crate::passes;
 
 /// Represent the result of a query.
 ///
@@ -62,7 +61,7 @@ impl<'a, T> std::ops::DerefMut for QueryResult<'a, T> {
 
 impl<'a, 'tcx> QueryResult<'a, &'tcx GlobalCtxt<'tcx>> {
     pub fn enter<T>(&mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T {
-        (*self.0).get_mut().enter(f)
+        (*self.0).borrow().enter(f)
     }
 }
 
@@ -90,8 +89,10 @@ impl<'tcx> Queries<'tcx> {
         }
     }
 
-    pub fn finish(&self) -> FileEncodeResult {
-        if let Some(gcx) = self.gcx_cell.get() { gcx.finish() } else { Ok(0) }
+    pub fn finish(&'tcx self) {
+        if let Some(gcx) = self.gcx_cell.get() {
+            gcx.finish();
+        }
     }
 
     pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
@@ -209,29 +210,10 @@ impl Compiler {
         let queries = Queries::new(self);
         let ret = f(&queries);
 
-        // NOTE: intentionally does not compute the global context if it hasn't been built yet,
-        // since that likely means there was a parse error.
-        if let Some(Ok(gcx)) = &mut *queries.gcx.result.borrow_mut() {
-            let gcx = gcx.get_mut();
-            // We assume that no queries are run past here. If there are new queries
-            // after this point, they'll show up as "<unknown>" in self-profiling data.
-            {
-                let _prof_timer =
-                    queries.compiler.sess.prof.generic_activity("self_profile_alloc_query_strings");
-                gcx.enter(rustc_query_impl::alloc_self_profile_query_strings);
-            }
-
-            self.sess.time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph));
-
-            gcx.enter(rustc_query_impl::query_key_hash_verify_all);
-        }
-
         // The timer's lifetime spans the dropping of `queries`, which contains
         // the global context.
         _timer = self.sess.timer("free_global_ctxt");
-        if let Err((path, error)) = queries.finish() {
-            self.sess.dcx().emit_fatal(errors::FailedWritingFile { path: &path, error });
-        }
+        queries.finish();
 
         ret
     }
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index e48c4d46b59..6beae14100d 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -784,7 +784,6 @@ fn test_unstable_options_tracking_hash() {
     tracked!(flatten_format_args, false);
     tracked!(fmt_debug, FmtDebug::Shallow);
     tracked!(force_unstable_if_unmarked, true);
-    tracked!(fuel, Some(("abc".to_string(), 99)));
     tracked!(function_return, FunctionReturn::ThunkExtern);
     tracked!(function_sections, Some(false));
     tracked!(human_readable_cgu_names, true);
@@ -830,7 +829,6 @@ fn test_unstable_options_tracking_hash() {
     tracked!(plt, Some(true));
     tracked!(polonius, Polonius::Legacy);
     tracked!(precise_enum_drop_elaboration, false);
-    tracked!(print_fuel, Some("abc".to_string()));
     tracked!(profile_sample_use, Some(PathBuf::from("abc")));
     tracked!(profiler_runtime, "abc".to_string());
     tracked!(regparm, Some(3));
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index bcb103957ba..b584e7afd98 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -566,19 +566,19 @@ impl Cursor<'_> {
 
     fn c_or_byte_string(
         &mut self,
-        mk_kind: impl FnOnce(bool) -> LiteralKind,
-        mk_kind_raw: impl FnOnce(Option<u8>) -> LiteralKind,
+        mk_kind: fn(bool) -> LiteralKind,
+        mk_kind_raw: fn(Option<u8>) -> LiteralKind,
         single_quoted: Option<fn(bool) -> LiteralKind>,
     ) -> TokenKind {
         match (self.first(), self.second(), single_quoted) {
-            ('\'', _, Some(mk_kind)) => {
+            ('\'', _, Some(single_quoted)) => {
                 self.bump();
                 let terminated = self.single_quoted_string();
                 let suffix_start = self.pos_within_token();
                 if terminated {
                     self.eat_literal_suffix();
                 }
-                let kind = mk_kind(terminated);
+                let kind = single_quoted(terminated);
                 Literal { kind, suffix_start }
             }
             ('"', _, _) => {
diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs
index 556bbf1f518..db7225fc2a8 100644
--- a/compiler/rustc_lexer/src/tests.rs
+++ b/compiler/rustc_lexer/src/tests.rs
@@ -77,61 +77,51 @@ fn test_too_many_hashes() {
     check_raw_str(&s2, Err(RawStrError::TooManyDelimiters { found: u32::from(max_count) + 1 }));
 }
 
+// https://github.com/rust-lang/rust/issues/70528
 #[test]
 fn test_valid_shebang() {
-    // https://github.com/rust-lang/rust/issues/70528
-    let input = "#!/usr/bin/rustrun\nlet x = 5;";
-    assert_eq!(strip_shebang(input), Some(18));
-}
+    let input = "#!/bin/bash";
+    assert_eq!(strip_shebang(input), Some(input.len()));
 
-#[test]
-fn test_invalid_shebang_valid_rust_syntax() {
-    // https://github.com/rust-lang/rust/issues/70528
-    let input = "#!    [bad_attribute]";
+    let input = "#![attribute]";
     assert_eq!(strip_shebang(input), None);
-}
 
-#[test]
-fn test_shebang_second_line() {
-    // Because shebangs are interpreted by the kernel, they must be on the first line
-    let input = "\n#!/bin/bash";
+    let input = "#!    /bin/bash";
+    assert_eq!(strip_shebang(input), Some(input.len()));
+
+    let input = "#!    [attribute]";
     assert_eq!(strip_shebang(input), None);
-}
 
-#[test]
-fn test_shebang_space() {
-    let input = "#!    /bin/bash";
+    let input = "#! /* blah */  /bin/bash";
     assert_eq!(strip_shebang(input), Some(input.len()));
-}
 
-#[test]
-fn test_shebang_empty_shebang() {
-    let input = "#!    \n[attribute(foo)]";
+    let input = "#! /* blah */  [attribute]";
     assert_eq!(strip_shebang(input), None);
-}
 
-#[test]
-fn test_invalid_shebang_comment() {
-    let input = "#!//bin/ami/a/comment\n[";
-    assert_eq!(strip_shebang(input), None)
-}
+    let input = "#! // blah\n/bin/bash";
+    assert_eq!(strip_shebang(input), Some(10)); // strip up to the newline
 
-#[test]
-fn test_invalid_shebang_another_comment() {
-    let input = "#!/*bin/ami/a/comment*/\n[attribute";
-    assert_eq!(strip_shebang(input), None)
-}
+    let input = "#! // blah\n[attribute]";
+    assert_eq!(strip_shebang(input), None);
 
-#[test]
-fn test_shebang_valid_rust_after() {
-    let input = "#!/*bin/ami/a/comment*/\npub fn main() {}";
-    assert_eq!(strip_shebang(input), Some(23))
-}
+    let input = "#! /* blah\nblah\nblah */  /bin/bash";
+    assert_eq!(strip_shebang(input), Some(10));
 
-#[test]
-fn test_shebang_followed_by_attrib() {
-    let input = "#!/bin/rust-scripts\n#![allow_unused(true)]";
-    assert_eq!(strip_shebang(input), Some(19));
+    let input = "#! /* blah\nblah\nblah */  [attribute]";
+    assert_eq!(strip_shebang(input), None);
+
+    let input = "#!\n/bin/sh";
+    assert_eq!(strip_shebang(input), Some(2));
+
+    let input = "#!\n[attribute]";
+    assert_eq!(strip_shebang(input), None);
+
+    // Because shebangs are interpreted by the kernel, they must be on the first line
+    let input = "\n#!/bin/bash";
+    assert_eq!(strip_shebang(input), None);
+
+    let input = "\n#![attribute]";
+    assert_eq!(strip_shebang(input), None);
 }
 
 fn check_lexing(src: &str, expect: Expect) {
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index bda982a3675..e130cfc1d73 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1407,7 +1407,7 @@ declare_lint_pass!(TypeAliasBounds => [TYPE_ALIAS_BOUNDS]);
 impl TypeAliasBounds {
     pub(crate) fn affects_object_lifetime_defaults(pred: &hir::WherePredicate<'_>) -> bool {
         // Bounds of the form `T: 'a` with `T` type param affect object lifetime defaults.
-        if let hir::WherePredicate::BoundPredicate(pred) = pred
+        if let hir::WherePredicateKind::BoundPredicate(pred) = pred.kind
             && pred.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Outlives(_)))
             && pred.bound_generic_params.is_empty() // indeed, even if absent from the RHS
             && pred.bounded_ty.as_generic_param().is_some()
@@ -1451,11 +1451,11 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
         let mut inline_sugg = Vec::new();
 
         for p in generics.predicates {
-            let span = p.span();
-            if p.in_where_clause() {
+            let span = p.span;
+            if p.kind.in_where_clause() {
                 where_spans.push(span);
             } else {
-                for b in p.bounds() {
+                for b in p.kind.bounds() {
                     inline_spans.push(b.span());
                 }
                 inline_sugg.push((span, String::new()));
@@ -2071,7 +2071,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
             let num_where_predicates = hir_generics
                 .predicates
                 .iter()
-                .filter(|predicate| predicate.in_where_clause())
+                .filter(|predicate| predicate.kind.in_where_clause())
                 .count();
 
             let mut bound_count = 0;
@@ -2080,8 +2080,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
             let mut dropped_where_predicate_count = 0;
             for (i, where_predicate) in hir_generics.predicates.iter().enumerate() {
                 let (relevant_lifetimes, bounds, predicate_span, in_where_clause) =
-                    match where_predicate {
-                        hir::WherePredicate::RegionPredicate(predicate) => {
+                    match where_predicate.kind {
+                        hir::WherePredicateKind::RegionPredicate(predicate) => {
                             if let Some(ResolvedArg::EarlyBound(region_def_id)) =
                                 cx.tcx.named_bound_var(predicate.lifetime.hir_id)
                             {
@@ -2090,21 +2090,21 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                                         cx.tcx,
                                         // don't warn if the inferred span actually came from the predicate we're looking at
                                         // this happens if the type is recursively defined
-                                        inferred_outlives
-                                            .iter()
-                                            .filter(|(_, span)| !predicate.span.contains(*span)),
+                                        inferred_outlives.iter().filter(|(_, span)| {
+                                            !where_predicate.span.contains(*span)
+                                        }),
                                         item.owner_id.def_id,
                                         region_def_id,
                                     ),
                                     &predicate.bounds,
-                                    predicate.span,
+                                    where_predicate.span,
                                     predicate.in_where_clause,
                                 )
                             } else {
                                 continue;
                             }
                         }
-                        hir::WherePredicate::BoundPredicate(predicate) => {
+                        hir::WherePredicateKind::BoundPredicate(predicate) => {
                             // FIXME we can also infer bounds on associated types,
                             // and should check for them here.
                             match predicate.bounded_ty.kind {
@@ -2118,12 +2118,12 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                                             // don't warn if the inferred span actually came from the predicate we're looking at
                                             // this happens if the type is recursively defined
                                             inferred_outlives.iter().filter(|(_, span)| {
-                                                !predicate.span.contains(*span)
+                                                !where_predicate.span.contains(*span)
                                             }),
                                             index,
                                         ),
                                         &predicate.bounds,
-                                        predicate.span,
+                                        where_predicate.span,
                                         predicate.origin == PredicateOrigin::WhereClause,
                                     )
                                 }
@@ -2161,7 +2161,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                     } else if i + 1 < num_where_predicates {
                         // If all the bounds on a predicate were inferable and there are
                         // further predicates, we want to eat the trailing comma.
-                        let next_predicate_span = hir_generics.predicates[i + 1].span();
+                        let next_predicate_span = hir_generics.predicates[i + 1].span;
                         if next_predicate_span.from_expansion() {
                             where_lint_spans.push(predicate_span);
                         } else {
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 6eec32beab0..7248b192763 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -14,7 +14,6 @@ use rustc_feature::Features;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
-use rustc_infer::traits::Reveal;
 use rustc_middle::bug;
 use rustc_middle::middle::privacy::EffectiveVisibilities;
 use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
@@ -702,7 +701,6 @@ impl<'tcx> LateContext<'tcx> {
     /// The typing mode of the currently visited node. Use this when
     /// building a new `InferCtxt`.
     pub fn typing_mode(&self) -> TypingMode<'tcx> {
-        debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing);
         // FIXME(#132279): In case we're in a body, we should use a typing
         // mode which reveals the opaque types defined by that body.
         TypingMode::non_body_analysis()
diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs
index e3e51ba263d..7e298a9a63c 100644
--- a/compiler/rustc_lint/src/dangling.rs
+++ b/compiler/rustc_lint/src/dangling.rs
@@ -130,11 +130,11 @@ impl DanglingPointerSearcher<'_, '_> {
 
 fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {
     if let ExprKind::MethodCall(method, receiver, _args, _span) = expr.kind
-        && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
-        && cx.tcx.has_attr(fn_id, sym::rustc_as_ptr)
         && is_temporary_rvalue(receiver)
         && let ty = cx.typeck_results().expr_ty(receiver)
         && owns_allocation(cx.tcx, ty)
+        && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
+        && cx.tcx.has_attr(fn_id, sym::rustc_as_ptr)
     {
         // FIXME: use `emit_node_lint` when `#[primary_span]` is added.
         cx.tcx.emit_node_span_lint(
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 352155729e5..dce6010a2c1 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -300,7 +300,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> {
         let affect_object_lifetime_defaults = self
             .preds
             .iter()
-            .filter(|pred| pred.in_where_clause() == self.in_where_clause)
+            .filter(|pred| pred.kind.in_where_clause() == self.in_where_clause)
             .any(|pred| TypeAliasBounds::affects_object_lifetime_defaults(pred));
 
         // If there are any shorthand assoc tys, then the bounds can't be removed automatically.
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 5ec920d39f4..e1a0e1ec579 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -1304,12 +1304,12 @@ impl EarlyLintPass for UnusedParens {
     }
 
     fn enter_where_predicate(&mut self, _: &EarlyContext<'_>, pred: &ast::WherePredicate) {
-        use rustc_ast::{WhereBoundPredicate, WherePredicate};
-        if let WherePredicate::BoundPredicate(WhereBoundPredicate {
+        use rustc_ast::{WhereBoundPredicate, WherePredicateKind};
+        if let WherePredicateKind::BoundPredicate(WhereBoundPredicate {
             bounded_ty,
             bound_generic_params,
             ..
-        }) = pred
+        }) = &pred.kind
             && let ast::TyKind::Paren(_) = &bounded_ty.kind
             && bound_generic_params.is_empty()
         {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 9036741e078..3b406c7e161 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -5173,7 +5173,7 @@ declare_lint! {
     Warn,
     "this function call or definition uses a vector type which is not enabled",
     @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
         reference: "issue #116558 <https://github.com/rust-lang/rust/issues/116558>",
     };
 }
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index cd70c3f2669..06550728f0f 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -2051,6 +2051,25 @@ extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() {
   return llvm::compression::zstd::isAvailable();
 }
 
+extern "C" void LLVMRustSetNoSanitizeAddress(LLVMValueRef Global) {
+  GlobalValue &GV = *unwrap<GlobalValue>(Global);
+  GlobalValue::SanitizerMetadata MD;
+  if (GV.hasSanitizerMetadata())
+    MD = GV.getSanitizerMetadata();
+  MD.NoAddress = true;
+  MD.IsDynInit = false;
+  GV.setSanitizerMetadata(MD);
+}
+
+extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) {
+  GlobalValue &GV = *unwrap<GlobalValue>(Global);
+  GlobalValue::SanitizerMetadata MD;
+  if (GV.hasSanitizerMetadata())
+    MD = GV.getSanitizerMetadata();
+  MD.NoHWAddress = true;
+  GV.setSanitizerMetadata(MD);
+}
+
 // Operations on composite constants.
 // These are clones of LLVM api functions that will become available in future
 // releases. They can be removed once Rust's minimum supported LLVM version
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index d80aa0cc4f4..6d7d88fa8d7 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -233,9 +233,6 @@ metadata_prev_alloc_error_handler =
 metadata_prev_global_alloc =
     previous global allocator defined here
 
-metadata_profiler_builtins_needs_core =
-    `profiler_builtins` crate (required by compiler options) is not compatible with crate attribute `#![no_core]`
-
 metadata_raw_dylib_no_nul =
     link name must not contain NUL characters if link kind is `raw-dylib`
 
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index a611e8010be..a18c6baec00 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -724,8 +724,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
     fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
         // If we're only compiling an rlib, then there's no need to select a
         // panic runtime, so we just skip this section entirely.
-        let any_non_rlib = self.tcx.crate_types().iter().any(|ct| *ct != CrateType::Rlib);
-        if !any_non_rlib {
+        let only_rlib = self.tcx.crate_types().iter().all(|ct| *ct == CrateType::Rlib);
+        if only_rlib {
             info!("panic runtime injection skipped, only generating rlib");
             return;
         }
@@ -799,20 +799,16 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         self.inject_dependency_if(cnum, "a panic runtime", &|data| data.needs_panic_runtime());
     }
 
-    fn inject_profiler_runtime(&mut self, krate: &ast::Crate) {
-        if self.sess.opts.unstable_opts.no_profiler_runtime
-            || !(self.sess.instrument_coverage() || self.sess.opts.cg.profile_generate.enabled())
-        {
+    fn inject_profiler_runtime(&mut self) {
+        let needs_profiler_runtime =
+            self.sess.instrument_coverage() || self.sess.opts.cg.profile_generate.enabled();
+        if !needs_profiler_runtime || self.sess.opts.unstable_opts.no_profiler_runtime {
             return;
         }
 
         info!("loading profiler");
 
         let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime);
-        if name == sym::profiler_builtins && attr::contains_name(&krate.attrs, sym::no_core) {
-            self.dcx().emit_err(errors::ProfilerBuiltinsNeedsCore);
-        }
-
         let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else {
             return;
         };
@@ -1046,7 +1042,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
 
     pub fn postprocess(&mut self, krate: &ast::Crate) {
         self.inject_forced_externs();
-        self.inject_profiler_runtime(krate);
+        self.inject_profiler_runtime();
         self.inject_allocator_crate(krate);
         self.inject_panic_runtime(krate);
 
@@ -1172,7 +1168,7 @@ fn attempt_load_dylib(path: &Path) -> Result<libloading::Library, libloading::Er
         // the expected format is lib<name>.a(libname.so) for the actual
         // dynamic library
         let library_name = path.file_stem().expect("expect a library name");
-        let mut archive_member = OsString::from("a(");
+        let mut archive_member = std::ffi::OsString::from("a(");
         archive_member.push(library_name);
         archive_member.push(".so)");
         let new_path = path.with_extension(archive_member);
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 16684ae6f26..b6c5619ec18 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -340,10 +340,6 @@ pub struct NoPanicStrategy {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_profiler_builtins_needs_core)]
-pub struct ProfilerBuiltinsNeedsCore;
-
-#[derive(Diagnostic)]
 #[diag(metadata_not_profiler_runtime)]
 pub struct NotProfilerRuntime {
     pub crate_name: Symbol,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 87357b74c41..56beff5aa64 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -15,6 +15,7 @@ use rustc_data_structures::sync::{Lock, Lrc, OnceLock};
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro};
+use rustc_hir::Safety;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefPath, DefPathData};
@@ -1101,6 +1102,7 @@ impl<'a> CrateMetadataRef<'a> {
                         did,
                         name: self.item_name(did.index),
                         vis: self.get_visibility(did.index),
+                        safety: self.get_safety(did.index),
                     })
                     .collect(),
                 adt_kind,
@@ -1162,6 +1164,10 @@ impl<'a> CrateMetadataRef<'a> {
             .map_id(|index| self.local_def_id(index))
     }
 
+    fn get_safety(self, id: DefIndex) -> Safety {
+        self.root.tables.safety.get(self, id).unwrap_or_else(|| self.missing("safety", id))
+    }
+
     fn get_trait_item_def_id(self, id: DefIndex) -> Option<DefId> {
         self.root.tables.trait_item_def_id.get(self, id).map(|d| d.decode_from_cdata(self))
     }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 8378e7c6e9b..dd149af5205 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1599,6 +1599,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 f.did.index
             }));
 
+            for field in &variant.fields {
+                self.tables.safety.set_some(field.did.index, field.safety);
+            }
+
             if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
                 let fn_sig = tcx.fn_sig(ctor_def_id);
                 // FIXME only encode signature for ctor_def_id
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 4a8f8521b4f..a486ad42482 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -411,6 +411,7 @@ define_tables! {
     associated_item_or_field_def_ids: Table<DefIndex, LazyArray<DefIndex>>,
     def_kind: Table<DefIndex, DefKind>,
     visibility: Table<DefIndex, LazyValue<ty::Visibility<DefIndex>>>,
+    safety: Table<DefIndex, hir::Safety>,
     def_span: Table<DefIndex, LazyValue<Span>>,
     def_ident_span: Table<DefIndex, LazyValue<Span>>,
     lookup_stability: Table<DefIndex, LazyValue<attr::Stability>>,
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 63abd2be9a5..9438350ca09 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -199,6 +199,13 @@ fixed_size_enum! {
 }
 
 fixed_size_enum! {
+    hir::Safety {
+        ( Unsafe )
+        ( Safe   )
+    }
+}
+
+fixed_size_enum! {
     ty::Asyncness {
         ( Yes )
         ( No  )
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index 52c3212ab80..5dd85978f00 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -73,6 +73,9 @@ middle_drop_check_overflow =
 
 middle_erroneous_constant = erroneous constant encountered
 
+middle_failed_writing_file =
+    failed to write file {$path}: {$error}"
+
 middle_layout_references_error =
     the type has an unknown layout
 
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index 5c2aa0005d4..6300d856393 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -1,5 +1,5 @@
-use std::fmt;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
+use std::{fmt, io};
 
 use rustc_errors::codes::*;
 use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage};
@@ -19,6 +19,13 @@ pub struct DropCheckOverflow<'tcx> {
 }
 
 #[derive(Diagnostic)]
+#[diag(middle_failed_writing_file)]
+pub struct FailedWritingFile<'a> {
+    pub path: &'a Path,
+    pub error: io::Error,
+}
+
+#[derive(Diagnostic)]
 #[diag(middle_opaque_hidden_type_mismatch)]
 pub struct OpaqueHiddenTypeMismatch<'tcx> {
     pub self_ty: Ty<'tcx>,
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 007e6f46006..4900575c36e 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -947,7 +947,7 @@ impl<'hir> Map<'hir> {
             Node::Infer(i) => i.span,
             Node::LetStmt(local) => local.span,
             Node::Crate(item) => item.spans.inner_span,
-            Node::WhereBoundPredicate(pred) => pred.span,
+            Node::WherePredicate(pred) => pred.span,
             Node::ArrayLenInfer(inf) => inf.span,
             Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span,
             Node::Synthetic => unreachable!(),
@@ -1225,7 +1225,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
             format!("{id} (generic_param {})", path_str(param.def_id))
         }
         Node::Crate(..) => String::from("(root_crate)"),
-        Node::WhereBoundPredicate(_) => node_str("where bound predicate"),
+        Node::WherePredicate(_) => node_str("where predicate"),
         Node::ArrayLenInfer(_) => node_str("array len infer"),
         Node::Synthetic => unreachable!(),
         Node::Err(_) => node_str("error"),
diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs
index 742797fdeef..92fa64b0987 100644
--- a/compiler/rustc_middle/src/hooks/mod.rs
+++ b/compiler/rustc_middle/src/hooks/mod.rs
@@ -108,6 +108,19 @@ declare_hooks! {
     /// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
     /// can just link to the upstream crate and therefore don't need a mono item.
     hook should_codegen_locally(instance: crate::ty::Instance<'tcx>) -> bool;
+
+    hook alloc_self_profile_query_strings() -> ();
+
+    /// Saves and writes the DepGraph to the file system.
+    ///
+    /// This function saves both the dep-graph and the query result cache,
+    /// and drops the result cache.
+    ///
+    /// This function should only run after all queries have completed.
+    /// Trying to execute a query afterwards would attempt to read the result cache we just dropped.
+    hook save_dep_graph() -> ();
+
+    hook query_key_hash_verify_all() -> ();
 }
 
 #[cold]
diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs
index b20673fe8da..7a91bfad483 100644
--- a/compiler/rustc_middle/src/middle/lang_items.rs
+++ b/compiler/rustc_middle/src/middle/lang_items.rs
@@ -68,6 +68,17 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
+    /// Given a [`ty::ClosureKind`], get the [`DefId`] of its corresponding `Fn`-family
+    /// trait, if it is defined.
+    pub fn async_fn_trait_kind_to_def_id(self, kind: ty::ClosureKind) -> Option<DefId> {
+        let items = self.lang_items();
+        match kind {
+            ty::ClosureKind::Fn => items.async_fn_trait(),
+            ty::ClosureKind::FnMut => items.async_fn_mut_trait(),
+            ty::ClosureKind::FnOnce => items.async_fn_once_trait(),
+        }
+    }
+
     /// Returns `true` if `id` is a `DefId` of [`Fn`], [`FnMut`] or [`FnOnce`] traits.
     pub fn is_fn_trait(self, id: DefId) -> bool {
         self.fn_trait_kind_from_def_id(id).is_some()
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index a51370369b8..7983329b0f7 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -105,8 +105,10 @@ impl<'tcx> ConstValue<'tcx> {
         typing_env: ty::TypingEnv<'tcx>,
         ty: Ty<'tcx>,
     ) -> Option<u128> {
-        let size =
-            tcx.layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(ty)).ok()?.size;
+        let size = tcx
+            .layout_of(typing_env.with_post_analysis_normalized(tcx).as_query_input(ty))
+            .ok()?
+            .size;
         self.try_to_bits(size)
     }
 
@@ -376,7 +378,7 @@ impl<'tcx> Const<'tcx> {
     ) -> Option<u128> {
         let int = self.try_eval_scalar_int(tcx, typing_env)?;
         let size = tcx
-            .layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(self.ty()))
+            .layout_of(typing_env.with_post_analysis_normalized(tcx).as_query_input(self.ty()))
             .ok()?
             .size;
         Some(int.to_bits(size))
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 11a4e7f89a7..33f9a2bdca6 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -155,22 +155,6 @@ impl Debug for CoverageKind {
     }
 }
 
-#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, Eq, PartialOrd, Ord)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct SourceRegion {
-    pub start_line: u32,
-    pub start_col: u32,
-    pub end_line: u32,
-    pub end_col: u32,
-}
-
-impl Debug for SourceRegion {
-    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        let &Self { start_line, start_col, end_line, end_col } = self;
-        write!(fmt, "{start_line}:{start_col} - {end_line}:{end_col}")
-    }
-}
-
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
 #[derive(TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
 pub enum Op {
@@ -232,7 +216,7 @@ impl MappingKind {
 #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
 pub struct Mapping {
     pub kind: MappingKind,
-    pub source_region: SourceRegion,
+    pub span: Span,
 }
 
 /// Stores per-function coverage information attached to a `mir::Body`,
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 6eeafe18b35..e540f0194ec 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -162,7 +162,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
         // improve caching of queries.
         let inputs =
-            self.erase_regions(typing_env.with_reveal_all_normalized(self).as_query_input(cid));
+            self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid));
         if !span.is_dummy() {
             // The query doesn't know where it is being invoked, so we need to fix the span.
             self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span))
@@ -182,7 +182,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
         // improve caching of queries.
         let inputs =
-            self.erase_regions(typing_env.with_reveal_all_normalized(self).as_query_input(cid));
+            self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid));
         debug!(?inputs);
         if !span.is_dummy() {
             // The query doesn't know where it is being invoked, so we need to fix the span.
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index e2379f282ec..56340ff0095 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -629,8 +629,7 @@ impl<'tcx> Body<'tcx> {
     ) -> Option<(u128, &'a SwitchTargets)> {
         // There are two places here we need to evaluate a constant.
         let eval_mono_const = |constant: &ConstOperand<'tcx>| {
-            // FIXME(#132279): what is this, why are we using an empty environment with
-            // `RevealAll` here.
+            // FIXME(#132279): what is this, why are we using an empty environment here.
             let typing_env = ty::TypingEnv::fully_monomorphized();
             let mono_literal = instance.instantiate_mir_and_normalize_erasing_regions(
                 tcx,
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 2bfcd0a6227..ece468947c2 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -603,8 +603,8 @@ fn write_function_coverage_info(
     for (id, expression) in expressions.iter_enumerated() {
         writeln!(w, "{INDENT}coverage {id:?} => {expression:?};")?;
     }
-    for coverage::Mapping { kind, source_region } in mappings {
-        writeln!(w, "{INDENT}coverage {kind:?} => {source_region:?};")?;
+    for coverage::Mapping { kind, span } in mappings {
+        writeln!(w, "{INDENT}coverage {kind:?} => {span:?};")?;
     }
     writeln!(w)?;
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 76338be33aa..0f2a6d598a0 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1373,18 +1373,20 @@ rustc_queries! {
     /// Gets the ParameterEnvironment for a given item; this environment
     /// will be in "user-facing" mode, meaning that it is suitable for
     /// type-checking etc, and it does not normalize specializable
-    /// associated types. This is almost always what you want,
-    /// unless you are doing MIR optimizations, in which case you
-    /// might want to use `reveal_all()` method to change modes.
+    /// associated types.
+    ///
+    /// You should almost certainly not use this. If you already have an InferCtxt, then
+    /// you should also probably have a `ParamEnv` from when it was built. If you don't,
+    /// then you should take a `TypingEnv` to ensure that you handle opaque types correctly.
     query param_env(def_id: DefId) -> ty::ParamEnv<'tcx> {
         desc { |tcx| "computing normalized predicates of `{}`", tcx.def_path_str(def_id) }
         feedable
     }
 
-    /// Like `param_env`, but returns the `ParamEnv` in `Reveal::All` mode.
-    /// Prefer this over `tcx.param_env(def_id).with_reveal_all_normalized(tcx)`,
-    /// as this method is more efficient.
-    query param_env_reveal_all_normalized(def_id: DefId) -> ty::ParamEnv<'tcx> {
+    /// Like `param_env`, but returns the `ParamEnv` after all opaque types have been
+    /// replaced with their hidden type. This is used in the old trait solver
+    /// when in `PostAnalysis` mode and should not be called directly.
+    query param_env_normalized_for_post_analysis(def_id: DefId) -> ty::ParamEnv<'tcx> {
         desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) }
     }
 
@@ -1465,13 +1467,13 @@ rustc_queries! {
     /// *IMPORTANT*: *DO NOT* run this query before promoted MIR body is constructed,
     /// because this query partially depends on that query.
     /// Otherwise, there is a risk of query cycles.
-    query list_significant_drop_tys(ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> &'tcx ty::List<Ty<'tcx>> {
+    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
-    /// executes in "reveal all" mode, and will normalize the input type.
+    /// executes in `TypingMode::PostAnalysis`, and will normalize the input type.
     query layout_of(
         key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>
     ) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 09731d565b6..d61ef7641ee 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -23,7 +23,7 @@ use rustc_span::def_id::{CRATE_DEF_ID, LocalDefId};
 use rustc_span::symbol::Symbol;
 use rustc_span::{DUMMY_SP, Span};
 // FIXME: Remove this import and import via `solve::`
-pub use rustc_type_ir::solve::{BuiltinImplSource, Reveal};
+pub use rustc_type_ir::solve::BuiltinImplSource;
 use smallvec::{SmallVec, smallvec};
 use thin_vec::ThinVec;
 
@@ -551,7 +551,7 @@ pub struct DerivedCause<'tcx> {
     pub parent_code: InternedObligationCauseCode<'tcx>,
 }
 
-#[derive(Clone, Debug, TypeVisitable)]
+#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
 pub enum SelectionError<'tcx> {
     /// The trait is not implemented.
     Unimplemented,
@@ -573,7 +573,7 @@ pub enum SelectionError<'tcx> {
     ConstArgHasWrongType { ct: ty::Const<'tcx>, ct_ty: Ty<'tcx>, expected_ty: Ty<'tcx> },
 }
 
-#[derive(Clone, Debug, TypeVisitable)]
+#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
 pub struct SignatureMismatchData<'tcx> {
     pub found_trait_ref: ty::TraitRef<'tcx>,
     pub expected_trait_ref: ty::TraitRef<'tcx>,
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index 05556ae38a8..094fc62afbb 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -11,20 +11,10 @@ use self::EvaluationResult::*;
 use super::{SelectionError, SelectionResult};
 use crate::ty;
 
-pub type SelectionCache<'tcx> = Cache<
-    // This cache does not use `ParamEnvAnd` in its keys because `ParamEnv::and` can replace
-    // caller bounds with an empty list if the `TraitPredicate` looks global, which may happen
-    // after erasing lifetimes from the predicate.
-    (ty::ParamEnv<'tcx>, ty::TraitPredicate<'tcx>),
-    SelectionResult<'tcx, SelectionCandidate<'tcx>>,
->;
-
-pub type EvaluationCache<'tcx> = Cache<
-    // See above: this cache does not use `ParamEnvAnd` in its keys due to sometimes incorrectly
-    // caching with the wrong `ParamEnv`.
-    (ty::ParamEnv<'tcx>, ty::PolyTraitPredicate<'tcx>),
-    EvaluationResult,
->;
+pub type SelectionCache<'tcx, ENV> =
+    Cache<(ENV, ty::TraitPredicate<'tcx>), SelectionResult<'tcx, SelectionCandidate<'tcx>>>;
+
+pub type EvaluationCache<'tcx, ENV> = Cache<(ENV, ty::PolyTraitPredicate<'tcx>), EvaluationResult>;
 
 /// The selection process begins by considering all impls, where
 /// clauses, and so forth that might resolve an obligation. Sometimes
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index 79d56702be2..447cbc8932e 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -18,6 +18,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_query_system::ich::StableHashingContext;
 use rustc_session::DataTypeKind;
 use rustc_span::symbol::sym;
+use rustc_type_ir::solve::AdtDestructorKind;
 use tracing::{debug, info, trace};
 
 use super::{
@@ -232,6 +233,13 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> {
     fn is_fundamental(self) -> bool {
         self.is_fundamental()
     }
+
+    fn destructor(self, tcx: TyCtxt<'tcx>) -> Option<AdtDestructorKind> {
+        Some(match self.destructor(tcx)?.constness {
+            hir::Constness::Const => AdtDestructorKind::Const,
+            hir::Constness::NotConst => AdtDestructorKind::NotConst,
+        })
+    }
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, TyEncodable, TyDecodable)]
@@ -402,10 +410,6 @@ impl<'tcx> AdtDef<'tcx> {
         self.destructor(tcx).is_some()
     }
 
-    pub fn has_non_const_dtor(self, tcx: TyCtxt<'tcx>) -> bool {
-        matches!(self.destructor(tcx), Some(Destructor { constness: hir::Constness::NotConst, .. }))
-    }
-
     /// Asserts this is a struct or union and returns its unique variant.
     pub fn non_enum_variant(self) -> &'tcx VariantDef {
         assert!(self.is_struct() || self.is_union());
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 47a84d4b258..aba5719138c 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -174,7 +174,6 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for CtfeProvenance {
 impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::ParamEnv<'tcx> {
     fn encode(&self, e: &mut E) {
         self.caller_bounds().encode(e);
-        self.reveal().encode(e);
     }
 }
 
@@ -310,8 +309,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::SymbolName<'tcx>
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::ParamEnv<'tcx> {
     fn decode(d: &mut D) -> Self {
         let caller_bounds = Decodable::decode(d);
-        let reveal = Decodable::decode(d);
-        ty::ParamEnv::new(caller_bounds, reveal)
+        ty::ParamEnv::new(caller_bounds)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index d853edb34c9..d27205e26ab 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -151,10 +151,6 @@ impl<'tcx> Const<'tcx> {
 }
 
 impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
-    fn try_to_target_usize(self, interner: TyCtxt<'tcx>) -> Option<u64> {
-        self.try_to_target_usize(interner)
-    }
-
     fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst) -> Self {
         Const::new_infer(tcx, infer)
     }
@@ -336,7 +332,7 @@ impl<'tcx> Const<'tcx> {
     pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option<u128> {
         let (scalar, ty) = self.try_to_scalar()?;
         let scalar = scalar.try_to_scalar_int().ok()?;
-        let input = typing_env.with_reveal_all_normalized(tcx).as_query_input(ty);
+        let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(ty);
         let size = tcx.layout_of(input).ok()?.size;
         Some(scalar.to_bits(size))
     }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 55c29825fbc..2c867e6b8ca 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -4,7 +4,7 @@
 
 pub mod tls;
 
-use std::assert_matches::assert_matches;
+use std::assert_matches::{assert_matches, debug_assert_matches};
 use std::borrow::Borrow;
 use std::cmp::Ordering;
 use std::hash::{Hash, Hasher};
@@ -377,10 +377,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     }
 
     fn impl_is_const(self, def_id: DefId) -> bool {
+        debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
         self.is_conditionally_const(def_id)
     }
 
     fn fn_is_const(self, def_id: DefId) -> bool {
+        debug_assert_matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
+        self.is_conditionally_const(def_id)
+    }
+
+    fn alias_has_const_conditions(self, def_id: DefId) -> bool {
+        debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
         self.is_conditionally_const(def_id)
     }
 
@@ -663,6 +670,7 @@ bidirectional_lang_item_map! {
     CoroutineYield,
     Destruct,
     DiscriminantKind,
+    Drop,
     DynMetadata,
     Fn,
     FnMut,
@@ -1318,12 +1326,12 @@ pub struct GlobalCtxt<'tcx> {
 
     /// Caches the results of trait selection. This cache is used
     /// for things that do not have to do with the parameters in scope.
-    pub selection_cache: traits::SelectionCache<'tcx>,
+    pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
 
     /// Caches the results of trait evaluation. This cache is used
     /// for things that do not have to do with the parameters in scope.
     /// Merge this with `selection_cache`?
-    pub evaluation_cache: traits::EvaluationCache<'tcx>,
+    pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
 
     /// Caches the results of goal evaluation in the new solver.
     pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
@@ -1363,8 +1371,17 @@ impl<'tcx> GlobalCtxt<'tcx> {
         tls::enter_context(&icx, || f(icx.tcx))
     }
 
-    pub fn finish(&self) -> FileEncodeResult {
-        self.dep_graph.finish_encoding()
+    pub fn finish(&'tcx self) {
+        // We assume that no queries are run past here. If there are new queries
+        // after this point, they'll show up as "<unknown>" in self-profiling data.
+        self.enter(|tcx| tcx.alloc_self_profile_query_strings());
+
+        self.enter(|tcx| tcx.save_dep_graph());
+        self.enter(|tcx| tcx.query_key_hash_verify_all());
+
+        if let Err((path, error)) = self.dep_graph.finish_encoding() {
+            self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error });
+        }
     }
 }
 
@@ -1558,10 +1575,6 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
-        self.sess.consider_optimizing(|| self.crate_name(LOCAL_CRATE), msg)
-    }
-
     /// Obtain all lang items of this crate and all dependencies (recursively)
     pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
         self.get_lang_items(())
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 84f52bfe48f..fd807882e0f 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, Diag, DiagArgValue, IntoDiagArg, into_diag_arg_using_display};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
-use rustc_hir::{self as hir, LangItem, PredicateOrigin, WherePredicate};
+use rustc_hir::{self as hir, LangItem, PredicateOrigin, WherePredicateKind};
 use rustc_span::{BytePos, Span};
 use rustc_type_ir::TyKind::*;
 
@@ -180,7 +180,7 @@ fn suggest_changing_unsized_bound(
     // First look at the `where` clause because we can have `where T: ?Sized`,
     // then look at params.
     for (where_pos, predicate) in generics.predicates.iter().enumerate() {
-        let WherePredicate::BoundPredicate(predicate) = predicate else {
+        let WherePredicateKind::BoundPredicate(predicate) = predicate.kind else {
             continue;
         };
         if !predicate.is_param_bound(param.def_id.to_def_id()) {
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 43d243b0584..4a82af32559 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -58,12 +58,9 @@ impl<'tcx> TypeError<'tcx> {
                 pluralize!(values.found)
             )
             .into(),
-            TypeError::FixedArraySize(values) => format!(
-                "expected an array with a fixed size of {} element{}, found one with {} element{}",
-                values.expected,
-                pluralize!(values.expected),
-                values.found,
-                pluralize!(values.found)
+            TypeError::ArraySize(values) => format!(
+                "expected an array with a size of {}, found one with a size of {}",
+                values.expected, values.found,
             )
             .into(),
             TypeError::ArgCount => "incorrect number of function parameters".into(),
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index dab3e18de33..73fd8aa5b6c 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -504,8 +504,8 @@ impl<'tcx> Instance<'tcx> {
     /// ```
     ///
     /// trying to resolve `Debug::fmt` applied to `T` will yield `Ok(None)`, because we do not
-    /// know what code ought to run. (Note that this setting is also affected by the
-    /// `RevealMode` in the parameter environment.)
+    /// know what code ought to run. This setting is also affected by the current `TypingMode`
+    /// of the environment.
     ///
     /// Presuming that coherence and type-check have succeeded, if this method is invoked
     /// in a monomorphic context (i.e., like during codegen), then it is guaranteed to return
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index fc29b438d3a..01ad76aedc3 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -682,14 +682,14 @@ pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasTypingEnv<
 /// Blanket extension trait for contexts that can compute layouts of types.
 pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> {
     /// Computes the layout of a type. Note that this implicitly
-    /// executes in "reveal all" mode, and will normalize the input type.
+    /// executes in `TypingMode::PostAnalysis`, and will normalize the input type.
     #[inline]
     fn layout_of(&self, ty: Ty<'tcx>) -> Self::LayoutOfResult {
         self.spanned_layout_of(ty, DUMMY_SP)
     }
 
     /// Computes the layout of a type, at `span`. Note that this implicitly
-    /// executes in "reveal all" mode, and will normalize the input type.
+    /// executes in `TypingMode::PostAnalysis`, and will normalize the input type.
     // FIXME(eddyb) avoid passing information like this, and instead add more
     // `TyCtxt::at`-like APIs to be able to do e.g. `cx.at(span).layout_of(ty)`.
     #[inline]
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 2bc055453a4..c7a2223ecd7 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -32,11 +32,10 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::steal::Steal;
-use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
 use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
-use rustc_hir::LangItem;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
+use rustc_hir::{LangItem, Safety};
 use rustc_index::IndexVec;
 use rustc_macros::{
     Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
@@ -104,7 +103,6 @@ use crate::metadata::ModChild;
 use crate::middle::privacy::EffectiveVisibilities;
 use crate::mir::{Body, CoroutineLayout};
 use crate::query::{IntoQueryParam, Providers};
-use crate::traits::{self, Reveal};
 use crate::ty;
 pub use crate::ty::diagnostics::*;
 use crate::ty::fast_reject::SimplifiedType;
@@ -960,147 +958,50 @@ impl<'tcx> rustc_type_ir::visit::Flags for Clauses<'tcx> {
 /// [dev guide chapter][param_env_guide] for more information.
 ///
 /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html
-#[derive(Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(HashStable, TypeVisitable, TypeFoldable)]
 pub struct ParamEnv<'tcx> {
-    /// This packs both caller bounds and the reveal enum into one pointer.
-    ///
     /// Caller bounds are `Obligation`s that the caller must satisfy. This is
     /// basically the set of bounds on the in-scope type parameters, translated
     /// into `Obligation`s, and elaborated and normalized.
     ///
     /// Use the `caller_bounds()` method to access.
-    ///
-    /// Typically, this is `Reveal::UserFacing`, but during codegen we
-    /// want `Reveal::All`.
-    ///
-    /// Note: This is packed, use the reveal() method to access it.
-    packed: CopyTaggedPtr<Clauses<'tcx>, ParamTag, true>,
+    caller_bounds: Clauses<'tcx>,
 }
 
 impl<'tcx> rustc_type_ir::inherent::ParamEnv<TyCtxt<'tcx>> for ParamEnv<'tcx> {
-    fn reveal(self) -> Reveal {
-        self.reveal()
-    }
-
     fn caller_bounds(self) -> impl IntoIterator<Item = ty::Clause<'tcx>> {
         self.caller_bounds()
     }
 }
 
-#[derive(Copy, Clone)]
-struct ParamTag {
-    reveal: traits::Reveal,
-}
-
-rustc_data_structures::impl_tag! {
-    impl Tag for ParamTag;
-    ParamTag { reveal: traits::Reveal::UserFacing },
-    ParamTag { reveal: traits::Reveal::All },
-}
-
-impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("ParamEnv")
-            .field("caller_bounds", &self.caller_bounds())
-            .field("reveal", &self.reveal())
-            .finish()
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        self.caller_bounds().hash_stable(hcx, hasher);
-        self.reveal().hash_stable(hcx, hasher);
-    }
-}
-
-impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
-    fn try_fold_with<F: ty::fold::FallibleTypeFolder<TyCtxt<'tcx>>>(
-        self,
-        folder: &mut F,
-    ) -> Result<Self, F::Error> {
-        Ok(ParamEnv::new(
-            self.caller_bounds().try_fold_with(folder)?,
-            self.reveal().try_fold_with(folder)?,
-        ))
-    }
-}
-
-impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
-    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
-        try_visit!(self.caller_bounds().visit_with(visitor));
-        self.reveal().visit_with(visitor)
-    }
-}
-
 impl<'tcx> ParamEnv<'tcx> {
-    /// Construct a trait environment suitable for contexts where
-    /// there are no where-clauses in scope. Hidden types (like `impl
-    /// Trait`) are left hidden. In majority of cases it is incorrect
+    /// Construct a trait environment suitable for contexts where there are
+    /// no where-clauses in scope. In the majority of cases it is incorrect
     /// to use an empty environment. See the [dev guide section][param_env_guide]
     /// for information on what a `ParamEnv` is and how to acquire one.
     ///
     /// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html
     #[inline]
     pub fn empty() -> Self {
-        Self::new(ListWithCachedTypeInfo::empty(), Reveal::UserFacing)
+        Self::new(ListWithCachedTypeInfo::empty())
     }
 
     #[inline]
     pub fn caller_bounds(self) -> Clauses<'tcx> {
-        self.packed.pointer()
-    }
-
-    #[inline]
-    pub fn reveal(self) -> traits::Reveal {
-        self.packed.tag().reveal
-    }
-
-    /// Construct a trait environment with no where-clauses in scope
-    /// where the values of all `impl Trait` and other hidden types
-    /// are revealed. This is suitable for monomorphized, post-typeck
-    /// environments like codegen or doing optimizations.
-    ///
-    /// N.B., if you want to have predicates in scope, use `ParamEnv::new`,
-    /// or invoke `param_env.with_reveal_all()`.
-    #[inline]
-    pub fn reveal_all() -> Self {
-        Self::new(ListWithCachedTypeInfo::empty(), Reveal::All)
+        self.caller_bounds
     }
 
     /// Construct a trait environment with the given set of predicates.
     #[inline]
-    pub fn new(caller_bounds: Clauses<'tcx>, reveal: Reveal) -> Self {
-        ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) }
-    }
-
-    /// Returns a new parameter environment with the same clauses, but
-    /// which "reveals" the true results of projections in all cases
-    /// (even for associated types that are specializable). This is
-    /// the desired behavior during codegen and certain other special
-    /// contexts; normally though we want to use `Reveal::UserFacing`,
-    /// which is the default.
-    /// All opaque types in the caller_bounds of the `ParamEnv`
-    /// will be normalized to their underlying types.
-    /// See PR #65989 and issue #65918 for more details
-    pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self {
-        if self.packed.tag().reveal == traits::Reveal::All {
-            return self;
-        }
-
-        // No need to reveal opaques with the new solver enabled,
-        // since we have lazy norm.
-        if tcx.next_trait_solver_globally() {
-            return ParamEnv::new(self.caller_bounds(), Reveal::All);
-        }
-
-        ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All)
+    pub fn new(caller_bounds: Clauses<'tcx>) -> Self {
+        ParamEnv { caller_bounds }
     }
 
     /// Returns this same environment but with no caller bounds.
     #[inline]
     pub fn without_caller_bounds(self) -> Self {
-        Self::new(ListWithCachedTypeInfo::empty(), self.reveal())
+        Self::new(ListWithCachedTypeInfo::empty())
     }
 
     /// Creates a pair of param-env and value for use in queries.
@@ -1148,7 +1049,7 @@ impl<'tcx> TypingEnv<'tcx> {
     /// use `TypingMode::PostAnalysis`, they may still have where-clauses
     /// in scope.
     pub fn fully_monomorphized() -> TypingEnv<'tcx> {
-        TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::reveal_all() }
+        TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::empty() }
     }
 
     /// Create a typing environment for use during analysis outside of a body.
@@ -1166,15 +1067,25 @@ impl<'tcx> TypingEnv<'tcx> {
     pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> {
         TypingEnv {
             typing_mode: TypingMode::PostAnalysis,
-            param_env: tcx.param_env_reveal_all_normalized(def_id),
+            param_env: tcx.param_env_normalized_for_post_analysis(def_id),
         }
     }
 
     /// Modify the `typing_mode` to `PostAnalysis` and eagerly reveal all
     /// opaque types in the `param_env`.
-    pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
-        let TypingEnv { typing_mode: _, param_env } = self;
-        let param_env = param_env.with_reveal_all_normalized(tcx);
+    pub fn with_post_analysis_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
+        let TypingEnv { typing_mode, param_env } = self;
+        if let TypingMode::PostAnalysis = typing_mode {
+            return self;
+        }
+
+        // No need to reveal opaques with the new solver enabled,
+        // since we have lazy norm.
+        let param_env = if tcx.next_trait_solver_globally() {
+            ParamEnv::new(param_env.caller_bounds())
+        } else {
+            ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds()))
+        };
         TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env }
     }
 
@@ -1365,6 +1276,11 @@ impl VariantDef {
     pub fn tail(&self) -> &FieldDef {
         self.tail_opt().expect("expected unsized ADT to have a tail field")
     }
+
+    /// Returns whether this variant has unsafe fields.
+    pub fn has_unsafe_fields(&self) -> bool {
+        self.fields.iter().any(|x| x.safety == Safety::Unsafe)
+    }
 }
 
 impl PartialEq for VariantDef {
@@ -1447,6 +1363,7 @@ pub struct FieldDef {
     pub did: DefId,
     pub name: Symbol,
     pub vis: Visibility<DefId>,
+    pub safety: hir::Safety,
 }
 
 impl PartialEq for FieldDef {
@@ -1459,15 +1376,16 @@ impl PartialEq for FieldDef {
         // of `FieldDef` changes, a compile-error will be produced, reminding
         // us to revisit this assumption.
 
-        let Self { did: lhs_did, name: _, vis: _ } = &self;
+        let Self { did: lhs_did, name: _, vis: _, safety: _ } = &self;
 
-        let Self { did: rhs_did, name: _, vis: _ } = other;
+        let Self { did: rhs_did, name: _, vis: _, safety: _ } = other;
 
         let res = lhs_did == rhs_did;
 
         // Double check that implicit assumption detailed above.
         if cfg!(debug_assertions) && res {
-            let deep = self.name == other.name && self.vis == other.vis;
+            let deep =
+                self.name == other.name && self.vis == other.vis && self.safety == other.safety;
             assert!(deep, "FieldDef for the same def-id has differing data");
         }
 
@@ -1487,7 +1405,7 @@ impl Hash for FieldDef {
         // of `FieldDef` changes, a compile-error will be produced, reminding
         // us to revisit this assumption.
 
-        let Self { did, name: _, vis: _ } = &self;
+        let Self { did, name: _, vis: _, safety: _ } = &self;
 
         did.hash(s)
     }
@@ -1640,10 +1558,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let is_box = self.is_lang_item(did.to_def_id(), LangItem::OwnedBox);
 
         // This is here instead of layout because the choice must make it into metadata.
-        if is_box
-            || !self
-                .consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did)))
-        {
+        if is_box {
             flags.insert(ReprFlags::IS_LINEAR);
         }
 
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 7c280bc8b49..f7322217aa3 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -86,6 +86,7 @@ trivially_parameterized_over_tcx! {
     rustc_attr::Stability,
     rustc_hir::Constness,
     rustc_hir::Defaultness,
+    rustc_hir::Safety,
     rustc_hir::CoroutineKind,
     rustc_hir::IsAsync,
     rustc_hir::LangItem,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 039c988f5c9..cd4123f0a3f 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -16,8 +16,8 @@ use rustc_hir::definitions::{DefKey, DefPathDataName};
 use rustc_macros::{Lift, extension};
 use rustc_session::Limit;
 use rustc_session::cstore::{ExternCrate, ExternCrateSource};
-use rustc_span::FileNameDisplayPreference;
 use rustc_span::symbol::{Ident, Symbol, kw};
+use rustc_span::{FileNameDisplayPreference, sym};
 use rustc_type_ir::{Upcast as _, elaborate};
 use smallvec::SmallVec;
 
@@ -26,8 +26,8 @@ use super::*;
 use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
 use crate::query::{IntoQueryParam, Providers};
 use crate::ty::{
-    ConstInt, Expr, GenericArgKind, ParamConst, ScalarInt, Term, TermKind, TypeFoldable,
-    TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
+    ConstInt, Expr, GenericArgKind, ParamConst, ScalarInt, Term, TermKind, TraitPredicate,
+    TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
 };
 
 macro_rules! p {
@@ -993,10 +993,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
 
             match bound_predicate.skip_binder() {
                 ty::ClauseKind::Trait(pred) => {
-                    let trait_ref = bound_predicate.rebind(pred.trait_ref);
-
                     // Don't print `+ Sized`, but rather `+ ?Sized` if absent.
-                    if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) {
+                    if tcx.is_lang_item(pred.def_id(), LangItem::Sized) {
                         match pred.polarity {
                             ty::PredicatePolarity::Positive => {
                                 has_sized_bound = true;
@@ -1007,24 +1005,22 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                     }
 
                     self.insert_trait_and_projection(
-                        trait_ref,
-                        pred.polarity,
+                        bound_predicate.rebind(pred),
                         None,
                         &mut traits,
                         &mut fn_traits,
                     );
                 }
                 ty::ClauseKind::Projection(pred) => {
-                    let proj_ref = bound_predicate.rebind(pred);
-                    let trait_ref = proj_ref.required_poly_trait_ref(tcx);
-
-                    // Projection type entry -- the def-id for naming, and the ty.
-                    let proj_ty = (proj_ref.projection_def_id(), proj_ref.term());
+                    let proj = bound_predicate.rebind(pred);
+                    let trait_ref = proj.map_bound(|proj| TraitPredicate {
+                        trait_ref: proj.projection_term.trait_ref(tcx),
+                        polarity: ty::PredicatePolarity::Positive,
+                    });
 
                     self.insert_trait_and_projection(
                         trait_ref,
-                        ty::PredicatePolarity::Positive,
-                        Some(proj_ty),
+                        Some((proj.projection_def_id(), proj.term())),
                         &mut traits,
                         &mut fn_traits,
                     );
@@ -1042,88 +1038,66 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
         let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !has_sized_bound;
 
-        for (fn_once_trait_ref, entry) in fn_traits {
+        for ((bound_args, is_async), entry) in fn_traits {
             write!(self, "{}", if first { "" } else { " + " })?;
             write!(self, "{}", if paren_needed { "(" } else { "" })?;
 
-            self.wrap_binder(&fn_once_trait_ref, |trait_ref, cx| {
-                define_scoped_cx!(cx);
-                // Get the (single) generic ty (the args) of this FnOnce trait ref.
-                let generics = tcx.generics_of(trait_ref.def_id);
-                let own_args = generics.own_args_no_defaults(tcx, trait_ref.args);
-
-                match (entry.return_ty, own_args[0].expect_ty()) {
-                    // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
-                    // a return type.
-                    (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
-                        let name = if entry.fn_trait_ref.is_some() {
-                            "Fn"
-                        } else if entry.fn_mut_trait_ref.is_some() {
-                            "FnMut"
-                        } else {
-                            "FnOnce"
-                        };
-
-                        p!(write("{}(", name));
+            let trait_def_id = if is_async {
+                tcx.async_fn_trait_kind_to_def_id(entry.kind).expect("expected AsyncFn lang items")
+            } else {
+                tcx.fn_trait_kind_to_def_id(entry.kind).expect("expected Fn lang items")
+            };
 
-                        for (idx, ty) in arg_tys.tuple_fields().iter().enumerate() {
-                            if idx > 0 {
-                                p!(", ");
-                            }
-                            p!(print(ty));
-                        }
+            if let Some(return_ty) = entry.return_ty {
+                self.wrap_binder(&bound_args, |args, cx| {
+                    define_scoped_cx!(cx);
+                    p!(write("{}", tcx.item_name(trait_def_id)));
+                    p!("(");
 
-                        p!(")");
-                        if let Some(ty) = return_ty.skip_binder().as_type() {
-                            if !ty.is_unit() {
-                                p!(" -> ", print(return_ty));
-                            }
+                    for (idx, ty) in args.iter().enumerate() {
+                        if idx > 0 {
+                            p!(", ");
                         }
-                        p!(write("{}", if paren_needed { ")" } else { "" }));
-
-                        first = false;
+                        p!(print(ty));
                     }
-                    // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
-                    // trait_refs we collected in the OpaqueFnEntry as normal trait refs.
-                    _ => {
-                        if entry.has_fn_once {
-                            traits
-                                .entry((fn_once_trait_ref, ty::PredicatePolarity::Positive))
-                                .or_default()
-                                .extend(
-                                    // Group the return ty with its def id, if we had one.
-                                    entry.return_ty.map(|ty| {
-                                        (tcx.require_lang_item(LangItem::FnOnceOutput, None), ty)
-                                    }),
-                                );
-                        }
-                        if let Some(trait_ref) = entry.fn_mut_trait_ref {
-                            traits.entry((trait_ref, ty::PredicatePolarity::Positive)).or_default();
-                        }
-                        if let Some(trait_ref) = entry.fn_trait_ref {
-                            traits.entry((trait_ref, ty::PredicatePolarity::Positive)).or_default();
+
+                    p!(")");
+                    if let Some(ty) = return_ty.skip_binder().as_type() {
+                        if !ty.is_unit() {
+                            p!(" -> ", print(return_ty));
                         }
                     }
-                }
+                    p!(write("{}", if paren_needed { ")" } else { "" }));
 
-                Ok(())
-            })?;
+                    first = false;
+                    Ok(())
+                })?;
+            } else {
+                // Otherwise, render this like a regular trait.
+                traits.insert(
+                    bound_args.map_bound(|args| ty::TraitPredicate {
+                        polarity: ty::PredicatePolarity::Positive,
+                        trait_ref: ty::TraitRef::new(tcx, trait_def_id, [Ty::new_tup(tcx, args)]),
+                    }),
+                    FxIndexMap::default(),
+                );
+            }
         }
 
         // Print the rest of the trait types (that aren't Fn* family of traits)
-        for ((trait_ref, polarity), assoc_items) in traits {
+        for (trait_pred, assoc_items) in traits {
             write!(self, "{}", if first { "" } else { " + " })?;
 
-            self.wrap_binder(&trait_ref, |trait_ref, cx| {
+            self.wrap_binder(&trait_pred, |trait_pred, cx| {
                 define_scoped_cx!(cx);
 
-                if polarity == ty::PredicatePolarity::Negative {
+                if trait_pred.polarity == ty::PredicatePolarity::Negative {
                     p!("!");
                 }
-                p!(print(trait_ref.print_only_trait_name()));
+                p!(print(trait_pred.trait_ref.print_only_trait_name()));
 
-                let generics = tcx.generics_of(trait_ref.def_id);
-                let own_args = generics.own_args_no_defaults(tcx, trait_ref.args);
+                let generics = tcx.generics_of(trait_pred.def_id());
+                let own_args = generics.own_args_no_defaults(tcx, trait_pred.trait_ref.args);
 
                 if !own_args.is_empty() || !assoc_items.is_empty() {
                     let mut first = true;
@@ -1230,51 +1204,48 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
     /// traits map or fn_traits map, depending on if the trait is in the Fn* family of traits.
     fn insert_trait_and_projection(
         &mut self,
-        trait_ref: ty::PolyTraitRef<'tcx>,
-        polarity: ty::PredicatePolarity,
+        trait_pred: ty::PolyTraitPredicate<'tcx>,
         proj_ty: Option<(DefId, ty::Binder<'tcx, Term<'tcx>>)>,
         traits: &mut FxIndexMap<
-            (ty::PolyTraitRef<'tcx>, ty::PredicatePolarity),
+            ty::PolyTraitPredicate<'tcx>,
             FxIndexMap<DefId, ty::Binder<'tcx, Term<'tcx>>>,
         >,
-        fn_traits: &mut FxIndexMap<ty::PolyTraitRef<'tcx>, OpaqueFnEntry<'tcx>>,
+        fn_traits: &mut FxIndexMap<
+            (ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>, bool),
+            OpaqueFnEntry<'tcx>,
+        >,
     ) {
-        let trait_def_id = trait_ref.def_id();
-
-        // If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce
-        // super-trait ref and record it there.
-        // We skip negative Fn* bounds since they can't use parenthetical notation anyway.
-        if polarity == ty::PredicatePolarity::Positive
-            && let Some(fn_once_trait) = self.tcx().lang_items().fn_once_trait()
-        {
-            // If we have a FnOnce, then insert it into
-            if trait_def_id == fn_once_trait {
-                let entry = fn_traits.entry(trait_ref).or_default();
-                // Optionally insert the return_ty as well.
-                if let Some((_, ty)) = proj_ty {
-                    entry.return_ty = Some(ty);
-                }
-                entry.has_fn_once = true;
-                return;
-            } else if self.tcx().is_lang_item(trait_def_id, LangItem::FnMut) {
-                let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref)
-                    .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
-                    .unwrap();
+        let tcx = self.tcx();
+        let trait_def_id = trait_pred.def_id();
 
-                fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref);
-                return;
-            } else if self.tcx().is_lang_item(trait_def_id, LangItem::Fn) {
-                let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref)
-                    .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
-                    .unwrap();
+        let fn_trait_and_async = if let Some(kind) = tcx.fn_trait_kind_from_def_id(trait_def_id) {
+            Some((kind, false))
+        } else if let Some(kind) = tcx.async_fn_trait_kind_from_def_id(trait_def_id) {
+            Some((kind, true))
+        } else {
+            None
+        };
 
-                fn_traits.entry(super_trait_ref).or_default().fn_trait_ref = Some(trait_ref);
-                return;
+        if trait_pred.polarity() == ty::PredicatePolarity::Positive
+            && let Some((kind, is_async)) = fn_trait_and_async
+            && let ty::Tuple(types) = *trait_pred.skip_binder().trait_ref.args.type_at(1).kind()
+        {
+            let entry = fn_traits
+                .entry((trait_pred.rebind(types), is_async))
+                .or_insert_with(|| OpaqueFnEntry { kind, return_ty: None });
+            if kind.extends(entry.kind) {
+                entry.kind = kind;
+            }
+            if let Some((proj_def_id, proj_ty)) = proj_ty
+                && tcx.item_name(proj_def_id) == sym::Output
+            {
+                entry.return_ty = Some(proj_ty);
             }
+            return;
         }
 
         // Otherwise, just group our traits and projection types.
-        traits.entry((trait_ref, polarity)).or_default().extend(proj_ty);
+        traits.entry(trait_pred).or_default().extend(proj_ty);
     }
 
     fn pretty_print_inherent_projection(
@@ -3189,10 +3160,10 @@ define_print_and_forward_display! {
 
     TraitRefPrintSugared<'tcx> {
         if !with_reduced_queries()
-            && let Some(kind) = cx.tcx().fn_trait_kind_from_def_id(self.0.def_id)
+            && cx.tcx().trait_def(self.0.def_id).paren_sugar
             && let ty::Tuple(args) = self.0.args.type_at(1).kind()
         {
-            p!(write("{}", kind.as_str()), "(");
+            p!(write("{}", cx.tcx().item_name(self.0.def_id)), "(");
             for (i, arg) in args.iter().enumerate() {
                 if i > 0 {
                     p!(", ");
@@ -3415,11 +3386,7 @@ pub fn provide(providers: &mut Providers) {
     *providers = Providers { trimmed_def_paths, ..*providers };
 }
 
-#[derive(Default)]
 pub struct OpaqueFnEntry<'tcx> {
-    // The trait ref is already stored as a key, so just track if we have it as a real predicate
-    has_fn_once: bool,
-    fn_mut_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
-    fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
+    kind: ty::ClosureKind,
     return_ty: Option<ty::Binder<'tcx, Term<'tcx>>>,
 }
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 504a3c8a6d8..afdec7a86d4 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -3,7 +3,6 @@ use std::iter;
 pub use rustc_type_ir::relate::*;
 
 use crate::ty::error::{ExpectedFound, TypeError};
-use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
 use crate::ty::{self as ty, Ty, TyCtxt};
 
 pub type RelateResult<'tcx, T> = rustc_type_ir::relate::RelateResult<TyCtxt<'tcx>, T>;
@@ -86,13 +85,10 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<
         // in `a`.
         let mut a_v: Vec<_> = a.into_iter().collect();
         let mut b_v: Vec<_> = b.into_iter().collect();
-        // `skip_binder` here is okay because `stable_cmp` doesn't look at binders
-        a_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
         a_v.dedup();
-        b_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
         b_v.dedup();
         if a_v.len() != b_v.len() {
-            return Err(TypeError::ExistentialMismatch(ExpectedFound::new(true, a, b)));
+            return Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b)));
         }
 
         let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| {
@@ -112,7 +108,7 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<
                     ty::ExistentialPredicate::AutoTrait(a),
                     ty::ExistentialPredicate::AutoTrait(b),
                 ) if a == b => Ok(ep_a.rebind(ty::ExistentialPredicate::AutoTrait(a))),
-                _ => Err(TypeError::ExistentialMismatch(ExpectedFound::new(true, a, b))),
+                _ => Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b))),
             }
         });
         tcx.mk_poly_existential_predicates_from_iter(v)
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index e48fac6c7e8..0af0a5f170d 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -237,7 +237,6 @@ TrivialTypeTraversalImpls! {
     crate::mir::coverage::ConditionId,
     crate::mir::Local,
     crate::mir::Promoted,
-    crate::traits::Reveal,
     crate::ty::adjustment::AutoBorrowMutability,
     crate::ty::AdtKind,
     crate::ty::BoundRegion,
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 20c3f84bb4d..55a7a837b6d 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -423,8 +423,8 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn async_drop_glue_morphology(self, did: DefId) -> AsyncDropGlueMorphology {
         let ty: Ty<'tcx> = self.type_of(did).instantiate_identity();
 
-        // Async drop glue morphology is an internal detail, so reveal_all probably
-        // should be fine
+        // Async drop glue morphology is an internal detail, so
+        // using `TypingMode::PostAnalysis` probably should be fine.
         let typing_env = ty::TypingEnv::fully_monomorphized();
         if ty.needs_async_drop(self, typing_env) {
             AsyncDropGlueMorphology::Custom
@@ -1053,7 +1053,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
                     // This is because for default trait methods with RPITITs, we
                     // install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))`
                     // predicate, which would trivially cause a cycle when we do
-                    // anything that requires `ParamEnv::with_reveal_all_normalized`.
+                    // anything that requires `TypingEnv::with_post_analysis_normalized`.
                     term: projection_pred.term,
                 })
                 .upcast(self.tcx)
@@ -1672,45 +1672,6 @@ pub fn needs_drop_components_with_async<'tcx>(
     }
 }
 
-pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool {
-    match *ty.kind() {
-        ty::Bool
-        | ty::Char
-        | ty::Int(_)
-        | ty::Uint(_)
-        | ty::Float(_)
-        | ty::Infer(ty::IntVar(_))
-        | ty::Infer(ty::FloatVar(_))
-        | ty::Str
-        | ty::RawPtr(_, _)
-        | ty::Ref(..)
-        | ty::FnDef(..)
-        | ty::FnPtr(..)
-        | ty::Never
-        | ty::Foreign(_) => true,
-
-        ty::Alias(..)
-        | ty::Dynamic(..)
-        | ty::Error(_)
-        | ty::Bound(..)
-        | ty::Param(_)
-        | ty::Placeholder(_)
-        | ty::Infer(_) => false,
-
-        // Not trivial because they have components, and instead of looking inside,
-        // we'll just perform trait selection.
-        ty::Closure(..)
-        | ty::CoroutineClosure(..)
-        | ty::Coroutine(..)
-        | ty::CoroutineWitness(..)
-        | ty::Adt(..) => false,
-
-        ty::Array(ty, _) | ty::Slice(ty) | ty::Pat(ty, _) => is_trivially_const_drop(ty),
-
-        ty::Tuple(tys) => tys.iter().all(|ty| is_trivially_const_drop(ty)),
-    }
-}
-
 /// Does the equivalent of
 /// ```ignore (illustrative)
 /// let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 55149570dbc..f28cf84fa69 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -125,6 +125,16 @@ mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed
     .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
     .label = initializing type with `rustc_layout_scalar_valid_range` attr
 
+mir_build_initializing_type_with_unsafe_field_requires_unsafe =
+    initializing type with an unsafe field is unsafe and requires unsafe block
+    .note = unsafe fields may carry library invariants
+    .label = initialization of struct with unsafe field
+
+mir_build_initializing_type_with_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
+    initializing type with an unsafe field is unsafe and requires unsafe block
+    .note = unsafe fields may carry library invariants
+    .label = initialization of struct with unsafe field
+
 mir_build_inline_assembly_requires_unsafe =
     use of inline assembly is unsafe and requires unsafe block
     .note = inline assembly is entirely unchecked and can cause undefined behavior
@@ -203,7 +213,7 @@ mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper =
 
 mir_build_lower_range_bound_must_be_less_than_upper = lower range bound must be less than upper
 
-mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 
 mir_build_moved = value is moved into `{$name}` here
 
@@ -338,8 +348,25 @@ mir_build_unreachable_pattern = unreachable pattern
     .unreachable_covered_by_catchall = matches any value
     .unreachable_covered_by_one = matches all the relevant values
     .unreachable_covered_by_many = multiple earlier patterns match some of the same values
+    .unreachable_pattern_const_reexport_accessible = there is a constant of the same name imported in another scope, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it needs to be imported in the pattern's scope
+    .unreachable_pattern_wanted_const = you might have meant to pattern match against the value of {$is_typo ->
+        [true] similarly named constant
+        *[false] constant
+        } `{$const_name}` instead of introducing a new catch-all binding
+    .unreachable_pattern_const_inaccessible = there is a constant of the same name, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it is not accessible from this scope
+    .unreachable_pattern_let_binding = there is a binding of the same name; if you meant to pattern match against the value of that binding, that is a feature of constants that is not available for `let` bindings
     .suggestion = remove the match arm
 
+mir_build_unsafe_field_requires_unsafe =
+    use of unsafe field is unsafe and requires unsafe block
+    .note = unsafe fields may carry library invariants
+    .label = use of unsafe field
+
+mir_build_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
+    use of unsafe field is unsafe and requires unsafe block
+    .note = unsafe fields may carry library invariants
+    .label = use of unsafe field
+
 mir_build_unsafe_fn_safe_body = an unsafe function restricts its caller, but its body is safe by default
 mir_build_unsafe_not_inherited = items do not inherit unsafety from separate enclosing items
 
@@ -388,6 +415,11 @@ mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe =
     .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
     .label = initializing type with `rustc_layout_scalar_valid_range` attr
 
+mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_unsafe_field_requires_unsafe =
+    initializing type with an unsafe field is unsafe and requires unsafe block
+    .note = unsafe fields may carry library invariants
+    .label = initialization of struct with unsafe field
+
 mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe =
     use of inline assembly is unsafe and requires unsafe block
     .note = inline assembly is entirely unchecked and can cause undefined behavior
@@ -408,6 +440,11 @@ mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe =
     .note = the field may not be properly initialized: using uninitialized data will cause undefined behavior
     .label = access to union field
 
+mir_build_unsafe_op_in_unsafe_fn_unsafe_field_requires_unsafe =
+    use of unsafe field is unsafe and requires unsafe block
+    .note = unsafe fields may carry library invariants
+    .label = use of unsafe field
+
 mir_build_unsized_pattern = cannot use unsized non-slice type `{$non_sm_ty}` in constant patterns
 
 mir_build_unused_unsafe = unnecessary `unsafe` block
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index b497e54d480..f37b3f977fa 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -4,7 +4,7 @@ use std::ops::Bound;
 
 use rustc_errors::DiagArgValue;
 use rustc_hir::def::DefKind;
-use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
+use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Safety};
 use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
 use rustc_middle::mir::BorrowKind;
 use rustc_middle::span_bug;
@@ -339,8 +339,13 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
         };
 
         match &pat.kind {
-            PatKind::Leaf { .. } => {
+            PatKind::Leaf { subpatterns, .. } => {
                 if let ty::Adt(adt_def, ..) = pat.ty.kind() {
+                    for pat in subpatterns {
+                        if adt_def.non_enum_variant().fields[pat.field].safety == Safety::Unsafe {
+                            self.requires_unsafe(pat.pattern.span, UseOfUnsafeField);
+                        }
+                    }
                     if adt_def.is_union() {
                         let old_in_union_destructure =
                             std::mem::replace(&mut self.in_union_destructure, true);
@@ -359,6 +364,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     visit::walk_pat(self, pat);
                 }
             }
+            PatKind::Variant { adt_def, args: _, variant_index, subpatterns } => {
+                for pat in subpatterns {
+                    let field = &pat.field;
+                    if adt_def.variant(*variant_index).fields[*field].safety == Safety::Unsafe {
+                        self.requires_unsafe(pat.pattern.span, UseOfUnsafeField);
+                    }
+                }
+                visit::walk_pat(self, pat);
+            }
             PatKind::Binding { mode: BindingMode(ByRef::Yes(rm), _), ty, .. } => {
                 if self.inside_adt {
                     let ty::Ref(_, ty, _) = ty.kind() else {
@@ -579,15 +593,20 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             }
             ExprKind::Adt(box AdtExpr {
                 adt_def,
-                variant_index: _,
+                variant_index,
                 args: _,
                 user_ty: _,
                 fields: _,
                 base: _,
-            }) => match self.tcx.layout_scalar_valid_range(adt_def.did()) {
-                (Bound::Unbounded, Bound::Unbounded) => {}
-                _ => self.requires_unsafe(expr.span, InitializingTypeWith),
-            },
+            }) => {
+                if adt_def.variant(variant_index).has_unsafe_fields() {
+                    self.requires_unsafe(expr.span, InitializingTypeWithUnsafeField)
+                }
+                match self.tcx.layout_scalar_valid_range(adt_def.did()) {
+                    (Bound::Unbounded, Bound::Unbounded) => {}
+                    _ => self.requires_unsafe(expr.span, InitializingTypeWith),
+                }
+            }
             ExprKind::Closure(box ClosureExpr {
                 closure_id,
                 args: _,
@@ -601,23 +620,24 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 let def_id = did.expect_local();
                 self.visit_inner_body(def_id);
             }
-            ExprKind::Field { lhs, .. } => {
+            ExprKind::Field { lhs, variant_index, name } => {
                 let lhs = &self.thir[lhs];
-                if let ty::Adt(adt_def, _) = lhs.ty.kind()
-                    && adt_def.is_union()
-                {
-                    if let Some(assigned_ty) = self.assignment_info {
-                        if assigned_ty.needs_drop(self.tcx, self.typing_env) {
-                            // This would be unsafe, but should be outright impossible since we
-                            // reject such unions.
-                            assert!(
-                                self.tcx.dcx().has_errors().is_some(),
-                                "union fields that need dropping should be impossible: \
-                                {assigned_ty}"
-                            );
+                if let ty::Adt(adt_def, _) = lhs.ty.kind() {
+                    if adt_def.variant(variant_index).fields[name].safety == Safety::Unsafe {
+                        self.requires_unsafe(expr.span, UseOfUnsafeField);
+                    } else if adt_def.is_union() {
+                        if let Some(assigned_ty) = self.assignment_info {
+                            if assigned_ty.needs_drop(self.tcx, self.typing_env) {
+                                // This would be unsafe, but should be outright impossible since we
+                                // reject such unions.
+                                assert!(
+                                    self.tcx.dcx().has_errors().is_some(),
+                                    "union fields that need dropping should be impossible: {assigned_ty}"
+                                );
+                            }
+                        } else {
+                            self.requires_unsafe(expr.span, AccessToUnionField);
                         }
-                    } else {
-                        self.requires_unsafe(expr.span, AccessToUnionField);
                     }
                 }
             }
@@ -689,8 +709,10 @@ enum UnsafeOpKind {
     CallToUnsafeFunction(Option<DefId>),
     UseOfInlineAssembly,
     InitializingTypeWith,
+    InitializingTypeWithUnsafeField,
     UseOfMutableStatic,
     UseOfExternStatic,
+    UseOfUnsafeField,
     DerefOfRawPointer,
     AccessToUnionField,
     MutationOfLayoutConstrainedField,
@@ -770,6 +792,15 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 },
             ),
+            InitializingTypeWithUnsafeField => tcx.emit_node_span_lint(
+                UNSAFE_OP_IN_UNSAFE_FN,
+                hir_id,
+                span,
+                UnsafeOpInUnsafeFnInitializingTypeWithUnsafeFieldRequiresUnsafe {
+                    span,
+                    unsafe_not_inherited_note,
+                },
+            ),
             UseOfMutableStatic => tcx.emit_node_span_lint(
                 UNSAFE_OP_IN_UNSAFE_FN,
                 hir_id,
@@ -788,6 +819,15 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 },
             ),
+            UseOfUnsafeField => tcx.emit_node_span_lint(
+                UNSAFE_OP_IN_UNSAFE_FN,
+                hir_id,
+                span,
+                UnsafeOpInUnsafeFnUseOfUnsafeFieldRequiresUnsafe {
+                    span,
+                    unsafe_not_inherited_note,
+                },
+            ),
             DerefOfRawPointer => tcx.emit_node_span_lint(
                 UNSAFE_OP_IN_UNSAFE_FN,
                 hir_id,
@@ -927,6 +967,20 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 });
             }
+            InitializingTypeWithUnsafeField if unsafe_op_in_unsafe_fn_allowed => {
+                dcx.emit_err(
+                    InitializingTypeWithUnsafeFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+                        span,
+                        unsafe_not_inherited_note,
+                    },
+                );
+            }
+            InitializingTypeWithUnsafeField => {
+                dcx.emit_err(InitializingTypeWithUnsafeFieldRequiresUnsafe {
+                    span,
+                    unsafe_not_inherited_note,
+                });
+            }
             UseOfMutableStatic if unsafe_op_in_unsafe_fn_allowed => {
                 dcx.emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
                     span,
@@ -945,6 +999,15 @@ impl UnsafeOpKind {
             UseOfExternStatic => {
                 dcx.emit_err(UseOfExternStaticRequiresUnsafe { span, unsafe_not_inherited_note });
             }
+            UseOfUnsafeField if unsafe_op_in_unsafe_fn_allowed => {
+                dcx.emit_err(UseOfUnsafeFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+                    span,
+                    unsafe_not_inherited_note,
+                });
+            }
+            UseOfUnsafeField => {
+                dcx.emit_err(UseOfUnsafeFieldRequiresUnsafe { span, unsafe_not_inherited_note });
+            }
             DerefOfRawPointer if unsafe_op_in_unsafe_fn_allowed => {
                 dcx.emit_err(DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
                     span,
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 676f7c98b8f..58487a48184 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -87,6 +87,16 @@ pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_unsafe_field_requires_unsafe, code = E0133)]
+#[note]
+pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithUnsafeFieldRequiresUnsafe {
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)]
 #[note]
 pub(crate) struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe {
@@ -107,6 +117,16 @@ pub(crate) struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(mir_build_unsafe_op_in_unsafe_fn_unsafe_field_requires_unsafe, code = E0133)]
+#[note]
+pub(crate) struct UnsafeOpInUnsafeFnUseOfUnsafeFieldRequiresUnsafe {
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe, code = E0133)]
 #[note]
 pub(crate) struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe {
@@ -251,6 +271,17 @@ pub(crate) struct InitializingTypeWithRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
+#[diag(mir_build_initializing_type_with_unsafe_field_requires_unsafe, code = E0133)]
+#[note]
+pub(crate) struct InitializingTypeWithUnsafeFieldRequiresUnsafe {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
+#[derive(Diagnostic)]
 #[diag(
     mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
     code = E0133
@@ -265,6 +296,20 @@ pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
+#[diag(
+    mir_build_initializing_type_with_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
+    code = E0133
+)]
+#[note]
+pub(crate) struct InitializingTypeWithUnsafeFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
+#[derive(Diagnostic)]
 #[diag(mir_build_mutable_static_requires_unsafe, code = E0133)]
 #[note]
 pub(crate) struct UseOfMutableStaticRequiresUnsafe {
@@ -309,6 +354,28 @@ pub(crate) struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
+#[diag(mir_build_unsafe_field_requires_unsafe, code = E0133)]
+#[note]
+pub(crate) struct UseOfUnsafeFieldRequiresUnsafe {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
+#[derive(Diagnostic)]
+#[diag(mir_build_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
+#[note]
+pub(crate) struct UseOfUnsafeFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
+#[derive(Diagnostic)]
 #[diag(mir_build_deref_raw_pointer_requires_unsafe, code = E0133)]
 #[note]
 pub(crate) struct DerefOfRawPointerRequiresUnsafe {
@@ -528,7 +595,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo
         }
 
         if let ty::Ref(_, sub_ty, _) = self.ty.kind() {
-            if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.typing_env()) {
+            if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.typing_env) {
                 diag.note(fluent::mir_build_reference_note);
             }
         }
@@ -593,6 +660,14 @@ pub(crate) struct UnreachablePattern<'tcx> {
     pub(crate) uninhabited_note: Option<()>,
     #[label(mir_build_unreachable_covered_by_catchall)]
     pub(crate) covered_by_catchall: Option<Span>,
+    #[subdiagnostic]
+    pub(crate) wanted_constant: Option<WantedConstant>,
+    #[note(mir_build_unreachable_pattern_const_reexport_accessible)]
+    pub(crate) accessible_constant: Option<Span>,
+    #[note(mir_build_unreachable_pattern_const_inaccessible)]
+    pub(crate) inaccessible_constant: Option<Span>,
+    #[note(mir_build_unreachable_pattern_let_binding)]
+    pub(crate) pattern_let_binding: Option<Span>,
     #[label(mir_build_unreachable_covered_by_one)]
     pub(crate) covered_by_one: Option<Span>,
     #[note(mir_build_unreachable_covered_by_many)]
@@ -602,6 +677,20 @@ pub(crate) struct UnreachablePattern<'tcx> {
     pub(crate) suggest_remove: Option<Span>,
 }
 
+#[derive(Subdiagnostic)]
+#[suggestion(
+    mir_build_unreachable_pattern_wanted_const,
+    code = "{const_path}",
+    applicability = "machine-applicable"
+)]
+pub(crate) struct WantedConstant {
+    #[primary_span]
+    pub(crate) span: Span,
+    pub(crate) is_typo: bool,
+    pub(crate) const_name: String,
+    pub(crate) const_path: String,
+}
+
 #[derive(Diagnostic)]
 #[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
 pub(crate) struct ConstPatternDependsOnGenericParameter {
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 47b7f332951..ee9bcce104e 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -284,7 +284,7 @@ impl<'tcx> Cx<'tcx> {
             let discr_ty = ty.to_ty(tcx);
 
             let size = tcx
-                .layout_of(self.typing_env().as_query_input(discr_ty))
+                .layout_of(self.typing_env.as_query_input(discr_ty))
                 .unwrap_or_else(|e| panic!("could not compute layout for {discr_ty:?}: {e:?}"))
                 .size;
 
@@ -1040,7 +1040,7 @@ impl<'tcx> Cx<'tcx> {
             // but distinguish between &STATIC and &THREAD_LOCAL as they have different semantics
             Res::Def(DefKind::Static { .. }, id) => {
                 // this is &raw for extern static or static mut, and & for other statics
-                let ty = self.tcx.static_ptr_ty(id, self.typing_env());
+                let ty = self.tcx.static_ptr_ty(id, self.typing_env);
                 let (temp_lifetime, backwards_incompatible) = self
                     .rvalue_scopes
                     .temporary_scope(self.region_scope_tree, expr.hir_id.local_id);
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index d47f7154c4b..a98c2bb61f6 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -12,7 +12,6 @@ use rustc_hir::lang_items::LangItem;
 use rustc_middle::bug;
 use rustc_middle::middle::region;
 use rustc_middle::thir::*;
-use rustc_middle::ty::solve::Reveal;
 use rustc_middle::ty::{self, RvalueScopes, TyCtxt};
 use tracing::instrument;
 
@@ -57,7 +56,7 @@ struct Cx<'tcx> {
     tcx: TyCtxt<'tcx>,
     thir: Thir<'tcx>,
 
-    param_env: ty::ParamEnv<'tcx>,
+    typing_env: ty::TypingEnv<'tcx>,
 
     region_scope_tree: &'tcx region::ScopeTree,
     typeck_results: &'tcx ty::TypeckResults<'tcx>,
@@ -98,7 +97,9 @@ impl<'tcx> Cx<'tcx> {
         Cx {
             tcx,
             thir: Thir::new(body_type),
-            param_env: tcx.param_env(def),
+            // FIXME(#132279): We're in a body, we should use a typing
+            // mode which reveals the opaque types defined by that body.
+            typing_env: ty::TypingEnv::non_body_analysis(tcx, def),
             region_scope_tree: tcx.region_scope_tree(def),
             typeck_results,
             rvalue_scopes: &typeck_results.rvalue_scopes,
@@ -110,20 +111,9 @@ impl<'tcx> Cx<'tcx> {
         }
     }
 
-    fn typing_mode(&self) -> ty::TypingMode<'tcx> {
-        debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing);
-        // FIXME(#132279): In case we're in a body, we should use a typing
-        // mode which reveals the opaque types defined by that body.
-        ty::TypingMode::non_body_analysis()
-    }
-
-    fn typing_env(&self) -> ty::TypingEnv<'tcx> {
-        ty::TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env }
-    }
-
     #[instrument(level = "debug", skip(self))]
     fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
-        pat_from_hir(self.tcx, self.typing_env(), self.typeck_results(), p)
+        pat_from_hir(self.tcx, self.typing_env, self.typeck_results(), p)
     }
 
     fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option<Param<'tcx>> {
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 27920008c80..e55cd35e243 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -7,7 +7,8 @@ use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, struct_span_code_e
 use rustc_hir::def::*;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{self as hir, BindingMode, ByRef, HirId};
-use rustc_infer::traits::Reveal;
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_lint::Level;
 use rustc_middle::bug;
 use rustc_middle::middle::limits::get_limit_size;
 use rustc_middle::thir::visit::Visitor;
@@ -22,8 +23,10 @@ use rustc_pattern_analysis::rustc::{
 use rustc_session::lint::builtin::{
     BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS,
 };
+use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::{Span, sym};
+use rustc_trait_selection::infer::InferCtxtExt;
 use tracing::instrument;
 
 use crate::errors::*;
@@ -39,7 +42,8 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err
         tcx,
         thir: &*thir,
         typeck_results,
-        param_env: tcx.param_env(def_id),
+        // FIXME(#132279): We're in a body, should handle opaques.
+        typing_env: ty::TypingEnv::non_body_analysis(tcx, def_id),
         lint_level: tcx.local_def_id_to_hir_id(def_id),
         let_source: LetSource::None,
         pattern_arena: &pattern_arena,
@@ -86,7 +90,7 @@ enum LetSource {
 
 struct MatchVisitor<'p, 'tcx> {
     tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
+    typing_env: ty::TypingEnv<'tcx>,
     typeck_results: &'tcx ty::TypeckResults<'tcx>,
     thir: &'p Thir<'tcx>,
     lint_level: HirId,
@@ -192,15 +196,6 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> {
 }
 
 impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
-    fn typing_env(&self) -> ty::TypingEnv<'tcx> {
-        // FIXME(#132279): We're in a body, should handle opaques.
-        debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing);
-        ty::TypingEnv {
-            typing_mode: ty::TypingMode::non_body_analysis(),
-            param_env: self.param_env,
-        }
-    }
-
     #[instrument(level = "trace", skip(self, f))]
     fn with_let_source(&mut self, let_source: LetSource, f: impl FnOnce(&mut Self)) {
         let old_let_source = self.let_source;
@@ -391,7 +386,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
         PatCtxt {
             tcx: self.tcx,
             typeck_results: self.typeck_results,
-            param_env: self.param_env,
+            typing_env: self.typing_env,
             module: self.tcx.parent_module(self.lint_level).to_def_id(),
             dropless_arena: self.dropless_arena,
             match_lint_level: self.lint_level,
@@ -745,8 +740,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
                 .variant(*variant_index)
                 .inhabited_predicate(self.tcx, *adt)
                 .instantiate(self.tcx, args);
-            variant_inhabited.apply(self.tcx, cx.typing_env(), cx.module)
-                && !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env())
+            variant_inhabited.apply(self.tcx, cx.typing_env, cx.module)
+                && !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env)
         } else {
             false
         };
@@ -785,7 +780,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat:
         return;
     };
 
-    let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env());
+    let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env);
 
     let sess = cx.tcx.sess;
 
@@ -969,6 +964,10 @@ fn report_unreachable_pattern<'p, 'tcx>(
         covered_by_one: None,
         covered_by_many: None,
         covered_by_many_n_more_count: 0,
+        wanted_constant: None,
+        accessible_constant: None,
+        inaccessible_constant: None,
+        pattern_let_binding: None,
         suggest_remove: None,
     };
     match explanation.covered_by.as_slice() {
@@ -991,7 +990,10 @@ fn report_unreachable_pattern<'p, 'tcx>(
             });
         }
         [covering_pat] if pat_is_catchall(covering_pat) => {
-            lint.covered_by_catchall = Some(covering_pat.data().span);
+            // A binding pattern that matches all, a single binding name.
+            let pat = covering_pat.data();
+            lint.covered_by_catchall = Some(pat.span);
+            find_fallback_pattern_typo(cx, hir_id, pat, &mut lint);
         }
         [covering_pat] => {
             lint.covered_by_one = Some(covering_pat.data().span);
@@ -1024,6 +1026,153 @@ fn report_unreachable_pattern<'p, 'tcx>(
     cx.tcx.emit_node_span_lint(UNREACHABLE_PATTERNS, hir_id, pat_span, lint);
 }
 
+/// Detect typos that were meant to be a `const` but were interpreted as a new pattern binding.
+fn find_fallback_pattern_typo<'tcx>(
+    cx: &PatCtxt<'_, 'tcx>,
+    hir_id: HirId,
+    pat: &Pat<'tcx>,
+    lint: &mut UnreachablePattern<'_>,
+) {
+    if let (Level::Allow, _) = cx.tcx.lint_level_at_node(UNREACHABLE_PATTERNS, hir_id) {
+        // 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;
+    }
+    if let PatKind::Binding { name, subpattern: None, ty, .. } = pat.kind {
+        // See if the binding might have been a `const` that was mistyped or out of scope.
+        let mut accessible = vec![];
+        let mut accessible_path = vec![];
+        let mut inaccessible = vec![];
+        let mut imported = vec![];
+        let mut imported_spans = vec![];
+        let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env);
+        let parent = cx.tcx.hir().get_parent_item(hir_id);
+
+        for item in cx.tcx.hir_crate_items(()).free_items() {
+            if let DefKind::Use = cx.tcx.def_kind(item.owner_id) {
+                // Look for consts being re-exported.
+                let item = cx.tcx.hir().expect_item(item.owner_id.def_id);
+                let use_name = item.ident.name;
+                let hir::ItemKind::Use(path, _) = item.kind else {
+                    continue;
+                };
+                for res in &path.res {
+                    if let Res::Def(DefKind::Const, id) = res
+                        && infcx.can_eq(param_env, ty, cx.tcx.type_of(id).instantiate_identity())
+                    {
+                        if cx.tcx.visibility(id).is_accessible_from(parent, cx.tcx) {
+                            // The original const is accessible, suggest using it directly.
+                            let item_name = cx.tcx.item_name(*id);
+                            accessible.push(item_name);
+                            accessible_path.push(with_no_trimmed_paths!(cx.tcx.def_path_str(id)));
+                        } else if cx
+                            .tcx
+                            .visibility(item.owner_id)
+                            .is_accessible_from(parent, cx.tcx)
+                        {
+                            // The const is accessible only through the re-export, point at
+                            // the `use`.
+                            imported.push(use_name);
+                            imported_spans.push(item.ident.span);
+                        }
+                    }
+                }
+            }
+            if let DefKind::Const = cx.tcx.def_kind(item.owner_id)
+                && infcx.can_eq(param_env, ty, cx.tcx.type_of(item.owner_id).instantiate_identity())
+            {
+                // Look for local consts.
+                let item_name = cx.tcx.item_name(item.owner_id.into());
+                let vis = cx.tcx.visibility(item.owner_id);
+                if vis.is_accessible_from(parent, cx.tcx) {
+                    accessible.push(item_name);
+                    let path = if item_name == name {
+                        // We know that the const wasn't in scope because it has the exact
+                        // same name, so we suggest the full path.
+                        with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id))
+                    } else {
+                        // The const is likely just typoed, and nothing else.
+                        cx.tcx.def_path_str(item.owner_id)
+                    };
+                    accessible_path.push(path);
+                } else if name == item_name {
+                    // The const exists somewhere in this crate, but it can't be imported
+                    // from this pattern's scope. We'll just point at its definition.
+                    inaccessible.push(cx.tcx.def_span(item.owner_id));
+                }
+            }
+        }
+        if let Some((i, &const_name)) =
+            accessible.iter().enumerate().find(|(_, &const_name)| const_name == name)
+        {
+            // The pattern name is an exact match, so the pattern needed to be imported.
+            lint.wanted_constant = Some(WantedConstant {
+                span: pat.span,
+                is_typo: false,
+                const_name: const_name.to_string(),
+                const_path: accessible_path[i].clone(),
+            });
+        } else if let Some(name) = find_best_match_for_name(&accessible, name, None) {
+            // The pattern name is likely a typo.
+            lint.wanted_constant = Some(WantedConstant {
+                span: pat.span,
+                is_typo: true,
+                const_name: name.to_string(),
+                const_path: name.to_string(),
+            });
+        } else if let Some(i) =
+            imported.iter().enumerate().find(|(_, &const_name)| const_name == name).map(|(i, _)| i)
+        {
+            // The const with the exact name wasn't re-exported from an import in this
+            // crate, we point at the import.
+            lint.accessible_constant = Some(imported_spans[i]);
+        } else if let Some(name) = find_best_match_for_name(&imported, name, None) {
+            // The typoed const wasn't re-exported by an import in this crate, we suggest
+            // the right name (which will likely require another follow up suggestion).
+            lint.wanted_constant = Some(WantedConstant {
+                span: pat.span,
+                is_typo: true,
+                const_path: name.to_string(),
+                const_name: name.to_string(),
+            });
+        } else if !inaccessible.is_empty() {
+            for span in inaccessible {
+                // The const with the exact name match isn't accessible, we just point at it.
+                lint.inaccessible_constant = Some(span);
+            }
+        } else {
+            // Look for local bindings for people that might have gotten confused with how
+            // `let` and `const` works.
+            for (_, node) in cx.tcx.hir().parent_iter(hir_id) {
+                match node {
+                    hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Let(let_stmt), .. }) => {
+                        if let hir::PatKind::Binding(_, _, binding_name, _) = let_stmt.pat.kind {
+                            if name == binding_name.name {
+                                lint.pattern_let_binding = Some(binding_name.span);
+                            }
+                        }
+                    }
+                    hir::Node::Block(hir::Block { stmts, .. }) => {
+                        for stmt in *stmts {
+                            if let hir::StmtKind::Let(let_stmt) = stmt.kind {
+                                if let hir::PatKind::Binding(_, _, binding_name, _) =
+                                    let_stmt.pat.kind
+                                {
+                                    if name == binding_name.name {
+                                        lint.pattern_let_binding = Some(binding_name.span);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    hir::Node::Item(_) => break,
+                    _ => {}
+                }
+            }
+        }
+    }
+}
+
 /// Report unreachable arms, if any.
 fn report_arm_reachability<'p, 'tcx>(
     cx: &PatCtxt<'p, 'tcx>,
@@ -1149,7 +1298,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
     }
 
     if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() {
-        if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.typing_env()) {
+        if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.typing_env) {
             err.note("references are always considered inhabited");
         }
     }
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 a40134e44e7..5db08f01fdb 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
@@ -80,14 +80,14 @@ impl<'tcx> ConstToPat<'tcx> {
         let pat_from_kind = |kind| Box::new(Pat { span: self.span, ty, kind });
 
         // It's not *technically* correct to be revealing opaque types here as borrowcheck has
-        // not run yet. However, CTFE itself uses `Reveal::All` unconditionally even during
-        // typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821). As a
-        // result we always use a revealed env when resolving the instance to evaluate.
+        // 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).
+        // As a result we always use a revealed env when resolving the instance to evaluate.
         //
-        // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
+        // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
         // instead of having this logic here
         let typing_env =
-            self.tcx.erase_regions(self.typing_env).with_reveal_all_normalized(self.tcx);
+            self.tcx.erase_regions(self.typing_env).with_post_analysis_normalized(self.tcx);
         let uv = self.tcx.erase_regions(uv);
 
         // try to resolve e.g. associated constants to their definition on an impl, and then
diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
index 5ebb343f4e1..11cf8c3e898 100644
--- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
@@ -1,6 +1,7 @@
 //! Random access inspection of the results of a dataflow analysis.
 
 use std::cmp::Ordering;
+use std::ops::{Deref, DerefMut};
 
 #[cfg(debug_assertions)]
 use rustc_index::bit_set::BitSet;
@@ -8,18 +9,63 @@ use rustc_middle::mir::{self, BasicBlock, Location};
 
 use super::{Analysis, Direction, Effect, EffectIndex, Results};
 
-/// Allows random access inspection of the results of a dataflow analysis.
+/// Some `ResultsCursor`s want to own a `Results`, and some want to borrow a `Results`, either
+/// mutable or immutably. This type allows all of the above. It's similar to `Cow`.
+pub enum ResultsHandle<'a, 'tcx, A>
+where
+    A: Analysis<'tcx>,
+{
+    Borrowed(&'a Results<'tcx, A>),
+    BorrowedMut(&'a mut Results<'tcx, A>),
+    Owned(Results<'tcx, A>),
+}
+
+impl<'tcx, A> Deref for ResultsHandle<'_, 'tcx, A>
+where
+    A: Analysis<'tcx>,
+{
+    type Target = Results<'tcx, A>;
+
+    fn deref(&self) -> &Results<'tcx, A> {
+        match self {
+            ResultsHandle::Borrowed(borrowed) => borrowed,
+            ResultsHandle::BorrowedMut(borrowed) => borrowed,
+            ResultsHandle::Owned(owned) => owned,
+        }
+    }
+}
+
+impl<'tcx, A> DerefMut for ResultsHandle<'_, 'tcx, A>
+where
+    A: Analysis<'tcx>,
+{
+    fn deref_mut(&mut self) -> &mut Results<'tcx, A> {
+        match self {
+            ResultsHandle::Borrowed(_borrowed) => {
+                panic!("tried to deref_mut a `ResultsHandle::Borrowed")
+            }
+            ResultsHandle::BorrowedMut(borrowed) => borrowed,
+            ResultsHandle::Owned(owned) => owned,
+        }
+    }
+}
+
+/// Allows random access inspection of the results of a dataflow analysis. Use this when you want
+/// to inspect domain values only in certain locations; use `ResultsVisitor` if you want to inspect
+/// domain values in many or all locations.
 ///
-/// This cursor only has linear performance within a basic block when its statements are visited in
-/// the same order as the `DIRECTION` of the analysis. In the worst case—when statements are
-/// visited in *reverse* order—performance will be quadratic in the number of statements in the
-/// block. The order in which basic blocks are inspected has no impact on performance.
+/// Because `Results` only has domain values for the entry of each basic block, these inspections
+/// involve some amount of domain value recomputations. This cursor only has linear performance
+/// within a basic block when its statements are visited in the same order as the `DIRECTION` of
+/// the analysis. In the worst case—when statements are visited in *reverse* order—performance will
+/// be quadratic in the number of statements in the block. The order in which basic blocks are
+/// inspected has no impact on performance.
 pub struct ResultsCursor<'mir, 'tcx, A>
 where
     A: Analysis<'tcx>,
 {
     body: &'mir mir::Body<'tcx>,
-    results: Results<'tcx, A>,
+    results: ResultsHandle<'mir, 'tcx, A>,
     state: A::Domain,
 
     pos: CursorPosition,
@@ -47,13 +93,8 @@ where
         self.body
     }
 
-    /// Unwraps this cursor, returning the underlying `Results`.
-    pub fn into_results(self) -> Results<'tcx, A> {
-        self.results
-    }
-
     /// Returns a new cursor that can inspect `results`.
-    pub fn new(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self {
+    pub fn new(body: &'mir mir::Body<'tcx>, results: ResultsHandle<'mir, 'tcx, A>) -> Self {
         let bottom_value = results.analysis.bottom_value(body);
         ResultsCursor {
             body,
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 9a5cf9d4e84..566a6b09b2b 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -9,30 +9,35 @@ use super::{Analysis, Effect, EffectIndex, Results, SwitchIntTarget};
 
 pub trait Direction {
     const IS_FORWARD: bool;
-
     const IS_BACKWARD: bool = !Self::IS_FORWARD;
 
-    /// Applies all effects between the given `EffectIndex`s.
-    ///
-    /// `effects.start()` must precede or equal `effects.end()` in this direction.
-    fn apply_effects_in_range<'tcx, A>(
+    /// Called by `iterate_to_fixpoint` during initial analysis computation.
+    fn apply_effects_in_block<'mir, 'tcx, A>(
         analysis: &mut A,
+        body: &mir::Body<'tcx>,
         state: &mut A::Domain,
         block: BasicBlock,
-        block_data: &mir::BasicBlockData<'tcx>,
-        effects: RangeInclusive<EffectIndex>,
+        block_data: &'mir mir::BasicBlockData<'tcx>,
+        propagate: impl FnMut(BasicBlock, &A::Domain),
     ) where
         A: Analysis<'tcx>;
 
-    fn apply_effects_in_block<'mir, 'tcx, A>(
+    /// Called by `ResultsCursor` to recompute the domain value for a location
+    /// in a basic block. Applies all effects between the given `EffectIndex`s.
+    ///
+    /// `effects.start()` must precede or equal `effects.end()` in this direction.
+    fn apply_effects_in_range<'tcx, A>(
         analysis: &mut A,
         state: &mut A::Domain,
         block: BasicBlock,
-        block_data: &'mir mir::BasicBlockData<'tcx>,
-    ) -> TerminatorEdges<'mir, 'tcx>
-    where
+        block_data: &mir::BasicBlockData<'tcx>,
+        effects: RangeInclusive<EffectIndex>,
+    ) where
         A: Analysis<'tcx>;
 
+    /// Called by `ResultsVisitor` to recompute the analysis domain values for
+    /// all locations in a basic block (starting from the entry value stored
+    /// in `Results`) and to visit them with `vis`.
     fn visit_results_in_block<'mir, 'tcx, A>(
         state: &mut A::Domain,
         block: BasicBlock,
@@ -41,16 +46,6 @@ pub trait Direction {
         vis: &mut impl ResultsVisitor<'mir, 'tcx, A>,
     ) where
         A: Analysis<'tcx>;
-
-    fn join_state_into_successors_of<'tcx, A>(
-        analysis: &mut A,
-        body: &mir::Body<'tcx>,
-        exit_state: &mut A::Domain,
-        block: BasicBlock,
-        edges: TerminatorEdges<'_, 'tcx>,
-        propagate: impl FnMut(BasicBlock, &A::Domain),
-    ) where
-        A: Analysis<'tcx>;
 }
 
 /// Dataflow that runs from the exit of a block (terminator), to its entry (the first statement).
@@ -61,23 +56,84 @@ impl Direction for Backward {
 
     fn apply_effects_in_block<'mir, 'tcx, A>(
         analysis: &mut A,
+        body: &mir::Body<'tcx>,
         state: &mut A::Domain,
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
-    ) -> TerminatorEdges<'mir, 'tcx>
-    where
+        mut propagate: impl FnMut(BasicBlock, &A::Domain),
+    ) where
         A: Analysis<'tcx>,
     {
         let terminator = block_data.terminator();
         let location = Location { block, statement_index: block_data.statements.len() };
         analysis.apply_before_terminator_effect(state, terminator, location);
-        let edges = analysis.apply_terminator_effect(state, terminator, location);
+        analysis.apply_terminator_effect(state, terminator, location);
         for (statement_index, statement) in block_data.statements.iter().enumerate().rev() {
             let location = Location { block, statement_index };
             analysis.apply_before_statement_effect(state, statement, location);
             analysis.apply_statement_effect(state, statement, location);
         }
-        edges
+
+        let exit_state = state;
+        for pred in body.basic_blocks.predecessors()[block].iter().copied() {
+            match body[pred].terminator().kind {
+                // Apply terminator-specific edge effects.
+                //
+                // FIXME(ecstaticmorse): Avoid cloning the exit state unconditionally.
+                mir::TerminatorKind::Call { destination, target: Some(dest), .. }
+                    if dest == block =>
+                {
+                    let mut tmp = exit_state.clone();
+                    analysis.apply_call_return_effect(
+                        &mut tmp,
+                        pred,
+                        CallReturnPlaces::Call(destination),
+                    );
+                    propagate(pred, &tmp);
+                }
+
+                mir::TerminatorKind::InlineAsm { ref targets, ref operands, .. }
+                    if targets.contains(&block) =>
+                {
+                    let mut tmp = exit_state.clone();
+                    analysis.apply_call_return_effect(
+                        &mut tmp,
+                        pred,
+                        CallReturnPlaces::InlineAsm(operands),
+                    );
+                    propagate(pred, &tmp);
+                }
+
+                mir::TerminatorKind::Yield { resume, resume_arg, .. } if resume == block => {
+                    let mut tmp = exit_state.clone();
+                    analysis.apply_call_return_effect(
+                        &mut tmp,
+                        resume,
+                        CallReturnPlaces::Yield(resume_arg),
+                    );
+                    propagate(pred, &tmp);
+                }
+
+                mir::TerminatorKind::SwitchInt { targets: _, ref discr } => {
+                    let mut applier = BackwardSwitchIntEdgeEffectsApplier {
+                        body,
+                        pred,
+                        exit_state,
+                        block,
+                        propagate: &mut propagate,
+                        effects_applied: false,
+                    };
+
+                    analysis.apply_switch_int_edge_effects(pred, discr, &mut applier);
+
+                    if !applier.effects_applied {
+                        propagate(pred, exit_state)
+                    }
+                }
+
+                _ => propagate(pred, exit_state),
+            }
+        }
     }
 
     fn apply_effects_in_range<'tcx, A>(
@@ -170,7 +226,6 @@ impl Direction for Backward {
 
         vis.visit_block_end(state);
 
-        // Terminator
         let loc = Location { block, statement_index: block_data.statements.len() };
         let term = block_data.terminator();
         results.analysis.apply_before_terminator_effect(state, term, loc);
@@ -188,82 +243,13 @@ impl Direction for Backward {
 
         vis.visit_block_start(state);
     }
-
-    fn join_state_into_successors_of<'tcx, A>(
-        analysis: &mut A,
-        body: &mir::Body<'tcx>,
-        exit_state: &mut A::Domain,
-        bb: BasicBlock,
-        _edges: TerminatorEdges<'_, 'tcx>,
-        mut propagate: impl FnMut(BasicBlock, &A::Domain),
-    ) where
-        A: Analysis<'tcx>,
-    {
-        for pred in body.basic_blocks.predecessors()[bb].iter().copied() {
-            match body[pred].terminator().kind {
-                // Apply terminator-specific edge effects.
-                //
-                // FIXME(ecstaticmorse): Avoid cloning the exit state unconditionally.
-                mir::TerminatorKind::Call { destination, target: Some(dest), .. } if dest == bb => {
-                    let mut tmp = exit_state.clone();
-                    analysis.apply_call_return_effect(
-                        &mut tmp,
-                        pred,
-                        CallReturnPlaces::Call(destination),
-                    );
-                    propagate(pred, &tmp);
-                }
-
-                mir::TerminatorKind::InlineAsm { ref targets, ref operands, .. }
-                    if targets.contains(&bb) =>
-                {
-                    let mut tmp = exit_state.clone();
-                    analysis.apply_call_return_effect(
-                        &mut tmp,
-                        pred,
-                        CallReturnPlaces::InlineAsm(operands),
-                    );
-                    propagate(pred, &tmp);
-                }
-
-                mir::TerminatorKind::Yield { resume, resume_arg, .. } if resume == bb => {
-                    let mut tmp = exit_state.clone();
-                    analysis.apply_call_return_effect(
-                        &mut tmp,
-                        resume,
-                        CallReturnPlaces::Yield(resume_arg),
-                    );
-                    propagate(pred, &tmp);
-                }
-
-                mir::TerminatorKind::SwitchInt { targets: _, ref discr } => {
-                    let mut applier = BackwardSwitchIntEdgeEffectsApplier {
-                        body,
-                        pred,
-                        exit_state,
-                        bb,
-                        propagate: &mut propagate,
-                        effects_applied: false,
-                    };
-
-                    analysis.apply_switch_int_edge_effects(pred, discr, &mut applier);
-
-                    if !applier.effects_applied {
-                        propagate(pred, exit_state)
-                    }
-                }
-
-                _ => propagate(pred, exit_state),
-            }
-        }
-    }
 }
 
 struct BackwardSwitchIntEdgeEffectsApplier<'mir, 'tcx, D, F> {
     body: &'mir mir::Body<'tcx>,
     pred: BasicBlock,
     exit_state: &'mir mut D,
-    bb: BasicBlock,
+    block: BasicBlock,
     propagate: &'mir mut F,
     effects_applied: bool,
 }
@@ -276,8 +262,8 @@ where
     fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget)) {
         assert!(!self.effects_applied);
 
-        let values = &self.body.basic_blocks.switch_sources()[&(self.bb, self.pred)];
-        let targets = values.iter().map(|&value| SwitchIntTarget { value, target: self.bb });
+        let values = &self.body.basic_blocks.switch_sources()[&(self.block, self.pred)];
+        let targets = values.iter().map(|&value| SwitchIntTarget { value, target: self.block });
 
         let mut tmp = None;
         for target in targets {
@@ -298,11 +284,12 @@ impl Direction for Forward {
 
     fn apply_effects_in_block<'mir, 'tcx, A>(
         analysis: &mut A,
+        _body: &mir::Body<'tcx>,
         state: &mut A::Domain,
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
-    ) -> TerminatorEdges<'mir, 'tcx>
-    where
+        mut propagate: impl FnMut(BasicBlock, &A::Domain),
+    ) where
         A: Analysis<'tcx>,
     {
         for (statement_index, statement) in block_data.statements.iter().enumerate() {
@@ -313,7 +300,53 @@ impl Direction for Forward {
         let terminator = block_data.terminator();
         let location = Location { block, statement_index: block_data.statements.len() };
         analysis.apply_before_terminator_effect(state, terminator, location);
-        analysis.apply_terminator_effect(state, terminator, location)
+        let edges = analysis.apply_terminator_effect(state, terminator, location);
+
+        let exit_state = state;
+        match edges {
+            TerminatorEdges::None => {}
+            TerminatorEdges::Single(target) => propagate(target, exit_state),
+            TerminatorEdges::Double(target, unwind) => {
+                propagate(target, exit_state);
+                propagate(unwind, exit_state);
+            }
+            TerminatorEdges::AssignOnReturn { return_, cleanup, place } => {
+                // This must be done *first*, otherwise the unwind path will see the assignments.
+                if let Some(cleanup) = cleanup {
+                    propagate(cleanup, exit_state);
+                }
+
+                if !return_.is_empty() {
+                    analysis.apply_call_return_effect(exit_state, block, place);
+                    for &target in return_ {
+                        propagate(target, exit_state);
+                    }
+                }
+            }
+            TerminatorEdges::SwitchInt { targets, discr } => {
+                let mut applier = ForwardSwitchIntEdgeEffectsApplier {
+                    exit_state,
+                    targets,
+                    propagate,
+                    effects_applied: false,
+                };
+
+                analysis.apply_switch_int_edge_effects(block, discr, &mut applier);
+
+                let ForwardSwitchIntEdgeEffectsApplier {
+                    exit_state,
+                    mut propagate,
+                    effects_applied,
+                    ..
+                } = applier;
+
+                if !effects_applied {
+                    for target in targets.all_targets() {
+                        propagate(*target, exit_state);
+                    }
+                }
+            }
+        }
     }
 
     fn apply_effects_in_range<'tcx, A>(
@@ -351,7 +384,8 @@ impl Direction for Forward {
                 let statement = &block_data.statements[from.statement_index];
                 analysis.apply_statement_effect(state, statement, location);
 
-                // If we only needed to apply the after effect of the statement at `idx`, we are done.
+                // If we only needed to apply the after effect of the statement at `idx`, we are
+                // done.
                 if from == to {
                     return;
                 }
@@ -419,62 +453,6 @@ impl Direction for Forward {
 
         vis.visit_block_end(state);
     }
-
-    fn join_state_into_successors_of<'tcx, A>(
-        analysis: &mut A,
-        _body: &mir::Body<'tcx>,
-        exit_state: &mut A::Domain,
-        bb: BasicBlock,
-        edges: TerminatorEdges<'_, 'tcx>,
-        mut propagate: impl FnMut(BasicBlock, &A::Domain),
-    ) where
-        A: Analysis<'tcx>,
-    {
-        match edges {
-            TerminatorEdges::None => {}
-            TerminatorEdges::Single(target) => propagate(target, exit_state),
-            TerminatorEdges::Double(target, unwind) => {
-                propagate(target, exit_state);
-                propagate(unwind, exit_state);
-            }
-            TerminatorEdges::AssignOnReturn { return_, cleanup, place } => {
-                // This must be done *first*, otherwise the unwind path will see the assignments.
-                if let Some(cleanup) = cleanup {
-                    propagate(cleanup, exit_state);
-                }
-
-                if !return_.is_empty() {
-                    analysis.apply_call_return_effect(exit_state, bb, place);
-                    for &target in return_ {
-                        propagate(target, exit_state);
-                    }
-                }
-            }
-            TerminatorEdges::SwitchInt { targets, discr } => {
-                let mut applier = ForwardSwitchIntEdgeEffectsApplier {
-                    exit_state,
-                    targets,
-                    propagate,
-                    effects_applied: false,
-                };
-
-                analysis.apply_switch_int_edge_effects(bb, discr, &mut applier);
-
-                let ForwardSwitchIntEdgeEffectsApplier {
-                    exit_state,
-                    mut propagate,
-                    effects_applied,
-                    ..
-                } = applier;
-
-                if !effects_applied {
-                    for target in targets.all_targets() {
-                        propagate(*target, exit_state);
-                    }
-                }
-            }
-        }
-    }
 }
 
 struct ForwardSwitchIntEdgeEffectsApplier<'mir, D, F> {
diff --git a/compiler/rustc_mir_dataflow/src/framework/fmt.rs b/compiler/rustc_mir_dataflow/src/framework/fmt.rs
index ed540cd148c..c177d98106f 100644
--- a/compiler/rustc_mir_dataflow/src/framework/fmt.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/fmt.rs
@@ -230,16 +230,3 @@ where
         write!(f, "{}", ctxt.move_data().move_paths[*self])
     }
 }
-
-impl<T, C> DebugWithContext<C> for crate::lattice::Dual<T>
-where
-    T: DebugWithContext<C>,
-{
-    fn fmt_with(&self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        (self.0).fmt_with(ctxt, f)
-    }
-
-    fn fmt_diff_with(&self, old: &Self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        (self.0).fmt_diff_with(&old.0, ctxt, f)
-    }
-}
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index 98a4f58cb5d..6e4994af8b4 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -47,20 +47,16 @@ where
 {
     pub(crate) fn new(
         body: &'mir Body<'tcx>,
-        results: Results<'tcx, A>,
+        results: &'mir Results<'tcx, A>,
         style: OutputStyle,
     ) -> Self {
         let reachable = mir::traversal::reachable_as_bitset(body);
-        Formatter { cursor: results.into_results_cursor(body).into(), style, reachable }
+        Formatter { cursor: results.as_results_cursor(body).into(), style, reachable }
     }
 
     fn body(&self) -> &'mir Body<'tcx> {
         self.cursor.borrow().body()
     }
-
-    pub(crate) fn into_results(self) -> Results<'tcx, A> {
-        self.cursor.into_inner().into_results()
-    }
 }
 
 /// A pair of a basic block and an index into that basic blocks `successors`.
diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs
index 4d03ee53b7c..6d2a7a099a0 100644
--- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs
@@ -25,8 +25,8 @@
 //!
 //! ## `PartialOrd`
 //!
-//! Given that they represent partially ordered sets, you may be surprised that [`JoinSemiLattice`]
-//! and [`MeetSemiLattice`] do not have [`PartialOrd`] as a supertrait. This
+//! Given that it represents a partially ordered set, you may be surprised that [`JoinSemiLattice`]
+//! does not have [`PartialOrd`] as a supertrait. This
 //! is because most standard library types use lexicographic ordering instead of set inclusion for
 //! their `PartialOrd` impl. Since we do not actually need to compare lattice elements to run a
 //! dataflow analysis, there's no need for a newtype wrapper with a custom `PartialOrd` impl. The
@@ -58,23 +58,6 @@ pub trait JoinSemiLattice: Eq {
     fn join(&mut self, other: &Self) -> bool;
 }
 
-/// A [partially ordered set][poset] that has a [greatest lower bound][glb] for any pair of
-/// elements in the set.
-///
-/// Dataflow analyses only require that their domains implement [`JoinSemiLattice`], not
-/// `MeetSemiLattice`. However, types that will be used as dataflow domains should implement both
-/// so that they can be used with [`Dual`].
-///
-/// [glb]: https://en.wikipedia.org/wiki/Infimum_and_supremum
-/// [poset]: https://en.wikipedia.org/wiki/Partially_ordered_set
-pub trait MeetSemiLattice: Eq {
-    /// Computes the greatest lower bound of two elements, storing the result in `self` and
-    /// returning `true` if `self` has changed.
-    ///
-    /// The lattice meet operator is abbreviated as `∧`.
-    fn meet(&mut self, other: &Self) -> bool;
-}
-
 /// A set that has a "bottom" element, which is less than or equal to any other element.
 pub trait HasBottom {
     const BOTTOM: Self;
@@ -105,17 +88,6 @@ impl JoinSemiLattice for bool {
     }
 }
 
-impl MeetSemiLattice for bool {
-    fn meet(&mut self, other: &Self) -> bool {
-        if let (true, false) = (*self, *other) {
-            *self = false;
-            return true;
-        }
-
-        false
-    }
-}
-
 impl HasBottom for bool {
     const BOTTOM: Self = false;
 
@@ -145,18 +117,6 @@ impl<I: Idx, T: JoinSemiLattice> JoinSemiLattice for IndexVec<I, T> {
     }
 }
 
-impl<I: Idx, T: MeetSemiLattice> MeetSemiLattice for IndexVec<I, T> {
-    fn meet(&mut self, other: &Self) -> bool {
-        assert_eq!(self.len(), other.len());
-
-        let mut changed = false;
-        for (a, b) in iter::zip(self, other) {
-            changed |= a.meet(b);
-        }
-        changed
-    }
-}
-
 /// A `BitSet` represents the lattice formed by the powerset of all possible values of
 /// the index type `T` ordered by inclusion. Equivalently, it is a tuple of "two-point" lattices,
 /// one for each possible value of `T`.
@@ -166,60 +126,12 @@ impl<T: Idx> JoinSemiLattice for BitSet<T> {
     }
 }
 
-impl<T: Idx> MeetSemiLattice for BitSet<T> {
-    fn meet(&mut self, other: &Self) -> bool {
-        self.intersect(other)
-    }
-}
-
 impl<T: Idx> JoinSemiLattice for ChunkedBitSet<T> {
     fn join(&mut self, other: &Self) -> bool {
         self.union(other)
     }
 }
 
-impl<T: Idx> MeetSemiLattice for ChunkedBitSet<T> {
-    fn meet(&mut self, other: &Self) -> bool {
-        self.intersect(other)
-    }
-}
-
-/// The counterpart of a given semilattice `T` using the [inverse order].
-///
-/// The dual of a join-semilattice is a meet-semilattice and vice versa. For example, the dual of a
-/// powerset has the empty set as its top element and the full set as its bottom element and uses
-/// set *intersection* as its join operator.
-///
-/// [inverse order]: https://en.wikipedia.org/wiki/Duality_(order_theory)
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub struct Dual<T>(pub T);
-
-impl<T: Idx> BitSetExt<T> for Dual<BitSet<T>> {
-    fn contains(&self, elem: T) -> bool {
-        self.0.contains(elem)
-    }
-
-    fn union(&mut self, other: &HybridBitSet<T>) {
-        self.0.union(other);
-    }
-
-    fn subtract(&mut self, other: &HybridBitSet<T>) {
-        self.0.subtract(other);
-    }
-}
-
-impl<T: MeetSemiLattice> JoinSemiLattice for Dual<T> {
-    fn join(&mut self, other: &Self) -> bool {
-        self.0.meet(&other.0)
-    }
-}
-
-impl<T: JoinSemiLattice> MeetSemiLattice for Dual<T> {
-    fn meet(&mut self, other: &Self) -> bool {
-        self.0.join(&other.0)
-    }
-}
-
 /// Extends a type `T` with top and bottom elements to make it a partially ordered set in which no
 /// value of `T` is comparable with any other.
 ///
@@ -257,22 +169,6 @@ impl<T: Clone + Eq> JoinSemiLattice for FlatSet<T> {
     }
 }
 
-impl<T: Clone + Eq> MeetSemiLattice for FlatSet<T> {
-    fn meet(&mut self, other: &Self) -> bool {
-        let result = match (&*self, other) {
-            (Self::Bottom, _) | (_, Self::Top) => return false,
-            (Self::Elem(ref a), Self::Elem(ref b)) if a == b => return false,
-
-            (Self::Top, Self::Elem(ref x)) => Self::Elem(x.clone()),
-
-            _ => Self::Bottom,
-        };
-
-        *self = result;
-        true
-    }
-}
-
 impl<T> HasBottom for FlatSet<T> {
     const BOTTOM: Self = Self::Bottom;
 
diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs
index 244dfe26ad3..bb652a75caa 100644
--- a/compiler/rustc_mir_dataflow/src/framework/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs
@@ -8,8 +8,9 @@
 //! The `impls` module contains several examples of dataflow analyses.
 //!
 //! Then call `iterate_to_fixpoint` on your type that impls `Analysis` to get a `Results`. From
-//! there, you can use a `ResultsCursor` to inspect the fixpoint solution to your dataflow problem,
-//! or implement the `ResultsVisitor` interface and use `visit_results`. The following example uses
+//! there, you can use a `ResultsCursor` to inspect the fixpoint solution to your dataflow problem
+//! (good for inspecting a small number of locations), or implement the `ResultsVisitor` interface
+//! and use `visit_results` (good for inspecting many or all locations). The following example uses
 //! the `ResultsCursor` approach.
 //!
 //! ```ignore (cross-crate-imports)
@@ -278,22 +279,17 @@ pub trait Analysis<'tcx> {
         // every iteration.
         let mut state = self.bottom_value(body);
         while let Some(bb) = dirty_queue.pop() {
-            let bb_data = &body[bb];
-
             // Set the state to the entry state of the block.
             // This is equivalent to `state = entry_sets[bb].clone()`,
             // but it saves an allocation, thus improving compile times.
             state.clone_from(&entry_sets[bb]);
 
-            // Apply the block transfer function, using the cached one if it exists.
-            let edges = Self::Direction::apply_effects_in_block(&mut self, &mut state, bb, bb_data);
-
-            Self::Direction::join_state_into_successors_of(
+            Self::Direction::apply_effects_in_block(
                 &mut self,
                 body,
                 &mut state,
                 bb,
-                edges,
+                &body[bb],
                 |target: BasicBlock, state: &Self::Domain| {
                     let set_changed = entry_sets[target].join(state);
                     if set_changed {
@@ -306,14 +302,13 @@ pub trait Analysis<'tcx> {
         let results = Results { analysis: self, entry_sets };
 
         if tcx.sess.opts.unstable_opts.dump_mir_dataflow {
-            let (res, results) = write_graphviz_results(tcx, body, results, pass_name);
+            let res = write_graphviz_results(tcx, body, &results, pass_name);
             if let Err(e) = res {
                 error!("Failed to write graphviz dataflow results: {}", e);
             }
-            results
-        } else {
-            results
         }
+
+        results
     }
 }
 
@@ -378,16 +373,6 @@ impl<T, S: GenKill<T>> GenKill<T> for MaybeReachable<S> {
     }
 }
 
-impl<T: Idx> GenKill<T> for lattice::Dual<BitSet<T>> {
-    fn gen_(&mut self, elem: T) {
-        self.0.insert(elem);
-    }
-
-    fn kill(&mut self, elem: T) {
-        self.0.remove(elem);
-    }
-}
-
 // NOTE: DO NOT CHANGE VARIANT ORDER. The derived `Ord` impls rely on the current order.
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
 enum Effect {
diff --git a/compiler/rustc_mir_dataflow/src/framework/results.rs b/compiler/rustc_mir_dataflow/src/framework/results.rs
index ff6cafbfbae..8493a7aa44b 100644
--- a/compiler/rustc_mir_dataflow/src/framework/results.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/results.rs
@@ -17,10 +17,13 @@ use super::{Analysis, ResultsCursor, ResultsVisitor, graphviz, visit_results};
 use crate::errors::{
     DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter,
 };
+use crate::framework::cursor::ResultsHandle;
 
 pub type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
 
-/// A dataflow analysis that has converged to fixpoint.
+/// A dataflow analysis that has converged to fixpoint. It only holds the domain values at the
+/// entry of each basic block. Domain values in other parts of the block are recomputed on the fly
+/// by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls).
 #[derive(Clone)]
 pub struct Results<'tcx, A>
 where
@@ -34,12 +37,30 @@ impl<'tcx, A> Results<'tcx, A>
 where
     A: Analysis<'tcx>,
 {
-    /// Creates a `ResultsCursor` that can inspect these `Results`.
+    /// Creates a `ResultsCursor` that can inspect these `Results`. Immutably borrows the `Results`,
+    /// which is appropriate when the `Results` is used outside the cursor.
+    pub fn as_results_cursor<'mir>(
+        &'mir self,
+        body: &'mir mir::Body<'tcx>,
+    ) -> ResultsCursor<'mir, 'tcx, A> {
+        ResultsCursor::new(body, ResultsHandle::Borrowed(self))
+    }
+
+    /// Creates a `ResultsCursor` that can mutate these `Results`. Mutably borrows the `Results`,
+    /// which is appropriate when the `Results` is used outside the cursor.
+    pub fn as_results_cursor_mut<'mir>(
+        &'mir mut self,
+        body: &'mir mir::Body<'tcx>,
+    ) -> ResultsCursor<'mir, 'tcx, A> {
+        ResultsCursor::new(body, ResultsHandle::BorrowedMut(self))
+    }
+
+    /// Creates a `ResultsCursor` that takes ownership of the `Results`.
     pub fn into_results_cursor<'mir>(
         self,
         body: &'mir mir::Body<'tcx>,
     ) -> ResultsCursor<'mir, 'tcx, A> {
-        ResultsCursor::new(body, self)
+        ResultsCursor::new(body, ResultsHandle::Owned(self))
     }
 
     /// Gets the dataflow state for the given block.
@@ -74,9 +95,9 @@ where
 pub(super) fn write_graphviz_results<'tcx, A>(
     tcx: TyCtxt<'tcx>,
     body: &mir::Body<'tcx>,
-    results: Results<'tcx, A>,
+    results: &Results<'tcx, A>,
     pass_name: Option<&'static str>,
-) -> (std::io::Result<()>, Results<'tcx, A>)
+) -> std::io::Result<()>
 where
     A: Analysis<'tcx>,
     A::Domain: DebugWithContext<A>,
@@ -87,7 +108,7 @@ where
     let def_id = body.source.def_id();
     let Ok(attrs) = RustcMirAttrs::parse(tcx, def_id) else {
         // Invalid `rustc_mir` attrs are reported in `RustcMirAttrs::parse`
-        return (Ok(()), results);
+        return Ok(());
     };
 
     let file = try {
@@ -104,12 +125,12 @@ where
                 create_dump_file(tcx, "dot", false, A::NAME, &pass_name.unwrap_or("-----"), body)?
             }
 
-            _ => return (Ok(()), results),
+            _ => return Ok(()),
         }
     };
     let mut file = match file {
         Ok(f) => f,
-        Err(e) => return (Err(e), results),
+        Err(e) => return Err(e),
     };
 
     let style = match attrs.formatter {
@@ -132,7 +153,7 @@ where
         file.write_all(&buf)?;
     };
 
-    (lhs, graphviz.into_results())
+    lhs
 }
 
 #[derive(Default)]
diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
index 5c7539eed4d..bde41974d47 100644
--- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
@@ -26,7 +26,9 @@ pub fn visit_results<'mir, 'tcx, A>(
     }
 }
 
-/// A visitor over the results of an `Analysis`.
+/// A visitor over the results of an `Analysis`. Use this when you want to inspect domain values in
+/// many or all locations; use `ResultsCursor` if you want to inspect domain values only in certain
+/// locations.
 pub trait ResultsVisitor<'mir, 'tcx, A>
 where
     A: Analysis<'tcx>,
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index 859019fd1f6..cec654cac72 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -15,7 +15,7 @@ use crate::{Analysis, GenKill};
 pub struct MaybeBorrowedLocals;
 
 impl MaybeBorrowedLocals {
-    pub(super) fn transfer_function<'a, T>(&'a self, trans: &'a mut T) -> TransferFunction<'a, T> {
+    pub(super) fn transfer_function<'a, T>(trans: &'a mut T) -> TransferFunction<'a, T> {
         TransferFunction { trans }
     }
 }
@@ -39,7 +39,7 @@ impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals {
         statement: &Statement<'tcx>,
         location: Location,
     ) {
-        self.transfer_function(trans).visit_statement(statement, location);
+        Self::transfer_function(trans).visit_statement(statement, location);
     }
 
     fn apply_terminator_effect<'mir>(
@@ -48,7 +48,7 @@ impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals {
         terminator: &'mir Terminator<'tcx>,
         location: Location,
     ) -> TerminatorEdges<'mir, 'tcx> {
-        self.transfer_function(trans).visit_terminator(terminator, location);
+        Self::transfer_function(trans).visit_terminator(terminator, location);
         terminator.edges()
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
index 9bb50d1e056..2c10d4b1cd3 100644
--- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
@@ -12,7 +12,7 @@ use crate::framework::SwitchIntEdgeEffects;
 use crate::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData, MovePathIndex};
 use crate::{
     Analysis, GenKill, MaybeReachable, drop_flag_effects, drop_flag_effects_for_function_entry,
-    drop_flag_effects_for_location, lattice, on_all_children_bits, on_lookup_result_bits,
+    drop_flag_effects_for_location, on_all_children_bits, on_lookup_result_bits,
 };
 
 /// `MaybeInitializedPlaces` tracks all places that might be
@@ -42,10 +42,10 @@ use crate::{
 /// }
 /// ```
 ///
-/// To determine whether a place *must* be initialized at a
-/// particular control-flow point, one can take the set-difference
-/// between this data and the data from `MaybeUninitializedPlaces` at the
-/// corresponding control-flow point.
+/// To determine whether a place is *definitely* initialized at a
+/// particular control-flow point, one can take the set-complement
+/// of the data from `MaybeUninitializedPlaces` at the corresponding
+/// control-flow point.
 ///
 /// Similarly, at a given `drop` statement, the set-intersection
 /// between this data and `MaybeUninitializedPlaces` yields the set of
@@ -117,10 +117,10 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
 /// }
 /// ```
 ///
-/// To determine whether a place *must* be uninitialized at a
-/// particular control-flow point, one can take the set-difference
-/// between this data and the data from `MaybeInitializedPlaces` at the
-/// corresponding control-flow point.
+/// To determine whether a place is *definitely* uninitialized at a
+/// particular control-flow point, one can take the set-complement
+/// of the data from `MaybeInitializedPlaces` at the corresponding
+/// control-flow point.
 ///
 /// Similarly, at a given `drop` statement, the set-intersection
 /// between this data and `MaybeInitializedPlaces` yields the set of
@@ -170,57 +170,6 @@ impl<'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
     }
 }
 
-/// `DefinitelyInitializedPlaces` tracks all places that are definitely
-/// initialized upon reaching a particular point in the control flow
-/// for a function.
-///
-/// For example, in code like the following, we have corresponding
-/// dataflow information shown in the right-hand comments.
-///
-/// ```rust
-/// struct S;
-/// fn foo(pred: bool) {                        // definite-init:
-///                                             // {          }
-///     let a = S; let mut b = S; let c; let d; // {a, b      }
-///
-///     if pred {
-///         drop(a);                            // {   b,     }
-///         b = S;                              // {   b,     }
-///
-///     } else {
-///         drop(b);                            // {a,        }
-///         d = S;                              // {a,       d}
-///
-///     }                                       // {          }
-///
-///     c = S;                                  // {       c  }
-/// }
-/// ```
-///
-/// To determine whether a place *may* be uninitialized at a
-/// particular control-flow point, one can take the set-complement
-/// of this data.
-///
-/// Similarly, at a given `drop` statement, the set-difference between
-/// this data and `MaybeInitializedPlaces` yields the set of places
-/// that would require a dynamic drop-flag at that statement.
-pub struct DefinitelyInitializedPlaces<'a, 'tcx> {
-    body: &'a Body<'tcx>,
-    move_data: &'a MoveData<'tcx>,
-}
-
-impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
-    pub fn new(body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
-        DefinitelyInitializedPlaces { body, move_data }
-    }
-}
-
-impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
-    fn move_data(&self) -> &MoveData<'tcx> {
-        self.move_data
-    }
-}
-
 /// `EverInitializedPlaces` tracks all places that might have ever been
 /// initialized upon reaching a particular point in the control flow
 /// for a function, without an intervening `StorageDead`.
@@ -293,19 +242,6 @@ impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
-    fn update_bits(
-        trans: &mut <Self as Analysis<'tcx>>::Domain,
-        path: MovePathIndex,
-        state: DropFlagState,
-    ) {
-        match state {
-            DropFlagState::Absent => trans.kill(path),
-            DropFlagState::Present => trans.gen_(path),
-        }
-    }
-}
-
 impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
     /// There can be many more `MovePathIndex` than there are locals in a MIR body.
     /// We use a chunked bitset to avoid paying too high a memory footprint.
@@ -554,70 +490,6 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Analysis<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
-    /// Use set intersection as the join operator.
-    type Domain = lattice::Dual<BitSet<MovePathIndex>>;
-
-    const NAME: &'static str = "definite_init";
-
-    fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain {
-        // bottom = initialized (start_block_effect counters this at outset)
-        lattice::Dual(BitSet::new_filled(self.move_data().move_paths.len()))
-    }
-
-    // sets on_entry bits for Arg places
-    fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) {
-        state.0.clear();
-
-        drop_flag_effects_for_function_entry(self.body, self.move_data, |path, s| {
-            assert!(s == DropFlagState::Present);
-            state.0.insert(path);
-        });
-    }
-
-    fn apply_statement_effect(
-        &mut self,
-        trans: &mut Self::Domain,
-        _statement: &mir::Statement<'tcx>,
-        location: Location,
-    ) {
-        drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
-            Self::update_bits(trans, path, s)
-        })
-    }
-
-    fn apply_terminator_effect<'mir>(
-        &mut self,
-        trans: &mut Self::Domain,
-        terminator: &'mir mir::Terminator<'tcx>,
-        location: Location,
-    ) -> TerminatorEdges<'mir, 'tcx> {
-        drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
-            Self::update_bits(trans, path, s)
-        });
-        terminator.edges()
-    }
-
-    fn apply_call_return_effect(
-        &mut self,
-        trans: &mut Self::Domain,
-        _block: mir::BasicBlock,
-        return_places: CallReturnPlaces<'_, 'tcx>,
-    ) {
-        return_places.for_each(|place| {
-            // when a call returns successfully, that means we need to set
-            // the bits for that dest_place to 1 (initialized).
-            on_lookup_result_bits(
-                self.move_data(),
-                self.move_data().rev_lookup.find(place.as_ref()),
-                |mpi| {
-                    trans.gen_(mpi);
-                },
-            );
-        });
-    }
-}
-
 impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
     /// There can be many more `InitIndex` than there are locals in a MIR body.
     /// We use a chunked bitset to avoid paying too high a memory footprint.
diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs
index 9b5bfa9bfa0..b9e194b00c5 100644
--- a/compiler/rustc_mir_dataflow/src/impls/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs
@@ -9,10 +9,11 @@ mod storage_liveness;
 
 pub use self::borrowed_locals::{MaybeBorrowedLocals, borrowed_locals};
 pub use self::initialized::{
-    DefinitelyInitializedPlaces, EverInitializedPlaces, MaybeInitializedPlaces,
-    MaybeUninitializedPlaces,
+    EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces,
 };
 pub use self::liveness::{
     MaybeLiveLocals, MaybeTransitiveLiveLocals, TransferFunction as LivenessTransferFunction,
 };
-pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageDead, MaybeStorageLive};
+pub use self::storage_liveness::{
+    MaybeRequiresStorage, MaybeStorageDead, MaybeStorageLive, always_storage_live_locals,
+};
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index 576289e228a..1aae06d79d3 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -7,6 +7,23 @@ use rustc_middle::mir::*;
 use super::MaybeBorrowedLocals;
 use crate::{Analysis, GenKill, ResultsCursor};
 
+/// The set of locals in a MIR body that do not have `StorageLive`/`StorageDead` annotations.
+///
+/// These locals have fixed storage for the duration of the body.
+pub fn always_storage_live_locals(body: &Body<'_>) -> BitSet<Local> {
+    let mut always_live_locals = BitSet::new_filled(body.local_decls.len());
+
+    for block in &*body.basic_blocks {
+        for statement in &block.statements {
+            if let StatementKind::StorageLive(l) | StatementKind::StorageDead(l) = statement.kind {
+                always_live_locals.remove(l);
+            }
+        }
+    }
+
+    always_live_locals
+}
+
 pub struct MaybeStorageLive<'a> {
     always_live_locals: Cow<'a, BitSet<Local>>,
 }
@@ -28,10 +45,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageLive<'a> {
     }
 
     fn initialize_start_block(&self, body: &Body<'tcx>, on_entry: &mut Self::Domain) {
-        assert_eq!(body.local_decls.len(), self.always_live_locals.domain_size());
-        for local in self.always_live_locals.iter() {
-            on_entry.insert(local);
-        }
+        on_entry.union(&*self.always_live_locals);
 
         for arg in body.args_iter() {
             on_entry.insert(arg);
@@ -135,7 +149,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
         loc: Location,
     ) {
         // If a place is borrowed in a statement, it needs storage for that statement.
-        self.borrowed_locals.mut_analysis().apply_statement_effect(trans, stmt, loc);
+        MaybeBorrowedLocals::transfer_function(trans).visit_statement(stmt, loc);
 
         match &stmt.kind {
             StatementKind::StorageDead(l) => trans.kill(*l),
@@ -180,10 +194,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
         loc: Location,
     ) {
         // If a place is borrowed in a terminator, it needs storage for that terminator.
-        self.borrowed_locals
-            .mut_analysis()
-            .transfer_function(trans)
-            .visit_terminator(terminator, loc);
+        MaybeBorrowedLocals::transfer_function(trans).visit_terminator(terminator, loc);
 
         match &terminator.kind {
             TerminatorKind::Call { destination, .. } => {
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index ab1453f1ed0..2248972cecc 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -25,7 +25,7 @@ pub use self::framework::{
 use self::move_paths::MoveData;
 
 pub mod debuginfo;
-pub mod drop_flag_effects;
+mod drop_flag_effects;
 pub mod elaborate_drops;
 mod errors;
 mod framework;
@@ -33,13 +33,12 @@ pub mod impls;
 pub mod move_paths;
 pub mod points;
 pub mod rustc_peek;
-pub mod storage;
-pub mod un_derefer;
+mod un_derefer;
 pub mod value_analysis;
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
-pub struct MoveDataParamEnv<'tcx> {
+pub struct MoveDataTypingEnv<'tcx> {
     pub move_data: MoveData<'tcx>,
-    pub param_env: ty::ParamEnv<'tcx>,
+    pub typing_env: ty::TypingEnv<'tcx>,
 }
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index 99d0ccde105..34ef8afdde3 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -12,9 +12,7 @@ use crate::errors::{
     PeekMustBePlaceOrRefPlace, StopAfterDataFlowEndedCompilation,
 };
 use crate::framework::BitSetExt;
-use crate::impls::{
-    DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeLiveLocals, MaybeUninitializedPlaces,
-};
+use crate::impls::{MaybeInitializedPlaces, MaybeLiveLocals, MaybeUninitializedPlaces};
 use crate::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex};
 use crate::{Analysis, JoinSemiLattice, ResultsCursor};
 
@@ -56,13 +54,6 @@ pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
         sanity_check_via_rustc_peek(tcx, flow_uninits.into_results_cursor(body));
     }
 
-    if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_definite_init).is_some() {
-        let flow_def_inits =
-            DefinitelyInitializedPlaces::new(body, &move_data).iterate_to_fixpoint(tcx, body, None);
-
-        sanity_check_via_rustc_peek(tcx, flow_def_inits.into_results_cursor(body));
-    }
-
     if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() {
         let flow_liveness = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None);
 
diff --git a/compiler/rustc_mir_dataflow/src/storage.rs b/compiler/rustc_mir_dataflow/src/storage.rs
deleted file mode 100644
index e5a0e1d312e..00000000000
--- a/compiler/rustc_mir_dataflow/src/storage.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use rustc_index::bit_set::BitSet;
-use rustc_middle::mir::{self, Local};
-
-/// The set of locals in a MIR body that do not have `StorageLive`/`StorageDead` annotations.
-///
-/// These locals have fixed storage for the duration of the body.
-pub fn always_storage_live_locals(body: &mir::Body<'_>) -> BitSet<Local> {
-    let mut always_live_locals = BitSet::new_filled(body.local_decls.len());
-
-    for block in &*body.basic_blocks {
-        for statement in &block.statements {
-            use mir::StatementKind::{StorageDead, StorageLive};
-            if let StorageLive(l) | StorageDead(l) = statement.kind {
-                always_live_locals.remove(l);
-            }
-        }
-    }
-
-    always_live_locals
-}
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 8295a806d71..9b9aeccf890 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -70,8 +70,8 @@ use rustc_middle::ty::{
 use rustc_middle::{bug, span_bug};
 use rustc_mir_dataflow::impls::{
     MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive,
+    always_storage_live_locals,
 };
-use rustc_mir_dataflow::storage::always_storage_live_locals;
 use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor};
 use rustc_span::Span;
 use rustc_span::def_id::{DefId, LocalDefId};
@@ -676,12 +676,11 @@ fn locals_live_across_suspend_points<'tcx>(
 
     let mut borrowed_locals_cursor = borrowed_locals_results.clone().into_results_cursor(body);
 
-    // Calculate the MIR locals that we actually need to keep storage around
-    // for.
-    let mut requires_storage_cursor =
+    // Calculate the MIR locals that we need to keep storage around for.
+    let mut requires_storage_results =
         MaybeRequiresStorage::new(borrowed_locals_results.into_results_cursor(body))
-            .iterate_to_fixpoint(tcx, body, None)
-            .into_results_cursor(body);
+            .iterate_to_fixpoint(tcx, body, None);
+    let mut requires_storage_cursor = requires_storage_results.as_results_cursor_mut(body);
 
     // Calculate the liveness of MIR locals ignoring borrows.
     let mut liveness =
@@ -697,8 +696,7 @@ fn locals_live_across_suspend_points<'tcx>(
             let loc = Location { block, statement_index: data.statements.len() };
 
             liveness.seek_to_block_end(block);
-            let mut live_locals: BitSet<_> = BitSet::new_empty(body.local_decls.len());
-            live_locals.union(liveness.get());
+            let mut live_locals = liveness.get().clone();
 
             if !movable {
                 // The `liveness` variable contains the liveness of MIR locals ignoring borrows.
@@ -754,7 +752,7 @@ fn locals_live_across_suspend_points<'tcx>(
         body,
         &saved_locals,
         always_live_locals.clone(),
-        requires_storage_cursor.into_results(),
+        requires_storage_results,
     );
 
     LivenessInfo {
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index e8b3d80be02..02fd289b6ef 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -13,16 +13,15 @@ use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_middle::hir::map::Map;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::mir::coverage::{
-    CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind, SourceRegion,
+    CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind,
 };
 use rustc_middle::mir::{
     self, BasicBlock, BasicBlockData, SourceInfo, Statement, StatementKind, Terminator,
     TerminatorKind,
 };
 use rustc_middle::ty::TyCtxt;
+use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::source_map::SourceMap;
-use rustc_span::{BytePos, Pos, SourceFile, Span};
 use tracing::{debug, debug_span, trace};
 
 use crate::coverage::counters::{CounterIncrementSite, CoverageCounters};
@@ -97,7 +96,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
     let coverage_counters =
         CoverageCounters::make_bcb_counters(&basic_coverage_blocks, &bcbs_with_counter_mappings);
 
-    let mappings = create_mappings(tcx, &hir_info, &extracted_mappings, &coverage_counters);
+    let mappings = create_mappings(&extracted_mappings, &coverage_counters);
     if mappings.is_empty() {
         // No spans could be converted into valid mappings, so skip this function.
         debug!("no spans could be converted into valid mappings; skipping");
@@ -136,18 +135,12 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
 ///
 /// Precondition: All BCBs corresponding to those spans have been given
 /// coverage counters.
-fn create_mappings<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    hir_info: &ExtractedHirInfo,
+fn create_mappings(
     extracted_mappings: &ExtractedMappings,
     coverage_counters: &CoverageCounters,
 ) -> Vec<Mapping> {
-    let source_map = tcx.sess.source_map();
-    let file = source_map.lookup_source_file(hir_info.body_span.lo());
-
     let term_for_bcb =
         |bcb| coverage_counters.term_for_bcb(bcb).expect("all BCBs with spans were given counters");
-    let region_for_span = |span: Span| make_source_region(source_map, hir_info, &file, span);
 
     // Fully destructure the mappings struct to make sure we don't miss any kinds.
     let ExtractedMappings {
@@ -160,22 +153,20 @@ fn create_mappings<'tcx>(
     } = extracted_mappings;
     let mut mappings = Vec::new();
 
-    mappings.extend(code_mappings.iter().filter_map(
+    mappings.extend(code_mappings.iter().map(
         // Ordinary code mappings are the simplest kind.
         |&mappings::CodeMapping { span, bcb }| {
-            let source_region = region_for_span(span)?;
             let kind = MappingKind::Code(term_for_bcb(bcb));
-            Some(Mapping { kind, source_region })
+            Mapping { kind, span }
         },
     ));
 
-    mappings.extend(branch_pairs.iter().filter_map(
+    mappings.extend(branch_pairs.iter().map(
         |&mappings::BranchPair { span, true_bcb, false_bcb }| {
             let true_term = term_for_bcb(true_bcb);
             let false_term = term_for_bcb(false_bcb);
             let kind = MappingKind::Branch { true_term, false_term };
-            let source_region = region_for_span(span)?;
-            Some(Mapping { kind, source_region })
+            Mapping { kind, span }
         },
     ));
 
@@ -183,7 +174,7 @@ fn create_mappings<'tcx>(
         |bcb| coverage_counters.term_for_bcb(bcb).expect("all BCBs with spans were given counters");
 
     // MCDC branch mappings are appended with their decisions in case decisions were ignored.
-    mappings.extend(mcdc_degraded_branches.iter().filter_map(
+    mappings.extend(mcdc_degraded_branches.iter().map(
         |&mappings::MCDCBranch {
              span,
              true_bcb,
@@ -192,10 +183,9 @@ fn create_mappings<'tcx>(
              true_index: _,
              false_index: _,
          }| {
-            let source_region = region_for_span(span)?;
             let true_term = term_for_bcb(true_bcb);
             let false_term = term_for_bcb(false_bcb);
-            Some(Mapping { kind: MappingKind::Branch { true_term, false_term }, source_region })
+            Mapping { kind: MappingKind::Branch { true_term, false_term }, span }
         },
     ));
 
@@ -203,7 +193,7 @@ fn create_mappings<'tcx>(
         let num_conditions = branches.len() as u16;
         let conditions = branches
             .into_iter()
-            .filter_map(
+            .map(
                 |&mappings::MCDCBranch {
                      span,
                      true_bcb,
@@ -212,31 +202,29 @@ fn create_mappings<'tcx>(
                      true_index: _,
                      false_index: _,
                  }| {
-                    let source_region = region_for_span(span)?;
                     let true_term = term_for_bcb(true_bcb);
                     let false_term = term_for_bcb(false_bcb);
-                    Some(Mapping {
+                    Mapping {
                         kind: MappingKind::MCDCBranch {
                             true_term,
                             false_term,
                             mcdc_params: condition_info,
                         },
-                        source_region,
-                    })
+                        span,
+                    }
                 },
             )
             .collect::<Vec<_>>();
 
-        if conditions.len() == num_conditions as usize
-            && let Some(source_region) = region_for_span(decision.span)
-        {
+        if conditions.len() == num_conditions as usize {
             // LLVM requires end index for counter mapping regions.
             let kind = MappingKind::MCDCDecision(DecisionInfo {
                 bitmap_idx: (decision.bitmap_idx + decision.num_test_vectors) as u32,
                 num_conditions,
             });
             mappings.extend(
-                std::iter::once(Mapping { kind, source_region }).chain(conditions.into_iter()),
+                std::iter::once(Mapping { kind, span: decision.span })
+                    .chain(conditions.into_iter()),
             );
         } else {
             mappings.extend(conditions.into_iter().map(|mapping| {
@@ -245,10 +233,7 @@ fn create_mappings<'tcx>(
                 else {
                     unreachable!("all mappings here are MCDCBranch as shown above");
                 };
-                Mapping {
-                    kind: MappingKind::Branch { true_term, false_term },
-                    source_region: mapping.source_region,
-                }
+                Mapping { kind: MappingKind::Branch { true_term, false_term }, span: mapping.span }
             }))
         }
     }
@@ -391,121 +376,6 @@ fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb
     data.statements.insert(0, statement);
 }
 
-fn ensure_non_empty_span(
-    source_map: &SourceMap,
-    hir_info: &ExtractedHirInfo,
-    span: Span,
-) -> Option<Span> {
-    if !span.is_empty() {
-        return Some(span);
-    }
-
-    let lo = span.lo();
-    let hi = span.hi();
-
-    // The span is empty, so try to expand it to cover an adjacent '{' or '}',
-    // but only within the bounds of the body span.
-    let try_next = hi < hir_info.body_span.hi();
-    let try_prev = hir_info.body_span.lo() < lo;
-    if !(try_next || try_prev) {
-        return None;
-    }
-
-    source_map
-        .span_to_source(span, |src, start, end| try {
-            // We're only checking for specific ASCII characters, so we don't
-            // have to worry about multi-byte code points.
-            if try_next && src.as_bytes()[end] == b'{' {
-                Some(span.with_hi(hi + BytePos(1)))
-            } else if try_prev && src.as_bytes()[start - 1] == b'}' {
-                Some(span.with_lo(lo - BytePos(1)))
-            } else {
-                None
-            }
-        })
-        .ok()?
-}
-
-/// Converts the span into its start line and column, and end line and column.
-///
-/// Line numbers and column numbers are 1-based. Unlike most column numbers emitted by
-/// the compiler, these column numbers are denoted in **bytes**, because that's what
-/// LLVM's `llvm-cov` tool expects to see in coverage maps.
-///
-/// Returns `None` if the conversion failed for some reason. This shouldn't happen,
-/// but it's hard to rule out entirely (especially in the presence of complex macros
-/// or other expansions), and if it does happen then skipping a span or function is
-/// better than an ICE or `llvm-cov` failure that the user might have no way to avoid.
-fn make_source_region(
-    source_map: &SourceMap,
-    hir_info: &ExtractedHirInfo,
-    file: &SourceFile,
-    span: Span,
-) -> Option<SourceRegion> {
-    let span = ensure_non_empty_span(source_map, hir_info, span)?;
-
-    let lo = span.lo();
-    let hi = span.hi();
-
-    // Column numbers need to be in bytes, so we can't use the more convenient
-    // `SourceMap` methods for looking up file coordinates.
-    let line_and_byte_column = |pos: BytePos| -> Option<(usize, usize)> {
-        let rpos = file.relative_position(pos);
-        let line_index = file.lookup_line(rpos)?;
-        let line_start = file.lines()[line_index];
-        // Line numbers and column numbers are 1-based, so add 1 to each.
-        Some((line_index + 1, (rpos - line_start).to_usize() + 1))
-    };
-
-    let (mut start_line, start_col) = line_and_byte_column(lo)?;
-    let (mut end_line, end_col) = line_and_byte_column(hi)?;
-
-    // Apply an offset so that code in doctests has correct line numbers.
-    // FIXME(#79417): Currently we have no way to offset doctest _columns_.
-    start_line = source_map.doctest_offset_line(&file.name, start_line);
-    end_line = source_map.doctest_offset_line(&file.name, end_line);
-
-    check_source_region(SourceRegion {
-        start_line: start_line as u32,
-        start_col: start_col as u32,
-        end_line: end_line as u32,
-        end_col: end_col as u32,
-    })
-}
-
-/// If `llvm-cov` sees a source region that is improperly ordered (end < start),
-/// it will immediately exit with a fatal error. To prevent that from happening,
-/// discard regions that are improperly ordered, or might be interpreted in a
-/// way that makes them improperly ordered.
-fn check_source_region(source_region: SourceRegion) -> Option<SourceRegion> {
-    let SourceRegion { start_line, start_col, end_line, end_col } = source_region;
-
-    // Line/column coordinates are supposed to be 1-based. If we ever emit
-    // coordinates of 0, `llvm-cov` might misinterpret them.
-    let all_nonzero = [start_line, start_col, end_line, end_col].into_iter().all(|x| x != 0);
-    // Coverage mappings use the high bit of `end_col` to indicate that a
-    // region is actually a "gap" region, so make sure it's unset.
-    let end_col_has_high_bit_unset = (end_col & (1 << 31)) == 0;
-    // If a region is improperly ordered (end < start), `llvm-cov` will exit
-    // with a fatal error, which is inconvenient for users and hard to debug.
-    let is_ordered = (start_line, start_col) <= (end_line, end_col);
-
-    if all_nonzero && end_col_has_high_bit_unset && is_ordered {
-        Some(source_region)
-    } else {
-        debug!(
-            ?source_region,
-            ?all_nonzero,
-            ?end_col_has_high_bit_unset,
-            ?is_ordered,
-            "Skipping source region that would be misinterpreted or rejected by LLVM"
-        );
-        // If this happens in a debug build, ICE to make it easier to notice.
-        debug_assert!(false, "Improper source region: {source_region:?}");
-        None
-    }
-}
-
 /// Function information extracted from HIR by the coverage instrumentor.
 #[derive(Debug)]
 struct ExtractedHirInfo {
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 9c74b2f0839..8f977d2979e 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -217,11 +217,6 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
                 else {
                     continue;
                 };
-                if !tcx.consider_optimizing(|| {
-                    format!("{} round {}", tcx.def_path_str(def_id), round_count)
-                }) {
-                    break;
-                }
 
                 // Replace `src` by `dest` everywhere.
                 merges.insert(*src, *dest);
diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
index 704ed508b22..17c8348140a 100644
--- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
+++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
@@ -108,10 +108,6 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
             let parent = BasicBlock::from_usize(i);
             let Some(opt_data) = evaluate_candidate(tcx, body, parent) else { continue };
 
-            if !tcx.consider_optimizing(|| format!("EarlyOtherwiseBranch {opt_data:?}")) {
-                break;
-            }
-
             trace!("SUCCESS: found optimization possibility to apply: {opt_data:?}");
 
             should_cleanup = true;
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index b0f041d8722..0c0f3b61977 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -3,7 +3,6 @@ use std::fmt;
 use rustc_abi::{FieldIdx, VariantIdx};
 use rustc_index::IndexVec;
 use rustc_index::bit_set::BitSet;
-use rustc_infer::traits::Reveal;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, TyCtxt};
@@ -13,7 +12,7 @@ use rustc_mir_dataflow::elaborate_drops::{
 use rustc_mir_dataflow::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
 use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
 use rustc_mir_dataflow::{
-    Analysis, MoveDataParamEnv, ResultsCursor, on_all_children_bits, on_lookup_result_bits,
+    Analysis, MoveDataTypingEnv, ResultsCursor, on_all_children_bits, on_lookup_result_bits,
 };
 use rustc_span::Span;
 use tracing::{debug, instrument};
@@ -61,7 +60,7 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
         // init/uninit for types that do need dropping.
         let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, typing_env));
         let elaborate_patch = {
-            let env = MoveDataParamEnv { move_data, param_env: typing_env.param_env };
+            let env = MoveDataTypingEnv { move_data, typing_env };
 
             let mut inits = MaybeInitializedPlaces::new(tcx, body, &env.move_data)
                 .skipping_unreachable_unwind()
@@ -149,7 +148,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> {
     }
 
     fn typing_env(&self) -> ty::TypingEnv<'tcx> {
-        self.typing_env()
+        self.env.typing_env
     }
 
     #[instrument(level = "debug", skip(self), ret)]
@@ -230,7 +229,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> {
 struct ElaborateDropsCtxt<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     body: &'a Body<'tcx>,
-    env: &'a MoveDataParamEnv<'tcx>,
+    env: &'a MoveDataTypingEnv<'tcx>,
     init_data: InitializationData<'a, 'tcx>,
     drop_flags: IndexVec<MovePathIndex, Option<Local>>,
     patch: MirPatch<'tcx>,
@@ -247,15 +246,6 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> {
         &self.env.move_data
     }
 
-    fn param_env(&self) -> ty::ParamEnv<'tcx> {
-        self.env.param_env
-    }
-
-    fn typing_env(&self) -> ty::TypingEnv<'tcx> {
-        debug_assert_eq!(self.param_env().reveal(), Reveal::All);
-        ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env() }
-    }
-
     fn create_drop_flag(&mut self, index: MovePathIndex, span: Span) {
         let patch = &mut self.patch;
         debug!("create_drop_flag({:?})", self.body.span);
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 976f4a8e919..d5a813ec8ec 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -638,7 +638,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         let proj = match proj {
             ProjectionElem::Deref => {
                 let ty = place.ty(self.local_decls, self.tcx).ty;
-                if let Some(Mutability::Not) = ty.ref_mutability()
+                // 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()
                     && let Some(pointee_ty) = ty.builtin_deref(true)
                     && pointee_ty.is_freeze(self.tcx, self.typing_env())
                 {
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 00f6c3845d4..0878fa26a92 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -210,12 +210,6 @@ impl<'tcx> Inliner<'tcx> {
         let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?;
         self.check_mir_body(callsite, callee_body, callee_attrs, cross_crate_inlinable)?;
 
-        if !self.tcx.consider_optimizing(|| {
-            format!("Inline {:?} into {:?}", callsite.callee, caller_body.source)
-        }) {
-            return Err("optimization fuel exhausted");
-        }
-
         let Ok(callee_body) = callsite.callee.try_instantiate_mir_and_normalize_erasing_regions(
             self.tcx,
             self.typing_env,
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 3352d583f2c..a6ba2f32d32 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -7,8 +7,8 @@ use rustc_middle::bug;
 use rustc_middle::mir::*;
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, layout};
-use rustc_span::sym;
 use rustc_span::symbol::Symbol;
+use rustc_span::{DUMMY_SP, sym};
 
 use crate::simplify::simplify_duplicate_switch_targets;
 use crate::take_array;
@@ -43,12 +43,12 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
                 match statement.kind {
                     StatementKind::Assign(box (_place, ref mut rvalue)) => {
                         if !preserve_ub_checks {
-                            ctx.simplify_ub_check(&statement.source_info, rvalue);
+                            ctx.simplify_ub_check(rvalue);
                         }
-                        ctx.simplify_bool_cmp(&statement.source_info, rvalue);
-                        ctx.simplify_ref_deref(&statement.source_info, rvalue);
-                        ctx.simplify_len(&statement.source_info, rvalue);
-                        ctx.simplify_ptr_aggregate(&statement.source_info, rvalue);
+                        ctx.simplify_bool_cmp(rvalue);
+                        ctx.simplify_ref_deref(rvalue);
+                        ctx.simplify_len(rvalue);
+                        ctx.simplify_ptr_aggregate(rvalue);
                         ctx.simplify_cast(rvalue);
                     }
                     _ => {}
@@ -70,23 +70,8 @@ struct InstSimplifyContext<'a, 'tcx> {
 }
 
 impl<'tcx> InstSimplifyContext<'_, 'tcx> {
-    fn should_simplify(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool {
-        self.should_simplify_custom(source_info, "Rvalue", rvalue)
-    }
-
-    fn should_simplify_custom(
-        &self,
-        source_info: &SourceInfo,
-        label: &str,
-        value: impl std::fmt::Debug,
-    ) -> bool {
-        self.tcx.consider_optimizing(|| {
-            format!("InstSimplify - {label}: {value:?} SourceInfo: {source_info:?}")
-        })
-    }
-
     /// Transform boolean comparisons into logical operations.
-    fn simplify_bool_cmp(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
+    fn simplify_bool_cmp(&self, rvalue: &mut Rvalue<'tcx>) {
         match rvalue {
             Rvalue::BinaryOp(op @ (BinOp::Eq | BinOp::Ne), box (a, b)) => {
                 let new = match (op, self.try_eval_bool(a), self.try_eval_bool(b)) {
@@ -117,9 +102,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
                     _ => None,
                 };
 
-                if let Some(new) = new
-                    && self.should_simplify(source_info, rvalue)
-                {
+                if let Some(new) = new {
                     *rvalue = new;
                 }
             }
@@ -134,17 +117,13 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
     }
 
     /// Transform `&(*a)` ==> `a`.
-    fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
+    fn simplify_ref_deref(&self, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) = rvalue {
             if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
                 if rvalue.ty(self.local_decls, self.tcx) != base.ty(self.local_decls, self.tcx).ty {
                     return;
                 }
 
-                if !self.should_simplify(source_info, rvalue) {
-                    return;
-                }
-
                 *rvalue = Rvalue::Use(Operand::Copy(Place {
                     local: base.local,
                     projection: self.tcx.mk_place_elems(base.projection),
@@ -154,36 +133,24 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
     }
 
     /// Transform `Len([_; N])` ==> `N`.
-    fn simplify_len(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
+    fn simplify_len(&self, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::Len(ref place) = *rvalue {
             let place_ty = place.ty(self.local_decls, self.tcx).ty;
             if let ty::Array(_, len) = *place_ty.kind() {
-                if !self.should_simplify(source_info, rvalue) {
-                    return;
-                }
-
                 let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx);
-                let constant = ConstOperand { span: source_info.span, const_, user_ty: None };
+                let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
                 *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
             }
         }
     }
 
     /// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
-    fn simplify_ptr_aggregate(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
+    fn simplify_ptr_aggregate(&self, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue
         {
             let meta_ty = fields.raw[1].ty(self.local_decls, self.tcx);
             if meta_ty.is_unit() {
                 // The mutable borrows we're holding prevent printing `rvalue` here
-                if !self.should_simplify_custom(
-                    source_info,
-                    "Aggregate::RawPtr",
-                    (&pointee_ty, *mutability, &fields),
-                ) {
-                    return;
-                }
-
                 let mut fields = std::mem::take(fields);
                 let _meta = fields.pop().unwrap();
                 let data = fields.pop().unwrap();
@@ -193,10 +160,10 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
         }
     }
 
-    fn simplify_ub_check(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
+    fn simplify_ub_check(&self, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue {
             let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks());
-            let constant = ConstOperand { span: source_info.span, const_, user_ty: None };
+            let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
             *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
         }
     }
@@ -284,16 +251,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
             return;
         }
 
-        if !self.tcx.consider_optimizing(|| {
-            format!(
-                "InstSimplify - Call: {:?} SourceInfo: {:?}",
-                (fn_def_id, fn_args),
-                terminator.source_info
-            )
-        }) {
-            return;
-        }
-
         let Ok([arg]) = take_array(args) else { return };
         let Some(arg_place) = arg.node.place() else { return };
 
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index 53e282e9b46..acf3eb2b62c 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -258,7 +258,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         // Normalization needed b/c known panics lint runs in
         // `mir_drops_elaborated_and_const_checked`, which happens before
         // optimized MIR. Only after optimizing the MIR can we guarantee
-        // that the `RevealAll` pass has happened and that the body's consts
+        // that the `PostAnalysisNormalize` pass has happened and that the body's consts
         // are normalized, so any call to resolve before that needs to be
         // manually normalized.
         let val = self.tcx.try_normalize_erasing_regions(self.typing_env, c.const_).ok()?;
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index bfb842e4485..f0fcb44603b 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -163,7 +163,7 @@ declare_passes! {
     mod remove_unneeded_drops : RemoveUnneededDrops;
     mod remove_zsts : RemoveZsts;
     mod required_consts : RequiredConstsVisitor;
-    mod reveal_all : RevealAll;
+    mod post_analysis_normalize : PostAnalysisNormalize;
     mod sanity_check : SanityCheck;
     // This pass is public to allow external drivers to perform MIR cleanup
     pub mod simplify :
@@ -604,8 +604,8 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         // These next passes must be executed together.
         &add_call_guards::CriticalCallEdges,
         // Must be done before drop elaboration because we need to drop opaque types, too.
-        &reveal_all::RevealAll,
-        // Calling this after reveal_all ensures that we don't deal with opaque types.
+        &post_analysis_normalize::PostAnalysisNormalize,
+        // Calling this after `PostAnalysisNormalize` ensures that we don't deal with opaque types.
         &add_subtyping_projections::Subtyper,
         &elaborate_drops::ElaborateDrops,
         // This will remove extraneous landing pads which are no longer
diff --git a/compiler/rustc_mir_transform/src/lint.rs b/compiler/rustc_mir_transform/src/lint.rs
index d8ff1cfc90b..29e762af8de 100644
--- a/compiler/rustc_mir_transform/src/lint.rs
+++ b/compiler/rustc_mir_transform/src/lint.rs
@@ -9,8 +9,7 @@ use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::visit::{PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
-use rustc_mir_dataflow::impls::{MaybeStorageDead, MaybeStorageLive};
-use rustc_mir_dataflow::storage::always_storage_live_locals;
+use rustc_mir_dataflow::impls::{MaybeStorageDead, MaybeStorageLive, always_storage_live_locals};
 use rustc_mir_dataflow::{Analysis, ResultsCursor};
 
 pub(super) fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String) {
diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
index b8502fcbafb..732a9cd9890 100644
--- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
+++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
@@ -216,22 +216,17 @@ fn true_significant_drop_ty<'tcx>(
 
 /// Returns the list of types with a "potentially sigificant" that may be dropped
 /// by dropping a value of type `ty`.
-#[instrument(level = "debug", skip(tcx, param_env))]
+#[instrument(level = "debug", skip(tcx, typing_env))]
 fn extract_component_raw<'tcx>(
     tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
+    typing_env: ty::TypingEnv<'tcx>,
     ty: Ty<'tcx>,
     ty_seen: &mut UnordSet<Ty<'tcx>>,
 ) -> SmallVec<[Ty<'tcx>; 4]> {
     // Droppiness does not depend on regions, so let us erase them.
-    let ty = tcx
-        .try_normalize_erasing_regions(
-            ty::TypingEnv { param_env, typing_mode: ty::TypingMode::PostAnalysis },
-            ty,
-        )
-        .unwrap_or(ty);
-
-    let tys = tcx.list_significant_drop_tys(param_env.and(ty));
+    let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
+
+    let tys = tcx.list_significant_drop_tys(typing_env.as_query_input(ty));
     debug!(?ty, "components");
     let mut out_tys = smallvec![];
     for ty in tys {
@@ -239,7 +234,7 @@ fn extract_component_raw<'tcx>(
             // Some types can be further opened up because the drop is simply delegated
             for ty in tys {
                 if ty_seen.insert(ty) {
-                    out_tys.extend(extract_component_raw(tcx, param_env, ty, ty_seen));
+                    out_tys.extend(extract_component_raw(tcx, typing_env, ty, ty_seen));
                 }
             }
         } else {
@@ -251,13 +246,13 @@ fn extract_component_raw<'tcx>(
     out_tys
 }
 
-#[instrument(level = "debug", skip(tcx, param_env))]
+#[instrument(level = "debug", skip(tcx, typing_env))]
 fn extract_component_with_significant_dtor<'tcx>(
     tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
+    typing_env: ty::TypingEnv<'tcx>,
     ty: Ty<'tcx>,
 ) -> SmallVec<[Ty<'tcx>; 4]> {
-    let mut tys = extract_component_raw(tcx, param_env, ty, &mut Default::default());
+    let mut tys = extract_component_raw(tcx, typing_env, ty, &mut Default::default());
     let mut deduplicate = FxHashSet::default();
     tys.retain(|oty| deduplicate.insert(*oty));
     tys.into_iter().collect()
@@ -359,7 +354,7 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
     // We group them per-block because they tend to scheduled in the same drop ladder block.
     let mut bid_per_block = IndexMap::default();
     let mut bid_places = UnordSet::new();
-    let param_env = tcx.param_env(def_id).with_reveal_all_normalized(tcx);
+    let typing_env = ty::TypingEnv::post_analysis(tcx, def_id);
     let mut ty_dropped_components = UnordMap::default();
     for (block, data) in body.basic_blocks.iter_enumerated() {
         for (statement_index, stmt) in data.statements.iter().enumerate() {
@@ -367,7 +362,7 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
                 let ty = place.ty(body, tcx).ty;
                 if ty_dropped_components
                     .entry(ty)
-                    .or_insert_with(|| extract_component_with_significant_dtor(tcx, param_env, ty))
+                    .or_insert_with(|| extract_component_with_significant_dtor(tcx, typing_env, ty))
                     .is_empty()
                 {
                     continue;
@@ -479,7 +474,7 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
                 if ty_dropped_components
                     .entry(observer_ty)
                     .or_insert_with(|| {
-                        extract_component_with_significant_dtor(tcx, param_env, observer_ty)
+                        extract_component_with_significant_dtor(tcx, typing_env, observer_ty)
                     })
                     .is_empty()
                 {
@@ -575,7 +570,7 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
             let name = name.as_str();
 
             let mut seen_dyn = false;
-            let destructors = extract_component_with_significant_dtor(tcx, param_env, observer_ty)
+            let destructors = extract_component_with_significant_dtor(tcx, typing_env, observer_ty)
                 .into_iter()
                 .filter_map(|ty| {
                     if let Some(span) = ty_dtor_span(tcx, ty) {
diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs
index ff027680c49..20e2a65b311 100644
--- a/compiler/rustc_mir_transform/src/match_branches.rs
+++ b/compiler/rustc_mir_transform/src/match_branches.rs
@@ -18,16 +18,11 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        let def_id = body.source.def_id();
         let typing_env = body.typing_env(tcx);
         let mut should_cleanup = false;
         for i in 0..body.basic_blocks.len() {
             let bbs = &*body.basic_blocks;
             let bb_idx = BasicBlock::from_usize(i);
-            if !tcx.consider_optimizing(|| format!("MatchBranchSimplification {def_id:?} ")) {
-                continue;
-            }
-
             match bbs[bb_idx].terminator().kind {
                 TerminatorKind::SwitchInt {
                     discr: ref _discr @ (Operand::Copy(_) | Operand::Move(_)),
diff --git a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs
index b6d6ef5de1d..a9227524ce5 100644
--- a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs
+++ b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs
@@ -14,10 +14,9 @@ impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators {
         sess.mir_opt_level() >= 4
     }
 
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+    fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         // find basic blocks with no statement and a return terminator
         let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks.len());
-        let def_id = body.source.def_id();
         let bbs = body.basic_blocks_mut();
         for idx in bbs.indices() {
             if bbs[idx].statements.is_empty()
@@ -28,10 +27,6 @@ impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators {
         }
 
         for bb in bbs {
-            if !tcx.consider_optimizing(|| format!("MultipleReturnTerminators {def_id:?} ")) {
-                break;
-            }
-
             if let TerminatorKind::Goto { target } = bb.terminator().kind {
                 if bbs_simple_returns.contains(target) {
                     bb.terminator_mut().kind = TerminatorKind::Return;
diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs
index 98fa149e2bc..cd026ed6806 100644
--- a/compiler/rustc_mir_transform/src/nrvo.rs
+++ b/compiler/rustc_mir_transform/src/nrvo.rs
@@ -45,10 +45,6 @@ impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace {
             return;
         };
 
-        if !tcx.consider_optimizing(|| format!("RenameReturnPlace {def_id:?}")) {
-            return;
-        }
-
         debug!(
             "`{:?}` was eligible for NRVO, making {:?} the return place",
             def_id, returned_local
diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/post_analysis_normalize.rs
index 587032ee720..3eecf79a7ea 100644
--- a/compiler/rustc_mir_transform/src/reveal_all.rs
+++ b/compiler/rustc_mir_transform/src/post_analysis_normalize.rs
@@ -1,26 +1,28 @@
-//! Normalizes MIR in RevealAll mode.
+//! Normalizes MIR in `TypingMode::PostAnalysis` mode, most notably revealing
+//! its opaques. We also only normalize specializable associated items once in
+//! `PostAnalysis` mode.
 
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 
-pub(super) struct RevealAll;
+pub(super) struct PostAnalysisNormalize;
 
-impl<'tcx> crate::MirPass<'tcx> for RevealAll {
+impl<'tcx> crate::MirPass<'tcx> for PostAnalysisNormalize {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         // FIXME(#132279): This is used during the phase transition from analysis
         // to runtime, so we have to manually specify the correct typing mode.
         let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id());
-        RevealAllVisitor { tcx, typing_env }.visit_body_preserves_cfg(body);
+        PostAnalysisNormalizeVisitor { tcx, typing_env }.visit_body_preserves_cfg(body);
     }
 }
 
-struct RevealAllVisitor<'tcx> {
+struct PostAnalysisNormalizeVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
     typing_env: ty::TypingEnv<'tcx>,
 }
 
-impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
+impl<'tcx> MutVisitor<'tcx> for PostAnalysisNormalizeVisitor<'tcx> {
     #[inline]
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
@@ -38,7 +40,7 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
             return;
         }
         // `OpaqueCast` projections are only needed if there are opaque types on which projections
-        // are performed. After the `RevealAll` pass, all opaque types are replaced with their
+        // are performed. After the `PostAnalysisNormalize` pass, all opaque types are replaced with their
         // hidden types, so we don't need these projections anymore.
         place.projection = self.tcx.mk_place_elems(
             &place
diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs
index af438ac2177..96bcdfa6fac 100644
--- a/compiler/rustc_mir_transform/src/ref_prop.rs
+++ b/compiler/rustc_mir_transform/src/ref_prop.rs
@@ -8,8 +8,7 @@ use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
 use rustc_mir_dataflow::Analysis;
-use rustc_mir_dataflow::impls::MaybeStorageDead;
-use rustc_mir_dataflow::storage::always_storage_live_locals;
+use rustc_mir_dataflow::impls::{MaybeStorageDead, always_storage_live_locals};
 use tracing::{debug, instrument};
 
 use crate::ssa::{SsaLocals, StorageLiveLocals};
diff --git a/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs b/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs
index ad62b47a66d..e335051d656 100644
--- a/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs
+++ b/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs
@@ -2,7 +2,8 @@
 //!
 //! When the MIR is built, we check `needs_drop` before emitting a `Drop` for a place. This pass is
 //! useful because (unlike MIR building) it runs after type checking, so it can make use of
-//! `Reveal::All` to provide more precise type information.
+//! `TypingMode::PostAnalysis` to provide more precise type information, especially about opaque
+//! types.
 
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
@@ -25,11 +26,6 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops {
                 if ty.ty.needs_drop(tcx, typing_env) {
                     continue;
                 }
-                if !tcx.consider_optimizing(|| {
-                    format!("RemoveUnneededDrops {:?}", body.source.def_id())
-                }) {
-                    continue;
-                }
                 debug!("SUCCESS: replacing `drop` with goto({:?})", target);
                 terminator.kind = TerminatorKind::Goto { target };
                 should_simplify = true;
diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs
index 6fd70fbe9b0..64e183bcbc0 100644
--- a/compiler/rustc_mir_transform/src/remove_zsts.rs
+++ b/compiler/rustc_mir_transform/src/remove_zsts.rs
@@ -17,10 +17,6 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveZsts {
             return;
         }
 
-        if !tcx.consider_optimizing(|| format!("RemoveZsts - {:?}", body.source.def_id())) {
-            return;
-        }
-
         let typing_env = body.typing_env(tcx);
         let local_decls = &body.local_decls;
         let mut replacer = Replacer { tcx, typing_env, local_decls };
@@ -94,16 +90,12 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
         }
     }
 
-    fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
+    fn visit_operand(&mut self, operand: &mut Operand<'tcx>, _: Location) {
         if let Operand::Constant(_) = operand {
             return;
         }
         let op_ty = operand.ty(self.local_decls, self.tcx);
-        if self.known_to_be_zst(op_ty)
-            && self.tcx.consider_optimizing(|| {
-                format!("RemoveZsts - Operand: {operand:?} Location: {loc:?}")
-            })
-        {
+        if self.known_to_be_zst(op_ty) {
             *operand = Operand::Constant(Box::new(self.make_zst(op_ty)))
         }
     }
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index f16cde7cd4e..809357ec110 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -141,7 +141,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
     debug!("make_shim({:?}) = untransformed {:?}", instance, result);
 
     // We don't validate MIR here because the shims may generate code that's
-    // only valid in a reveal-all param-env. However, since we do initial
+    // only valid in a `PostAnalysis` param-env. However, since we do initial
     // validation with the MirBuilt phase, which uses a user-facing param-env.
     // This causes validation errors when TAITs are involved.
     pm::run_passes_no_validate(
diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs
index 9cd32459c7b..734703ec78b 100644
--- a/compiler/rustc_mir_transform/src/unreachable_prop.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs
@@ -43,12 +43,6 @@ impl crate::MirPass<'_> for UnreachablePropagation {
             }
         }
 
-        if !tcx
-            .consider_optimizing(|| format!("UnreachablePropagation {:?} ", body.source.def_id()))
-        {
-            return;
-        }
-
         patch.apply(body);
 
         // We do want do keep some unreachable blocks, but make them empty.
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 1739fdcc9af..51e5c49cea1 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -646,7 +646,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             {
                 self.fail(
                     location,
-                    format!("explicit opaque type cast to `{ty}` after `RevealAll`"),
+                    format!("explicit opaque type cast to `{ty}` after `PostAnalysisNormalize`"),
                 )
             }
             ProjectionElem::Index(index) => {
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 8ee9ac3df72..5efe7ffc7b9 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1556,7 +1556,7 @@ fn create_mono_items_for_default_impls<'tcx>(
     // Unlike 'lazy' monomorphization that begins by collecting items transitively
     // called by `main` or other global items, when eagerly monomorphizing impl
     // items, we never actually check that the predicates of this impl are satisfied
-    // in a empty reveal-all param env (i.e. with no assumptions).
+    // in a empty param env (i.e. with no assumptions).
     //
     // Even though this impl has no type or const generic parameters, because we don't
     // consider higher-ranked predicates such as `for<'a> &'a mut [u8]: Copy` to
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index 545ab15b945..adac35b57cd 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -321,7 +321,7 @@ where
 
         let mut candidates = vec![];
 
-        if let TypingMode::Coherence = self.typing_mode(goal.param_env) {
+        if let TypingMode::Coherence = self.typing_mode() {
             if let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal) {
                 return vec![candidate];
             }
@@ -337,7 +337,7 @@ where
 
         self.assemble_param_env_candidates(goal, &mut candidates);
 
-        match self.typing_mode(goal.param_env) {
+        match self.typing_mode() {
             TypingMode::Coherence => {}
             TypingMode::Analysis { .. } | TypingMode::PostAnalysis => {
                 self.discard_impls_shadowed_by_env(goal, &mut candidates);
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 a56febec48c..05ce61bc067 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
@@ -12,7 +12,7 @@ use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
 use tracing::instrument;
 
 use crate::delegate::SolverDelegate;
-use crate::solve::{EvalCtxt, Goal, NoSolution};
+use crate::solve::{AdtDestructorKind, EvalCtxt, Goal, NoSolution};
 
 // Calculates the constituent types of a type for `auto trait` purposes.
 #[instrument(level = "trace", skip(ecx), ret)]
@@ -703,6 +703,78 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>(
     }
 }
 
+pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>(
+    cx: I,
+    self_ty: I::Ty,
+) -> Result<Vec<ty::TraitRef<I>>, NoSolution> {
+    let destruct_def_id = cx.require_lang_item(TraitSolverLangItem::Destruct);
+
+    match self_ty.kind() {
+        // An ADT is `~const Destruct` only if all of the fields are,
+        // *and* if there is a `Drop` impl, that `Drop` impl is also `~const`.
+        ty::Adt(adt_def, args) => {
+            let mut const_conditions: Vec<_> = adt_def
+                .all_field_tys(cx)
+                .iter_instantiated(cx, args)
+                .map(|field_ty| ty::TraitRef::new(cx, destruct_def_id, [field_ty]))
+                .collect();
+            match adt_def.destructor(cx) {
+                // `Drop` impl exists, but it's not const. Type cannot be `~const Destruct`.
+                Some(AdtDestructorKind::NotConst) => return Err(NoSolution),
+                // `Drop` impl exists, and it's const. Require `Ty: ~const Drop` to hold.
+                Some(AdtDestructorKind::Const) => {
+                    let drop_def_id = cx.require_lang_item(TraitSolverLangItem::Drop);
+                    let drop_trait_ref = ty::TraitRef::new(cx, drop_def_id, [self_ty]);
+                    const_conditions.push(drop_trait_ref);
+                }
+                // No `Drop` impl, no need to require anything else.
+                None => {}
+            }
+            Ok(const_conditions)
+        }
+
+        ty::Array(ty, _) | ty::Pat(ty, _) | ty::Slice(ty) => {
+            Ok(vec![ty::TraitRef::new(cx, destruct_def_id, [ty])])
+        }
+
+        ty::Tuple(tys) => Ok(tys
+            .iter()
+            .map(|field_ty| ty::TraitRef::new(cx, destruct_def_id, [field_ty]))
+            .collect()),
+
+        // Trivially implement `~const Destruct`
+        ty::Bool
+        | ty::Char
+        | ty::Int(..)
+        | ty::Uint(..)
+        | ty::Float(..)
+        | ty::Str
+        | ty::RawPtr(..)
+        | ty::Ref(..)
+        | ty::FnDef(..)
+        | ty::FnPtr(..)
+        | ty::Never
+        | ty::Infer(ty::InferTy::FloatVar(_) | ty::InferTy::IntVar(_))
+        | ty::Error(_) => Ok(vec![]),
+
+        // Coroutines and closures could implement `~const Drop`,
+        // but they don't really need to right now.
+        ty::Closure(_, _)
+        | ty::CoroutineClosure(_, _)
+        | ty::Coroutine(_, _)
+        | ty::CoroutineWitness(_, _) => Err(NoSolution),
+
+        ty::Dynamic(..) | ty::Param(_) | ty::Alias(..) | ty::Placeholder(_) | ty::Foreign(_) => {
+            Err(NoSolution)
+        }
+
+        ty::Bound(..)
+        | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
+            panic!("unexpected type `{self_ty:?}`")
+        }
+    }
+}
+
 /// Assemble a list of predicates that would be present on a theoretical
 /// user impl for an object type. These predicates must be checked any time
 /// we assemble a built-in object candidate for an object type, since they
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 603a68eb890..81b5199002b 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -84,6 +84,10 @@ where
         let cx = ecx.cx();
         let mut candidates = vec![];
 
+        if !ecx.cx().alias_has_const_conditions(alias_ty.def_id) {
+            return vec![];
+        }
+
         for clause in elaborate::elaborate(
             cx,
             cx.explicit_implied_const_bounds(alias_ty.def_id)
@@ -338,10 +342,27 @@ where
     }
 
     fn consider_builtin_destruct_candidate(
-        _ecx: &mut EvalCtxt<'_, D>,
-        _goal: Goal<I, Self>,
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
     ) -> Result<Candidate<I>, NoSolution> {
-        Err(NoSolution)
+        let cx = ecx.cx();
+
+        let self_ty = goal.predicate.self_ty();
+        let const_conditions = structural_traits::const_conditions_for_destruct(cx, self_ty)?;
+
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
+            ecx.add_goals(
+                GoalSource::Misc,
+                const_conditions.into_iter().map(|trait_ref| {
+                    goal.with(
+                        cx,
+                        ty::Binder::dummy(trait_ref)
+                            .to_host_effect_clause(cx, goal.predicate.constness),
+                    )
+                }),
+            );
+            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        })
     }
 
     fn consider_builtin_transmute_candidate(
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index 2f50070d438..a143af13688 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -55,7 +55,6 @@ where
         &self,
         goal: Goal<I, T>,
     ) -> (Vec<I::GenericArg>, CanonicalInput<I, T>) {
-        let param_env_for_debug_assertion = goal.param_env;
         let opaque_types = self.delegate.clone_opaque_types_for_query_response();
         let (goal, opaque_types) =
             (goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate));
@@ -72,10 +71,7 @@ where
                     .mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }),
             },
         );
-        let query_input = ty::CanonicalQueryInput {
-            canonical,
-            typing_mode: self.typing_mode(param_env_for_debug_assertion),
-        };
+        let query_input = ty::CanonicalQueryInput { canonical, typing_mode: self.typing_mode() };
         (orig_values, query_input)
     }
 
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 979a3794748..40d1576256e 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -214,8 +214,8 @@ where
     D: SolverDelegate<Interner = I>,
     I: Interner,
 {
-    pub(super) fn typing_mode(&self, param_env_for_debug_assertion: I::ParamEnv) -> TypingMode<I> {
-        self.delegate.typing_mode(param_env_for_debug_assertion)
+    pub(super) fn typing_mode(&self) -> TypingMode<I> {
+        self.delegate.typing_mode()
     }
 
     pub(super) fn set_is_normalizes_to_goal(&mut self) {
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index 6b407640426..33bd1cf2f56 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -71,7 +71,7 @@ where
                 Ok(())
             }
             ty::AliasTermKind::OpaqueTy => {
-                match self.typing_mode(param_env) {
+                match self.typing_mode() {
                     // Opaques are never rigid outside of analysis mode.
                     TypingMode::Coherence | TypingMode::PostAnalysis => Err(NoSolution),
                     // During analysis, opaques are only rigid if we may not define it.
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 d1d701695ab..336bcb9df33 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
@@ -1,6 +1,5 @@
 //! Computes a normalizes-to (projection) goal for opaque types. This goal
-//! behaves differently depending on the param-env's reveal mode and whether
-//! the opaque is in a defining scope.
+//! behaves differently depending on the current `TypingMode`.
 
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_type_ir::inherent::*;
@@ -22,7 +21,7 @@ where
         let opaque_ty = goal.predicate.alias;
         let expected = goal.predicate.term.as_type().expect("no such thing as an opaque const");
 
-        match self.typing_mode(goal.param_env) {
+        match self.typing_mode() {
             TypingMode::Coherence => {
                 // An impossible opaque type bound is the only way this goal will fail
                 // e.g. assigning `impl Copy := NotCopy`
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 ce16258d180..096dc32ccc9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -67,7 +67,7 @@ where
         let maximal_certainty = match (impl_polarity, goal.predicate.polarity) {
             // In intercrate mode, this is ambiguous. But outside of intercrate,
             // it's not a real impl.
-            (ty::ImplPolarity::Reservation, _) => match ecx.typing_mode(goal.param_env) {
+            (ty::ImplPolarity::Reservation, _) => match ecx.typing_mode() {
                 TypingMode::Coherence => Certainty::AMBIGUOUS,
                 TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Err(NoSolution),
             },
@@ -174,7 +174,7 @@ where
         // ideally we want to avoid, since we can make progress on this goal
         // via an alias bound or a locally-inferred hidden type instead.
         if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() {
-            match ecx.typing_mode(goal.param_env) {
+            match ecx.typing_mode() {
                 TypingMode::Coherence | TypingMode::PostAnalysis => {
                     unreachable!("rigid opaque outside of analysis: {goal:?}");
                 }
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index cafd4b6dca2..8c4f669c332 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -827,7 +827,7 @@ parse_unexpected_expr_in_pat =
     }, found an expression
 
     .label = not a pattern
-    .note = arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+    .note = arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 parse_unexpected_expr_in_pat_const_sugg = consider extracting the expression into a `const`
 
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 5023e83bd67..8db3b174a89 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -18,6 +18,7 @@ use rustc_span::symbol::Symbol;
 use rustc_span::{BytePos, Pos, Span};
 use tracing::debug;
 
+use crate::lexer::diagnostics::TokenTreeDiagInfo;
 use crate::lexer::unicode_chars::UNICODE_ARRAY;
 use crate::{errors, make_unclosed_delims_error};
 
@@ -56,7 +57,7 @@ pub(crate) fn lex_token_trees<'psess, 'src>(
     }
 
     let cursor = Cursor::new(src);
-    let string_reader = StringReader {
+    let mut lexer = Lexer {
         psess,
         start_pos,
         pos: start_pos,
@@ -65,34 +66,31 @@ pub(crate) fn lex_token_trees<'psess, 'src>(
         override_span,
         nbsp_is_whitespace: false,
         last_lifetime: None,
+        token: Token::dummy(),
+        diag_info: TokenTreeDiagInfo::default(),
     };
-    let (stream, res, unmatched_delims) =
-        tokentrees::TokenTreesReader::lex_all_token_trees(string_reader);
-    match res {
-        Ok(()) if unmatched_delims.is_empty() => Ok(stream),
-        _ => {
-            // Return error if there are unmatched delimiters or unclosed delimiters.
-            // We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch
-            // because the delimiter mismatch is more likely to be the root cause of error
-
-            let mut buffer = Vec::with_capacity(1);
-            for unmatched in unmatched_delims {
-                if let Some(err) = make_unclosed_delims_error(unmatched, psess) {
-                    buffer.push(err);
-                }
-            }
-            if let Err(errs) = res {
-                // Add unclosing delimiter or diff marker errors
-                for err in errs {
-                    buffer.push(err);
-                }
-            }
-            Err(buffer)
+    let (_open_spacing, stream, res) = lexer.lex_token_trees(/* is_delimited */ false);
+    let unmatched_delims = lexer.diag_info.unmatched_delims;
+
+    if res.is_ok() && unmatched_delims.is_empty() {
+        Ok(stream)
+    } else {
+        // Return error if there are unmatched delimiters or unclosed delimiters.
+        // We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch
+        // because the delimiter mismatch is more likely to be the root cause of error
+        let mut buffer: Vec<_> = unmatched_delims
+            .into_iter()
+            .filter_map(|unmatched_delim| make_unclosed_delims_error(unmatched_delim, psess))
+            .collect();
+        if let Err(errs) = res {
+            // Add unclosing delimiter or diff marker errors
+            buffer.extend(errs);
         }
+        Err(buffer)
     }
 }
 
-struct StringReader<'psess, 'src> {
+struct Lexer<'psess, 'src> {
     psess: &'psess ParseSess,
     /// Initial position, read-only.
     start_pos: BytePos,
@@ -111,9 +109,14 @@ struct StringReader<'psess, 'src> {
     /// Track the `Span` for the leading `'` of the last lifetime. Used for
     /// diagnostics to detect possible typo where `"` was meant.
     last_lifetime: Option<Span>,
+
+    /// The current token.
+    token: Token,
+
+    diag_info: TokenTreeDiagInfo,
 }
 
-impl<'psess, 'src> StringReader<'psess, 'src> {
+impl<'psess, 'src> Lexer<'psess, 'src> {
     fn dcx(&self) -> DiagCtxtHandle<'psess> {
         self.psess.dcx()
     }
@@ -124,7 +127,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
 
     /// Returns the next token, paired with a bool indicating if the token was
     /// preceded by whitespace.
-    fn next_token(&mut self) -> (Token, bool) {
+    fn next_token_from_cursor(&mut self) -> (Token, bool) {
         let mut preceded_by_whitespace = false;
         let mut swallow_next_invalid = 0;
         // Skip trivial (whitespace & comments) tokens
@@ -231,7 +234,8 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
                         .push(span);
                     token::Ident(sym, IdentIsRaw::No)
                 }
-                // split up (raw) c string literals to an ident and a string literal when edition < 2021.
+                // split up (raw) c string literals to an ident and a string literal when edition <
+                // 2021.
                 rustc_lexer::TokenKind::Literal {
                     kind: kind @ (LiteralKind::CStr { .. } | LiteralKind::RawCStr { .. }),
                     suffix_start: _,
@@ -252,7 +256,9 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
                     let prefix_span = self.mk_sp(start, lit_start);
                     return (Token::new(self.ident(start), prefix_span), preceded_by_whitespace);
                 }
-                rustc_lexer::TokenKind::GuardedStrPrefix => self.maybe_report_guarded_str(start, str_before),
+                rustc_lexer::TokenKind::GuardedStrPrefix => {
+                    self.maybe_report_guarded_str(start, str_before)
+                }
                 rustc_lexer::TokenKind::Literal { kind, suffix_start } => {
                     let suffix_start = start + BytePos(suffix_start);
                     let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind);
@@ -296,13 +302,20 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
                     if prefix_span.at_least_rust_2021() {
                         let span = self.mk_sp(start, self.pos);
 
-                        let lifetime_name_without_tick = Symbol::intern(&self.str_from(ident_start));
+                        let lifetime_name_without_tick =
+                            Symbol::intern(&self.str_from(ident_start));
                         if !lifetime_name_without_tick.can_be_raw() {
-                            self.dcx().emit_err(errors::CannotBeRawLifetime { span, ident: lifetime_name_without_tick });
+                            self.dcx().emit_err(
+                                errors::CannotBeRawLifetime {
+                                    span,
+                                    ident: lifetime_name_without_tick
+                                }
+                            );
                         }
 
                         // Put the `'` back onto the lifetime name.
-                        let mut lifetime_name = String::with_capacity(lifetime_name_without_tick.as_str().len() + 1);
+                        let mut lifetime_name =
+                            String::with_capacity(lifetime_name_without_tick.as_str().len() + 1);
                         lifetime_name.push('\'');
                         lifetime_name += lifetime_name_without_tick.as_str();
                         let sym = Symbol::intern(&lifetime_name);
diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index 7b21ffacc84..c6c9eb3b0b2 100644
--- a/compiler/rustc_parse/src/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -4,41 +4,19 @@ use rustc_ast_pretty::pprust::token_to_string;
 use rustc_errors::{Applicability, PErr};
 use rustc_span::symbol::kw;
 
-use super::diagnostics::{
-    TokenTreeDiagInfo, report_suspicious_mismatch_block, same_indentation_level,
-};
-use super::{StringReader, UnmatchedDelim};
+use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level};
+use super::{Lexer, UnmatchedDelim};
 use crate::Parser;
 
-pub(super) struct TokenTreesReader<'psess, 'src> {
-    string_reader: StringReader<'psess, 'src>,
-    /// The "next" token, which has been obtained from the `StringReader` but
-    /// not yet handled by the `TokenTreesReader`.
-    token: Token,
-    diag_info: TokenTreeDiagInfo,
-}
-
-impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
-    pub(super) fn lex_all_token_trees(
-        string_reader: StringReader<'psess, 'src>,
-    ) -> (TokenStream, Result<(), Vec<PErr<'psess>>>, Vec<UnmatchedDelim>) {
-        let mut tt_reader = TokenTreesReader {
-            string_reader,
-            token: Token::dummy(),
-            diag_info: TokenTreeDiagInfo::default(),
-        };
-        let (_open_spacing, stream, res) = tt_reader.lex_token_trees(/* is_delimited */ false);
-        (stream, res, tt_reader.diag_info.unmatched_delims)
-    }
-
+impl<'psess, 'src> Lexer<'psess, 'src> {
     // Lex into a token stream. The `Spacing` in the result is that of the
     // opening delimiter.
-    fn lex_token_trees(
+    pub(super) fn lex_token_trees(
         &mut self,
         is_delimited: bool,
     ) -> (Spacing, TokenStream, Result<(), Vec<PErr<'psess>>>) {
         // Move past the opening delimiter.
-        let (_, open_spacing) = self.bump(false);
+        let open_spacing = self.bump_minimal();
 
         let mut buf = Vec::new();
         loop {
@@ -71,7 +49,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
                 }
                 _ => {
                     // Get the next normal token.
-                    let (this_tok, this_spacing) = self.bump(true);
+                    let (this_tok, this_spacing) = self.bump();
                     buf.push(TokenTree::Token(this_tok, this_spacing));
                 }
             }
@@ -80,7 +58,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
 
     fn eof_err(&mut self) -> PErr<'psess> {
         let msg = "this file contains an unclosed delimiter";
-        let mut err = self.string_reader.dcx().struct_span_err(self.token.span, msg);
+        let mut err = self.dcx().struct_span_err(self.token.span, msg);
 
         let unclosed_delimiter_show_limit = 5;
         let len = usize::min(unclosed_delimiter_show_limit, self.diag_info.open_braces.len());
@@ -110,7 +88,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
             report_suspicious_mismatch_block(
                 &mut err,
                 &self.diag_info,
-                self.string_reader.psess.source_map(),
+                self.psess.source_map(),
                 *delim,
             )
         }
@@ -136,7 +114,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
 
         // Expand to cover the entire delimited token tree.
         let delim_span = DelimSpan::from_pair(pre_span, self.token.span);
-        let sm = self.string_reader.psess.source_map();
+        let sm = self.psess.source_map();
 
         let close_spacing = match self.token.kind {
             // Correct delimiter.
@@ -160,7 +138,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
                 }
 
                 // Move past the closing delimiter.
-                self.bump(false).1
+                self.bump_minimal()
             }
             // Incorrect delimiter.
             token::CloseDelim(close_delim) => {
@@ -203,7 +181,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
                 //     bar(baz(
                 // }  // Incorrect delimiter but matches the earlier `{`
                 if !self.diag_info.open_braces.iter().any(|&(b, _)| b == close_delim) {
-                    self.bump(false).1
+                    self.bump_minimal()
                 } else {
                     // The choice of value here doesn't matter.
                     Spacing::Alone
@@ -225,14 +203,14 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
     }
 
     // Move on to the next token, returning the current token and its spacing.
-    // Will glue adjacent single-char tokens together if `glue` is set.
-    fn bump(&mut self, glue: bool) -> (Token, Spacing) {
+    // Will glue adjacent single-char tokens together.
+    fn bump(&mut self) -> (Token, Spacing) {
         let (this_spacing, next_tok) = loop {
-            let (next_tok, is_next_tok_preceded_by_whitespace) = self.string_reader.next_token();
+            let (next_tok, is_next_tok_preceded_by_whitespace) = self.next_token_from_cursor();
 
             if is_next_tok_preceded_by_whitespace {
                 break (Spacing::Alone, next_tok);
-            } else if glue && let Some(glued) = self.token.glue(&next_tok) {
+            } else if let Some(glued) = self.token.glue(&next_tok) {
                 self.token = glued;
             } else {
                 let this_spacing = if next_tok.is_punct() {
@@ -249,6 +227,26 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
         (this_tok, this_spacing)
     }
 
+    // Cut-down version of `bump` used when the token kind is known in advance.
+    fn bump_minimal(&mut self) -> Spacing {
+        let (next_tok, is_next_tok_preceded_by_whitespace) = self.next_token_from_cursor();
+
+        let this_spacing = if is_next_tok_preceded_by_whitespace {
+            Spacing::Alone
+        } else {
+            if next_tok.is_punct() {
+                Spacing::Joint
+            } else if next_tok == token::Eof {
+                Spacing::Alone
+            } else {
+                Spacing::JointHidden
+            }
+        };
+
+        self.token = next_tok;
+        this_spacing
+    }
+
     fn unclosed_delim_err(
         &mut self,
         tts: TokenStream,
@@ -256,7 +254,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
     ) -> Vec<PErr<'psess>> {
         // If there are unclosed delims, see if there are diff markers and if so, point them
         // out instead of complaining about the unclosed delims.
-        let mut parser = Parser::new(self.string_reader.psess, tts, None);
+        let mut parser = Parser::new(self.psess, tts, None);
         let mut diff_errs = vec![];
         // Suggest removing a `{` we think appears in an `if`/`while` condition.
         // We want to suggest removing a `{` only if we think we're in an `if`/`while` condition,
@@ -314,14 +312,9 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
         // An unexpected closing delimiter (i.e., there is no matching opening delimiter).
         let token_str = token_to_string(&self.token);
         let msg = format!("unexpected closing delimiter: `{token_str}`");
-        let mut err = self.string_reader.dcx().struct_span_err(self.token.span, msg);
+        let mut err = self.dcx().struct_span_err(self.token.span, msg);
 
-        report_suspicious_mismatch_block(
-            &mut err,
-            &self.diag_info,
-            self.string_reader.psess.source_map(),
-            delim,
-        );
+        report_suspicious_mismatch_block(&mut err, &self.diag_info, self.psess.source_map(), delim);
         err.span_label(self.token.span, "unexpected closing delimiter");
         err
     }
diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs
index d78b3664b1e..42eef27803e 100644
--- a/compiler/rustc_parse/src/lexer/unicode_chars.rs
+++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs
@@ -4,7 +4,7 @@
 use rustc_span::symbol::kw;
 use rustc_span::{BytePos, Pos, Span};
 
-use super::StringReader;
+use super::Lexer;
 use crate::errors::TokenSubstitution;
 use crate::token::{self, Delimiter};
 
@@ -338,7 +338,7 @@ const ASCII_ARRAY: &[(&str, &str, Option<token::TokenKind>)] = &[
 ];
 
 pub(super) fn check_for_substitution(
-    reader: &StringReader<'_, '_>,
+    lexer: &Lexer<'_, '_>,
     pos: BytePos,
     ch: char,
     count: usize,
@@ -351,11 +351,11 @@ pub(super) fn check_for_substitution(
 
     let Some((_, ascii_name, token)) = ASCII_ARRAY.iter().find(|&&(s, _, _)| s == ascii_str) else {
         let msg = format!("substitution character not found for '{ch}'");
-        reader.dcx().span_bug(span, msg);
+        lexer.dcx().span_bug(span, msg);
     };
 
     // special help suggestion for "directed" double quotes
-    let sugg = if let Some(s) = peek_delimited(&reader.src[reader.src_index(pos)..], '“', '”') {
+    let sugg = if let Some(s) = peek_delimited(&lexer.src[lexer.src_index(pos)..], '“', '”') {
         let span = Span::with_root_ctxt(
             pos,
             pos + Pos::from_usize('“'.len_utf8() + s.len() + '”'.len_utf8()),
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 5aebe716b0a..76ecb77d750 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -1,6 +1,7 @@
 use ast::token::Delimiter;
 use rustc_ast::{
-    self as ast, AttrVec, GenericBounds, GenericParam, GenericParamKind, TyKind, WhereClause, token,
+    self as ast, AttrVec, DUMMY_NODE_ID, GenericBounds, GenericParam, GenericParamKind, TyKind,
+    WhereClause, token,
 };
 use rustc_errors::{Applicability, PResult};
 use rustc_span::Span;
@@ -14,8 +15,8 @@ use crate::errors::{
     WhereClauseBeforeTupleStructBodySugg,
 };
 
-enum PredicateOrStructBody {
-    Predicate(ast::WherePredicate),
+enum PredicateKindOrStructBody {
+    PredicateKind(ast::WherePredicateKind),
     StructBody(ThinVec<ast::FieldDef>),
 }
 
@@ -218,10 +219,11 @@ impl<'a> Parser<'a> {
                 } else if this.token.can_begin_type() {
                     // Trying to write an associated type bound? (#26271)
                     let snapshot = this.create_snapshot_for_diagnostic();
-                    match this.parse_ty_where_predicate() {
-                        Ok(where_predicate) => {
+                    let lo = this.token.span;
+                    match this.parse_ty_where_predicate_kind() {
+                        Ok(_) => {
                             this.dcx().emit_err(errors::BadAssocTypeBounds {
-                                span: where_predicate.span(),
+                                span: lo.to(this.prev_token.span),
                             });
                             // FIXME - try to continue parsing other generics?
                         }
@@ -340,31 +342,33 @@ impl<'a> Parser<'a> {
         loop {
             let where_sp = where_lo.to(self.prev_token.span);
             let pred_lo = self.token.span;
-            if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
+            let kind = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
                 let lifetime = self.expect_lifetime();
                 // Bounds starting with a colon are mandatory, but possibly empty.
                 self.expect(&token::Colon)?;
                 let bounds = self.parse_lt_param_bounds();
-                where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
-                    ast::WhereRegionPredicate {
-                        span: pred_lo.to(self.prev_token.span),
-                        lifetime,
-                        bounds,
-                    },
-                ));
+                ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
+                    lifetime,
+                    bounds,
+                })
             } else if self.check_type() {
-                match self.parse_ty_where_predicate_or_recover_tuple_struct_body(
+                match self.parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
                     struct_, pred_lo, where_sp,
                 )? {
-                    PredicateOrStructBody::Predicate(pred) => where_clause.predicates.push(pred),
-                    PredicateOrStructBody::StructBody(body) => {
+                    PredicateKindOrStructBody::PredicateKind(kind) => kind,
+                    PredicateKindOrStructBody::StructBody(body) => {
                         tuple_struct_body = Some(body);
                         break;
                     }
                 }
             } else {
                 break;
-            }
+            };
+            where_clause.predicates.push(ast::WherePredicate {
+                kind,
+                id: DUMMY_NODE_ID,
+                span: pred_lo.to(self.prev_token.span),
+            });
 
             let prev_token = self.prev_token.span;
             let ate_comma = self.eat(&token::Comma);
@@ -384,12 +388,12 @@ impl<'a> Parser<'a> {
         Ok((where_clause, tuple_struct_body))
     }
 
-    fn parse_ty_where_predicate_or_recover_tuple_struct_body(
+    fn parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
         &mut self,
         struct_: Option<(Ident, Span)>,
         pred_lo: Span,
         where_sp: Span,
-    ) -> PResult<'a, PredicateOrStructBody> {
+    ) -> PResult<'a, PredicateKindOrStructBody> {
         let mut snapshot = None;
 
         if let Some(struct_) = struct_
@@ -399,8 +403,8 @@ impl<'a> Parser<'a> {
             snapshot = Some((struct_, self.create_snapshot_for_diagnostic()));
         };
 
-        match self.parse_ty_where_predicate() {
-            Ok(pred) => Ok(PredicateOrStructBody::Predicate(pred)),
+        match self.parse_ty_where_predicate_kind() {
+            Ok(pred) => Ok(PredicateKindOrStructBody::PredicateKind(pred)),
             Err(type_err) => {
                 let Some(((struct_name, body_insertion_point), mut snapshot)) = snapshot else {
                     return Err(type_err);
@@ -436,7 +440,7 @@ impl<'a> Parser<'a> {
                         });
 
                         self.restore_snapshot(snapshot);
-                        Ok(PredicateOrStructBody::StructBody(body))
+                        Ok(PredicateKindOrStructBody::StructBody(body))
                     }
                     Ok(_) => Err(type_err),
                     Err(body_err) => {
@@ -448,8 +452,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn parse_ty_where_predicate(&mut self) -> PResult<'a, ast::WherePredicate> {
-        let lo = self.token.span;
+    fn parse_ty_where_predicate_kind(&mut self) -> PResult<'a, ast::WherePredicateKind> {
         // Parse optional `for<'a, 'b>`.
         // This `for` is parsed greedily and applies to the whole predicate,
         // the bounded type can have its own `for` applying only to it.
@@ -464,8 +467,7 @@ impl<'a> Parser<'a> {
         let ty = self.parse_ty_for_where_clause()?;
         if self.eat(&token::Colon) {
             let bounds = self.parse_generic_bounds()?;
-            Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                span: lo.to(self.prev_token.span),
+            Ok(ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
                 bound_generic_params: lifetime_defs,
                 bounded_ty: ty,
                 bounds,
@@ -474,11 +476,7 @@ impl<'a> Parser<'a> {
         // FIXME: We are just dropping the binders in lifetime_defs on the floor here.
         } else if self.eat(&token::Eq) || self.eat(&token::EqEq) {
             let rhs_ty = self.parse_ty()?;
-            Ok(ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
-                span: lo.to(self.prev_token.span),
-                lhs_ty: ty,
-                rhs_ty,
-            }))
+            Ok(ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { lhs_ty: ty, rhs_ty }))
         } else {
             self.maybe_recover_bounds_doubled_colon(&ty)?;
             self.unexpected_any()
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index fddbf5896ad..26e81b7676b 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1791,6 +1791,17 @@ impl<'a> Parser<'a> {
         Ok((fields, recovered))
     }
 
+    fn parse_unsafe_field(&mut self) -> Safety {
+        // not using parse_safety as that also accepts `safe`.
+        if self.eat_keyword(kw::Unsafe) {
+            let span = self.prev_token.span;
+            self.psess.gated_spans.gate(sym::unsafe_fields, span);
+            Safety::Unsafe(span)
+        } else {
+            Safety::Default
+        }
+    }
+
     pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> {
         // This is the case where we find `struct Foo<T>(T) where T: Copy;`
         // Unit like structs are handled in parse_item_struct function
@@ -1814,6 +1825,8 @@ impl<'a> Parser<'a> {
                         return Err(err);
                     }
                 };
+                // Unsafe fields are not supported in tuple structs, as doing so would result in a
+                // parsing ambiguity for `struct X(unsafe fn())`.
                 let ty = match p.parse_ty() {
                     Ok(ty) => ty,
                     Err(err) => {
@@ -1828,6 +1841,7 @@ impl<'a> Parser<'a> {
                     FieldDef {
                         span: lo.to(ty.span),
                         vis,
+                        safety: Safety::Default,
                         ident: None,
                         id: DUMMY_NODE_ID,
                         ty,
@@ -1850,7 +1864,8 @@ impl<'a> Parser<'a> {
         self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
             let lo = this.token.span;
             let vis = this.parse_visibility(FollowedByType::No)?;
-            this.parse_single_struct_field(adt_ty, lo, vis, attrs)
+            let safety = this.parse_unsafe_field();
+            this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs)
                 .map(|field| (field, Trailing::No, UsePreAttrPos::No))
         })
     }
@@ -1861,10 +1876,11 @@ impl<'a> Parser<'a> {
         adt_ty: &str,
         lo: Span,
         vis: Visibility,
+        safety: Safety,
         attrs: AttrVec,
     ) -> PResult<'a, FieldDef> {
         let mut seen_comma: bool = false;
-        let a_var = self.parse_name_and_ty(adt_ty, lo, vis, attrs)?;
+        let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?;
         if self.token == token::Comma {
             seen_comma = true;
         }
@@ -1992,6 +2008,7 @@ impl<'a> Parser<'a> {
         adt_ty: &str,
         lo: Span,
         vis: Visibility,
+        safety: Safety,
         attrs: AttrVec,
     ) -> PResult<'a, FieldDef> {
         let name = self.parse_field_ident(adt_ty, lo)?;
@@ -2017,6 +2034,7 @@ impl<'a> Parser<'a> {
             span: lo.to(self.prev_token.span),
             ident: Some(name),
             vis,
+            safety,
             id: DUMMY_NODE_ID,
             ty,
             attrs,
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index c4326427f67..004b5b34813 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -1,11 +1,12 @@
 use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token};
+use rustc_ast::util::parser::AssocOp;
 use rustc_ast::visit::{self, Visitor};
 use rustc_ast::{
-    self as ast, Arm, AttrVec, BinOpKind, BindingMode, ByRef, Expr, ExprKind, ExprPrecedence,
-    LocalKind, MacCall, Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd,
-    RangeSyntax, Stmt, StmtKind,
+    self as ast, Arm, AttrVec, BinOpKind, BindingMode, ByRef, Expr, ExprKind, LocalKind, MacCall,
+    Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt,
+    StmtKind,
 };
 use rustc_ast_pretty::pprust;
 use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey};
@@ -458,7 +459,7 @@ impl<'a> Parser<'a> {
                 .create_err(UnexpectedExpressionInPattern {
                     span,
                     is_bound,
-                    expr_precedence: expr.precedence().order(),
+                    expr_precedence: expr.precedence(),
                 })
                 .stash(span, StashKey::ExprInPat)
                 .unwrap(),
@@ -545,7 +546,8 @@ impl<'a> Parser<'a> {
                             let expr = match &err.args["expr_precedence"] {
                                 DiagArgValue::Number(expr_precedence) => {
                                     if *expr_precedence
-                                        <= ExprPrecedence::Binary(BinOpKind::Eq).order() as i32
+                                        <= AssocOp::from_ast_binop(BinOpKind::Eq).precedence()
+                                            as i32
                                     {
                                         format!("({expr})")
                                     } else {
@@ -568,8 +570,9 @@ impl<'a> Parser<'a> {
                                 }
                                 Some(guard) => {
                                     // Are parentheses required around the old guard?
-                                    let wrap_guard = guard.precedence().order()
-                                        <= ExprPrecedence::Binary(BinOpKind::And).order();
+                                    let wrap_guard = guard.precedence()
+                                        <= AssocOp::from_ast_binop(BinOpKind::And).precedence()
+                                            as i8;
 
                                     err.subdiagnostic(
                                         UnexpectedExpressionInPatternSugg::UpdateGuard {
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 08098ae7f6c..0712af422ad 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -558,6 +558,10 @@ passes_no_mangle_foreign =
 passes_no_patterns =
     patterns not allowed in naked function parameters
 
+passes_no_sanitize =
+    `#[no_sanitize({$attr_str})]` should be applied to {$accepted_kind}
+    .label = not {$accepted_kind}
+
 passes_non_exported_macro_invalid_attrs =
     attribute should be applied to function or closure
     .label = not a function or closure
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 87069e0b057..074fe77324f 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -126,9 +126,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 [sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
                 [sym::coverage, ..] => self.check_coverage(attr, span, target),
                 [sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target),
-                [sym::no_sanitize, ..] => {
-                    self.check_applied_to_fn_or_method(hir_id, attr, span, target)
-                }
+                [sym::no_sanitize, ..] => self.check_no_sanitize(attr, span, target),
                 [sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target),
                 [sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
                 [sym::target_feature, ..] => {
@@ -450,6 +448,39 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
+    fn check_no_sanitize(&self, attr: &Attribute, span: Span, target: Target) {
+        if let Some(list) = attr.meta_item_list() {
+            for item in list.iter() {
+                let sym = item.name_or_empty();
+                match sym {
+                    sym::address | sym::hwaddress => {
+                        let is_valid =
+                            matches!(target, Target::Fn | Target::Method(..) | Target::Static);
+                        if !is_valid {
+                            self.dcx().emit_err(errors::NoSanitize {
+                                attr_span: item.span(),
+                                defn_span: span,
+                                accepted_kind: "a function or static",
+                                attr_str: sym.as_str(),
+                            });
+                        }
+                    }
+                    _ => {
+                        let is_valid = matches!(target, Target::Fn | Target::Method(..));
+                        if !is_valid {
+                            self.dcx().emit_err(errors::NoSanitize {
+                                attr_span: item.span(),
+                                defn_span: span,
+                                accepted_kind: "a function",
+                                attr_str: sym.as_str(),
+                            });
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     fn check_generic_attr(
         &self,
         hir_id: HirId,
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 2d1734c0314..fbf25cb476a 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1846,3 +1846,14 @@ pub(crate) struct AttrCrateLevelOnlySugg {
     #[primary_span]
     pub attr: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(passes_no_sanitize)]
+pub(crate) struct NoSanitize<'a> {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub defn_span: Span,
+    pub accepted_kind: &'a str,
+    pub attr_str: &'a str,
+}
diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs
index db34189be2a..b8f66a2b2ec 100644
--- a/compiler/rustc_passes/src/input_stats.rs
+++ b/compiler/rustc_passes/src/input_stats.rs
@@ -360,11 +360,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_where_predicate(&mut self, p: &'v hir::WherePredicate<'v>) {
-        record_variants!((self, p, p, None, hir, WherePredicate, WherePredicate), [
-            BoundPredicate,
-            RegionPredicate,
-            EqPredicate
-        ]);
+        record_variants!(
+            (self, p, p.kind, Some(p.hir_id), hir, WherePredicate, WherePredicateKind),
+            [BoundPredicate, RegionPredicate, EqPredicate]
+        );
         hir_visit::walk_where_predicate(self, p)
     }
 
@@ -611,7 +610,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_where_predicate(&mut self, p: &'v ast::WherePredicate) {
-        record_variants!((self, p, p, None, ast, WherePredicate, WherePredicate), [
+        record_variants!((self, p, &p.kind, None, ast, WherePredicate, WherePredicateKind), [
             BoundPredicate,
             RegionPredicate,
             EqPredicate
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 4a793f1875e..2809ad453ff 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -590,16 +590,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
     }
 
     fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) {
-        // if the const impl is derived using the `derive_const` attribute,
-        // then it would be "stable" at least for the impl.
-        // We gate usages of it using `feature(const_trait_impl)` anyways
-        // so there is no unstable leakage
-        if self.tcx.is_automatically_derived(def_id.to_def_id()) {
-            return;
-        }
-
-        let is_const = self.tcx.is_const_fn(def_id.to_def_id())
-            || self.tcx.is_const_trait_impl(def_id.to_def_id());
+        let is_const = self.tcx.is_const_fn(def_id.to_def_id());
 
         // Reachable const fn must have a stability attribute.
         if is_const
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index cc0763ac751..009d817a1a9 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -9,7 +9,6 @@ use rustc_index::{Idx, IndexVec};
 use rustc_middle::middle::stability::EvalResult;
 use rustc_middle::mir::{self, Const};
 use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary};
-use rustc_middle::traits::Reveal;
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{
     self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef,
@@ -86,7 +85,7 @@ pub struct RustcPatCtxt<'p, 'tcx: 'p> {
     /// not. E.g., `struct Foo { _private: ! }` cannot be seen to be empty
     /// outside its module and should not be matchable with an empty match statement.
     pub module: DefId,
-    pub param_env: ty::ParamEnv<'tcx>,
+    pub typing_env: ty::TypingEnv<'tcx>,
     /// To allocate the result of `self.ctor_sub_tys()`
     pub dropless_arena: &'p DroplessArena,
     /// Lint level at the match.
@@ -109,20 +108,11 @@ impl<'p, 'tcx: 'p> fmt::Debug for RustcPatCtxt<'p, 'tcx> {
 }
 
 impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
-    pub fn typing_mode(&self) -> ty::TypingMode<'tcx> {
-        debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing);
-        // FIXME(#132279): This is inside of a body. If we need to use the `param_env`
-        // and `typing_mode` we should reveal opaques defined by that body.
-        ty::TypingMode::non_body_analysis()
-    }
-
-    pub fn typing_env(&self) -> ty::TypingEnv<'tcx> {
-        ty::TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env }
-    }
-
     /// Type inference occasionally gives us opaque types in places where corresponding patterns
     /// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited
     /// types, we use the corresponding concrete type if possible.
+    // FIXME(#132279): This will be unnecessary once we have a TypingMode which supports revealing
+    // opaque types defined in a body.
     #[inline]
     pub fn reveal_opaque_ty(&self, ty: Ty<'tcx>) -> RevealedTy<'tcx> {
         fn reveal_inner<'tcx>(cx: &RustcPatCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> RevealedTy<'tcx> {
@@ -151,7 +141,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
     pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
         !ty.inhabited_predicate(self.tcx).apply_revealing_opaque(
             self.tcx,
-            self.typing_env(),
+            self.typing_env,
             self.module,
             &|key| self.reveal_opaque_key(key),
         )
@@ -191,7 +181,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
         variant.fields.iter().map(move |field| {
             let ty = field.ty(self.tcx, args);
             // `field.ty()` doesn't normalize after instantiating.
-            let ty = self.tcx.normalize_erasing_regions(self.typing_env(), ty);
+            let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty);
             let ty = self.reveal_opaque_ty(ty);
             (field, ty)
         })
@@ -381,7 +371,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                         let is_inhabited = v
                             .inhabited_predicate(cx.tcx, *def)
                             .instantiate(cx.tcx, args)
-                            .apply_revealing_opaque(cx.tcx, cx.typing_env(), cx.module, &|key| {
+                            .apply_revealing_opaque(cx.tcx, cx.typing_env, cx.module, &|key| {
                                 cx.reveal_opaque_key(key)
                             });
                         // Variants that depend on a disabled unstable feature.
@@ -442,7 +432,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
         match bdy {
             PatRangeBoundary::NegInfinity => MaybeInfiniteInt::NegInfinity,
             PatRangeBoundary::Finite(value) => {
-                let bits = value.eval_bits(self.tcx, self.typing_env());
+                let bits = value.eval_bits(self.tcx, self.typing_env);
                 match *ty.kind() {
                     ty::Int(ity) => {
                         let size = Integer::from_int_ty(&self.tcx, ity).size().bits();
@@ -551,7 +541,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
             PatKind::Constant { value } => {
                 match ty.kind() {
                     ty::Bool => {
-                        ctor = match value.try_eval_bool(cx.tcx, cx.typing_env()) {
+                        ctor = match value.try_eval_bool(cx.tcx, cx.typing_env) {
                             Some(b) => Bool(b),
                             None => Opaque(OpaqueId::new()),
                         };
@@ -559,7 +549,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                         arity = 0;
                     }
                     ty::Char | ty::Int(_) | ty::Uint(_) => {
-                        ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) {
+                        ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) {
                             Some(bits) => {
                                 let x = match *ty.kind() {
                                     ty::Int(ity) => {
@@ -576,7 +566,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                         arity = 0;
                     }
                     ty::Float(ty::FloatTy::F16) => {
-                        ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) {
+                        ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) {
                             Some(bits) => {
                                 use rustc_apfloat::Float;
                                 let value = rustc_apfloat::ieee::Half::from_bits(bits);
@@ -588,7 +578,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                         arity = 0;
                     }
                     ty::Float(ty::FloatTy::F32) => {
-                        ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) {
+                        ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) {
                             Some(bits) => {
                                 use rustc_apfloat::Float;
                                 let value = rustc_apfloat::ieee::Single::from_bits(bits);
@@ -600,7 +590,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                         arity = 0;
                     }
                     ty::Float(ty::FloatTy::F64) => {
-                        ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) {
+                        ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) {
                             Some(bits) => {
                                 use rustc_apfloat::Float;
                                 let value = rustc_apfloat::ieee::Double::from_bits(bits);
@@ -612,7 +602,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                         arity = 0;
                     }
                     ty::Float(ty::FloatTy::F128) => {
-                        ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) {
+                        ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) {
                             Some(bits) => {
                                 use rustc_apfloat::Float;
                                 let value = rustc_apfloat::ieee::Quad::from_bits(bits);
@@ -661,8 +651,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                     }
                     ty::Float(fty) => {
                         use rustc_apfloat::Float;
-                        let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env()));
-                        let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env()));
+                        let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env));
+                        let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env));
                         match fty {
                             ty::FloatTy::F16 => {
                                 use rustc_apfloat::ieee::Half;
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index df898e0587f..a1917fed4d9 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -222,3 +222,9 @@ pub fn query_system<'tcx>(
 }
 
 rustc_middle::rustc_query_append! { define_queries! }
+
+pub fn provide(providers: &mut rustc_middle::util::Providers) {
+    providers.hooks.alloc_self_profile_query_strings =
+        |tcx| alloc_self_profile_query_strings(tcx.tcx);
+    providers.hooks.query_key_hash_verify_all = |tcx| query_key_hash_verify_all(tcx.tcx);
+}
diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs
index 5f989b264aa..7d80e54bf87 100644
--- a/compiler/rustc_query_impl/src/profiling_support.rs
+++ b/compiler/rustc_query_impl/src/profiling_support.rs
@@ -252,6 +252,8 @@ pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) {
         return;
     }
 
+    let _prof_timer = tcx.sess.prof.generic_activity("self_profile_alloc_query_strings");
+
     let mut string_cache = QueryKeyStringCache::new();
 
     for alloc in super::ALLOC_SELF_PROFILE_QUERY_STRINGS.iter() {
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 6602c788969..b13de2875bc 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -257,8 +257,14 @@ resolve_lowercase_self =
     attempt to use a non-constant value in a constant
     .suggestion = try using `Self`
 
+resolve_macro_cannot_use_as_attr =
+    `{$ident}` exists, but a declarative macro cannot be used as an attribute macro
+
+resolve_macro_cannot_use_as_derive =
+     `{$ident}` exists, but a declarative macro cannot be used as a derive macro
+
 resolve_macro_defined_later =
-    a macro with the same name exists, but it appears later at here
+    a macro with the same name exists, but it appears later
 
 resolve_macro_expanded_extern_crate_cannot_shadow_extern_arguments =
     macro-expanded `extern crate` items cannot shadow names passed with `--extern`
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index bf27b767a49..7536869e2fe 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -191,7 +191,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
             ItemKind::Const(..) => DefKind::Const,
             ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn,
             ItemKind::MacroDef(def) => {
-                let edition = self.resolver.tcx.sess.edition();
+                let edition = i.span.edition();
                 let macro_data =
                     self.resolver.compile_macro(def, i.ident, &i.attrs, i.span, i.id, edition);
                 let macro_kind = macro_data.ext.macro_kind();
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 5b78acd904a..4c76617a391 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -35,7 +35,8 @@ use tracing::debug;
 
 use crate::errors::{
     self, AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion, ConsiderAddingADerive,
-    ExplicitUnsafeTraits, MacroDefinedLater, MacroSuggMovePosition, MaybeMissingMacroRulesName,
+    ExplicitUnsafeTraits, MacroDefinedLater, MacroRulesNot, MacroSuggMovePosition,
+    MaybeMissingMacroRulesName,
 };
 use crate::imports::{Import, ImportKind};
 use crate::late::{PatternSource, Rib};
@@ -1473,8 +1474,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             let scope = self.local_macro_def_scopes[&def_id];
             let parent_nearest = parent_scope.module.nearest_parent_mod();
             if Some(parent_nearest) == scope.opt_def_id() {
-                err.subdiagnostic(MacroDefinedLater { span: unused_ident.span });
-                err.subdiagnostic(MacroSuggMovePosition { span: ident.span, ident });
+                match macro_kind {
+                    MacroKind::Bang => {
+                        err.subdiagnostic(MacroDefinedLater { span: unused_ident.span });
+                        err.subdiagnostic(MacroSuggMovePosition { span: ident.span, ident });
+                    }
+                    MacroKind::Attr => {
+                        err.subdiagnostic(MacroRulesNot::Attr { span: unused_ident.span, ident });
+                    }
+                    MacroKind::Derive => {
+                        err.subdiagnostic(MacroRulesNot::Derive { span: unused_ident.span, ident });
+                    }
+                }
+
                 return;
             }
         }
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index f605b7096f0..24f5a812a82 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -666,6 +666,22 @@ pub(crate) struct MacroSuggMovePosition {
 }
 
 #[derive(Subdiagnostic)]
+pub(crate) enum MacroRulesNot {
+    #[label(resolve_macro_cannot_use_as_attr)]
+    Attr {
+        #[primary_span]
+        span: Span,
+        ident: Ident,
+    },
+    #[label(resolve_macro_cannot_use_as_derive)]
+    Derive {
+        #[primary_span]
+        span: Span,
+        ident: Ident,
+    },
+}
+
+#[derive(Subdiagnostic)]
 #[note(resolve_missing_macro_rules_name)]
 pub(crate) struct MaybeMissingMacroRulesName {
     #[primary_span]
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 26b345f5941..60815ffdb1b 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1268,15 +1268,14 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
         debug!("visit_where_predicate {:?}", p);
         let previous_value = replace(&mut self.diag_metadata.current_where_predicate, Some(p));
         self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
-            if let WherePredicate::BoundPredicate(WhereBoundPredicate {
-                ref bounded_ty,
-                ref bounds,
-                ref bound_generic_params,
-                span: predicate_span,
+            if let WherePredicateKind::BoundPredicate(WhereBoundPredicate {
+                bounded_ty,
+                bounds,
+                bound_generic_params,
                 ..
-            }) = p
+            }) = &p.kind
             {
-                let span = predicate_span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());
+                let span = p.span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());
                 this.with_generic_param_rib(
                     bound_generic_params,
                     RibKind::Normal,
@@ -3940,12 +3939,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             }
             Res::SelfCtor(_) => {
                 // We resolve `Self` in pattern position as an ident sometimes during recovery,
-                // so delay a bug instead of ICEing. (Note: is this no longer true? We now ICE. If
-                // this triggers, please convert to a delayed bug and add a test.)
-                self.r.dcx().span_bug(
+                // so delay a bug instead of ICEing.
+                self.r.dcx().span_delayed_bug(
                     ident.span,
                     "unexpected `SelfCtor` in pattern, expected identifier"
                 );
+                None
             }
             _ => span_bug!(
                 ident.span,
@@ -4794,14 +4793,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 let res = self.r.resolve_rustdoc_path(path.as_str(), *ns, self.parent_scope);
                 if let Some(res) = res
                     && let Some(def_id) = res.opt_def_id()
-                    && !def_id.is_local()
-                    && self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
-                    && matches!(
-                        self.r.tcx.sess.opts.resolve_doc_links,
-                        ResolveDocLinks::ExportedMetadata
-                    )
+                    && self.is_invalid_proc_macro_item_for_doc(def_id)
                 {
-                    // Encoding foreign def ids in proc macro crate metadata will ICE.
+                    // Encoding def ids in proc macro crate metadata will ICE,
+                    // because it will only store proc macros for it.
                     return None;
                 }
                 res
@@ -4810,6 +4805,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         res
     }
 
+    fn is_invalid_proc_macro_item_for_doc(&self, did: DefId) -> bool {
+        if !matches!(self.r.tcx.sess.opts.resolve_doc_links, ResolveDocLinks::ExportedMetadata)
+            || !self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
+        {
+            return false;
+        }
+        let Some(local_did) = did.as_local() else { return true };
+        let Some(node_id) = self.r.def_id_to_node_id.get(local_did) else { return true };
+        !self.r.proc_macros.contains(node_id)
+    }
+
     fn resolve_doc_links(&mut self, attrs: &[Attribute], maybe_exported: MaybeExported<'_>) {
         match self.r.tcx.sess.opts.resolve_doc_links {
             ResolveDocLinks::None => return,
@@ -4872,14 +4878,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         .traits_in_scope(None, &self.parent_scope, SyntaxContext::root(), None)
                         .into_iter()
                         .filter_map(|tr| {
-                            if !tr.def_id.is_local()
-                                && self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
-                                && matches!(
-                                    self.r.tcx.sess.opts.resolve_doc_links,
-                                    ResolveDocLinks::ExportedMetadata
-                                )
-                            {
-                                // Encoding foreign def ids in proc macro crate metadata will ICE.
+                            if self.is_invalid_proc_macro_item_for_doc(tr.def_id) {
+                                // Encoding def ids in proc macro crate metadata will ICE.
+                                // because it will only store proc macros for it.
                                 return None;
                             }
                             Some(tr.def_id)
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 09f5a8e96d3..663c3ac0045 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1206,7 +1206,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         let PathSource::TupleStruct(_, _) = source else { return };
         let Some(Res::Def(DefKind::Fn, _)) = res else { return };
         err.primary_message("expected a pattern, found a function call");
-        err.note("function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>");
+        err.note("function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>");
     }
 
     fn suggest_changing_type_to_const_param(
@@ -1317,21 +1317,24 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
     /// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.
     fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diag<'_>) -> bool {
         // Detect that we are actually in a `where` predicate.
-        let (bounded_ty, bounds, where_span) =
-            if let Some(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                bounded_ty,
-                bound_generic_params,
-                bounds,
-                span,
-            })) = self.diag_metadata.current_where_predicate
-            {
-                if !bound_generic_params.is_empty() {
-                    return false;
-                }
-                (bounded_ty, bounds, span)
-            } else {
+        let (bounded_ty, bounds, where_span) = if let Some(ast::WherePredicate {
+            kind:
+                ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
+                    bounded_ty,
+                    bound_generic_params,
+                    bounds,
+                }),
+            span,
+            ..
+        }) = self.diag_metadata.current_where_predicate
+        {
+            if !bound_generic_params.is_empty() {
                 return false;
-            };
+            }
+            (bounded_ty, bounds, span)
+        } else {
+            return false;
+        };
 
         // Confirm that the target is an associated type.
         let (ty, _, path) = if let ast::TyKind::Path(Some(qself), path) = &bounded_ty.kind {
@@ -2840,9 +2843,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                         // for<'a, 'b> T: Trait<T> + 'b
                         // ^^^^^^^^^^^  suggest outer binder `for<'a, 'b>`
                         if let LifetimeBinderKind::WhereBound = kind
-                            && let Some(ast::WherePredicate::BoundPredicate(
+                            && let Some(predicate) = self.diag_metadata.current_where_predicate
+                            && let ast::WherePredicateKind::BoundPredicate(
                                 ast::WhereBoundPredicate { bounded_ty, bounds, .. },
-                            )) = self.diag_metadata.current_where_predicate
+                            ) = &predicate.kind
                             && bounded_ty.id == binder
                         {
                             for bound in bounds {
@@ -3473,7 +3477,6 @@ fn mk_where_bound_predicate(
     };
 
     let new_where_bound_predicate = ast::WhereBoundPredicate {
-        span: DUMMY_SP,
         bound_generic_params: ThinVec::new(),
         bounded_ty: ast::ptr::P(ty.clone()),
         bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef {
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index 893c532f1fb..8fd87893a98 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -84,8 +84,6 @@ session_not_supported = not supported
 
 session_octal_float_literal_not_supported = octal float literal is not supported
 
-session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg}
-
 session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist
 
 session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index d60c56fee75..0124397ea46 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2356,14 +2356,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
         early_dcx.early_warn(format!("number of threads was capped at {}", parse::MAX_THREADS_CAP));
     }
 
-    let fuel = unstable_opts.fuel.is_some() || unstable_opts.print_fuel.is_some();
-    if fuel && unstable_opts.threads > 1 {
-        early_dcx.early_fatal("optimization fuel is incompatible with multiple threads");
-    }
-    if fuel && cg.incremental.is_some() {
-        early_dcx.early_fatal("optimization fuel is incompatible with incremental compilation");
-    }
-
     let incremental = cg.incremental.as_ref().map(PathBuf::from);
 
     let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state);
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 33f84f10447..736a5ce0704 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -464,12 +464,6 @@ pub fn report_lit_error(
 }
 
 #[derive(Diagnostic)]
-#[diag(session_optimization_fuel_exhausted)]
-pub(crate) struct OptimisationFuelExhausted {
-    pub(crate) msg: String,
-}
-
-#[derive(Diagnostic)]
 #[diag(session_incompatible_linker_flavor)]
 #[note]
 pub(crate) struct IncompatibleLinkerFlavor {
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index cbfe5d22f1d..a2d75917c82 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -358,7 +358,7 @@ fn build_options<O: Default>(
 
 #[allow(non_upper_case_globals)]
 mod desc {
-    pub(crate) const parse_no_flag: &str = "no value";
+    pub(crate) const parse_no_value: &str = "no value";
     pub(crate) const parse_bool: &str =
         "one of: `y`, `yes`, `on`, `true`, `n`, `no`, `off` or `false`";
     pub(crate) const parse_opt_bool: &str = parse_bool;
@@ -394,7 +394,6 @@ mod desc {
     pub(crate) const parse_collapse_macro_debuginfo: &str = "one of `no`, `external`, or `yes`";
     pub(crate) const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
     pub(crate) const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
-    pub(crate) const parse_optimization_fuel: &str = "crate=integer";
     pub(crate) const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
     pub(crate) const parse_instrument_coverage: &str = parse_bool;
     pub(crate) const parse_coverage_options: &str =
@@ -462,14 +461,18 @@ pub mod parse {
     pub(crate) use super::*;
     pub(crate) const MAX_THREADS_CAP: usize = 256;
 
-    /// This is for boolean options that don't take a value and start with
-    /// `no-`. This style of option is deprecated.
-    pub(crate) fn parse_no_flag(slot: &mut bool, v: Option<&str>) -> bool {
+    /// This is for boolean options that don't take a value, and are true simply
+    /// by existing on the command-line.
+    ///
+    /// This style of option is deprecated, and is mainly used by old options
+    /// beginning with `no-`.
+    pub(crate) fn parse_no_value(slot: &mut bool, v: Option<&str>) -> bool {
         match v {
             None => {
                 *slot = true;
                 true
             }
+            // Trying to specify a value is always forbidden.
             Some(_) => false,
         }
     }
@@ -944,21 +947,6 @@ pub mod parse {
         true
     }
 
-    pub(crate) fn parse_optimization_fuel(
-        slot: &mut Option<(String, u64)>,
-        v: Option<&str>,
-    ) -> bool {
-        match v {
-            None => false,
-            Some(s) => {
-                let [crate_name, fuel] = *s.split('=').collect::<Vec<_>>() else { return false };
-                let Ok(fuel) = fuel.parse::<u64>() else { return false };
-                *slot = Some((crate_name.to_string(), fuel));
-                true
-            }
-        }
-    }
-
     pub(crate) fn parse_unpretty(slot: &mut Option<String>, v: Option<&str>) -> bool {
         match v {
             None => false,
@@ -1609,16 +1597,16 @@ options! {
         "perform LLVM link-time optimizations"),
     metadata: Vec<String> = (Vec::new(), parse_list, [TRACKED],
         "metadata to mangle symbol names with"),
-    no_prepopulate_passes: bool = (false, parse_no_flag, [TRACKED],
+    no_prepopulate_passes: bool = (false, parse_no_value, [TRACKED],
         "give an empty list of passes to the pass manager"),
     no_redzone: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "disable the use of the redzone"),
     #[rustc_lint_opt_deny_field_access("documented to do nothing")]
-    no_stack_check: bool = (false, parse_no_flag, [UNTRACKED],
+    no_stack_check: bool = (false, parse_no_value, [UNTRACKED],
         "this option is deprecated and does nothing"),
-    no_vectorize_loops: bool = (false, parse_no_flag, [TRACKED],
+    no_vectorize_loops: bool = (false, parse_no_value, [TRACKED],
         "disable loop vectorization optimization passes"),
-    no_vectorize_slp: bool = (false, parse_no_flag, [TRACKED],
+    no_vectorize_slp: bool = (false, parse_no_value, [TRACKED],
         "disable LLVM's SLP vectorization pass"),
     opt_level: String = ("0".to_string(), parse_string, [TRACKED],
         "optimization level (0-3, s, or z; default: 0)"),
@@ -1790,8 +1778,6 @@ options! {
         `shallow` prints only type names, `none` prints nothing and disables `{:?}`. (default: `full`)"),
     force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
         "force all crates to be `rustc_private` unstable (default: no)"),
-    fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
-        "set the optimization fuel quota for a crate"),
     function_return: FunctionReturn = (FunctionReturn::default(), parse_function_return, [TRACKED],
         "replace returns with jumps to `__x86_return_thunk` (default: `keep`)"),
     function_sections: Option<bool> = (None, parse_opt_bool, [TRACKED],
@@ -1915,25 +1901,25 @@ options! {
         "dump facts from NLL analysis into side files (default: no)"),
     nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED],
         "the directory the NLL facts are dumped into (default: `nll-facts`)"),
-    no_analysis: bool = (false, parse_no_flag, [UNTRACKED],
+    no_analysis: bool = (false, parse_no_value, [UNTRACKED],
         "parse and expand the source, but run no analysis"),
-    no_codegen: bool = (false, parse_no_flag, [TRACKED_NO_CRATE_HASH],
+    no_codegen: bool = (false, parse_no_value, [TRACKED_NO_CRATE_HASH],
         "run all passes except codegen; no output"),
-    no_generate_arange_section: bool = (false, parse_no_flag, [TRACKED],
+    no_generate_arange_section: bool = (false, parse_no_value, [TRACKED],
         "omit DWARF address ranges that give faster lookups"),
     no_implied_bounds_compat: bool = (false, parse_bool, [TRACKED],
         "disable the compatibility version of the `implied_bounds_ty` query"),
-    no_jump_tables: bool = (false, parse_no_flag, [TRACKED],
+    no_jump_tables: bool = (false, parse_no_value, [TRACKED],
         "disable the jump tables and lookup tables that can be generated from a switch case lowering"),
-    no_leak_check: bool = (false, parse_no_flag, [UNTRACKED],
+    no_leak_check: bool = (false, parse_no_value, [UNTRACKED],
         "disable the 'leak check' for subtyping; unsound, but useful for tests"),
-    no_link: bool = (false, parse_no_flag, [TRACKED],
+    no_link: bool = (false, parse_no_value, [TRACKED],
         "compile without linking"),
-    no_parallel_backend: bool = (false, parse_no_flag, [UNTRACKED],
+    no_parallel_backend: bool = (false, parse_no_value, [UNTRACKED],
         "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"),
-    no_profiler_runtime: bool = (false, parse_no_flag, [TRACKED],
+    no_profiler_runtime: bool = (false, parse_no_value, [TRACKED],
         "prevent automatic injection of the profiler_builtins crate"),
-    no_trait_vptr: bool = (false, parse_no_flag, [TRACKED],
+    no_trait_vptr: bool = (false, parse_no_value, [TRACKED],
         "disable generation of trait vptr in vtable for upcasting"),
     no_unique_section_names: bool = (false, parse_bool, [TRACKED],
         "do not use unique names for text and data sections when -Z function-sections is used"),
@@ -1974,8 +1960,6 @@ options! {
     #[rustc_lint_opt_deny_field_access("use `Session::print_codegen_stats` instead of this field")]
     print_codegen_stats: bool = (false, parse_bool, [UNTRACKED],
         "print codegen statistics (default: no)"),
-    print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
-        "make rustc print the total optimization fuel used by a crate"),
     print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
         "print the LLVM optimization passes being run (default: no)"),
     print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
@@ -1991,7 +1975,7 @@ options! {
     proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread,
         parse_proc_macro_execution_strategy, [UNTRACKED],
         "how to run proc-macro code (default: same-thread)"),
-    profile_closures: bool = (false, parse_no_flag, [UNTRACKED],
+    profile_closures: bool = (false, parse_no_value, [UNTRACKED],
         "profile size of closures"),
     profile_sample_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
         "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"),
@@ -2165,8 +2149,14 @@ written to standard error output)"),
         "enable unsound and buggy MIR optimizations (default: no)"),
     /// This name is kind of confusing: Most unstable options enable something themselves, while
     /// this just allows "normal" options to be feature-gated.
+    ///
+    /// The main check for `-Zunstable-options` takes place separately from the
+    /// usual parsing of `-Z` options (see [`crate::config::nightly_options`]),
+    /// so this boolean value is mostly used for enabling unstable _values_ of
+    /// stable options. That separate check doesn't handle boolean values, so
+    /// to avoid an inconsistent state we also forbid them here.
     #[rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field")]
-    unstable_options: bool = (false, parse_bool, [UNTRACKED],
+    unstable_options: bool = (false, parse_no_value, [UNTRACKED],
         "adds unstable command line options to rustc interface (default: no)"),
     use_ctors_section: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "use legacy .ctors section for initializers rather than .init_array"),
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 29fabdd1deb..f585410adb9 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -4,7 +4,6 @@ use std::path::{Path, PathBuf};
 use std::str::FromStr;
 use std::sync::Arc;
 use std::sync::atomic::AtomicBool;
-use std::sync::atomic::Ordering::SeqCst;
 use std::{env, fmt, io};
 
 use rustc_data_structures::flock;
@@ -12,7 +11,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_data_structures::jobserver::{self, Client};
 use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef};
 use rustc_data_structures::sync::{
-    AtomicU64, DynSend, DynSync, Lock, Lrc, MappedReadGuard, ReadGuard, RwLock,
+    DynSend, DynSync, Lock, Lrc, MappedReadGuard, ReadGuard, RwLock,
 };
 use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter;
 use rustc_errors::codes::*;
@@ -49,13 +48,6 @@ use crate::parse::{ParseSess, add_feature_diagnostics};
 use crate::search_paths::SearchPath;
 use crate::{errors, filesearch, lint};
 
-struct OptimizationFuel {
-    /// If `-zfuel=crate=n` is specified, initially set to `n`, otherwise `0`.
-    remaining: u64,
-    /// We're rejecting all further optimizations.
-    out_of_fuel: bool,
-}
-
 /// The behavior of the CTFE engine when an error occurs with regards to backtraces.
 #[derive(Clone, Copy)]
 pub enum CtfeBacktrace {
@@ -163,12 +155,6 @@ pub struct Session {
     /// Data about code being compiled, gathered during compilation.
     pub code_stats: CodeStats,
 
-    /// Tracks fuel info if `-zfuel=crate=n` is specified.
-    optimization_fuel: Lock<OptimizationFuel>,
-
-    /// Always set to zero and incremented so that we can print fuel expended by a crate.
-    pub print_fuel: AtomicU64,
-
     /// Loaded up early on in the initialization of this `Session` to avoid
     /// false positives about a job server in our environment.
     pub jobserver: Client,
@@ -532,41 +518,6 @@ impl Session {
         self.opts.incremental.as_ref().map(|_| self.incr_comp_session_dir())
     }
 
-    /// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n.
-    /// This expends fuel if applicable, and records fuel if applicable.
-    pub fn consider_optimizing(
-        &self,
-        get_crate_name: impl Fn() -> Symbol,
-        msg: impl Fn() -> String,
-    ) -> bool {
-        let mut ret = true;
-        if let Some((ref c, _)) = self.opts.unstable_opts.fuel {
-            if c == get_crate_name().as_str() {
-                assert_eq!(self.threads(), 1);
-                let mut fuel = self.optimization_fuel.lock();
-                ret = fuel.remaining != 0;
-                if fuel.remaining == 0 && !fuel.out_of_fuel {
-                    if self.dcx().can_emit_warnings() {
-                        // We only call `msg` in case we can actually emit warnings.
-                        // Otherwise, this could cause a `must_produce_diag` ICE
-                        // (issue #79546).
-                        self.dcx().emit_warn(errors::OptimisationFuelExhausted { msg: msg() });
-                    }
-                    fuel.out_of_fuel = true;
-                } else if fuel.remaining > 0 {
-                    fuel.remaining -= 1;
-                }
-            }
-        }
-        if let Some(ref c) = self.opts.unstable_opts.print_fuel {
-            if c == get_crate_name().as_str() {
-                assert_eq!(self.threads(), 1);
-                self.print_fuel.fetch_add(1, SeqCst);
-            }
-        }
-        ret
-    }
-
     /// Is this edition 2015?
     pub fn is_rust_2015(&self) -> bool {
         self.edition().is_rust_2015()
@@ -1097,12 +1048,6 @@ pub fn build_session(
         Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
     };
 
-    let optimization_fuel = Lock::new(OptimizationFuel {
-        remaining: sopts.unstable_opts.fuel.as_ref().map_or(0, |&(_, i)| i),
-        out_of_fuel: false,
-    });
-    let print_fuel = AtomicU64::new(0);
-
     let prof = SelfProfilerRef::new(
         self_profiler,
         sopts.unstable_opts.time_passes.then(|| sopts.unstable_opts.time_passes_format),
@@ -1130,8 +1075,6 @@ pub fn build_session(
         incr_comp_session: RwLock::new(IncrCompSession::NotInitialized),
         prof,
         code_stats: Default::default(),
-        optimization_fuel,
-        print_fuel,
         jobserver: jobserver::client(),
         lint_store: None,
         registered_lints: false,
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index a326e8583ea..d4b034ea219 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -313,6 +313,7 @@ macro_rules! optional {
 macro_rules! run_driver {
     ($args:expr, $callback:expr $(, $with_tcx:ident)?) => {{
         use rustc_driver::{Callbacks, Compilation, RunCompiler};
+        use rustc_middle::ty::TyCtxt;
         use rustc_interface::{interface, Queries};
         use stable_mir::CompilerError;
         use std::ops::ControlFlow;
@@ -373,23 +374,21 @@ macro_rules! run_driver {
             fn after_analysis<'tcx>(
                 &mut self,
                 _compiler: &interface::Compiler,
-                queries: &'tcx Queries<'tcx>,
+                tcx: TyCtxt<'tcx>,
             ) -> Compilation {
-                queries.global_ctxt().unwrap().enter(|tcx| {
-                    if let Some(callback) = self.callback.take() {
-                        rustc_internal::run(tcx, || {
-                            self.result = Some(callback($(optional!($with_tcx tcx))?));
-                        })
-                        .unwrap();
-                        if self.result.as_ref().is_some_and(|val| val.is_continue()) {
-                            Compilation::Continue
-                        } else {
-                            Compilation::Stop
-                        }
-                    } else {
+                if let Some(callback) = self.callback.take() {
+                    rustc_internal::run(tcx, || {
+                        self.result = Some(callback($(optional!($with_tcx tcx))?));
+                    })
+                    .unwrap();
+                    if self.result.as_ref().is_some_and(|val| val.is_continue()) {
                         Compilation::Continue
+                    } else {
+                        Compilation::Stop
                     }
-                })
+                } else {
+                    Compilation::Continue
+                }
             }
         }
 
diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs
index fe09daf522c..36f9b4cff60 100644
--- a/compiler/rustc_span/src/edition.rs
+++ b/compiler/rustc_span/src/edition.rs
@@ -33,7 +33,7 @@ pub const EDITION_NAME_LIST: &str = "2015|2018|2021|2024";
 
 pub const DEFAULT_EDITION: Edition = Edition::Edition2015;
 
-pub const LATEST_STABLE_EDITION: Edition = Edition::Edition2021;
+pub const LATEST_STABLE_EDITION: Edition = Edition::Edition2024;
 
 impl fmt::Display for Edition {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -62,7 +62,7 @@ impl Edition {
             Edition::Edition2015 => true,
             Edition::Edition2018 => true,
             Edition::Edition2021 => true,
-            Edition::Edition2024 => false,
+            Edition::Edition2024 => true,
         }
     }
 
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 8966cfc9171..1481e1cbd91 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -1829,6 +1829,8 @@ impl StableSourceFileId {
 }
 
 impl SourceFile {
+    const MAX_FILE_SIZE: u32 = u32::MAX - 1;
+
     pub fn new(
         name: FileName,
         mut src: String,
@@ -1849,6 +1851,9 @@ impl SourceFile {
         let stable_id = StableSourceFileId::from_filename_in_current_crate(&name);
         let source_len = src.len();
         let source_len = u32::try_from(source_len).map_err(|_| OffsetOverflowError)?;
+        if source_len > Self::MAX_FILE_SIZE {
+            return Err(OffsetOverflowError);
+        }
 
         let (lines, multibyte_chars) = analyze_source_file::analyze_source_file(&src);
 
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index e74a5c2d8fe..55e106b661b 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -115,6 +115,12 @@ impl FileLoader for RealFileLoader {
     }
 
     fn read_file(&self, path: &Path) -> io::Result<String> {
+        if path.metadata().is_ok_and(|metadata| metadata.len() > SourceFile::MAX_FILE_SIZE.into()) {
+            return Err(io::Error::other(format!(
+                "text files larger than {} bytes are unsupported",
+                SourceFile::MAX_FILE_SIZE
+            )));
+        }
         fs::read_to_string(path)
     }
 
@@ -297,7 +303,10 @@ impl SourceMap {
     /// unmodified.
     pub fn new_source_file(&self, filename: FileName, src: String) -> Lrc<SourceFile> {
         self.try_new_source_file(filename, src).unwrap_or_else(|OffsetOverflowError| {
-            eprintln!("fatal error: rustc does not support files larger than 4GB");
+            eprintln!(
+                "fatal error: rustc does not support text files larger than {} bytes",
+                SourceFile::MAX_FILE_SIZE
+            );
             crate::fatal_error::FatalError.raise()
         })
     }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index a2d9859645f..5252c446e1d 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -416,7 +416,9 @@ symbols! {
         asm,
         asm_const,
         asm_experimental_arch,
+        asm_experimental_reg,
         asm_goto,
+        asm_goto_with_outputs,
         asm_sym,
         asm_unwind,
         assert,
@@ -610,6 +612,7 @@ symbols! {
         const_compare_raw_pointers,
         const_constructor,
         const_deallocate,
+        const_destruct,
         const_eval_limit,
         const_eval_select,
         const_evaluatable_checked,
@@ -1725,7 +1728,6 @@ symbols! {
         rustc_partition_reused,
         rustc_pass_by_value,
         rustc_peek,
-        rustc_peek_definite_init,
         rustc_peek_liveness,
         rustc_peek_maybe_init,
         rustc_peek_maybe_uninit,
@@ -2086,6 +2088,7 @@ symbols! {
         unsafe_cell,
         unsafe_cell_raw_get,
         unsafe_extern_blocks,
+        unsafe_fields,
         unsafe_no_drop_flag,
         unsafe_pin_internals,
         unsize,
@@ -2137,6 +2140,7 @@ symbols! {
         vec_pop,
         vec_with_capacity,
         vecdeque_iter,
+        vector,
         version,
         vfp2,
         vis,
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 10778e9acf1..db8d23776e5 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -604,9 +604,13 @@ impl InlineAsmRegClass {
 
     /// Returns a list of supported types for this register class, each with an
     /// options target feature required to use this type.
+    ///
+    /// At the codegen stage, it is fine to always pass true for `allow_experimental_reg`,
+    /// since all the stability checking will have been done in prior stages.
     pub fn supported_types(
         self,
         arch: InlineAsmArch,
+        allow_experimental_reg: bool,
     ) -> &'static [(InlineAsmType, Option<Symbol>)] {
         match self {
             Self::X86(r) => r.supported_types(arch),
@@ -618,7 +622,7 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.supported_types(arch),
             Self::LoongArch(r) => r.supported_types(arch),
             Self::Mips(r) => r.supported_types(arch),
-            Self::S390x(r) => r.supported_types(arch),
+            Self::S390x(r) => r.supported_types(arch, allow_experimental_reg),
             Self::Sparc(r) => r.supported_types(arch),
             Self::SpirV(r) => r.supported_types(arch),
             Self::Wasm(r) => r.supported_types(arch),
@@ -696,8 +700,11 @@ impl InlineAsmRegClass {
 
     /// Returns whether registers in this class can only be used as clobbers
     /// and not as inputs/outputs.
-    pub fn is_clobber_only(self, arch: InlineAsmArch) -> bool {
-        self.supported_types(arch).is_empty()
+    ///
+    /// At the codegen stage, it is fine to always pass true for `allow_experimental_reg`,
+    /// since all the stability checking will have been done in prior stages.
+    pub fn is_clobber_only(self, arch: InlineAsmArch, allow_experimental_reg: bool) -> bool {
+        self.supported_types(arch, allow_experimental_reg).is_empty()
     }
 }
 
diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
index 9b31190a72b..410590b722b 100644
--- a/compiler/rustc_target/src/asm/s390x.rs
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -38,11 +38,22 @@ impl S390xInlineAsmRegClass {
     pub fn supported_types(
         self,
         _arch: InlineAsmArch,
+        allow_experimental_reg: bool,
     ) -> &'static [(InlineAsmType, Option<Symbol>)] {
         match self {
             Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; },
             Self::freg => types! { _: F32, F64; },
-            Self::vreg => &[],
+            Self::vreg => {
+                if allow_experimental_reg {
+                    // non-clobber-only vector register support is unstable.
+                    types! {
+                        vector: I32, F32, I64, F64, I128, F128,
+                            VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
+                    }
+                } else {
+                    &[]
+                }
+            }
             Self::areg => &[],
         }
     }
diff --git a/compiler/rustc_target/src/callconv/aarch64.rs b/compiler/rustc_target/src/callconv/aarch64.rs
index 55b65fb1caa..67345f0d47b 100644
--- a/compiler/rustc_target/src/callconv/aarch64.rs
+++ b/compiler/rustc_target/src/callconv/aarch64.rs
@@ -1,5 +1,10 @@
+use std::iter;
+
+use rustc_abi::{BackendRepr, Primitive};
+
 use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
 use crate::abi::{HasDataLayout, TyAbiInterface};
+use crate::spec::{HasTargetSpec, Target};
 
 /// Indicates the variant of the AArch64 ABI we are compiling for.
 /// Used to accommodate Apple and Microsoft's deviations from the usual AAPCS ABI.
@@ -15,7 +20,7 @@ pub(crate) enum AbiKind {
 fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
 where
     Ty: TyAbiInterface<'a, C> + Copy,
-    C: HasDataLayout,
+    C: HasDataLayout + HasTargetSpec,
 {
     arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
         let size = arg.layout.size;
@@ -27,7 +32,9 @@ where
 
         let valid_unit = match unit.kind {
             RegKind::Integer => false,
-            RegKind::Float => true,
+            // The softfloat ABI treats floats like integers, so they
+            // do not get homogeneous aggregate treatment.
+            RegKind::Float => cx.target_spec().abi != "softfloat",
             RegKind::Vector => size.bits() == 64 || size.bits() == 128,
         };
 
@@ -35,10 +42,42 @@ where
     })
 }
 
+fn softfloat_float_abi<Ty>(target: &Target, arg: &mut ArgAbi<'_, Ty>) {
+    if target.abi != "softfloat" {
+        return;
+    }
+    // Do *not* use the float registers for passing arguments, as that would make LLVM pick the ABI
+    // and its choice depends on whether `neon` instructions are enabled. Instead, we follow the
+    // AAPCS "softfloat" ABI, which specifies that floats should be passed as equivalently-sized
+    // integers. Nominally this only exists for "R" profile chips, but sometimes people don't want
+    // to use hardfloats even if the hardware supports them, so we do this for all softfloat
+    // targets.
+    if let BackendRepr::Scalar(s) = arg.layout.backend_repr
+        && let Primitive::Float(f) = s.primitive()
+    {
+        arg.cast_to(Reg { kind: RegKind::Integer, size: f.size() });
+    } else if let BackendRepr::ScalarPair(s1, s2) = arg.layout.backend_repr
+        && (matches!(s1.primitive(), Primitive::Float(_))
+            || matches!(s2.primitive(), Primitive::Float(_)))
+    {
+        // This case can only be reached for the Rust ABI, so we can do whatever we want here as
+        // long as it does not depend on target features (i.e., as long as we do not use float
+        // registers). So we pass small things in integer registers and large things via pointer
+        // indirection. This means we lose the nice "pass it as two arguments" optimization, but we
+        // currently just have to way to combine a `PassMode::Cast` with that optimization (and we
+        // need a cast since we want to pass the float as an int).
+        if arg.layout.size.bits() <= target.pointer_width.into() {
+            arg.cast_to(Reg { kind: RegKind::Integer, size: arg.layout.size });
+        } else {
+            arg.make_indirect();
+        }
+    }
+}
+
 fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, kind: AbiKind)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
-    C: HasDataLayout,
+    C: HasDataLayout + HasTargetSpec,
 {
     if !ret.layout.is_sized() {
         // Not touching this...
@@ -51,6 +90,7 @@ where
             // See also: <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-Arguments-to-Functions-Correctly>
             ret.extend_integer_width_to(32)
         }
+        softfloat_float_abi(cx.target_spec(), ret);
         return;
     }
     if let Some(uniform) = is_homogeneous_aggregate(cx, ret) {
@@ -69,7 +109,7 @@ where
 fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, kind: AbiKind)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
-    C: HasDataLayout,
+    C: HasDataLayout + HasTargetSpec,
 {
     if !arg.layout.is_sized() {
         // Not touching this...
@@ -82,6 +122,8 @@ where
             // See also: <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-Arguments-to-Functions-Correctly>
             arg.extend_integer_width_to(32);
         }
+        softfloat_float_abi(cx.target_spec(), arg);
+
         return;
     }
     if let Some(uniform) = is_homogeneous_aggregate(cx, arg) {
@@ -112,7 +154,7 @@ where
 pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, kind: AbiKind)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
-    C: HasDataLayout,
+    C: HasDataLayout + HasTargetSpec,
 {
     if !fn_abi.ret.is_ignore() {
         classify_ret(cx, &mut fn_abi.ret, kind);
@@ -125,3 +167,13 @@ where
         classify_arg(cx, arg, kind);
     }
 }
+
+pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+where
+    Ty: TyAbiInterface<'a, C> + Copy,
+    C: HasDataLayout + HasTargetSpec,
+{
+    for arg in fn_abi.args.iter_mut().chain(iter::once(&mut fn_abi.ret)) {
+        softfloat_float_abi(cx.target_spec(), arg);
+    }
+}
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index aa639f1624f..fb0fe402934 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -738,6 +738,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "x86" => x86::compute_rust_abi_info(cx, self, abi),
             "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self, abi),
             "loongarch64" => loongarch::compute_rust_abi_info(cx, self, abi),
+            "aarch64" => aarch64::compute_rust_abi_info(cx, self),
             _ => {}
         };
 
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 321ab40403a..fead20ec7d1 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2327,8 +2327,6 @@ pub struct TargetOptions {
     /// If we give emcc .o files that are actually .bc files it
     /// will 'just work'.
     pub obj_is_bitcode: bool,
-    /// Whether the target requires that emitted object code includes bitcode.
-    pub forces_embed_bitcode: bool,
     /// Content of the LLVM cmdline section associated with embedded bitcode.
     pub bitcode_llvm_cmdline: StaticCow<str>,
 
@@ -2671,7 +2669,6 @@ impl Default for TargetOptions {
             allow_asm: true,
             has_thread_local: false,
             obj_is_bitcode: false,
-            forces_embed_bitcode: false,
             bitcode_llvm_cmdline: "".into(),
             min_atomic_width: None,
             max_atomic_width: None,
@@ -3412,7 +3409,6 @@ impl Target {
         key!(main_needs_argc_argv, bool);
         key!(has_thread_local, bool);
         key!(obj_is_bitcode, bool);
-        key!(forces_embed_bitcode, bool);
         key!(bitcode_llvm_cmdline);
         key!(max_atomic_width, Option<u64>);
         key!(min_atomic_width, Option<u64>);
@@ -3687,7 +3683,6 @@ impl ToJson for Target {
         target_option_val!(main_needs_argc_argv);
         target_option_val!(has_thread_local);
         target_option_val!(obj_is_bitcode);
-        target_option_val!(forces_embed_bitcode);
         target_option_val!(bitcode_llvm_cmdline);
         target_option_val!(min_atomic_width);
         target_option_val!(max_atomic_width);
diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs
index bd47d12ef9f..3225cdc759d 100644
--- a/compiler/rustc_target/src/spec/tests/tests_impl.rs
+++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs
@@ -1,5 +1,7 @@
 use std::assert_matches::assert_matches;
 
+use rustc_data_structures::fx::FxHashSet;
+
 use super::super::*;
 
 // Test target self-consistency and JSON encoding/decoding roundtrip.
@@ -19,6 +21,9 @@ impl Target {
         if self.is_like_msvc {
             assert!(self.is_like_windows);
         }
+        if self.os == "emscripten" {
+            assert!(self.is_like_wasm);
+        }
 
         // Check that default linker flavor is compatible with some other key properties.
         assert_eq!(self.is_like_osx, matches!(self.linker_flavor, LinkerFlavor::Darwin(..)));
@@ -137,7 +142,7 @@ impl Target {
             assert!(self.dynamic_linking);
         }
         // Apparently PIC was slow on wasm at some point, see comments in wasm_base.rs
-        if self.dynamic_linking && !(self.is_like_wasm && self.os != "emscripten") {
+        if self.dynamic_linking && !self.is_like_wasm {
             assert_eq!(self.relocation_model, RelocModel::Pic);
         }
         if self.position_independent_executables {
@@ -170,6 +175,27 @@ impl Target {
             }
             _ => {}
         }
+
+        // Check that the given target-features string makes some basic sense.
+        if !self.features.is_empty() {
+            let mut features_enabled = FxHashSet::default();
+            let mut features_disabled = FxHashSet::default();
+            for feat in self.features.split(',') {
+                if let Some(feat) = feat.strip_prefix("+") {
+                    features_enabled.insert(feat);
+                    if features_disabled.contains(feat) {
+                        panic!("target feature `{feat}` is both enabled and disabled");
+                    }
+                } else if let Some(feat) = feat.strip_prefix("-") {
+                    features_disabled.insert(feat);
+                    if features_enabled.contains(feat) {
+                        panic!("target feature `{feat}` is both enabled and disabled");
+                    }
+                } else {
+                    panic!("target feature `{feat}` is invalid, must start with `+` or `-`");
+                }
+            }
+        }
     }
 
     // Add your target to the whitelist if it has `std` library
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index 929fa559d75..0f9d4cb1982 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -152,7 +152,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         err: TypeError<'tcx>,
     ) -> Diag<'a> {
         self.report_and_explain_type_error(
-            TypeTrace::types(cause, true, expected, actual),
+            TypeTrace::types(cause, expected, actual),
             param_env,
             err,
         )
@@ -167,7 +167,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         err: TypeError<'tcx>,
     ) -> Diag<'a> {
         self.report_and_explain_type_error(
-            TypeTrace::consts(cause, true, expected, actual),
+            TypeTrace::consts(cause, expected, actual),
             param_env,
             err,
         )
@@ -1792,12 +1792,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
     fn suggest_specify_actual_length(
         &self,
-        terr: TypeError<'_>,
-        trace: &TypeTrace<'_>,
+        terr: TypeError<'tcx>,
+        trace: &TypeTrace<'tcx>,
         span: Span,
     ) -> Option<TypeErrorAdditionalDiags> {
         let hir = self.tcx.hir();
-        let TypeError::FixedArraySize(sz) = terr else {
+        let TypeError::ArraySize(sz) = terr else {
             return None;
         };
         let tykind = match self.tcx.hir_node_by_def_id(trace.cause.body_id) {
@@ -1838,9 +1838,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         if let Some(tykind) = tykind
             && let hir::TyKind::Array(_, length) = tykind
             && let hir::ArrayLen::Body(ct) = length
+            && let Some((scalar, ty)) = sz.found.try_to_scalar()
+            && ty == self.tcx.types.usize
         {
             let span = ct.span();
-            Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { span, length: sz.found })
+            Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength {
+                span,
+                length: scalar.to_target_usize(&self.tcx).unwrap(),
+            })
         } else {
             None
         }
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 4e7d7b79ff4..75191894525 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
@@ -725,7 +725,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     &obligation.cause,
                     None,
                     None,
-                    TypeError::Sorts(ty::error::ExpectedFound::new(true, expected_ty, ct_ty)),
+                    TypeError::Sorts(ty::error::ExpectedFound::new(expected_ty, ct_ty)),
                     false,
                 );
                 diag
@@ -1449,7 +1449,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 secondary_span,
                 values.map(|(_, normalized_ty, expected_ty)| {
                     obligation.param_env.and(infer::ValuePairs::Terms(ExpectedFound::new(
-                        true,
                         expected_ty,
                         normalized_ty,
                     )))
@@ -1804,24 +1803,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 StringPart::highlighted("cargo tree".to_string()),
                 StringPart::normal("` to explore your dependency tree".to_string()),
             ]);
-
-            // FIXME: this is a giant hack for the benefit of this specific diagnostic. Because
-            // we're so nested in method calls before the error gets emitted, bubbling a single bit
-            // flag informing the top level caller to stop adding extra detail to the diagnostic,
-            // would actually be harder to follow. So we do something naughty here: we consume the
-            // diagnostic, emit it and leave in its place a "delayed bug" that will continue being
-            // modified but won't actually be printed to end users. This *is not ideal*, but allows
-            // us to reduce the verbosity of an error that is already quite verbose and increase its
-            // specificity. Below we modify the main message as well, in a way that *could* break if
-            // the implementation of Diagnostics change significantly, but that would be caught with
-            // a make test failure when this diagnostic is tested.
-            err.primary_message(format!(
-                "{} because the trait comes from a different crate version",
-                err.messages[0].0.as_str().unwrap(),
-            ));
-            let diag = err.clone();
-            err.downgrade_to_delayed_bug();
-            self.tcx.dcx().emit_diagnostic(diag);
             return true;
         }
 
@@ -2755,7 +2736,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             (obligation.cause.clone(), terr)
         };
         self.report_and_explain_type_error(
-            TypeTrace::trait_refs(&cause, true, expected_trait_ref, found_trait_ref),
+            TypeTrace::trait_refs(&cause, expected_trait_ref, found_trait_ref),
             obligation.param_env,
             terr,
         )
@@ -2846,7 +2827,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait() && not_tupled
         {
             return Ok(self.report_and_explain_type_error(
-                TypeTrace::trait_refs(&obligation.cause, true, expected_trait_ref, found_trait_ref),
+                TypeTrace::trait_refs(&obligation.cause, expected_trait_ref, found_trait_ref),
                 obligation.param_env,
                 ty::error::TypeError::Mismatch,
             ));
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 5ad15feadff..27b45f70946 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -5312,9 +5312,10 @@ fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
     };
     let name = tcx.item_name(proj.projection_term.def_id);
     let mut predicates = generics.predicates.iter().peekable();
-    let mut prev: Option<&hir::WhereBoundPredicate<'_>> = None;
+    let mut prev: Option<(&hir::WhereBoundPredicate<'_>, Span)> = None;
     while let Some(pred) = predicates.next() {
-        let hir::WherePredicate::BoundPredicate(pred) = pred else {
+        let curr_span = pred.span;
+        let hir::WherePredicateKind::BoundPredicate(pred) = pred.kind else {
             continue;
         };
         let mut bounds = pred.bounds.iter();
@@ -5340,8 +5341,8 @@ fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
                         .iter()
                         .filter(|p| {
                             matches!(
-                                p,
-                                hir::WherePredicate::BoundPredicate(p)
+                                p.kind,
+                                hir::WherePredicateKind::BoundPredicate(p)
                                 if hir::PredicateOrigin::WhereClause == p.origin
                             )
                         })
@@ -5351,20 +5352,21 @@ fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
                     // There's only one `where` bound, that needs to be removed. Remove the whole
                     // `where` clause.
                     generics.where_clause_span
-                } else if let Some(hir::WherePredicate::BoundPredicate(next)) = predicates.peek()
+                } else if let Some(next_pred) = predicates.peek()
+                    && let hir::WherePredicateKind::BoundPredicate(next) = next_pred.kind
                     && pred.origin == next.origin
                 {
                     // There's another bound, include the comma for the current one.
-                    pred.span.until(next.span)
-                } else if let Some(prev) = prev
+                    curr_span.until(next_pred.span)
+                } else if let Some((prev, prev_span)) = prev
                     && pred.origin == prev.origin
                 {
                     // Last bound, try to remove the previous comma.
-                    prev.span.shrink_to_hi().to(pred.span)
+                    prev_span.shrink_to_hi().to(curr_span)
                 } else if pred.origin == hir::PredicateOrigin::WhereClause {
-                    pred.span.with_hi(generics.where_clause_span.hi())
+                    curr_span.with_hi(generics.where_clause_span.hi())
                 } else {
-                    pred.span
+                    curr_span
                 };
 
                 err.span_suggestion_verbose(
@@ -5417,7 +5419,7 @@ fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
                 );
             }
         }
-        prev = Some(pred);
+        prev = Some((pred, curr_span));
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index 2cc787c8bc5..09bba24ba61 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -204,7 +204,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
             // and the obligation is monomorphic, otherwise passes such as
             // transmute checking and polymorphic MIR optimizations could
             // get a result which isn't correct for all monomorphizations.
-            match self.typing_mode_unchecked() {
+            match self.typing_mode() {
                 TypingMode::Coherence | TypingMode::Analysis { .. } => false,
                 TypingMode::PostAnalysis => {
                     let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref);
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 53e5420d27a..0f90c45d032 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -264,14 +264,14 @@ fn fulfillment_error_for_no_solution<'tcx>(
             let (a, b) = infcx.enter_forall_and_leak_universe(
                 obligation.predicate.kind().rebind((pred.a, pred.b)),
             );
-            let expected_found = ExpectedFound::new(true, a, b);
+            let expected_found = ExpectedFound::new(a, b);
             FulfillmentErrorCode::Subtype(expected_found, TypeError::Sorts(expected_found))
         }
         ty::PredicateKind::Coerce(pred) => {
             let (a, b) = infcx.enter_forall_and_leak_universe(
                 obligation.predicate.kind().rebind((pred.a, pred.b)),
             );
-            let expected_found = ExpectedFound::new(false, a, b);
+            let expected_found = ExpectedFound::new(b, a);
             FulfillmentErrorCode::Subtype(expected_found, TypeError::Sorts(expected_found))
         }
         ty::PredicateKind::Clause(_)
@@ -346,12 +346,21 @@ fn find_best_leaf_obligation<'tcx>(
     consider_ambiguities: bool,
 ) -> PredicateObligation<'tcx> {
     let obligation = infcx.resolve_vars_if_possible(obligation.clone());
+    // FIXME: we use a probe here as the `BestObligation` visitor does not
+    // check whether it uses candidates which get shadowed by where-bounds.
+    //
+    // We should probably fix the visitor to not do so instead, as this also
+    // means the leaf obligation may be incorrect.
     infcx
-        .visit_proof_tree(obligation.clone().into(), &mut BestObligation {
-            obligation: obligation.clone(),
-            consider_ambiguities,
+        .fudge_inference_if_ok(|| {
+            infcx
+                .visit_proof_tree(obligation.clone().into(), &mut BestObligation {
+                    obligation: obligation.clone(),
+                    consider_ambiguities,
+                })
+                .break_value()
+                .ok_or(())
         })
-        .break_value()
         .unwrap_or(obligation)
 }
 
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index fac0414d714..6730f28893d 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -318,13 +318,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                 elaborate(tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned()));
             new_env = ty::ParamEnv::new(
                 tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())),
-                param_env.reveal(),
             );
         }
 
         let final_user_env = ty::ParamEnv::new(
             tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())),
-            user_env.reveal(),
         );
         debug!(
             "evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
index cf63f14fb93..e0a9ddf1876 100644
--- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
+++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -150,8 +150,8 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]>
                     .predicates
                     .iter()
                     .filter_map(|pred| {
-                        match pred {
-                            hir::WherePredicate::BoundPredicate(pred)
+                        match pred.kind {
+                            hir::WherePredicateKind::BoundPredicate(pred)
                                 if pred.bounded_ty.hir_id.owner.to_def_id() == trait_def_id =>
                             {
                                 // Fetch spans for trait bounds that are Sized:
@@ -707,7 +707,7 @@ fn receiver_is_dispatchable<'tcx>(
         let caller_bounds =
             param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
 
-        ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds), param_env.reveal())
+        ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds))
     };
 
     // Receiver: DispatchFromDyn<Receiver[Self => U]>
diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs
index cb36f1a62db..07fb2efb7fe 100644
--- a/compiler/rustc_trait_selection/src/traits/effects.rs
+++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -20,13 +20,18 @@ pub fn evaluate_host_effect_obligation<'tcx>(
     selcx: &mut SelectionContext<'_, 'tcx>,
     obligation: &HostEffectObligation<'tcx>,
 ) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
-    if matches!(selcx.infcx.typing_mode(obligation.param_env), TypingMode::Coherence) {
+    if matches!(selcx.infcx.typing_mode(), TypingMode::Coherence) {
         span_bug!(
             obligation.cause.span,
             "should not select host obligation in old solver in intercrate mode"
         );
     }
 
+    // Force ambiguity for infer self ty.
+    if obligation.predicate.self_ty().is_ty_var() {
+        return Err(EvaluationFailure::Ambiguous);
+    }
+
     match evaluate_host_effect_from_bounds(selcx, obligation) {
         Ok(result) => return Ok(result),
         Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous),
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 2ec5f0d2249..03e483f555d 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -557,8 +557,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                             ProcessResult::Changed(mk_pending(ok.obligations))
                         }
                         Ok(Err(err)) => {
-                            let expected_found =
-                                ExpectedFound::new(subtype.a_is_expected, subtype.a, subtype.b);
+                            let expected_found = if subtype.a_is_expected {
+                                ExpectedFound::new(subtype.a, subtype.b)
+                            } else {
+                                ExpectedFound::new(subtype.b, subtype.a)
+                            };
                             ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err))
                         }
                     }
@@ -578,7 +581,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                         }
                         Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
                         Ok(Err(err)) => {
-                            let expected_found = ExpectedFound::new(false, coerce.a, coerce.b);
+                            let expected_found = ExpectedFound::new(coerce.b, coerce.a);
                             ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err))
                         }
                     }
@@ -703,7 +706,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 }
                                 Err(err) => {
                                     ProcessResult::Error(FulfillmentErrorCode::ConstEquate(
-                                        ExpectedFound::new(true, c1, c2),
+                                        ExpectedFound::new(c1, c2),
                                         err,
                                     ))
                                 }
@@ -727,7 +730,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 ProcessResult::Unchanged
                             } else {
                                 // Two different constants using generic parameters ~> error.
-                                let expected_found = ExpectedFound::new(true, c1, c2);
+                                let expected_found = ExpectedFound::new(c1, c2);
                                 ProcessResult::Error(FulfillmentErrorCode::ConstEquate(
                                     expected_found,
                                     TypeError::ConstMismatch(expected_found),
@@ -768,8 +771,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
         stalled_on: &mut Vec<TyOrConstInferVar>,
     ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
         let infcx = self.selcx.infcx;
-        if obligation.predicate.is_global()
-            && !matches!(infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
+        if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence)
         {
             // no type variables present, can use evaluation for better caching.
             // FIXME: consider caching errors too.
@@ -824,8 +826,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
     ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
         let tcx = self.selcx.tcx();
         let infcx = self.selcx.infcx;
-        if obligation.predicate.is_global()
-            && !matches!(infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
+        if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence)
         {
             // no type variables present, can use evaluation for better caching.
             // FIXME: consider caching errors too.
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 80cef690028..069fab6a6e6 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -423,7 +423,7 @@ pub fn normalize_param_env_or_error<'tcx>(
 
     debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
 
-    let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal());
+    let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates));
     if !elaborated_env.has_aliases() {
         return elaborated_env;
     }
@@ -470,8 +470,7 @@ pub fn normalize_param_env_or_error<'tcx>(
     // here. I believe they should not matter, because we are ignoring TypeOutlives param-env
     // predicates here anyway. Keeping them here anyway because it seems safer.
     let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned();
-    let outlives_env =
-        ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env), unnormalized_env.reveal());
+    let outlives_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env));
     let Ok(outlives_predicates) =
         do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates)
     else {
@@ -484,7 +483,7 @@ pub fn normalize_param_env_or_error<'tcx>(
     let mut predicates = non_outlives_predicates;
     predicates.extend(outlives_predicates);
     debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
-    ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal())
+    ty::ParamEnv::new(tcx.mk_clauses(&predicates))
 }
 
 #[derive(Debug)]
@@ -552,8 +551,18 @@ pub fn try_evaluate_const<'tcx>(
         | ty::ConstKind::Placeholder(_)
         | ty::ConstKind::Expr(_) => Err(EvaluateConstErr::HasGenericsOrInfers),
         ty::ConstKind::Unevaluated(uv) => {
-            // Postpone evaluation of constants that depend on generic parameters or inference variables.
-            let (args, param_env) = if tcx.features().generic_const_exprs()
+            // Postpone evaluation of constants that depend on generic parameters or
+            // inference variables.
+            //
+            // We use `TypingMode::PostAnalysis`  here which is 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).
+            // As a result we always use a revealed env when resolving the instance to evaluate.
+            //
+            // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
+            // instead of having this logic here
+            let (args, typing_env) = if tcx.features().generic_const_exprs()
                 && uv.has_non_region_infer()
             {
                 // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
@@ -569,13 +578,17 @@ pub fn try_evaluate_const<'tcx>(
                             // the generic arguments provided for it, then we should *not* attempt to evaluate it.
                             return Err(EvaluateConstErr::HasGenericsOrInfers);
                         } else {
-                            (replace_param_and_infer_args_with_placeholder(tcx, uv.args), param_env)
+                            let args = replace_param_and_infer_args_with_placeholder(tcx, uv.args);
+                            let typing_env = infcx
+                                .typing_env(tcx.erase_regions(param_env))
+                                .with_post_analysis_normalized(tcx);
+                            (args, typing_env)
                         }
                     }
                     Err(_) | Ok(None) => {
                         let args = GenericArgs::identity_for_item(tcx, uv.def);
-                        let param_env = tcx.param_env(uv.def);
-                        (args, param_env)
+                        let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
+                        (args, typing_env)
                     }
                 }
             } else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() {
@@ -594,27 +607,20 @@ pub fn try_evaluate_const<'tcx>(
                 );
 
                 let args = GenericArgs::identity_for_item(tcx, uv.def);
-                let param_env = tcx.param_env(uv.def);
-                (args, param_env)
+                let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
+                (args, typing_env)
             } else {
                 // FIXME: This codepath is reachable under `associated_const_equality` and in the
                 // future will be reachable by `min_generic_const_args`. We should handle inference
                 // variables and generic parameters properly instead of doing nothing.
-                (uv.args, param_env)
+                let typing_env = infcx
+                    .typing_env(tcx.erase_regions(param_env))
+                    .with_post_analysis_normalized(tcx);
+                (uv.args, typing_env)
             };
             let uv = ty::UnevaluatedConst::new(uv.def, args);
 
-            // It's not *technically* correct to be revealing opaque types here as we could still be
-            // before borrowchecking. However, CTFE itself uses `Reveal::All` unconditionally even during
-            // typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821). As a result we
-            // always use a revealed env when resolving the instance to evaluate.
-            //
-            // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
-            // instead of having this logic here
-            let typing_env =
-                tcx.erase_regions(infcx.typing_env(param_env)).with_reveal_all_normalized(tcx);
             let erased_uv = tcx.erase_regions(uv);
-
             use rustc_middle::mir::interpret::ErrorHandled;
             match tcx.const_eval_resolve_for_typeck(typing_env, erased_uv, DUMMY_SP) {
                 Ok(Ok(val)) => Ok(ty::Const::new_value(
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index 5c38d162712..4d3d8c66e62 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -111,14 +111,13 @@ where
 
 pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
     infcx: &InferCtxt<'tcx>,
-    param_env_for_debug_assertion: ty::ParamEnv<'tcx>,
     value: &T,
 ) -> bool {
     let mut flags = ty::TypeFlags::HAS_ALIAS;
 
-    // Opaques are treated as rigid with `Reveal::UserFacing`,
+    // Opaques are treated as rigid outside of `TypingMode::PostAnalysis`,
     // so we can ignore those.
-    match infcx.typing_mode(param_env_for_debug_assertion) {
+    match infcx.typing_mode() {
         TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
             flags.remove(ty::TypeFlags::HAS_TY_OPAQUE)
         }
@@ -158,11 +157,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
             "Normalizing {value:?} without wrapping in a `Binder`"
         );
 
-        if !needs_normalization(self.selcx.infcx, self.param_env, &value) {
-            value
-        } else {
-            value.fold_with(self)
-        }
+        if !needs_normalization(self.selcx.infcx, &value) { value } else { value.fold_with(self) }
     }
 }
 
@@ -182,7 +177,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
     }
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        if !needs_normalization(self.selcx.infcx, self.param_env, &ty) {
+        if !needs_normalization(self.selcx.infcx, &ty) {
             return ty;
         }
 
@@ -217,7 +212,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
         match kind {
             ty::Opaque => {
                 // Only normalize `impl Trait` outside of type inference, usually in codegen.
-                match self.selcx.infcx.typing_mode(self.param_env) {
+                match self.selcx.infcx.typing_mode() {
                     TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
                         ty.super_fold_with(self)
                     }
@@ -407,8 +402,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
     #[instrument(skip(self), level = "debug")]
     fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
         let tcx = self.selcx.tcx();
-        if tcx.features().generic_const_exprs()
-            || !needs_normalization(self.selcx.infcx, self.param_env, &constant)
+        if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &constant)
         {
             constant
         } else {
@@ -426,7 +420,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
 
     #[inline]
     fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
-        if p.allow_normalization() && needs_normalization(self.selcx.infcx, self.param_env, &p) {
+        if p.allow_normalization() && needs_normalization(self.selcx.infcx, &p) {
             p.super_fold_with(self)
         } else {
             p
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index aab854e9caf..2864f277df5 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -10,7 +10,6 @@ use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::DefineOpaqueTypes;
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_infer::traits::{ObligationCauseCode, PredicateObligations};
-pub use rustc_middle::traits::Reveal;
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
 use rustc_middle::ty::fast_reject::DeepRejectCtxt;
@@ -975,7 +974,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                     // and the obligation is monomorphic, otherwise passes such as
                     // transmute checking and polymorphic MIR optimizations could
                     // get a result which isn't correct for all monomorphizations.
-                    match selcx.infcx.typing_mode(obligation.param_env) {
+                    match selcx.infcx.typing_mode() {
                         TypingMode::Coherence | TypingMode::Analysis { .. } => {
                             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 5f89894fb82..22cfbb2c840 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -89,7 +89,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
             }
         }
 
-        if !needs_normalization(self.infcx, self.param_env, &value) {
+        if !needs_normalization(self.infcx, &value) {
             return Ok(Normalized { value, obligations: PredicateObligations::new() });
         }
 
@@ -191,7 +191,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
 
     #[instrument(level = "debug", skip(self))]
     fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
-        if !needs_normalization(self.infcx, self.param_env, &ty) {
+        if !needs_normalization(self.infcx, &ty) {
             return Ok(ty);
         }
 
@@ -215,7 +215,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
         let res = match kind {
             ty::Opaque => {
                 // Only normalize `impl Trait` outside of type inference, usually in codegen.
-                match self.infcx.typing_mode(self.param_env) {
+                match self.infcx.typing_mode() {
                     TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
                         ty.try_super_fold_with(self)?
                     }
@@ -334,7 +334,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
         &mut self,
         constant: ty::Const<'tcx>,
     ) -> Result<ty::Const<'tcx>, Self::Error> {
-        if !needs_normalization(self.infcx, self.param_env, &constant) {
+        if !needs_normalization(self.infcx, &constant) {
             return Ok(constant);
         }
 
@@ -353,7 +353,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
         &mut self,
         p: ty::Predicate<'tcx>,
     ) -> Result<ty::Predicate<'tcx>, Self::Error> {
-        if p.allow_normalization() && needs_normalization(self.infcx, self.param_env, &p) {
+        if p.allow_normalization() && needs_normalization(self.infcx, &p) {
             p.try_super_fold_with(self)
         } else {
             Ok(p)
diff --git a/compiler/rustc_trait_selection/src/traits/select/_match.rs b/compiler/rustc_trait_selection/src/traits/select/_match.rs
index 3980d672a11..7c19c35a4f7 100644
--- a/compiler/rustc_trait_selection/src/traits/select/_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/_match.rs
@@ -70,7 +70,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
             ) => Ok(a),
 
             (&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
-                Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
+                Err(TypeError::Sorts(ExpectedFound::new(a, b)))
             }
 
             (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(self.cx(), guar)),
@@ -95,7 +95,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
             }
 
             (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
-                return Err(TypeError::ConstMismatch(ExpectedFound::new(true, a, b)));
+                return Err(TypeError::ConstMismatch(ExpectedFound::new(a, b)));
             }
 
             _ => {}
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 345e1cc31f3..32b4567aba4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -91,14 +91,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             } else if tcx.is_lang_item(def_id, LangItem::Sized) {
                 // Sized is never implementable by end-users, it is
                 // always automatically computed.
-
-                // FIXME: Consider moving this check to the top level as it
-                // may also be useful for predicates other than `Sized`
-                // Error type cannot possibly implement `Sized` (fixes #123154)
-                if let Err(e) = obligation.predicate.skip_binder().self_ty().error_reported() {
-                    return Err(SelectionError::Overflow(e.into()));
-                }
-
                 let sized_conditions = self.sized_conditions(obligation);
                 self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
             } else if tcx.is_lang_item(def_id, LangItem::Unsize) {
@@ -230,13 +222,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ) -> Result<(), SelectionError<'tcx>> {
         debug!(?stack.obligation);
 
-        // An error type will unify with anything. So, avoid
-        // matching an error type with `ParamCandidate`.
-        // This helps us avoid spurious errors like issue #121941.
-        if stack.obligation.predicate.references_error() {
-            return Ok(());
-        }
-
         let bounds = stack
             .obligation
             .param_env
@@ -563,19 +548,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         obligation: &PolyTraitObligation<'tcx>,
         candidates: &mut SelectionCandidateSet<'tcx>,
     ) {
-        // Essentially any user-written impl will match with an error type,
-        // so creating `ImplCandidates` isn't useful. However, we might
-        // end up finding a candidate elsewhere (e.g. a `BuiltinCandidate` for `Sized`)
-        // This helps us avoid overflow: see issue #72839
-        // Since compilation is already guaranteed to fail, this is just
-        // to try to show the 'nicest' possible errors to the user.
-        // We don't check for errors in the `ParamEnv` - in practice,
-        // it seems to cause us to be overly aggressive in deciding
-        // to give up searching for candidates, leading to spurious errors.
-        if obligation.predicate.references_error() {
-            return;
-        }
-
         let drcx = DeepRejectCtxt::relate_rigid_infer(self.tcx());
         let obligation_args = obligation.predicate.skip_binder().trait_ref.args;
         self.tcx().for_each_relevant_impl(
@@ -788,9 +760,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         //
                         // Note that this is only sound as projection candidates of opaque types
                         // are always applicable for auto traits.
-                    } else if let TypingMode::Coherence =
-                        self.infcx.typing_mode(obligation.param_env)
-                    {
+                    } else if let TypingMode::Coherence = self.infcx.typing_mode() {
                         // We do not emit auto trait candidates for opaque types in coherence.
                         // Doing so can result in weird dependency cycles.
                         candidates.ambiguous = true;
@@ -933,7 +903,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         //
         // FIXME(@lcnr): This should probably only trigger during analysis,
         // disabling candidates during codegen is also questionable.
-        if let TypingMode::Coherence = self.infcx.typing_mode(param_env) {
+        if let TypingMode::Coherence = self.infcx.typing_mode() {
             return None;
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 5b4e895189b..3b64a47181a 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -222,7 +222,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// Enables tracking of intercrate ambiguity causes. See
     /// the documentation of [`Self::intercrate_ambiguity_causes`] for more.
     pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
-        assert_matches!(self.infcx.typing_mode_unchecked(), TypingMode::Coherence);
+        assert_matches!(self.infcx.typing_mode(), TypingMode::Coherence);
         assert!(self.intercrate_ambiguity_causes.is_none());
         self.intercrate_ambiguity_causes = Some(FxIndexSet::default());
         debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
@@ -234,7 +234,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     pub fn take_intercrate_ambiguity_causes(
         &mut self,
     ) -> FxIndexSet<IntercrateAmbiguityCause<'tcx>> {
-        assert_matches!(self.infcx.typing_mode_unchecked(), TypingMode::Coherence);
+        assert_matches!(self.infcx.typing_mode(), TypingMode::Coherence);
         self.intercrate_ambiguity_causes.take().unwrap_or_default()
     }
 
@@ -1027,7 +1027,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         previous_stack: TraitObligationStackList<'o, 'tcx>,
         mut obligation: PolyTraitObligation<'tcx>,
     ) -> Result<EvaluationResult, OverflowError> {
-        if !matches!(self.infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
+        if !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
             && obligation.is_global()
             && obligation.param_env.caller_bounds().iter().all(|bound| bound.has_param())
         {
@@ -1310,13 +1310,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> Option<EvaluationResult> {
-        let tcx = self.tcx();
+        let infcx = self.infcx;
+        let tcx = infcx.tcx;
         if self.can_use_global_caches(param_env, trait_pred) {
-            if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) {
-                return Some(res);
+            let key = (infcx.typing_env(param_env), trait_pred);
+            if let Some(res) = tcx.evaluation_cache.get(&key, tcx) {
+                Some(res)
+            } else {
+                debug_assert_eq!(infcx.evaluation_cache.get(&(param_env, trait_pred), tcx), None);
+                None
             }
+        } else {
+            self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx)
         }
-        self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx)
     }
 
     fn insert_evaluation_cache(
@@ -1332,18 +1338,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             return;
         }
 
-        if self.can_use_global_caches(param_env, trait_pred) && !trait_pred.has_infer() {
+        let infcx = self.infcx;
+        let tcx = infcx.tcx;
+        if self.can_use_global_caches(param_env, trait_pred) {
             debug!(?trait_pred, ?result, "insert_evaluation_cache global");
             // This may overwrite the cache with the same value
-            // FIXME: Due to #50507 this overwrites the different values
-            // This should be changed to use HashMapExt::insert_same
-            // when that is fixed
-            self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result);
+            tcx.evaluation_cache.insert(
+                (infcx.typing_env(param_env), trait_pred),
+                dep_node,
+                result,
+            );
             return;
+        } else {
+            debug!(?trait_pred, ?result, "insert_evaluation_cache local");
+            self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result);
         }
-
-        debug!(?trait_pred, ?result, "insert_evaluation_cache");
-        self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result);
     }
 
     fn check_recursion_depth<T>(
@@ -1459,7 +1468,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
         let obligation = &stack.obligation;
-        match self.infcx.typing_mode(obligation.param_env) {
+        match self.infcx.typing_mode() {
             TypingMode::Coherence => {}
             TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Ok(()),
         }
@@ -1485,11 +1494,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // If there are any inference variables in the `ParamEnv`, then we
         // always use a cache local to this particular scope. Otherwise, we
         // switch to a global cache.
-        if param_env.has_infer() {
+        if param_env.has_infer() || pred.has_infer() {
             return false;
         }
 
-        match self.infcx.typing_mode(param_env) {
+        match self.infcx.typing_mode() {
             // Avoid using the global cache during coherence and just rely
             // on the local cache. It is really just a simplification to
             // avoid us having to fear that coherence results "pollute"
@@ -1522,15 +1531,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> {
-        let tcx = self.tcx();
+        let infcx = self.infcx;
+        let tcx = infcx.tcx;
         let pred = cache_fresh_trait_pred.skip_binder();
 
         if self.can_use_global_caches(param_env, cache_fresh_trait_pred) {
-            if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
-                return Some(res);
+            if let Some(res) = tcx.selection_cache.get(&(infcx.typing_env(param_env), pred), tcx) {
+                Some(res)
+            } else {
+                debug_assert_eq!(infcx.selection_cache.get(&(param_env, pred), tcx), None);
+                None
             }
+        } else {
+            infcx.selection_cache.get(&(param_env, pred), tcx)
         }
-        self.infcx.selection_cache.get(&(param_env, pred), tcx)
     }
 
     /// Determines whether can we safely cache the result
@@ -1567,7 +1581,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         dep_node: DepNodeIndex,
         candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>,
     ) {
-        let tcx = self.tcx();
+        let infcx = self.infcx;
+        let tcx = infcx.tcx;
         let pred = cache_fresh_trait_pred.skip_binder();
 
         if !self.can_cache_candidate(&candidate) {
@@ -1578,10 +1593,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         if self.can_use_global_caches(param_env, cache_fresh_trait_pred) {
             if let Err(Overflow(OverflowError::Canonical)) = candidate {
                 // Don't cache overflow globally; we only produce this in certain modes.
-            } else if !pred.has_infer() && !candidate.has_infer() {
+            } else {
                 debug!(?pred, ?candidate, "insert_candidate_cache global");
+                debug_assert!(!candidate.has_infer());
+
                 // This may overwrite the cache with the same value.
-                tcx.selection_cache.insert((param_env, pred), dep_node, candidate);
+                tcx.selection_cache.insert(
+                    (infcx.typing_env(param_env), pred),
+                    dep_node,
+                    candidate,
+                );
                 return;
             }
         }
@@ -2487,10 +2508,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id);
 
         let trait_ref = impl_trait_header.trait_ref.instantiate(self.tcx(), impl_args);
-        if trait_ref.references_error() {
-            return Err(());
-        }
-
         debug!(?impl_trait_header);
 
         let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } =
@@ -2522,7 +2539,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         nested_obligations.extend(obligations);
 
         if impl_trait_header.polarity == ty::ImplPolarity::Reservation
-            && !matches!(self.infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
+            && !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
         {
             debug!("reservation impls only apply in intercrate mode");
             return Err(());
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 5bf3dbcbc32..a9cd705465e 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -15,24 +15,24 @@ use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::codes::*;
 use rustc_errors::{Diag, EmissionGuarantee};
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_infer::infer::DefineOpaqueTypes;
 use rustc_middle::bug;
 use rustc_middle::query::LocalCrate;
 use rustc_middle::ty::print::PrintTraitRefExt as _;
-use rustc_middle::ty::{
-    self, GenericArgsRef, ImplSubject, Ty, TyCtxt, TypeVisitableExt, TypingMode,
-};
+use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode};
 use rustc_session::lint::builtin::{COHERENCE_LEAK_CHECK, ORDER_DEPENDENT_TRAIT_OBJECTS};
 use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, sym};
+use rustc_type_ir::solve::NoSolution;
 use specialization_graph::GraphExt;
 use tracing::{debug, instrument};
 
-use super::{SelectionContext, util};
 use crate::error_reporting::traits::to_pretty_impl_header;
 use crate::errors::NegativePositiveConflict;
-use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
+use crate::infer::{InferCtxt, TyCtxtInferExt};
 use crate::traits::select::IntercrateAmbiguityCause;
-use crate::traits::{FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt, coherence};
+use crate::traits::{
+    FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt, coherence,
+    predicates_for_generics,
+};
 
 /// Information pertinent to an overlapping impl error.
 #[derive(Debug)]
@@ -87,9 +87,14 @@ pub fn translate_args<'tcx>(
     source_args: GenericArgsRef<'tcx>,
     target_node: specialization_graph::Node,
 ) -> GenericArgsRef<'tcx> {
-    translate_args_with_cause(infcx, param_env, source_impl, source_args, target_node, |_, _| {
-        ObligationCause::dummy()
-    })
+    translate_args_with_cause(
+        infcx,
+        param_env,
+        source_impl,
+        source_args,
+        target_node,
+        &ObligationCause::dummy(),
+    )
 }
 
 /// Like [translate_args], but obligations from the parent implementation
@@ -104,7 +109,7 @@ pub fn translate_args_with_cause<'tcx>(
     source_impl: DefId,
     source_args: GenericArgsRef<'tcx>,
     target_node: specialization_graph::Node,
-    cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
+    cause: &ObligationCause<'tcx>,
 ) -> GenericArgsRef<'tcx> {
     debug!(
         "translate_args({:?}, {:?}, {:?}, {:?})",
@@ -123,7 +128,7 @@ pub fn translate_args_with_cause<'tcx>(
             }
 
             fulfill_implication(infcx, param_env, source_trait_ref, source_impl, target_impl, cause)
-                .unwrap_or_else(|()| {
+                .unwrap_or_else(|_| {
                     bug!(
                         "When translating generic parameters from {source_impl:?} to \
                         {target_impl:?}, the expected specialization failed to hold"
@@ -137,6 +142,84 @@ pub fn translate_args_with_cause<'tcx>(
     source_args.rebase_onto(infcx.tcx, source_impl, target_args)
 }
 
+/// Attempt to fulfill all obligations of `target_impl` after unification with
+/// `source_trait_ref`. If successful, returns the generic parameters for *all* the
+/// generics of `target_impl`, including both those needed to unify with
+/// `source_trait_ref` and those whose identity is determined via a where
+/// clause in the impl.
+fn fulfill_implication<'tcx>(
+    infcx: &InferCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    source_trait_ref: ty::TraitRef<'tcx>,
+    source_impl: DefId,
+    target_impl: DefId,
+    cause: &ObligationCause<'tcx>,
+) -> Result<GenericArgsRef<'tcx>, NoSolution> {
+    debug!(
+        "fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)",
+        param_env, source_trait_ref, target_impl
+    );
+
+    let ocx = ObligationCtxt::new(infcx);
+    let source_trait_ref = ocx.normalize(cause, param_env, source_trait_ref);
+
+    if !ocx.select_all_or_error().is_empty() {
+        infcx.dcx().span_delayed_bug(
+            infcx.tcx.def_span(source_impl),
+            format!("failed to fully normalize {source_trait_ref}"),
+        );
+        return Err(NoSolution);
+    }
+
+    let target_args = infcx.fresh_args_for_item(DUMMY_SP, target_impl);
+    let target_trait_ref = ocx.normalize(
+        cause,
+        param_env,
+        infcx
+            .tcx
+            .impl_trait_ref(target_impl)
+            .expect("expected source impl to be a trait impl")
+            .instantiate(infcx.tcx, target_args),
+    );
+
+    // do the impls unify? If not, no specialization.
+    ocx.eq(cause, param_env, source_trait_ref, target_trait_ref)?;
+
+    // Now check that the source trait ref satisfies all the where clauses of the target impl.
+    // This is not just for correctness; we also need this to constrain any params that may
+    // only be referenced via projection predicates.
+    let predicates = ocx.normalize(
+        cause,
+        param_env,
+        infcx.tcx.predicates_of(target_impl).instantiate(infcx.tcx, target_args),
+    );
+    let obligations = predicates_for_generics(|_, _| cause.clone(), param_env, predicates);
+    ocx.register_obligations(obligations);
+
+    let errors = ocx.select_all_or_error();
+    if !errors.is_empty() {
+        // no dice!
+        debug!(
+            "fulfill_implication: for impls on {:?} and {:?}, \
+                 could not fulfill: {:?} given {:?}",
+            source_trait_ref,
+            target_trait_ref,
+            errors,
+            param_env.caller_bounds()
+        );
+        return Err(NoSolution);
+    }
+
+    debug!(
+        "fulfill_implication: an impl for {:?} specializes {:?}",
+        source_trait_ref, target_trait_ref
+    );
+
+    // Now resolve the *generic parameters* we built for the target earlier, replacing
+    // the inference variables inside with whatever we got from fulfillment.
+    Ok(infcx.resolve_vars_if_possible(target_args))
+}
+
 pub(super) fn specialization_enabled_in(tcx: TyCtxt<'_>, _: LocalCrate) -> bool {
     tcx.features().specialization() || tcx.features().min_specialization()
 }
@@ -182,8 +265,9 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
         return false;
     }
 
-    // create a parameter environment corresponding to a (placeholder) instantiation of impl1
-    let penv = tcx.param_env(impl1_def_id);
+    // create a parameter environment corresponding to an identity instantiation of impl1,
+    // i.e. the most generic instantiation of impl1.
+    let param_env = tcx.param_env(impl1_def_id);
 
     // Create an infcx, taking the predicates of impl1 as assumptions:
     let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
@@ -191,90 +275,15 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
     // Attempt to prove that impl2 applies, given all of the above.
     fulfill_implication(
         &infcx,
-        penv,
+        param_env,
         impl1_trait_header.trait_ref.instantiate_identity(),
         impl1_def_id,
         impl2_def_id,
-        |_, _| ObligationCause::dummy(),
+        &ObligationCause::dummy(),
     )
     .is_ok()
 }
 
-/// Attempt to fulfill all obligations of `target_impl` after unification with
-/// `source_trait_ref`. If successful, returns the generic parameters for *all* the
-/// generics of `target_impl`, including both those needed to unify with
-/// `source_trait_ref` and those whose identity is determined via a where
-/// clause in the impl.
-fn fulfill_implication<'tcx>(
-    infcx: &InferCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    source_trait_ref: ty::TraitRef<'tcx>,
-    source_impl: DefId,
-    target_impl: DefId,
-    error_cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
-) -> Result<GenericArgsRef<'tcx>, ()> {
-    debug!(
-        "fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)",
-        param_env, source_trait_ref, target_impl
-    );
-
-    let ocx = ObligationCtxt::new(infcx);
-    let source_trait_ref = ocx.normalize(&ObligationCause::dummy(), param_env, source_trait_ref);
-
-    if !ocx.select_all_or_error().is_empty() {
-        infcx.dcx().span_delayed_bug(
-            infcx.tcx.def_span(source_impl),
-            format!("failed to fully normalize {source_trait_ref}"),
-        );
-    }
-
-    let source_trait_ref = infcx.resolve_vars_if_possible(source_trait_ref);
-    let source_trait = ImplSubject::Trait(source_trait_ref);
-
-    let selcx = SelectionContext::new(infcx);
-    let target_args = infcx.fresh_args_for_item(DUMMY_SP, target_impl);
-    let (target_trait, obligations) =
-        util::impl_subject_and_oblig(&selcx, param_env, target_impl, target_args, error_cause);
-
-    // do the impls unify? If not, no specialization.
-    let Ok(InferOk { obligations: more_obligations, .. }) = infcx
-        .at(&ObligationCause::dummy(), param_env)
-        // Ok to use `Yes`, as all the generic params are already replaced by inference variables,
-        // which will match the opaque type no matter if it is defining or not.
-        // Any concrete type that would match the opaque would already be handled by coherence rules,
-        // and thus either be ok to match here and already have errored, or it won't match, in which
-        // case there is no issue anyway.
-        .eq(DefineOpaqueTypes::Yes, source_trait, target_trait)
-    else {
-        debug!("fulfill_implication: {:?} does not unify with {:?}", source_trait, target_trait);
-        return Err(());
-    };
-
-    // attempt to prove all of the predicates for impl2 given those for impl1
-    // (which are packed up in penv)
-    ocx.register_obligations(obligations.chain(more_obligations));
-
-    let errors = ocx.select_all_or_error();
-    if !errors.is_empty() {
-        // no dice!
-        debug!(
-            "fulfill_implication: for impls on {:?} and {:?}, \
-                 could not fulfill: {:?} given {:?}",
-            source_trait,
-            target_trait,
-            errors,
-            param_env.caller_bounds()
-        );
-        return Err(());
-    }
-
-    debug!("fulfill_implication: an impl for {:?} specializes {:?}", source_trait, target_trait);
-
-    // Now resolve the *generic parameters* we built for the target earlier, replacing
-    // the inference variables inside with whatever we got from fulfillment.
-    Ok(infcx.resolve_vars_if_possible(target_args))
-}
-
 /// Query provider for `specialization_graph_of`.
 pub(super) fn specialization_graph_provider(
     tcx: TyCtxt<'_>,
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index b7a2f20b769..da1045b664a 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -3,19 +3,16 @@ use std::collections::BTreeMap;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::Diag;
 use rustc_hir::def_id::DefId;
-use rustc_infer::infer::{InferCtxt, InferOk};
+use rustc_infer::infer::InferCtxt;
 pub use rustc_infer::traits::util::*;
 use rustc_middle::bug;
 use rustc_middle::ty::{
-    self, GenericArgsRef, ImplSubject, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
-    TypeVisitableExt, Upcast,
+    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, Upcast,
 };
 use rustc_span::Span;
 use smallvec::{SmallVec, smallvec};
 use tracing::debug;
 
-use super::{NormalizeExt, ObligationCause, PredicateObligation, SelectionContext};
-
 ///////////////////////////////////////////////////////////////////////////
 // `TraitAliasExpander` iterator
 ///////////////////////////////////////////////////////////////////////////
@@ -166,34 +163,6 @@ impl<'tcx> Iterator for TraitAliasExpander<'tcx> {
 // Other
 ///////////////////////////////////////////////////////////////////////////
 
-/// Instantiate all bound parameters of the impl subject with the given args,
-/// returning the resulting subject and all obligations that arise.
-/// The obligations are closed under normalization.
-pub(crate) fn impl_subject_and_oblig<'a, 'tcx>(
-    selcx: &SelectionContext<'a, 'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    impl_def_id: DefId,
-    impl_args: GenericArgsRef<'tcx>,
-    cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
-) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
-    let subject = selcx.tcx().impl_subject(impl_def_id);
-    let subject = subject.instantiate(selcx.tcx(), impl_args);
-
-    let InferOk { value: subject, obligations: normalization_obligations1 } =
-        selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(subject);
-
-    let predicates = selcx.tcx().predicates_of(impl_def_id);
-    let predicates = predicates.instantiate(selcx.tcx(), impl_args);
-    let InferOk { value: predicates, obligations: normalization_obligations2 } =
-        selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(predicates);
-    let impl_obligations = super::predicates_for_generics(cause, param_env, predicates);
-
-    let impl_obligations =
-        impl_obligations.chain(normalization_obligations1).chain(normalization_obligations2);
-
-    (subject, impl_obligations)
-}
-
 /// Casts a trait reference into a reference to one of its super
 /// traits; returns `None` if `target_trait_def_id` is not a
 /// supertrait.
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 437343b569c..c95b1641d1f 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -963,30 +963,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
 /// bounds that must hold on the elided self type. These are derived
 /// from the declarations of `SomeTrait`, `Send`, and friends -- if
 /// they declare `trait SomeTrait : 'static`, for example, then
-/// `'static` would appear in the list. The hard work is done by
-/// `infer::required_region_bounds`, see that for more information.
-pub fn object_region_bounds<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
-) -> Vec<ty::Region<'tcx>> {
-    let predicates = existential_predicates.iter().filter_map(|predicate| {
-        if let ty::ExistentialPredicate::Projection(_) = predicate.skip_binder() {
-            None
-        } else {
-            Some(predicate.with_self_ty(tcx, tcx.types.trait_object_dummy_self))
-        }
-    });
-
-    required_region_bounds(tcx, tcx.types.trait_object_dummy_self, predicates)
-}
-
-/// Given a set of predicates that apply to an object type, returns
-/// the region bounds that the (erased) `Self` type must
-/// outlive. Precisely *because* the `Self` type is erased, the
-/// parameter `erased_self_ty` must be supplied to indicate what type
-/// has been used to represent `Self` in the predicates
-/// themselves. This should really be a unique type; `FreshTy(0)` is a
-/// popular choice.
+/// `'static` would appear in the list.
 ///
 /// N.B., in some cases, particularly around higher-ranked bounds,
 /// this function returns a kind of conservative approximation.
@@ -996,13 +973,14 @@ pub fn object_region_bounds<'tcx>(
 ///
 /// Requires that trait definitions have been processed so that we can
 /// elaborate predicates and walk supertraits.
-#[instrument(skip(tcx, predicates), level = "debug", ret)]
-pub(crate) fn required_region_bounds<'tcx>(
+pub fn object_region_bounds<'tcx>(
     tcx: TyCtxt<'tcx>,
-    erased_self_ty: Ty<'tcx>,
-    predicates: impl Iterator<Item = ty::Clause<'tcx>>,
+    existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
 ) -> Vec<ty::Region<'tcx>> {
-    assert!(!erased_self_ty.has_escaping_bound_vars());
+    let erased_self_ty = tcx.types.trait_object_dummy_self;
+
+    let predicates =
+        existential_predicates.iter().map(|predicate| predicate.with_self_ty(tcx, erased_self_ty));
 
     traits::elaborate(tcx, predicates)
         .filter_map(|pred| {
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 29fc92e1f2f..8798772e398 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -133,8 +133,10 @@ fn resolve_associated_item<'tcx>(
                     bug!("{:?} not found in {:?}", trait_item_id, impl_data.impl_def_id);
                 });
 
-            // Since this is a trait item, we need to see if the item is either a trait default item
-            // or a specialization because we can't resolve those unless we can `Reveal::All`.
+            // Since this is a trait item, we need to see if the item is either a trait
+            // default item or a specialization because we can't resolve those until we're
+            // in `TypingMode::PostAnalysis`.
+            //
             // NOTE: This should be kept in sync with the similar code in
             // `rustc_trait_selection::traits::project::assemble_candidates_from_impls()`.
             let eligible = if leaf_def.is_final() {
@@ -155,7 +157,7 @@ fn resolve_associated_item<'tcx>(
                 return Ok(None);
             }
 
-            let typing_env = typing_env.with_reveal_all_normalized(tcx);
+            let typing_env = typing_env.with_post_analysis_normalized(tcx);
             let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
             let args = rcvr_args.rebase_onto(tcx, trait_def_id, impl_data.args);
             let args = translate_args(
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 092e140a600..66134b81b2a 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -46,10 +46,10 @@ fn layout_of<'tcx>(
     let PseudoCanonicalInput { typing_env, value: ty } = query;
     debug!(?ty);
 
-    // Optimization: We convert to RevealAll and convert opaque types in the where bounds
-    // to their hidden types. This reduces overall uncached invocations of `layout_of` and
-    // is thus a small performance improvement.
-    let typing_env = typing_env.with_reveal_all_normalized(tcx);
+    // Optimization: We convert to TypingMode::PostAnalysis and convert opaque types in
+    // the where bounds to their hidden types. This reduces overall uncached invocations
+    // of `layout_of` and is thus a small performance improvement.
+    let typing_env = typing_env.with_post_analysis_normalized(tcx);
     let unnormalized_ty = ty;
 
     // FIXME: We might want to have two different versions of `layout_of`:
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index 469a4ac3e41..d85da7d355e 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -431,13 +431,13 @@ fn adt_significant_drop_tys(
 #[instrument(level = "debug", skip(tcx), ret)]
 fn list_significant_drop_tys<'tcx>(
     tcx: TyCtxt<'tcx>,
-    ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
+    key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>,
 ) -> &'tcx ty::List<Ty<'tcx>> {
     tcx.mk_type_list(
         &drop_tys_helper(
             tcx,
-            ty.value,
-            ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: ty.param_env },
+            key.value,
+            key.typing_env,
             adt_consider_insignificant_dtor(tcx),
             true,
             true,
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 2127ba8a423..61f2262dfe8 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -6,8 +6,7 @@ use rustc_index::bit_set::BitSet;
 use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{
-    self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
-    TypeVisitor, Upcast,
+    self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast,
 };
 use rustc_span::DUMMY_SP;
 use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
@@ -95,9 +94,6 @@ fn adt_sized_constraint<'tcx>(
     let tail_ty = tcx.type_of(tail_def.did).instantiate_identity();
 
     let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?;
-    if let Err(guar) = constraint_ty.error_reported() {
-        return Some(ty::EarlyBinder::bind(Ty::new_error(tcx, guar)));
-    }
 
     // perf hack: if there is a `constraint_ty: Sized` bound, then we know
     // that the type is sized and do not need to check it on the impl.
@@ -162,8 +158,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
 
     let local_did = def_id.as_local();
 
-    let unnormalized_env =
-        ty::ParamEnv::new(tcx.mk_clauses(&predicates), traits::Reveal::UserFacing);
+    let unnormalized_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates));
 
     let body_id = local_did.unwrap_or(CRATE_DEF_ID);
     let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
@@ -253,8 +248,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
     }
 }
 
-fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
-    tcx.param_env(def_id).with_reveal_all_normalized(tcx)
+fn param_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
+    // This is a bit ugly but the easiest way to avoid code duplication.
+    let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id);
+    typing_env.with_post_analysis_normalized(tcx).param_env
 }
 
 /// If the given trait impl enables exploiting the former order dependence of trait objects,
@@ -366,7 +363,7 @@ pub(crate) fn provide(providers: &mut Providers) {
         asyncness,
         adt_sized_constraint,
         param_env,
-        param_env_reveal_all_normalized,
+        param_env_normalized_for_post_analysis,
         self_ty_of_trait_impl_enabling_order_dep_trait_object_hack,
         defaultness,
         unsizing_params_for_adt,
diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs
index 2c1ad9de9aa..0d574445df8 100644
--- a/compiler/rustc_type_ir/src/elaborate.rs
+++ b/compiler/rustc_type_ir/src/elaborate.rs
@@ -45,14 +45,12 @@ pub trait Elaboratable<I: Interner> {
 
 pub struct ClauseWithSupertraitSpan<I: Interner> {
     pub pred: I::Predicate,
-    // Span of the original elaborated predicate.
-    pub original_span: I::Span,
     // Span of the supertrait predicatae that lead to this clause.
     pub supertrait_span: I::Span,
 }
 impl<I: Interner> ClauseWithSupertraitSpan<I> {
     pub fn new(pred: I::Predicate, span: I::Span) -> Self {
-        ClauseWithSupertraitSpan { pred, original_span: span, supertrait_span: span }
+        ClauseWithSupertraitSpan { pred, supertrait_span: span }
     }
 }
 impl<I: Interner> Elaboratable<I> for ClauseWithSupertraitSpan<I> {
@@ -63,7 +61,6 @@ impl<I: Interner> Elaboratable<I> for ClauseWithSupertraitSpan<I> {
     fn child(&self, clause: <I as Interner>::Clause) -> Self {
         ClauseWithSupertraitSpan {
             pred: clause.as_predicate(),
-            original_span: self.original_span,
             supertrait_span: self.supertrait_span,
         }
     }
@@ -75,11 +72,7 @@ impl<I: Interner> Elaboratable<I> for ClauseWithSupertraitSpan<I> {
         _parent_trait_pred: crate::Binder<I, crate::TraitPredicate<I>>,
         _index: usize,
     ) -> Self {
-        ClauseWithSupertraitSpan {
-            pred: clause.as_predicate(),
-            original_span: self.original_span,
-            supertrait_span: supertrait_span,
-        }
+        ClauseWithSupertraitSpan { pred: clause.as_predicate(), supertrait_span: supertrait_span }
     }
 }
 
diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs
index cdff77f742d..55671b84dbc 100644
--- a/compiler/rustc_type_ir/src/error.rs
+++ b/compiler/rustc_type_ir/src/error.rs
@@ -12,12 +12,8 @@ pub struct ExpectedFound<T> {
 }
 
 impl<T> ExpectedFound<T> {
-    pub fn new(a_is_expected: bool, a: T, b: T) -> Self {
-        if a_is_expected {
-            ExpectedFound { expected: a, found: b }
-        } else {
-            ExpectedFound { expected: b, found: a }
-        }
+    pub fn new(expected: T, found: T) -> Self {
+        ExpectedFound { expected, found }
     }
 }
 
@@ -33,7 +29,7 @@ pub enum TypeError<I: Interner> {
     Mutability,
     ArgumentMutability(usize),
     TupleSize(ExpectedFound<usize>),
-    FixedArraySize(ExpectedFound<u64>),
+    ArraySize(ExpectedFound<I::Const>),
     ArgCount,
 
     RegionsDoesNotOutlive(I::Region, I::Region),
@@ -73,7 +69,7 @@ impl<I: Interner> TypeError<I> {
         use self::TypeError::*;
         match self {
             CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | PolarityMismatch(_) | Mismatch
-            | AbiMismatch(_) | FixedArraySize(_) | ArgumentSorts(..) | Sorts(_)
+            | AbiMismatch(_) | ArraySize(_) | ArgumentSorts(..) | Sorts(_)
             | VariadicMismatch(_) | TargetFeatureCast(_) => false,
 
             Mutability
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs
index b01d3dc5269..13ad505bc04 100644
--- a/compiler/rustc_type_ir/src/infer_ctxt.rs
+++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -39,9 +39,38 @@ pub enum TypingMode<I: Interner> {
     ///
     /// We only normalize opaque types which may get defined by the current body,
     /// which are stored in `defining_opaque_types`.
+    ///
+    /// We also refuse to project any associated type that is marked `default`.
+    /// Non-`default` ("final") types are always projected. This is necessary in
+    /// general for soundness of specialization. However, we *could* allow projections
+    /// in fully-monomorphic cases. We choose not to, because we prefer for `default type`
+    /// to force the type definition to be treated abstractly by any consumers of the
+    /// impl. Concretely, that means that the following example will
+    /// fail to compile:
+    ///
+    /// ```compile_fail,E0308
+    /// #![feature(specialization)]
+    /// trait Assoc {
+    ///     type Output;
+    /// }
+    ///
+    /// impl<T> Assoc for T {
+    ///     default type Output = bool;
+    /// }
+    ///
+    /// fn main() {
+    ///     let x: <() as Assoc>::Output = true;
+    /// }
+    /// ```
     Analysis { defining_opaque_types: I::DefiningOpaqueTypes },
     /// After analysis, mostly during codegen and MIR optimizations, we're able to
-    /// reveal all opaque types.
+    /// reveal all opaque types. As the concrete type should *never* be observable
+    /// directly by the user, this should not be used by checks which may expose
+    /// such details to the user.
+    ///
+    /// There are some exceptions to this as for example `layout_of` and const-evaluation
+    /// always run in `PostAnalysis` mode, even when used during analysis. This exposes
+    /// some information about the underlying type to users, but not the type itself.
     PostAnalysis,
 }
 
@@ -70,10 +99,7 @@ pub trait InferCtxtLike: Sized {
         true
     }
 
-    fn typing_mode(
-        &self,
-        param_env_for_debug_assertion: <Self::Interner as Interner>::ParamEnv,
-    ) -> TypingMode<Self::Interner>;
+    fn typing_mode(&self) -> TypingMode<Self::Interner>;
 
     fn universe(&self) -> ty::UniverseIndex;
     fn create_next_universe(&self) -> ty::UniverseIndex;
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 5af1aa2f8fa..a201f2b1c11 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -11,7 +11,7 @@ use rustc_ast_ir::Mutability;
 use crate::elaborate::Elaboratable;
 use crate::fold::{TypeFoldable, TypeSuperFoldable};
 use crate::relate::Relate;
-use crate::solve::Reveal;
+use crate::solve::AdtDestructorKind;
 use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
 use crate::{self as ty, CollectAndApply, Interner, UpcastFrom};
 
@@ -257,8 +257,6 @@ pub trait Const<I: Interner<Const = Self>>:
     + Relate<I>
     + Flags
 {
-    fn try_to_target_usize(self, interner: I) -> Option<u64>;
-
     fn new_infer(interner: I, var: ty::InferConst) -> Self;
 
     fn new_var(interner: I, var: ty::ConstVid) -> Self;
@@ -537,11 +535,11 @@ pub trait AdtDef<I: Interner>: Copy + Debug + Hash + Eq {
     fn sized_constraint(self, interner: I) -> Option<ty::EarlyBinder<I, I::Ty>>;
 
     fn is_fundamental(self) -> bool;
+
+    fn destructor(self, interner: I) -> Option<AdtDestructorKind>;
 }
 
 pub trait ParamEnv<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
-    fn reveal(self) -> Reveal;
-
     fn caller_bounds(self) -> impl IntoIterator<Item = I::Clause>;
 }
 
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 93b9c2e2892..0ae688848eb 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -225,6 +225,7 @@ pub trait Interner:
 
     fn impl_is_const(self, def_id: Self::DefId) -> bool;
     fn fn_is_const(self, def_id: Self::DefId) -> bool;
+    fn alias_has_const_conditions(self, def_id: Self::DefId) -> bool;
     fn const_conditions(
         self,
         def_id: Self::DefId,
diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs
index df43346065d..eeb80bc3ab4 100644
--- a/compiler/rustc_type_ir/src/lang_items.rs
+++ b/compiler/rustc_type_ir/src/lang_items.rs
@@ -19,6 +19,7 @@ pub enum TraitSolverLangItem {
     CoroutineYield,
     Destruct,
     DiscriminantKind,
+    Drop,
     DynMetadata,
     Fn,
     FnMut,
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index 8a8e624e72a..4213ef4803b 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -444,7 +444,7 @@ pub enum AliasTermKind {
     /// An associated type in an inherent `impl`
     InherentTy,
     /// An opaque type (usually from `impl Trait` in type aliases or function return types)
-    /// Can only be normalized away in RevealAll mode
+    /// Can only be normalized away in PostAnalysis mode or its defining scope.
     OpaqueTy,
     /// A type alias that actually checks its trait bounds.
     /// Currently only used if the type alias references opaque types.
@@ -684,19 +684,6 @@ impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
         self.skip_binder().projection_term.trait_def_id(cx)
     }
 
-    /// Get the trait ref required for this projection to be well formed.
-    /// Note that for generic associated types the predicates of the associated
-    /// type also need to be checked.
-    #[inline]
-    pub fn required_poly_trait_ref(&self, cx: I) -> ty::Binder<I, TraitRef<I>> {
-        // Note: unlike with `TraitRef::to_poly_trait_ref()`,
-        // `self.0.trait_ref` is permitted to have escaping regions.
-        // This is because here `self` has a `Binder` and so does our
-        // return value, so we are preserving the number of binding
-        // levels.
-        self.map_bound(|predicate| predicate.projection_term.trait_ref(cx))
-    }
-
     pub fn term(&self) -> ty::Binder<I, I::Term> {
         self.map_bound(|predicate| predicate.term)
     }
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index ad17911830b..0b013b2017f 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -171,16 +171,16 @@ impl<I: Interner> Relate<I> for ty::FnSig<I> {
             return Err(TypeError::VariadicMismatch({
                 let a = a.c_variadic;
                 let b = b.c_variadic;
-                ExpectedFound::new(true, a, b)
+                ExpectedFound::new(a, b)
             }));
         }
 
         if a.safety != b.safety {
-            return Err(TypeError::SafetyMismatch(ExpectedFound::new(true, a.safety, b.safety)));
+            return Err(TypeError::SafetyMismatch(ExpectedFound::new(a.safety, b.safety)));
         }
 
         if a.abi != b.abi {
-            return Err(TypeError::AbiMismatch(ExpectedFound::new(true, a.abi, b.abi)));
+            return Err(TypeError::AbiMismatch(ExpectedFound::new(a.abi, b.abi)));
         };
 
         let a_inputs = a.inputs();
@@ -233,7 +233,7 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> {
             Err(TypeError::ProjectionMismatched({
                 let a = a.def_id;
                 let b = b.def_id;
-                ExpectedFound::new(true, a, b)
+                ExpectedFound::new(a, b)
             }))
         } else {
             let args = match a.kind(relation.cx()) {
@@ -274,7 +274,7 @@ impl<I: Interner> Relate<I> for ty::AliasTerm<I> {
             Err(TypeError::ProjectionMismatched({
                 let a = a.def_id;
                 let b = b.def_id;
-                ExpectedFound::new(true, a, b)
+                ExpectedFound::new(a, b)
             }))
         } else {
             let args = match a.kind(relation.cx()) {
@@ -309,7 +309,7 @@ impl<I: Interner> Relate<I> for ty::ExistentialProjection<I> {
             Err(TypeError::ProjectionMismatched({
                 let a = a.def_id;
                 let b = b.def_id;
-                ExpectedFound::new(true, a, b)
+                ExpectedFound::new(a, b)
             }))
         } else {
             let term = relation.relate_with_variance(
@@ -340,7 +340,7 @@ impl<I: Interner> Relate<I> for ty::TraitRef<I> {
             Err(TypeError::Traits({
                 let a = a.def_id;
                 let b = b.def_id;
-                ExpectedFound::new(true, a, b)
+                ExpectedFound::new(a, b)
             }))
         } else {
             let args = relate_args_invariantly(relation, a.args, b.args)?;
@@ -360,7 +360,7 @@ impl<I: Interner> Relate<I> for ty::ExistentialTraitRef<I> {
             Err(TypeError::Traits({
                 let a = a.def_id;
                 let b = b.def_id;
-                ExpectedFound::new(true, a, b)
+                ExpectedFound::new(a, b)
             }))
         } else {
             let args = relate_args_invariantly(relation, a.args, b.args)?;
@@ -501,19 +501,10 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
             let t = relation.relate(a_t, b_t)?;
             match relation.relate(sz_a, sz_b) {
                 Ok(sz) => Ok(Ty::new_array_with_const_len(cx, t, sz)),
-                Err(err) => {
-                    // Check whether the lengths are both concrete/known values,
-                    // but are unequal, for better diagnostics.
-                    let sz_a = sz_a.try_to_target_usize(cx);
-                    let sz_b = sz_b.try_to_target_usize(cx);
-
-                    match (sz_a, sz_b) {
-                        (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err(
-                            TypeError::FixedArraySize(ExpectedFound::new(true, sz_a_val, sz_b_val)),
-                        ),
-                        _ => Err(err),
-                    }
+                Err(TypeError::ConstMismatch(_)) => {
+                    Err(TypeError::ArraySize(ExpectedFound::new(sz_a, sz_b)))
                 }
+                Err(e) => Err(e),
             }
         }
 
@@ -529,9 +520,9 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
                     iter::zip(as_.iter(), bs.iter()).map(|(a, b)| relation.relate(a, b)),
                 )?)
             } else if !(as_.is_empty() || bs.is_empty()) {
-                Err(TypeError::TupleSize(ExpectedFound::new(true, as_.len(), bs.len())))
+                Err(TypeError::TupleSize(ExpectedFound::new(as_.len(), bs.len())))
             } else {
-                Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
+                Err(TypeError::Sorts(ExpectedFound::new(a, b)))
             }
         }
 
@@ -558,7 +549,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
             Ok(Ty::new_pat(cx, ty, pat))
         }
 
-        _ => Err(TypeError::Sorts(ExpectedFound::new(true, a, b))),
+        _ => Err(TypeError::Sorts(ExpectedFound::new(a, b))),
     }
 }
 
@@ -637,7 +628,7 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
         }
         _ => false,
     };
-    if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(ExpectedFound::new(true, a, b))) }
+    if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(ExpectedFound::new(a, b))) }
 }
 
 impl<I: Interner, T: Relate<I>> Relate<I> for ty::Binder<I, T> {
@@ -658,9 +649,7 @@ impl<I: Interner> Relate<I> for ty::TraitPredicate<I> {
     ) -> RelateResult<I, ty::TraitPredicate<I>> {
         let trait_ref = relation.relate(a.trait_ref, b.trait_ref)?;
         if a.polarity != b.polarity {
-            return Err(TypeError::PolarityMismatch(ExpectedFound::new(
-                true, a.polarity, b.polarity,
-            )));
+            return Err(TypeError::PolarityMismatch(ExpectedFound::new(a.polarity, b.polarity)));
         }
         Ok(ty::TraitPredicate { trait_ref, polarity: a.polarity })
     }
diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs
index 53751f7711a..c8abfee314e 100644
--- a/compiler/rustc_type_ir/src/relate/combine.rs
+++ b/compiler/rustc_type_ir/src/relate/combine.rs
@@ -123,13 +123,11 @@ where
         }
 
         // All other cases of inference are errors
-        (ty::Infer(_), _) | (_, ty::Infer(_)) => {
-            Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
-        }
+        (ty::Infer(_), _) | (_, ty::Infer(_)) => Err(TypeError::Sorts(ExpectedFound::new(a, b))),
 
         (ty::Alias(ty::Opaque, _), _) | (_, ty::Alias(ty::Opaque, _)) => {
             assert!(!infcx.next_trait_solver());
-            match infcx.typing_mode(relation.param_env()) {
+            match infcx.typing_mode() {
                 // During coherence, opaque types should be treated as *possibly*
                 // equal to any other type. This is an
                 // extremely heavy hammer, but can be relaxed in a forwards-compatible
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index fe455873051..8fe512026e5 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -10,54 +10,6 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen
 
 use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast};
 
-/// Depending on the stage of compilation, we want projection to be
-/// more or less conservative.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
-pub enum Reveal {
-    /// At type-checking time, we refuse to project any associated
-    /// type that is marked `default`. Non-`default` ("final") types
-    /// are always projected. This is necessary in general for
-    /// soundness of specialization. However, we *could* allow
-    /// projections in fully-monomorphic cases. We choose not to,
-    /// because we prefer for `default type` to force the type
-    /// definition to be treated abstractly by any consumers of the
-    /// impl. Concretely, that means that the following example will
-    /// fail to compile:
-    ///
-    /// ```compile_fail,E0308
-    /// #![feature(specialization)]
-    /// trait Assoc {
-    ///     type Output;
-    /// }
-    ///
-    /// impl<T> Assoc for T {
-    ///     default type Output = bool;
-    /// }
-    ///
-    /// fn main() {
-    ///     let x: <() as Assoc>::Output = true;
-    /// }
-    /// ```
-    ///
-    /// We also do not reveal the hidden type of opaque types during
-    /// type-checking.
-    UserFacing,
-
-    /// At codegen time, all monomorphic projections will succeed.
-    /// Also, `impl Trait` is normalized to the concrete type,
-    /// which has to be already collected by type-checking.
-    ///
-    /// NOTE: as `impl Trait`'s concrete type should *never*
-    /// be observable directly by the user, `Reveal::All`
-    /// should not be used by checks which may expose
-    /// type equality or type contents to the user.
-    /// There are some exceptions, e.g., around auto traits and
-    /// transmute-checking, which expose some details, but
-    /// not the whole concrete type of the `impl Trait`.
-    All,
-}
-
 pub type CanonicalInput<I, T = <I as Interner>::Predicate> =
     ty::CanonicalQueryInput<I, QueryInput<I, T>>;
 pub type CanonicalResponse<I> = Canonical<I, Response<I>>;
@@ -326,3 +278,10 @@ impl MaybeCause {
         }
     }
 }
+
+/// Indicates that a `impl Drop for Adt` is `const` or not.
+#[derive(Debug)]
+pub enum AdtDestructorKind {
+    NotConst,
+    Const,
+}
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index 499e6d3dd37..033fcdb6c03 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -41,7 +41,7 @@ pub enum AliasTyKind {
     /// An associated type in an inherent `impl`
     Inherent,
     /// An opaque type (usually from `impl Trait` in type aliases or function return types)
-    /// Can only be normalized away in RevealAll mode
+    /// Can only be normalized away in PostAnalysis mode or its defining scope.
     Opaque,
     /// A type alias that actually checks its trait bounds.
     /// Currently only used if the type alias references opaque types.
diff --git a/config.example.toml b/config.example.toml
index d3233ad17b5..9ec0d77e79b 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -496,15 +496,18 @@
 #
 #debug = false
 
-# Whether to download the stage 1 and 2 compilers from CI.
-# This is useful if you are working on tools, doc-comments, or library (you will be able to build
-# the standard library without needing to build the compiler).
+# Whether to download the stage 1 and 2 compilers from CI. This is useful if you
+# are working on tools, doc-comments, or library (you will be able to build the
+# standard library without needing to build the compiler).
 #
-# Set this to "if-unchanged" if you are working on `src/tools`, `tests` or `library` (on CI, `library`
-# changes triggers in-tree compiler build) to speed up the build process.
+# Set this to "if-unchanged" if you are working on `src/tools`, `tests` or
+# `library` (on CI, `library` changes triggers in-tree compiler build) to speed
+# up the build process if you don't need to build a compiler from the latest
+# commit from `master`.
 #
-# Set this to `true` to always download or `false` to always use the in-tree compiler.
-#download-rustc = "if-unchanged"
+# Set this to `true` to always download or `false` to always use the in-tree
+# compiler.
+#download-rustc = false
 
 # Number of codegen units to use for each compiler invocation. A value of 0
 # means "the number of cores on this machine", and 1+ is passed through to the
@@ -770,6 +773,7 @@
 #validate-mir-opts = 3
 
 # Configure `std` features used during bootstrap.
+#
 # Default features will be expanded in the following cases:
 #  - If `rust.llvm-libunwind` or `target.llvm-libunwind` is enabled:
 #    - "llvm-libunwind" will be added for in-tree LLVM builds.
@@ -777,6 +781,9 @@
 #  - If `rust.backtrace` is enabled, "backtrace" will be added.
 #  - If `rust.profiler` or `target.profiler` is enabled, "profiler" will be added.
 #  - If building for a zkvm target, "compiler-builtins-mem" will be added.
+#
+# Since libstd also builds libcore and liballoc as dependencies and all their features are mirrored
+# as libstd features, this option can also be used to configure features such as optimize_for_size.
 #std-features = ["panic_unwind"]
 
 # =============================================================================
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 97996d5f0b2..197e0a8fedb 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -42,9 +42,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
 
 [[package]]
 name = "cc"
-version = "1.1.22"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0"
+checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8"
 dependencies = [
  "shlex",
 ]
@@ -235,8 +235,6 @@ name = "profiler_builtins"
 version = "0.0.0"
 dependencies = [
  "cc",
- "compiler_builtins",
- "core",
 ]
 
 [[package]]
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 98402a46201..04b7315e650 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -61,7 +61,7 @@ pub use std::alloc::Global;
 /// of the allocator registered with the `#[global_allocator]` attribute
 /// if there is one, or the `std` crate’s default.
 ///
-/// This function is expected to be deprecated in favor of the `alloc` method
+/// This function is expected to be deprecated in favor of the `allocate` method
 /// of the [`Global`] type when it and the [`Allocator`] trait become stable.
 ///
 /// # Safety
@@ -106,7 +106,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 {
 /// of the allocator registered with the `#[global_allocator]` attribute
 /// if there is one, or the `std` crate’s default.
 ///
-/// This function is expected to be deprecated in favor of the `dealloc` method
+/// This function is expected to be deprecated in favor of the `deallocate` method
 /// of the [`Global`] type when it and the [`Allocator`] trait become stable.
 ///
 /// # Safety
@@ -125,7 +125,7 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
 /// of the allocator registered with the `#[global_allocator]` attribute
 /// if there is one, or the `std` crate’s default.
 ///
-/// This function is expected to be deprecated in favor of the `realloc` method
+/// This function is expected to be deprecated in favor of the `grow` and `shrink` methods
 /// of the [`Global`] type when it and the [`Allocator`] trait become stable.
 ///
 /// # Safety
@@ -145,7 +145,7 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8
 /// of the allocator registered with the `#[global_allocator]` attribute
 /// if there is one, or the `std` crate’s default.
 ///
-/// This function is expected to be deprecated in favor of the `alloc_zeroed` method
+/// This function is expected to be deprecated in favor of the `allocate_zeroed` method
 /// of the [`Global`] type when it and the [`Allocator`] trait become stable.
 ///
 /// # Safety
diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs
index 75bb86916a8..0da6af54bc2 100644
--- a/library/alloc/src/collections/btree/map/entry.rs
+++ b/library/alloc/src/collections/btree/map/entry.rs
@@ -269,6 +269,31 @@ impl<'a, K: Ord, V, A: Allocator + Clone> Entry<'a, K, V, A> {
             Vacant(entry) => Vacant(entry),
         }
     }
+
+    /// Sets the value of the entry, and returns an `OccupiedEntry`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(btree_entry_insert)]
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map: BTreeMap<&str, String> = BTreeMap::new();
+    /// let entry = map.entry("poneyland").insert_entry("hoho".to_string());
+    ///
+    /// assert_eq!(entry.key(), &"poneyland");
+    /// ```
+    #[inline]
+    #[unstable(feature = "btree_entry_insert", issue = "65225")]
+    pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, A> {
+        match self {
+            Occupied(mut entry) => {
+                entry.insert(value);
+                entry
+            }
+            Vacant(entry) => entry.insert_entry(value),
+        }
+    }
 }
 
 impl<'a, K: Ord, V: Default, A: Allocator + Clone> Entry<'a, K, V, A> {
@@ -348,41 +373,61 @@ impl<'a, K: Ord, V, A: Allocator + Clone> VacantEntry<'a, K, V, A> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_confusables("push", "put")]
-    pub fn insert(mut self, value: V) -> &'a mut V {
-        let out_ptr = match self.handle {
+    pub fn insert(self, value: V) -> &'a mut V {
+        self.insert_entry(value).into_mut()
+    }
+
+    /// Sets the value of the entry with the `VacantEntry`'s key,
+    /// and returns an `OccupiedEntry`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(btree_entry_insert)]
+    /// use std::collections::BTreeMap;
+    /// use std::collections::btree_map::Entry;
+    ///
+    /// let mut map: BTreeMap<&str, u32> = BTreeMap::new();
+    ///
+    /// if let Entry::Vacant(o) = map.entry("poneyland") {
+    ///     let entry = o.insert_entry(37);
+    ///     assert_eq!(entry.get(), &37);
+    /// }
+    /// assert_eq!(map["poneyland"], 37);
+    /// ```
+    #[unstable(feature = "btree_entry_insert", issue = "65225")]
+    pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V, A> {
+        let handle = match self.handle {
             None => {
                 // SAFETY: There is no tree yet so no reference to it exists.
-                let map = unsafe { self.dormant_map.awaken() };
-                let mut root = NodeRef::new_leaf(self.alloc.clone());
-                let val_ptr = root.borrow_mut().push(self.key, value);
-                map.root = Some(root.forget_type());
-                map.length = 1;
-                val_ptr
-            }
-            Some(handle) => {
-                let new_handle =
-                    handle.insert_recursing(self.key, value, self.alloc.clone(), |ins| {
-                        drop(ins.left);
-                        // SAFETY: Pushing a new root node doesn't invalidate
-                        // handles to existing nodes.
-                        let map = unsafe { self.dormant_map.reborrow() };
-                        let root = map.root.as_mut().unwrap(); // same as ins.left
-                        root.push_internal_level(self.alloc).push(ins.kv.0, ins.kv.1, ins.right)
-                    });
-
-                // Get the pointer to the value
-                let val_ptr = new_handle.into_val_mut();
-
-                // SAFETY: We have consumed self.handle.
-                let map = unsafe { self.dormant_map.awaken() };
-                map.length += 1;
-                val_ptr
+                let map = unsafe { self.dormant_map.reborrow() };
+                let root = map.root.insert(NodeRef::new_leaf(self.alloc.clone()).forget_type());
+                // SAFETY: We *just* created the root as a leaf, and we're
+                // stacking the new handle on the original borrow lifetime.
+                unsafe {
+                    let mut leaf = root.borrow_mut().cast_to_leaf_unchecked();
+                    leaf.push_with_handle(self.key, value)
+                }
             }
+            Some(handle) => handle.insert_recursing(self.key, value, self.alloc.clone(), |ins| {
+                drop(ins.left);
+                // SAFETY: Pushing a new root node doesn't invalidate
+                // handles to existing nodes.
+                let map = unsafe { self.dormant_map.reborrow() };
+                let root = map.root.as_mut().unwrap(); // same as ins.left
+                root.push_internal_level(self.alloc.clone()).push(ins.kv.0, ins.kv.1, ins.right)
+            }),
         };
 
-        // Now that we have finished growing the tree using borrowed references,
-        // dereference the pointer to a part of it, that we picked up along the way.
-        unsafe { &mut *out_ptr }
+        // SAFETY: modifying the length doesn't invalidate handles to existing nodes.
+        unsafe { self.dormant_map.reborrow().length += 1 };
+
+        OccupiedEntry {
+            handle: handle.forget_node_type(),
+            dormant_map: self.dormant_map,
+            alloc: self.alloc,
+            _marker: PhantomData,
+        }
     }
 }
 
diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs
index db16d82be7d..5975134382e 100644
--- a/library/alloc/src/collections/btree/map/tests.rs
+++ b/library/alloc/src/collections/btree/map/tests.rs
@@ -2272,6 +2272,54 @@ fn test_into_iter_drop_leak_height_0() {
 
 #[test]
 #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+fn test_into_iter_drop_leak_kv_panic_in_key() {
+    let a_k = CrashTestDummy::new(0);
+    let a_v = CrashTestDummy::new(1);
+    let b_k = CrashTestDummy::new(2);
+    let b_v = CrashTestDummy::new(3);
+    let c_k = CrashTestDummy::new(4);
+    let c_v = CrashTestDummy::new(5);
+    let mut map = BTreeMap::new();
+    map.insert(a_k.spawn(Panic::Never), a_v.spawn(Panic::Never));
+    map.insert(b_k.spawn(Panic::InDrop), b_v.spawn(Panic::Never));
+    map.insert(c_k.spawn(Panic::Never), c_v.spawn(Panic::Never));
+
+    catch_unwind(move || drop(map.into_iter())).unwrap_err();
+
+    assert_eq!(a_k.dropped(), 1);
+    assert_eq!(a_v.dropped(), 1);
+    assert_eq!(b_k.dropped(), 1);
+    assert_eq!(b_v.dropped(), 1);
+    assert_eq!(c_k.dropped(), 1);
+    assert_eq!(c_v.dropped(), 1);
+}
+
+#[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+fn test_into_iter_drop_leak_kv_panic_in_val() {
+    let a_k = CrashTestDummy::new(0);
+    let a_v = CrashTestDummy::new(1);
+    let b_k = CrashTestDummy::new(2);
+    let b_v = CrashTestDummy::new(3);
+    let c_k = CrashTestDummy::new(4);
+    let c_v = CrashTestDummy::new(5);
+    let mut map = BTreeMap::new();
+    map.insert(a_k.spawn(Panic::Never), a_v.spawn(Panic::Never));
+    map.insert(b_k.spawn(Panic::Never), b_v.spawn(Panic::InDrop));
+    map.insert(c_k.spawn(Panic::Never), c_v.spawn(Panic::Never));
+
+    catch_unwind(move || drop(map.into_iter())).unwrap_err();
+
+    assert_eq!(a_k.dropped(), 1);
+    assert_eq!(a_v.dropped(), 1);
+    assert_eq!(b_k.dropped(), 1);
+    assert_eq!(b_v.dropped(), 1);
+    assert_eq!(c_k.dropped(), 1);
+    assert_eq!(c_v.dropped(), 1);
+}
+
+#[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_into_iter_drop_leak_height_1() {
     let size = MIN_INSERTS_HEIGHT_1;
     for panic_point in vec![0, 1, size - 2, size - 1] {
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index 2a853ef4216..0c93eff0d20 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -739,7 +739,7 @@ impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
 
 impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
     /// Unsafely asserts to the compiler the static information that this node is a `Leaf`.
-    unsafe fn cast_to_leaf_unchecked(self) -> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
+    pub unsafe fn cast_to_leaf_unchecked(self) -> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
         debug_assert!(self.height == 0);
         NodeRef { height: self.height, node: self.node, _marker: PhantomData }
     }
@@ -1173,11 +1173,25 @@ impl<K, V, NodeType> Handle<NodeRef<marker::Dying, K, V, NodeType>, marker::KV>
     /// The node that the handle refers to must not yet have been deallocated.
     #[inline]
     pub unsafe fn drop_key_val(mut self) {
+        // Run the destructor of the value even if the destructor of the key panics.
+        struct Dropper<'a, T>(&'a mut MaybeUninit<T>);
+        impl<T> Drop for Dropper<'_, T> {
+            #[inline]
+            fn drop(&mut self) {
+                unsafe {
+                    self.0.assume_init_drop();
+                }
+            }
+        }
+
         debug_assert!(self.idx < self.node.len());
         let leaf = self.node.as_leaf_dying();
         unsafe {
-            leaf.keys.get_unchecked_mut(self.idx).assume_init_drop();
-            leaf.vals.get_unchecked_mut(self.idx).assume_init_drop();
+            let key = leaf.keys.get_unchecked_mut(self.idx);
+            let val = leaf.vals.get_unchecked_mut(self.idx);
+            let _guard = Dropper(val);
+            key.assume_init_drop();
+            // dropping the guard will drop the value
         }
     }
 }
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 4764d7f0b0f..67fbda34bb9 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -10,11 +10,13 @@ use crate::convert::Infallible;
 use crate::error::Error;
 use crate::fmt;
 use crate::hash::{self, Hash};
+use crate::intrinsics::transmute_unchecked;
 use crate::iter::{UncheckedIterator, repeat_n};
 use crate::mem::{self, MaybeUninit};
 use crate::ops::{
     ChangeOutputType, ControlFlow, FromResidual, Index, IndexMut, NeverShortCircuit, Residual, Try,
 };
+use crate::ptr::{null, null_mut};
 use crate::slice::{Iter, IterMut};
 
 mod ascii;
@@ -577,7 +579,8 @@ impl<T, const N: usize> [T; N] {
     /// Returns a mutable slice containing the entire array. Equivalent to
     /// `&mut s[..]`.
     #[stable(feature = "array_as_slice", since = "1.57.0")]
-    pub fn as_mut_slice(&mut self) -> &mut [T] {
+    #[rustc_const_unstable(feature = "const_array_as_mut_slice", issue = "133333")]
+    pub const fn as_mut_slice(&mut self) -> &mut [T] {
         self
     }
 
@@ -606,8 +609,20 @@ impl<T, const N: usize> [T; N] {
     /// assert_eq!(strings.len(), 3);
     /// ```
     #[stable(feature = "array_methods", since = "1.77.0")]
-    pub fn each_ref(&self) -> [&T; N] {
-        from_trusted_iterator(self.iter())
+    #[rustc_const_unstable(feature = "const_array_each_ref", issue = "133289")]
+    pub const fn each_ref(&self) -> [&T; N] {
+        let mut buf = [null::<T>(); N];
+
+        // FIXME(const-hack): We would like to simply use iterators for this (as in the original implementation), but this is not allowed in constant expressions.
+        let mut i = 0;
+        while i < N {
+            buf[i] = &raw const self[i];
+
+            i += 1;
+        }
+
+        // SAFETY: `*const T` has the same layout as `&T`, and we've also initialised each pointer as a valid reference.
+        unsafe { transmute_unchecked(buf) }
     }
 
     /// Borrows each element mutably and returns an array of mutable references
@@ -625,8 +640,20 @@ impl<T, const N: usize> [T; N] {
     /// assert_eq!(floats, [0.0, 2.7, -1.0]);
     /// ```
     #[stable(feature = "array_methods", since = "1.77.0")]
-    pub fn each_mut(&mut self) -> [&mut T; N] {
-        from_trusted_iterator(self.iter_mut())
+    #[rustc_const_unstable(feature = "const_array_each_ref", issue = "133289")]
+    pub const fn each_mut(&mut self) -> [&mut T; N] {
+        let mut buf = [null_mut::<T>(); N];
+
+        // FIXME(const-hack): We would like to simply use iterators for this (as in the original implementation), but this is not allowed in constant expressions.
+        let mut i = 0;
+        while i < N {
+            buf[i] = &raw mut self[i];
+
+            i += 1;
+        }
+
+        // SAFETY: `*mut T` has the same layout as `&mut T`, and we've also initialised each pointer as a valid reference.
+        unsafe { transmute_unchecked(buf) }
     }
 
     /// Divides one array reference into two at an index.
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index f2d7e0f481e..683e45b35f7 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -199,32 +199,12 @@ static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\
       8081828384858687888990919293949596979899";
 
 macro_rules! impl_Display {
-    ($($t:ident $(as $positive:ident)? named $name:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => {
+    ($($signed:ident, $unsigned:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => {
 
         $(
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl fmt::Display for $t {
+        impl fmt::Display for $unsigned {
             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                // If it's a signed integer.
-                $(
-                    let is_nonnegative = *self >= 0;
-
-                    #[cfg(not(feature = "optimize_for_size"))]
-                    {
-                        if !is_nonnegative {
-                            // convert the negative num to positive by summing 1 to its 2s complement
-                            return (!self as $positive).wrapping_add(1)._fmt(false, f);
-                        }
-                    }
-                    #[cfg(feature = "optimize_for_size")]
-                    {
-                        if !is_nonnegative {
-                            // convert the negative num to positive by summing 1 to its 2s complement
-                            return $gen_name((!self.$conv_fn()).wrapping_add(1), false, f);
-                        }
-                    }
-                )?
-                // If it's a positive integer.
                 #[cfg(not(feature = "optimize_for_size"))]
                 {
                     self._fmt(true, f)
@@ -236,10 +216,24 @@ macro_rules! impl_Display {
             }
         }
 
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl fmt::Display for $signed {
+            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                #[cfg(not(feature = "optimize_for_size"))]
+                {
+                    return self.unsigned_abs()._fmt(*self >= 0, f);
+                }
+                #[cfg(feature = "optimize_for_size")]
+                {
+                    return $gen_name(self.unsigned_abs().$conv_fn(), *self >= 0, f);
+                }
+            }
+        }
+
         #[cfg(not(feature = "optimize_for_size"))]
-        impl $t {
-            fn _fmt(mut self: $t, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                const SIZE: usize = $t::MAX.ilog(10) as usize + 1;
+        impl $unsigned {
+            fn _fmt(mut self, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                const SIZE: usize = $unsigned::MAX.ilog(10) as usize + 1;
                 let mut buf = [MaybeUninit::<u8>::uninit(); SIZE];
                 let mut curr = SIZE;
                 let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
@@ -258,7 +252,7 @@ macro_rules! impl_Display {
                     #[allow(unused_comparisons)]
                     // This block will be removed for smaller types at compile time and in the worst
                     // case, it will prevent to have the `10000` literal to overflow for `i8` and `u8`.
-                    if core::mem::size_of::<$t>() >= 2 {
+                    if core::mem::size_of::<$unsigned>() >= 2 {
                         // eagerly decode 4 characters at a time
                         while self >= 10000 {
                             let rem = (self % 10000) as usize;
@@ -312,8 +306,8 @@ macro_rules! impl_Display {
 
         #[cfg(feature = "optimize_for_size")]
         fn $gen_name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            // 2^128 is about 3*10^38, so 39 gives an extra byte of space
-            let mut buf = [MaybeUninit::<u8>::uninit(); 39];
+            const SIZE: usize = $u::MAX.ilog(10) as usize + 1;
+            let mut buf = [MaybeUninit::<u8>::uninit(); SIZE];
             let mut curr = buf.len();
             let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
 
@@ -523,16 +517,11 @@ impl_Debug! {
 mod imp {
     use super::*;
     impl_Display!(
-        i8 as u8 named fmt_i8,
-        u8 named fmt_u8,
-        i16 as u16  named fmt_i16,
-        u16 named fmt_u16,
-        i32 as u32 named fmt_i32,
-        u32 named fmt_u32,
-        i64 as u64 named fmt_i64,
-        u64 named fmt_u64,
-        isize as usize named fmt_isize,
-        usize named fmt_usize,
+        i8, u8,
+        i16, u16,
+        i32, u32,
+        i64, u64,
+        isize, usize,
         ; as u64 via to_u64 named fmt_u64
     );
     impl_Exp!(
@@ -545,18 +534,13 @@ mod imp {
 mod imp {
     use super::*;
     impl_Display!(
-        i8 as u8 named fmt_i8,
-        u8 named fmt_u8,
-        i16 as u16  named fmt_i16,
-        u16 named fmt_u16,
-        i32 as u32 named fmt_i32,
-        u32 named fmt_u32,
-        isize as usize named fmt_isize,
-        usize named fmt_usize,
+        i8, u8,
+        i16, u16,
+        i32, u32,
+        isize, usize,
         ; as u32 via to_u32 named fmt_u32);
     impl_Display!(
-        i64 as u64 named fmt_i64,
-        u64 named fmt_u64,
+        i64, u64,
         ; as u64 via to_u64 named fmt_u64);
 
     impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize as u32 via to_u32 named exp_u32);
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index e9859a58696..2f75bfae988 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -4267,7 +4267,11 @@ pub const fn minnumf16(_x: f16, _y: f16) -> f16 {
 /// The stabilized version of this intrinsic is
 /// [`f32::min`]
 #[rustc_nounwind]
-#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
+#[cfg_attr(
+    bootstrap,
+    rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")
+)]
+#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn minnumf32(_x: f32, _y: f32) -> f32 {
@@ -4284,7 +4288,11 @@ pub const fn minnumf32(_x: f32, _y: f32) -> f32 {
 /// The stabilized version of this intrinsic is
 /// [`f64::min`]
 #[rustc_nounwind]
-#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
+#[cfg_attr(
+    bootstrap,
+    rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")
+)]
+#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn minnumf64(_x: f64, _y: f64) -> f64 {
@@ -4335,7 +4343,11 @@ pub const fn maxnumf16(_x: f16, _y: f16) -> f16 {
 /// The stabilized version of this intrinsic is
 /// [`f32::max`]
 #[rustc_nounwind]
-#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
+#[cfg_attr(
+    bootstrap,
+    rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")
+)]
+#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn maxnumf32(_x: f32, _y: f32) -> f32 {
@@ -4352,7 +4364,11 @@ pub const fn maxnumf32(_x: f32, _y: f32) -> f32 {
 /// The stabilized version of this intrinsic is
 /// [`f64::max`]
 #[rustc_nounwind]
-#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
+#[cfg_attr(
+    bootstrap,
+    rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")
+)]
+#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn maxnumf64(_x: f64, _y: f64) -> f64 {
@@ -4393,7 +4409,11 @@ pub const unsafe fn fabsf16(_x: f16) -> f16 {
 /// The stabilized version of this intrinsic is
 /// [`f32::abs`](../../std/primitive.f32.html#method.abs)
 #[rustc_nounwind]
-#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
+#[cfg_attr(
+    bootstrap,
+    rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")
+)]
+#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn fabsf32(_x: f32) -> f32 {
@@ -4405,7 +4425,11 @@ pub const unsafe fn fabsf32(_x: f32) -> f32 {
 /// The stabilized version of this intrinsic is
 /// [`f64::abs`](../../std/primitive.f64.html#method.abs)
 #[rustc_nounwind]
-#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
+#[cfg_attr(
+    bootstrap,
+    rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")
+)]
+#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn fabsf64(_x: f64) -> f64 {
@@ -4441,7 +4465,11 @@ pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 {
 /// The stabilized version of this intrinsic is
 /// [`f32::copysign`](../../std/primitive.f32.html#method.copysign)
 #[rustc_nounwind]
-#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
+#[cfg_attr(
+    bootstrap,
+    rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")
+)]
+#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 {
@@ -4452,7 +4480,11 @@ pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 {
 /// The stabilized version of this intrinsic is
 /// [`f64::copysign`](../../std/primitive.f64.html#method.copysign)
 #[rustc_nounwind]
-#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_float_methods", issue = "130843"))]
+#[cfg_attr(
+    bootstrap,
+    rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")
+)]
+#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 {
diff --git a/library/core/src/io/borrowed_buf.rs b/library/core/src/io/borrowed_buf.rs
index dbc60aa8154..4227e503ba7 100644
--- a/library/core/src/io/borrowed_buf.rs
+++ b/library/core/src/io/borrowed_buf.rs
@@ -108,6 +108,26 @@ impl<'data> BorrowedBuf<'data> {
         }
     }
 
+    /// Returns a shared reference to the filled portion of the buffer with its original lifetime.
+    #[inline]
+    pub fn into_filled(self) -> &'data [u8] {
+        // SAFETY: We only slice the filled part of the buffer, which is always valid
+        unsafe {
+            let buf = self.buf.get_unchecked(..self.filled);
+            MaybeUninit::slice_assume_init_ref(buf)
+        }
+    }
+
+    /// Returns a mutable reference to the filled portion of the buffer with its original lifetime.
+    #[inline]
+    pub fn into_filled_mut(self) -> &'data mut [u8] {
+        // SAFETY: We only slice the filled part of the buffer, which is always valid
+        unsafe {
+            let buf = self.buf.get_unchecked_mut(..self.filled);
+            MaybeUninit::slice_assume_init_mut(buf)
+        }
+    }
+
     /// Returns a cursor over the unfilled part of the buffer.
     #[inline]
     pub fn unfilled<'this>(&'this mut self) -> BorrowedCursor<'this> {
diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
index da4f68a0de4..4fa719de5eb 100644
--- a/library/core/src/iter/range.rs
+++ b/library/core/src/iter/range.rs
@@ -22,23 +22,21 @@ unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u6
 /// The *predecessor* operation moves towards values that compare lesser.
 #[unstable(feature = "step_trait", issue = "42168")]
 pub trait Step: Clone + PartialOrd + Sized {
-    /// Returns the number of *successor* steps required to get from `start` to `end`.
+    /// Returns the bounds on the number of *successor* steps required to get from `start` to `end`
+    /// like [`Iterator::size_hint()`][Iterator::size_hint()].
     ///
-    /// Returns `None` if the number of steps would overflow `usize`
-    /// (or is infinite, or if `end` would never be reached).
+    /// Returns `(usize::MAX, None)` if the number of steps would overflow `usize`, or is infinite.
     ///
     /// # Invariants
     ///
     /// For any `a`, `b`, and `n`:
     ///
-    /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::forward_checked(&a, n) == Some(b)`
-    /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::backward_checked(&b, n) == Some(a)`
-    /// * `steps_between(&a, &b) == Some(n)` only if `a <= b`
-    ///   * Corollary: `steps_between(&a, &b) == Some(0)` if and only if `a == b`
-    ///   * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`;
-    ///     this is the case when it would require more than `usize::MAX` steps to get to `b`
-    /// * `steps_between(&a, &b) == None` if `a > b`
-    fn steps_between(start: &Self, end: &Self) -> Option<usize>;
+    /// * `steps_between(&a, &b) == (n, Some(n))` if and only if `Step::forward_checked(&a, n) == Some(b)`
+    /// * `steps_between(&a, &b) == (n, Some(n))` if and only if `Step::backward_checked(&b, n) == Some(a)`
+    /// * `steps_between(&a, &b) == (n, Some(n))` only if `a <= b`
+    ///   * Corollary: `steps_between(&a, &b) == (0, Some(0))` if and only if `a == b`
+    /// * `steps_between(&a, &b) == (0, None)` if `a > b`
+    fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>);
 
     /// Returns the value that would be obtained by taking the *successor*
     /// of `self` `count` times.
@@ -169,7 +167,7 @@ pub trait Step: Clone + PartialOrd + Sized {
     /// For any `a`:
     ///
     /// * if there exists `b` such that `b < a`, it is safe to call `Step::backward_unchecked(a, 1)`
-    /// * if there exists `b`, `n` such that `steps_between(&b, &a) == Some(n)`,
+    /// * if there exists `b`, `n` such that `steps_between(&b, &a) == (n, Some(n))`,
     ///   it is safe to call `Step::backward_unchecked(a, m)` for any `m <= n`.
     ///   * Corollary: `Step::backward_unchecked(a, 0)` is always safe.
     ///
@@ -261,12 +259,13 @@ macro_rules! step_integer_impls {
                 step_unsigned_methods!();
 
                 #[inline]
-                fn steps_between(start: &Self, end: &Self) -> Option<usize> {
+                fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
                     if *start <= *end {
                         // This relies on $u_narrower <= usize
-                        Some((*end - *start) as usize)
+                        let steps = (*end - *start) as usize;
+                        (steps, Some(steps))
                     } else {
-                        None
+                        (0, None)
                     }
                 }
 
@@ -294,16 +293,17 @@ macro_rules! step_integer_impls {
                 step_signed_methods!($u_narrower);
 
                 #[inline]
-                fn steps_between(start: &Self, end: &Self) -> Option<usize> {
+                fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
                     if *start <= *end {
                         // This relies on $i_narrower <= usize
                         //
                         // Casting to isize extends the width but preserves the sign.
                         // Use wrapping_sub in isize space and cast to usize to compute
                         // the difference that might not fit inside the range of isize.
-                        Some((*end as isize).wrapping_sub(*start as isize) as usize)
+                        let steps = (*end as isize).wrapping_sub(*start as isize) as usize;
+                        (steps, Some(steps))
                     } else {
-                        None
+                        (0, None)
                     }
                 }
 
@@ -359,11 +359,15 @@ macro_rules! step_integer_impls {
                 step_unsigned_methods!();
 
                 #[inline]
-                fn steps_between(start: &Self, end: &Self) -> Option<usize> {
+                fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
                     if *start <= *end {
-                        usize::try_from(*end - *start).ok()
+                        if let Ok(steps) = usize::try_from(*end - *start) {
+                            (steps, Some(steps))
+                        } else {
+                            (usize::MAX, None)
+                        }
                     } else {
-                        None
+                        (0, None)
                     }
                 }
 
@@ -385,16 +389,22 @@ macro_rules! step_integer_impls {
                 step_signed_methods!($u_wider);
 
                 #[inline]
-                fn steps_between(start: &Self, end: &Self) -> Option<usize> {
+                fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
                     if *start <= *end {
                         match end.checked_sub(*start) {
-                            Some(result) => usize::try_from(result).ok(),
+                            Some(result) => {
+                                if let Ok(steps) = usize::try_from(result) {
+                                    (steps, Some(steps))
+                                } else {
+                                    (usize::MAX, None)
+                                }
+                            }
                             // If the difference is too big for e.g. i128,
                             // it's also gonna be too big for usize with fewer bits.
-                            None => None,
+                            None => (usize::MAX, None),
                         }
                     } else {
-                        None
+                        (0, None)
                     }
                 }
 
@@ -433,18 +443,26 @@ step_integer_impls! {
 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
 impl Step for char {
     #[inline]
-    fn steps_between(&start: &char, &end: &char) -> Option<usize> {
+    fn steps_between(&start: &char, &end: &char) -> (usize, Option<usize>) {
         let start = start as u32;
         let end = end as u32;
         if start <= end {
             let count = end - start;
             if start < 0xD800 && 0xE000 <= end {
-                usize::try_from(count - 0x800).ok()
+                if let Ok(steps) = usize::try_from(count - 0x800) {
+                    (steps, Some(steps))
+                } else {
+                    (usize::MAX, None)
+                }
             } else {
-                usize::try_from(count).ok()
+                if let Ok(steps) = usize::try_from(count) {
+                    (steps, Some(steps))
+                } else {
+                    (usize::MAX, None)
+                }
             }
         } else {
-            None
+            (0, None)
         }
     }
 
@@ -512,7 +530,7 @@ impl Step for char {
 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
 impl Step for AsciiChar {
     #[inline]
-    fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> Option<usize> {
+    fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> (usize, Option<usize>) {
         Step::steps_between(&start.to_u8(), &end.to_u8())
     }
 
@@ -554,7 +572,7 @@ impl Step for AsciiChar {
 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
 impl Step for Ipv4Addr {
     #[inline]
-    fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> Option<usize> {
+    fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> (usize, Option<usize>) {
         u32::steps_between(&start.to_bits(), &end.to_bits())
     }
 
@@ -586,7 +604,7 @@ impl Step for Ipv4Addr {
 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
 impl Step for Ipv6Addr {
     #[inline]
-    fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> Option<usize> {
+    fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> (usize, Option<usize>) {
         u128::steps_between(&start.to_bits(), &end.to_bits())
     }
 
@@ -690,11 +708,8 @@ impl<A: Step> RangeIteratorImpl for ops::Range<A> {
 
     #[inline]
     default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
-        let available = if self.start <= self.end {
-            Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
-        } else {
-            0
-        };
+        let steps = Step::steps_between(&self.start, &self.end);
+        let available = steps.1.unwrap_or(steps.0);
 
         let taken = available.min(n);
 
@@ -731,11 +746,8 @@ impl<A: Step> RangeIteratorImpl for ops::Range<A> {
 
     #[inline]
     default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
-        let available = if self.start <= self.end {
-            Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
-        } else {
-            0
-        };
+        let steps = Step::steps_between(&self.start, &self.end);
+        let available = steps.1.unwrap_or(steps.0);
 
         let taken = available.min(n);
 
@@ -775,11 +787,8 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
 
     #[inline]
     fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
-        let available = if self.start <= self.end {
-            Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
-        } else {
-            0
-        };
+        let steps = Step::steps_between(&self.start, &self.end);
+        let available = steps.1.unwrap_or(steps.0);
 
         let taken = available.min(n);
 
@@ -819,11 +828,8 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
 
     #[inline]
     fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
-        let available = if self.start <= self.end {
-            Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
-        } else {
-            0
-        };
+        let steps = Step::steps_between(&self.start, &self.end);
+        let available = steps.1.unwrap_or(steps.0);
 
         let taken = available.min(n);
 
@@ -846,8 +852,7 @@ impl<A: Step> Iterator for ops::Range<A> {
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         if self.start < self.end {
-            let hint = Step::steps_between(&self.start, &self.end);
-            (hint.unwrap_or(usize::MAX), hint)
+            Step::steps_between(&self.start, &self.end)
         } else {
             (0, Some(0))
         }
@@ -856,7 +861,7 @@ impl<A: Step> Iterator for ops::Range<A> {
     #[inline]
     fn count(self) -> usize {
         if self.start < self.end {
-            Step::steps_between(&self.start, &self.end).expect("count overflowed usize")
+            Step::steps_between(&self.start, &self.end).1.expect("count overflowed usize")
         } else {
             0
         }
@@ -980,11 +985,11 @@ impl<A: Step> DoubleEndedIterator for ops::Range<A> {
 // Safety:
 // The following invariants for `Step::steps_between` exist:
 //
-// > * `steps_between(&a, &b) == Some(n)` only if `a <= b`
-// >   * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`;
+// > * `steps_between(&a, &b) == (n, Some(n))` only if `a <= b`
+// >   * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != (n, None)`;
 // >     this is the case when it would require more than `usize::MAX` steps to
 // >     get to `b`
-// > * `steps_between(&a, &b) == None` if `a > b`
+// > * `steps_between(&a, &b) == (0, None)` if `a > b`
 //
 // The first invariant is what is generally required for `TrustedLen` to be
 // sound. The note addendum satisfies an additional `TrustedLen` invariant.
@@ -1253,10 +1258,8 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
             return (0, Some(0));
         }
 
-        match Step::steps_between(&self.start, &self.end) {
-            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
-            None => (usize::MAX, None),
-        }
+        let hint = Step::steps_between(&self.start, &self.end);
+        (hint.0.saturating_add(1), hint.1.and_then(|steps| steps.checked_add(1)))
     }
 
     #[inline]
@@ -1266,6 +1269,7 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
         }
 
         Step::steps_between(&self.start, &self.end)
+            .1
             .and_then(|steps| steps.checked_add(1))
             .expect("count overflowed usize")
     }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index d30bf96cfd4..a178d101254 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -118,7 +118,6 @@
 #![feature(const_black_box)]
 #![feature(const_eq_ignore_ascii_case)]
 #![feature(const_eval_select)]
-#![feature(const_float_methods)]
 #![feature(const_heap)]
 #![feature(const_nonnull_new)]
 #![feature(const_ptr_sub_ptr)]
@@ -174,6 +173,7 @@
 #![feature(const_is_char_boundary)]
 #![feature(const_precise_live_drops)]
 #![feature(const_str_split_at)]
+#![feature(const_trait_impl)]
 #![feature(decl_macro)]
 #![feature(deprecated_suggestion)]
 #![feature(doc_cfg)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index c8ea52a1fb0..1620b949590 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -953,10 +953,11 @@ marker_impls! {
 ///
 /// This should be used for `~const` bounds,
 /// as non-const bounds will always hold for every type.
-#[unstable(feature = "const_trait_impl", issue = "67792")]
+#[unstable(feature = "const_destruct", issue = "133214")]
 #[lang = "destruct"]
 #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
 #[rustc_deny_explicit_impl(implement_via_object = false)]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Destruct {}
 
 /// A marker for tuple types.
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 58315cb74f0..27273e4eedf 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -255,7 +255,11 @@ impl<T: Copy> Clone for MaybeUninit<T> {
 #[stable(feature = "maybe_uninit_debug", since = "1.41.0")]
 impl<T> fmt::Debug for MaybeUninit<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.pad(type_name::<Self>())
+        // NB: there is no `.pad_fmt` so we can't use a simpler `format_args!("MaybeUninit<{..}>").
+        // This needs to be adjusted if `MaybeUninit` moves modules.
+        let full_name = type_name::<Self>();
+        let short_name = full_name.split_once("mem::maybe_uninit::").unwrap().1;
+        f.pad(short_name)
     }
 }
 
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index d3360c18207..6746f0b2b31 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -1594,16 +1594,15 @@ impl Ipv6Addr {
     /// # Examples
     ///
     /// ```
-    /// #![feature(ip)]
-    ///
     /// use std::net::Ipv6Addr;
     ///
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local(), false);
     /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true);
     /// ```
-    #[unstable(feature = "ip", issue = "27709")]
     #[must_use]
     #[inline]
+    #[stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")]
     pub const fn is_unique_local(&self) -> bool {
         (self.segments()[0] & 0xfe00) == 0xfc00
     }
@@ -1665,8 +1664,6 @@ impl Ipv6Addr {
     /// # Examples
     ///
     /// ```
-    /// #![feature(ip)]
-    ///
     /// use std::net::Ipv6Addr;
     ///
     /// // The loopback address (`::1`) does not actually have link-local scope.
@@ -1680,9 +1677,10 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0).is_unicast_link_local(), true);
     /// assert_eq!(Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), true);
     /// ```
-    #[unstable(feature = "ip", issue = "27709")]
     #[must_use]
     #[inline]
+    #[stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")]
     pub const fn is_unicast_link_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfe80
     }
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 3fac1ef099f..abeccb7eea2 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -334,7 +334,7 @@ impl f128 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
     pub const fn is_finite(self) -> bool {
         // There's no need to handle NaN separately: if self is NaN,
         // the comparison is not true, exactly as desired.
@@ -612,7 +612,6 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn recip(self) -> Self {
         1.0 / self
@@ -633,7 +632,6 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_degrees(self) -> Self {
         // Use a literal for better precision.
@@ -657,7 +655,6 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_radians(self) -> f128 {
         // Use a literal for better precision.
@@ -686,7 +683,7 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn max(self, other: f128) -> f128 {
         intrinsics::maxnumf128(self, other)
@@ -712,7 +709,7 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn min(self, other: f128) -> f128 {
         intrinsics::minnumf128(self, other)
@@ -1251,7 +1248,6 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn clamp(mut self, min: f128, max: f128) -> f128 {
         const_assert!(
@@ -1292,7 +1288,7 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn abs(self) -> Self {
         // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available
@@ -1322,7 +1318,7 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn signum(self) -> f128 {
         if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) }
@@ -1360,7 +1356,7 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn copysign(self, sign: f128) -> f128 {
         // SAFETY: this is actually a safe intrinsic
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index eaac19f22f7..0d3e9269570 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -326,7 +326,7 @@ impl f16 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
     pub const fn is_finite(self) -> bool {
         // There's no need to handle NaN separately: if self is NaN,
         // the comparison is not true, exactly as desired.
@@ -605,7 +605,6 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn recip(self) -> Self {
         1.0 / self
@@ -626,7 +625,6 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_degrees(self) -> Self {
         // Use a literal for better precision.
@@ -650,7 +648,6 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_radians(self) -> f16 {
         // Use a literal for better precision.
@@ -677,7 +674,7 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn max(self, other: f16) -> f16 {
         intrinsics::maxnumf16(self, other)
@@ -702,7 +699,7 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     pub const fn min(self, other: f16) -> f16 {
         intrinsics::minnumf16(self, other)
@@ -1228,7 +1225,6 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn clamp(mut self, min: f16, max: f16) -> f16 {
         const_assert!(
@@ -1269,7 +1265,7 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn abs(self) -> Self {
         // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available
@@ -1298,7 +1294,7 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn signum(self) -> f16 {
         if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) }
@@ -1336,7 +1332,7 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn copysign(self, sign: f16) -> f16 {
         // SAFETY: this is actually a safe intrinsic
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index ae9e69f56fb..47dfce7530f 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -569,7 +569,6 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")]
     #[inline]
-    #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
     pub const fn is_finite(self) -> bool {
         // There's no need to handle NaN separately: if self is NaN,
         // the comparison is not true, exactly as desired.
@@ -819,7 +818,7 @@ impl f32 {
     /// ```
     #[must_use = "this returns the result of the operation, without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn recip(self) -> f32 {
         1.0 / self
@@ -837,7 +836,7 @@ impl f32 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_degrees(self) -> f32 {
         // Use a constant for better precision.
@@ -857,7 +856,7 @@ impl f32 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_radians(self) -> f32 {
         const RADS_PER_DEG: f32 = consts::PI / 180.0;
@@ -879,7 +878,7 @@ impl f32 {
     /// ```
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn max(self, other: f32) -> f32 {
         intrinsics::maxnumf32(self, other)
@@ -900,7 +899,7 @@ impl f32 {
     /// ```
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn min(self, other: f32) -> f32 {
         intrinsics::minnumf32(self, other)
@@ -1397,7 +1396,7 @@ impl f32 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "clamp", since = "1.50.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn clamp(mut self, min: f32, max: f32) -> f32 {
         const_assert!(
@@ -1434,7 +1433,7 @@ impl f32 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn abs(self) -> f32 {
         // SAFETY: this is actually a safe intrinsic
@@ -1459,7 +1458,7 @@ impl f32 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn signum(self) -> f32 {
         if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) }
@@ -1494,7 +1493,7 @@ impl f32 {
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "copysign", since = "1.35.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     pub const fn copysign(self, sign: f32) -> f32 {
         // SAFETY: this is actually a safe intrinsic
         unsafe { intrinsics::copysignf32(self, sign) }
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 98dcbffd3b4..c89023c1ae4 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -568,7 +568,6 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")]
     #[inline]
-    #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
     pub const fn is_finite(self) -> bool {
         // There's no need to handle NaN separately: if self is NaN,
         // the comparison is not true, exactly as desired.
@@ -836,7 +835,7 @@ impl f64 {
     /// ```
     #[must_use = "this returns the result of the operation, without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn recip(self) -> f64 {
         1.0 / self
@@ -854,7 +853,7 @@ impl f64 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_degrees(self) -> f64 {
         // The division here is correctly rounded with respect to the true
@@ -875,7 +874,7 @@ impl f64 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_radians(self) -> f64 {
         const RADS_PER_DEG: f64 = consts::PI / 180.0;
@@ -897,7 +896,7 @@ impl f64 {
     /// ```
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn max(self, other: f64) -> f64 {
         intrinsics::maxnumf64(self, other)
@@ -918,7 +917,7 @@ impl f64 {
     /// ```
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn min(self, other: f64) -> f64 {
         intrinsics::minnumf64(self, other)
@@ -1397,7 +1396,7 @@ impl f64 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "clamp", since = "1.50.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn clamp(mut self, min: f64, max: f64) -> f64 {
         const_assert!(
@@ -1434,7 +1433,7 @@ impl f64 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn abs(self) -> f64 {
         // SAFETY: this is actually a safe intrinsic
@@ -1459,7 +1458,7 @@ impl f64 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn signum(self) -> f64 {
         if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) }
@@ -1493,7 +1492,7 @@ impl f64 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "copysign", since = "1.35.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn copysign(self, sign: f64) -> f64 {
         // SAFETY: this is actually a safe intrinsic
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 318bb8ee4cd..64dcb4c91e6 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -2101,6 +2101,7 @@ macro_rules! int_impl {
         ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_neg(), -100);")]
+        #[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").wrapping_neg(), 100);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.wrapping_neg(), ", stringify!($SelfT), "::MIN);")]
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
index 133ae04f026..565bccf5898 100644
--- a/library/core/src/ops/arith.rs
+++ b/library/core/src/ops/arith.rs
@@ -73,6 +73,7 @@
     append_const_msg
 )]
 #[doc(alias = "+")]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Add<Rhs = Self> {
     /// The resulting type after applying the `+` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -94,6 +95,7 @@ pub trait Add<Rhs = Self> {
 macro_rules! add_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(bootstrap)]
         impl Add for $t {
             type Output = $t;
 
@@ -103,6 +105,17 @@ macro_rules! add_impl {
             fn add(self, other: $t) -> $t { self + other }
         }
 
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(not(bootstrap))]
+        impl const Add for $t {
+            type Output = $t;
+
+            #[inline]
+            #[track_caller]
+            #[rustc_inherit_overflow_checks]
+            fn add(self, other: $t) -> $t { self + other }
+        }
+
         forward_ref_binop! { impl Add, add for $t, $t }
     )*)
 }
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
index 45688727c9b..e9bb40d0fdd 100644
--- a/library/core/src/ops/deref.rs
+++ b/library/core/src/ops/deref.rs
@@ -133,6 +133,7 @@
 #[doc(alias = "&*")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Deref"]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Deref {
     /// The resulting type after dereferencing.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -147,6 +148,7 @@ pub trait Deref {
     fn deref(&self) -> &Self::Target;
 }
 
+#[cfg(bootstrap)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Deref for &T {
     type Target = T;
@@ -157,9 +159,21 @@ impl<T: ?Sized> Deref for &T {
     }
 }
 
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> const Deref for &T {
+    type Target = T;
+
+    #[rustc_diagnostic_item = "noop_method_deref"]
+    fn deref(&self) -> &T {
+        *self
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> !DerefMut for &T {}
 
+#[cfg(bootstrap)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Deref for &mut T {
     type Target = T;
@@ -169,6 +183,16 @@ impl<T: ?Sized> Deref for &mut T {
     }
 }
 
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> const Deref for &mut T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        *self
+    }
+}
+
 /// Used for mutable dereferencing operations, like in `*v = 1;`.
 ///
 /// In addition to being used for explicit dereferencing operations with the
@@ -258,9 +282,23 @@ impl<T: ?Sized> Deref for &mut T {
 /// *x = 'b';
 /// assert_eq!('b', x.value);
 /// ```
+#[cfg(not(bootstrap))]
+#[lang = "deref_mut"]
+#[doc(alias = "*")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
+pub trait DerefMut: ~const Deref {
+    /// Mutably dereferences the value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_diagnostic_item = "deref_mut_method"]
+    fn deref_mut(&mut self) -> &mut Self::Target;
+}
+
+/// Bootstrap
 #[lang = "deref_mut"]
 #[doc(alias = "*")]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(bootstrap)]
 pub trait DerefMut: Deref {
     /// Mutably dereferences the value.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -268,6 +306,7 @@ pub trait DerefMut: Deref {
     fn deref_mut(&mut self) -> &mut Self::Target;
 }
 
+#[cfg(bootstrap)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> DerefMut for &mut T {
     fn deref_mut(&mut self) -> &mut T {
@@ -275,6 +314,14 @@ impl<T: ?Sized> DerefMut for &mut T {
     }
 }
 
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> const DerefMut for &mut T {
+    fn deref_mut(&mut self) -> &mut T {
+        *self
+    }
+}
+
 /// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`]
 /// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness
 /// of deref patterns.
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
index a6f63ad68d6..f3314364e54 100644
--- a/library/core/src/ops/drop.rs
+++ b/library/core/src/ops/drop.rs
@@ -203,7 +203,7 @@
 /// [nomicon]: ../../nomicon/phantom-data.html#an-exception-the-special-case-of-the-standard-library-and-its-unstable-may_dangle
 #[lang = "drop"]
 #[stable(feature = "rust1", since = "1.0.0")]
-// FIXME(const_trait_impl) #[const_trait]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Drop {
     /// Executes the destructor for this type.
     ///
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index c855f963771..b3defba5a98 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -10,10 +10,10 @@ use crate::cmp::Ordering::{self, Equal, Greater, Less};
 use crate::intrinsics::{exact_div, select_unpredictable, unchecked_sub};
 use crate::mem::{self, SizedTypeProperties};
 use crate::num::NonZero;
-use crate::ops::{Bound, OneSidedRange, Range, RangeBounds};
+use crate::ops::{Bound, OneSidedRange, Range, RangeBounds, RangeInclusive};
 use crate::simd::{self, Simd};
 use crate::ub_checks::assert_unsafe_precondition;
-use crate::{fmt, hint, ptr, slice};
+use crate::{fmt, hint, ptr, range, slice};
 
 #[unstable(
     feature = "slice_internals",
@@ -4469,6 +4469,12 @@ impl<T> [T] {
 
     /// Returns mutable references to many indices at once, without doing any checks.
     ///
+    /// An index can be either a `usize`, a [`Range`] or a [`RangeInclusive`]. Note
+    /// that this method takes an array, so all indices must be of the same type.
+    /// If passed an array of `usize`s this method gives back an array of mutable references
+    /// to single elements, while if passed an array of ranges it gives back an array of
+    /// mutable references to slices.
+    ///
     /// For a safe alternative see [`get_many_mut`].
     ///
     /// # Safety
@@ -4489,30 +4495,49 @@ impl<T> [T] {
     ///     *b *= 100;
     /// }
     /// assert_eq!(x, &[10, 2, 400]);
+    ///
+    /// unsafe {
+    ///     let [a, b] = x.get_many_unchecked_mut([0..1, 1..3]);
+    ///     a[0] = 8;
+    ///     b[0] = 88;
+    ///     b[1] = 888;
+    /// }
+    /// assert_eq!(x, &[8, 88, 888]);
+    ///
+    /// unsafe {
+    ///     let [a, b] = x.get_many_unchecked_mut([1..=2, 0..=0]);
+    ///     a[0] = 11;
+    ///     a[1] = 111;
+    ///     b[0] = 1;
+    /// }
+    /// assert_eq!(x, &[1, 11, 111]);
     /// ```
     ///
     /// [`get_many_mut`]: slice::get_many_mut
     /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
     #[unstable(feature = "get_many_mut", issue = "104642")]
     #[inline]
-    pub unsafe fn get_many_unchecked_mut<const N: usize>(
+    pub unsafe fn get_many_unchecked_mut<I, const N: usize>(
         &mut self,
-        indices: [usize; N],
-    ) -> [&mut T; N] {
+        indices: [I; N],
+    ) -> [&mut I::Output; N]
+    where
+        I: GetManyMutIndex + SliceIndex<Self>,
+    {
         // NB: This implementation is written as it is because any variation of
         // `indices.map(|i| self.get_unchecked_mut(i))` would make miri unhappy,
         // or generate worse code otherwise. This is also why we need to go
         // through a raw pointer here.
         let slice: *mut [T] = self;
-        let mut arr: mem::MaybeUninit<[&mut T; N]> = mem::MaybeUninit::uninit();
+        let mut arr: mem::MaybeUninit<[&mut I::Output; N]> = mem::MaybeUninit::uninit();
         let arr_ptr = arr.as_mut_ptr();
 
         // SAFETY: We expect `indices` to contain disjunct values that are
         // in bounds of `self`.
         unsafe {
             for i in 0..N {
-                let idx = *indices.get_unchecked(i);
-                *(*arr_ptr).get_unchecked_mut(i) = &mut *slice.get_unchecked_mut(idx);
+                let idx = indices.get_unchecked(i).clone();
+                arr_ptr.cast::<&mut I::Output>().add(i).write(&mut *slice.get_unchecked_mut(idx));
             }
             arr.assume_init()
         }
@@ -4520,8 +4545,18 @@ impl<T> [T] {
 
     /// Returns mutable references to many indices at once.
     ///
-    /// Returns an error if any index is out-of-bounds, or if the same index was
-    /// passed more than once.
+    /// An index can be either a `usize`, a [`Range`] or a [`RangeInclusive`]. Note
+    /// that this method takes an array, so all indices must be of the same type.
+    /// If passed an array of `usize`s this method gives back an array of mutable references
+    /// to single elements, while if passed an array of ranges it gives back an array of
+    /// mutable references to slices.
+    ///
+    /// Returns an error if any index is out-of-bounds, or if there are overlapping indices.
+    /// An empty range is not considered to overlap if it is located at the beginning or at
+    /// the end of another range, but is considered to overlap if it is located in the middle.
+    ///
+    /// This method does a O(n^2) check to check that there are no overlapping indices, so be careful
+    /// when passing many indices.
     ///
     /// # Examples
     ///
@@ -4534,13 +4569,30 @@ impl<T> [T] {
     ///     *b = 612;
     /// }
     /// assert_eq!(v, &[413, 2, 612]);
+    ///
+    /// if let Ok([a, b]) = v.get_many_mut([0..1, 1..3]) {
+    ///     a[0] = 8;
+    ///     b[0] = 88;
+    ///     b[1] = 888;
+    /// }
+    /// assert_eq!(v, &[8, 88, 888]);
+    ///
+    /// if let Ok([a, b]) = v.get_many_mut([1..=2, 0..=0]) {
+    ///     a[0] = 11;
+    ///     a[1] = 111;
+    ///     b[0] = 1;
+    /// }
+    /// assert_eq!(v, &[1, 11, 111]);
     /// ```
     #[unstable(feature = "get_many_mut", issue = "104642")]
     #[inline]
-    pub fn get_many_mut<const N: usize>(
+    pub fn get_many_mut<I, const N: usize>(
         &mut self,
-        indices: [usize; N],
-    ) -> Result<[&mut T; N], GetManyMutError<N>> {
+        indices: [I; N],
+    ) -> Result<[&mut I::Output; N], GetManyMutError<N>>
+    where
+        I: GetManyMutIndex + SliceIndex<Self>,
+    {
         if !get_many_check_valid(&indices, self.len()) {
             return Err(GetManyMutError { _private: () });
         }
@@ -4885,14 +4937,15 @@ impl<T, const N: usize> SlicePattern for [T; N] {
 ///
 /// This will do `binomial(N + 1, 2) = N * (N + 1) / 2 = 0, 1, 3, 6, 10, ..`
 /// comparison operations.
-fn get_many_check_valid<const N: usize>(indices: &[usize; N], len: usize) -> bool {
+#[inline]
+fn get_many_check_valid<I: GetManyMutIndex, const N: usize>(indices: &[I; N], len: usize) -> bool {
     // NB: The optimizer should inline the loops into a sequence
     // of instructions without additional branching.
     let mut valid = true;
-    for (i, &idx) in indices.iter().enumerate() {
-        valid &= idx < len;
-        for &idx2 in &indices[..i] {
-            valid &= idx != idx2;
+    for (i, idx) in indices.iter().enumerate() {
+        valid &= idx.is_in_bounds(len);
+        for idx2 in &indices[..i] {
+            valid &= !idx.is_overlapping(idx2);
         }
     }
     valid
@@ -4916,6 +4969,7 @@ fn get_many_check_valid<const N: usize>(indices: &[usize; N], len: usize) -> boo
 #[unstable(feature = "get_many_mut", issue = "104642")]
 // NB: The N here is there to be forward-compatible with adding more details
 // to the error type at a later point
+#[derive(Clone, PartialEq, Eq)]
 pub struct GetManyMutError<const N: usize> {
     _private: (),
 }
@@ -4933,3 +4987,111 @@ impl<const N: usize> fmt::Display for GetManyMutError<N> {
         fmt::Display::fmt("an index is out of bounds or appeared multiple times in the array", f)
     }
 }
+
+mod private_get_many_mut_index {
+    use super::{Range, RangeInclusive, range};
+
+    #[unstable(feature = "get_many_mut_helpers", issue = "none")]
+    pub trait Sealed {}
+
+    #[unstable(feature = "get_many_mut_helpers", issue = "none")]
+    impl Sealed for usize {}
+    #[unstable(feature = "get_many_mut_helpers", issue = "none")]
+    impl Sealed for Range<usize> {}
+    #[unstable(feature = "get_many_mut_helpers", issue = "none")]
+    impl Sealed for RangeInclusive<usize> {}
+    #[unstable(feature = "get_many_mut_helpers", issue = "none")]
+    impl Sealed for range::Range<usize> {}
+    #[unstable(feature = "get_many_mut_helpers", issue = "none")]
+    impl Sealed for range::RangeInclusive<usize> {}
+}
+
+/// A helper trait for `<[T]>::get_many_mut()`.
+///
+/// # Safety
+///
+/// If `is_in_bounds()` returns `true` and `is_overlapping()` returns `false`,
+/// it must be safe to index the slice with the indices.
+#[unstable(feature = "get_many_mut_helpers", issue = "none")]
+pub unsafe trait GetManyMutIndex: Clone + private_get_many_mut_index::Sealed {
+    /// Returns `true` if `self` is in bounds for `len` slice elements.
+    #[unstable(feature = "get_many_mut_helpers", issue = "none")]
+    fn is_in_bounds(&self, len: usize) -> bool;
+
+    /// Returns `true` if `self` overlaps with `other`.
+    ///
+    /// Note that we don't consider zero-length ranges to overlap at the beginning or the end,
+    /// but do consider them to overlap in the middle.
+    #[unstable(feature = "get_many_mut_helpers", issue = "none")]
+    fn is_overlapping(&self, other: &Self) -> bool;
+}
+
+#[unstable(feature = "get_many_mut_helpers", issue = "none")]
+// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly.
+unsafe impl GetManyMutIndex for usize {
+    #[inline]
+    fn is_in_bounds(&self, len: usize) -> bool {
+        *self < len
+    }
+
+    #[inline]
+    fn is_overlapping(&self, other: &Self) -> bool {
+        *self == *other
+    }
+}
+
+#[unstable(feature = "get_many_mut_helpers", issue = "none")]
+// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly.
+unsafe impl GetManyMutIndex for Range<usize> {
+    #[inline]
+    fn is_in_bounds(&self, len: usize) -> bool {
+        (self.start <= self.end) & (self.end <= len)
+    }
+
+    #[inline]
+    fn is_overlapping(&self, other: &Self) -> bool {
+        (self.start < other.end) & (other.start < self.end)
+    }
+}
+
+#[unstable(feature = "get_many_mut_helpers", issue = "none")]
+// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly.
+unsafe impl GetManyMutIndex for RangeInclusive<usize> {
+    #[inline]
+    fn is_in_bounds(&self, len: usize) -> bool {
+        (self.start <= self.end) & (self.end < len)
+    }
+
+    #[inline]
+    fn is_overlapping(&self, other: &Self) -> bool {
+        (self.start <= other.end) & (other.start <= self.end)
+    }
+}
+
+#[unstable(feature = "get_many_mut_helpers", issue = "none")]
+// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly.
+unsafe impl GetManyMutIndex for range::Range<usize> {
+    #[inline]
+    fn is_in_bounds(&self, len: usize) -> bool {
+        Range::from(*self).is_in_bounds(len)
+    }
+
+    #[inline]
+    fn is_overlapping(&self, other: &Self) -> bool {
+        Range::from(*self).is_overlapping(&Range::from(*other))
+    }
+}
+
+#[unstable(feature = "get_many_mut_helpers", issue = "none")]
+// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly.
+unsafe impl GetManyMutIndex for range::RangeInclusive<usize> {
+    #[inline]
+    fn is_in_bounds(&self, len: usize) -> bool {
+        RangeInclusive::from(*self).is_in_bounds(len)
+    }
+
+    #[inline]
+    fn is_overlapping(&self, other: &Self) -> bool {
+        RangeInclusive::from(*self).is_overlapping(&RangeInclusive::from(*other))
+    }
+}
diff --git a/library/core/tests/fmt/mod.rs b/library/core/tests/fmt/mod.rs
index 704d2461399..f7512abae38 100644
--- a/library/core/tests/fmt/mod.rs
+++ b/library/core/tests/fmt/mod.rs
@@ -43,3 +43,10 @@ fn pad_integral_resets() {
 
     assert_eq!(format!("{Bar:<03}"), "1  0051  ");
 }
+
+#[test]
+fn test_maybe_uninit_short() {
+    // Ensure that the trimmed `MaybeUninit` Debug implementation doesn't break
+    let x = core::mem::MaybeUninit::new(0u32);
+    assert_eq!(format!("{x:?}"), "MaybeUninit<u32>");
+}
diff --git a/library/core/tests/iter/traits/step.rs b/library/core/tests/iter/traits/step.rs
index 3d82a40cd29..bf935af397c 100644
--- a/library/core/tests/iter/traits/step.rs
+++ b/library/core/tests/iter/traits/step.rs
@@ -2,26 +2,37 @@ use core::iter::*;
 
 #[test]
 fn test_steps_between() {
-    assert_eq!(Step::steps_between(&20_u8, &200_u8), Some(180_usize));
-    assert_eq!(Step::steps_between(&-20_i8, &80_i8), Some(100_usize));
-    assert_eq!(Step::steps_between(&-120_i8, &80_i8), Some(200_usize));
-    assert_eq!(Step::steps_between(&20_u32, &4_000_100_u32), Some(4_000_080_usize));
-    assert_eq!(Step::steps_between(&-20_i32, &80_i32), Some(100_usize));
-    assert_eq!(Step::steps_between(&-2_000_030_i32, &2_000_050_i32), Some(4_000_080_usize));
+    assert_eq!(Step::steps_between(&20_u8, &200_u8), (180_usize, Some(180_usize)));
+    assert_eq!(Step::steps_between(&-20_i8, &80_i8), (100_usize, Some(100_usize)));
+    assert_eq!(Step::steps_between(&-120_i8, &80_i8), (200_usize, Some(200_usize)));
+    assert_eq!(
+        Step::steps_between(&20_u32, &4_000_100_u32),
+        (4_000_080_usize, Some(4_000_080_usize))
+    );
+    assert_eq!(Step::steps_between(&-20_i32, &80_i32), (100_usize, Some(100_usize)));
+    assert_eq!(
+        Step::steps_between(&-2_000_030_i32, &2_000_050_i32),
+        (4_000_080_usize, Some(4_000_080_usize))
+    );
 
     // Skip u64/i64 to avoid differences with 32-bit vs 64-bit platforms
 
-    assert_eq!(Step::steps_between(&20_u128, &200_u128), Some(180_usize));
-    assert_eq!(Step::steps_between(&-20_i128, &80_i128), Some(100_usize));
+    assert_eq!(Step::steps_between(&20_u128, &200_u128), (180_usize, Some(180_usize)));
+    assert_eq!(Step::steps_between(&-20_i128, &80_i128), (100_usize, Some(100_usize)));
     if cfg!(target_pointer_width = "64") {
-        assert_eq!(Step::steps_between(&10_u128, &0x1_0000_0000_0000_0009_u128), Some(usize::MAX));
+        assert_eq!(
+            Step::steps_between(&10_u128, &0x1_0000_0000_0000_0009_u128),
+            (usize::MAX, Some(usize::MAX))
+        );
     }
-    assert_eq!(Step::steps_between(&10_u128, &0x1_0000_0000_0000_000a_u128), None);
-    assert_eq!(Step::steps_between(&10_i128, &0x1_0000_0000_0000_000a_i128), None);
+    assert_eq!(Step::steps_between(&10_u128, &0x1_0000_0000_0000_000a_u128), (usize::MAX, None));
+    assert_eq!(Step::steps_between(&10_i128, &0x1_0000_0000_0000_000a_i128), (usize::MAX, None));
     assert_eq!(
         Step::steps_between(&-0x1_0000_0000_0000_0000_i128, &0x1_0000_0000_0000_0000_i128,),
-        None,
+        (usize::MAX, None),
     );
+
+    assert_eq!(Step::steps_between(&100_u32, &10_u32), (0, None));
 }
 
 #[test]
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 9ae2bcc8526..510dd4967c9 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -2,6 +2,7 @@ use core::cell::Cell;
 use core::cmp::Ordering;
 use core::mem::MaybeUninit;
 use core::num::NonZero;
+use core::ops::{Range, RangeInclusive};
 use core::slice;
 
 #[test]
@@ -2553,6 +2554,14 @@ fn test_get_many_mut_normal_2() {
     *a += 10;
     *b += 100;
     assert_eq!(v, vec![101, 2, 3, 14, 5]);
+
+    let [a, b] = v.get_many_mut([0..=1, 2..=2]).unwrap();
+    assert_eq!(a, &mut [101, 2][..]);
+    assert_eq!(b, &mut [3][..]);
+    a[0] += 10;
+    a[1] += 20;
+    b[0] += 100;
+    assert_eq!(v, vec![111, 22, 103, 14, 5]);
 }
 
 #[test]
@@ -2563,12 +2572,23 @@ fn test_get_many_mut_normal_3() {
     *b += 100;
     *c += 1000;
     assert_eq!(v, vec![11, 2, 1003, 4, 105]);
+
+    let [a, b, c] = v.get_many_mut([0..1, 4..5, 1..4]).unwrap();
+    assert_eq!(a, &mut [11][..]);
+    assert_eq!(b, &mut [105][..]);
+    assert_eq!(c, &mut [2, 1003, 4][..]);
+    a[0] += 10;
+    b[0] += 100;
+    c[0] += 1000;
+    assert_eq!(v, vec![21, 1002, 1003, 4, 205]);
 }
 
 #[test]
 fn test_get_many_mut_empty() {
     let mut v = vec![1, 2, 3, 4, 5];
-    let [] = v.get_many_mut([]).unwrap();
+    let [] = v.get_many_mut::<usize, 0>([]).unwrap();
+    let [] = v.get_many_mut::<RangeInclusive<usize>, 0>([]).unwrap();
+    let [] = v.get_many_mut::<Range<usize>, 0>([]).unwrap();
     assert_eq!(v, vec![1, 2, 3, 4, 5]);
 }
 
@@ -2607,6 +2627,54 @@ fn test_get_many_mut_duplicate() {
 }
 
 #[test]
+fn test_get_many_mut_range_oob() {
+    let mut v = vec![1, 2, 3, 4, 5];
+    assert!(v.get_many_mut([0..6]).is_err());
+    assert!(v.get_many_mut([5..6]).is_err());
+    assert!(v.get_many_mut([6..6]).is_err());
+    assert!(v.get_many_mut([0..=5]).is_err());
+    assert!(v.get_many_mut([0..=6]).is_err());
+    assert!(v.get_many_mut([5..=5]).is_err());
+}
+
+#[test]
+fn test_get_many_mut_range_overlapping() {
+    let mut v = vec![1, 2, 3, 4, 5];
+    assert!(v.get_many_mut([0..1, 0..2]).is_err());
+    assert!(v.get_many_mut([0..1, 1..2, 0..1]).is_err());
+    assert!(v.get_many_mut([0..3, 1..1]).is_err());
+    assert!(v.get_many_mut([0..3, 1..2]).is_err());
+    assert!(v.get_many_mut([0..=0, 2..=2, 0..=1]).is_err());
+    assert!(v.get_many_mut([0..=4, 0..=0]).is_err());
+    assert!(v.get_many_mut([4..=4, 0..=0, 3..=4]).is_err());
+}
+
+#[test]
+fn test_get_many_mut_range_empty_at_edge() {
+    let mut v = vec![1, 2, 3, 4, 5];
+    assert_eq!(
+        v.get_many_mut([0..0, 0..5, 5..5]),
+        Ok([&mut [][..], &mut [1, 2, 3, 4, 5], &mut []]),
+    );
+    assert_eq!(
+        v.get_many_mut([0..0, 0..1, 1..1, 1..2, 2..2, 2..3, 3..3, 3..4, 4..4, 4..5, 5..5]),
+        Ok([
+            &mut [][..],
+            &mut [1],
+            &mut [],
+            &mut [2],
+            &mut [],
+            &mut [3],
+            &mut [],
+            &mut [4],
+            &mut [],
+            &mut [5],
+            &mut [],
+        ]),
+    );
+}
+
+#[test]
 fn test_slice_from_raw_parts_in_const() {
     static FANCY: i32 = 4;
     static FANCY_SLICE: &[i32] = unsafe { std::slice::from_raw_parts(&FANCY, 1) };
diff --git a/library/profiler_builtins/Cargo.toml b/library/profiler_builtins/Cargo.toml
index f94ea9a6cda..c601a41b433 100644
--- a/library/profiler_builtins/Cargo.toml
+++ b/library/profiler_builtins/Cargo.toml
@@ -9,9 +9,6 @@ bench = false
 doc = false
 
 [dependencies]
-core = { path = "../core" }
-compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] }
 
 [build-dependencies]
-# FIXME: Pinned due to build error when bumped (#132556)
-cc = "=1.1.22"
+cc = "1.2"
diff --git a/library/profiler_builtins/src/lib.rs b/library/profiler_builtins/src/lib.rs
index ac685b18c29..a258f7d31a1 100644
--- a/library/profiler_builtins/src/lib.rs
+++ b/library/profiler_builtins/src/lib.rs
@@ -1,11 +1,15 @@
-#![no_std]
+// tidy-alphabetical-start
+#![allow(internal_features)]
+#![feature(no_core)]
 #![feature(profiler_runtime)]
+#![feature(staged_api)]
+// tidy-alphabetical-end
+
+// Other attributes:
+#![no_core]
 #![profiler_runtime]
 #![unstable(
     feature = "profiler_runtime_lib",
     reason = "internal implementation detail of rustc right now",
     issue = "none"
 )]
-#![allow(unused_features)]
-#![allow(internal_features)]
-#![feature(staged_api)]
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index d732a15117e..27f4daba44b 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -653,19 +653,28 @@ pub fn home_dir() -> Option<PathBuf> {
 /// may result in "insecure temporary file" security vulnerabilities. Consider
 /// using a crate that securely creates temporary files or directories.
 ///
+/// Note that the returned value may be a symbolic link, not a directory.
+///
 /// # Platform-specific behavior
 ///
 /// On Unix, returns the value of the `TMPDIR` environment variable if it is
-/// set, otherwise for non-Android it returns `/tmp`. On Android, since there
-/// is no global temporary folder (it is usually allocated per-app), it returns
-/// `/data/local/tmp`.
+/// set, otherwise the value is OS-specific:
+/// - On Android, there is no global temporary folder (it is usually allocated
+///   per-app), it returns `/data/local/tmp`.
+/// - On Darwin-based OSes (macOS, iOS, etc) it returns the directory provided
+///   by `confstr(_CS_DARWIN_USER_TEMP_DIR, ...)`, as recommended by [Apple's
+///   security guidelines][appledoc].
+/// - On all other unix-based OSes, it returns `/tmp`.
+///
 /// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] /
 /// [`GetTempPath`][GetTempPath], which this function uses internally.
+///
 /// Note that, this [may change in the future][changes].
 ///
 /// [changes]: io#platform-specific-behavior
 /// [GetTempPath2]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a
 /// [GetTempPath]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
+/// [appledoc]: https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10
 ///
 /// ```no_run
 /// use std::env;
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 79dfb47d0c4..328185d1f2b 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -550,11 +550,15 @@ impl OsString {
         OsStr::from_inner_mut(self.inner.leak())
     }
 
-    /// Provides plumbing to core `Vec::truncate`.
-    /// More well behaving alternative to allowing outer types
-    /// full mutable access to the core `Vec`.
+    /// Truncate the the `OsString` to the specified length.
+    ///
+    /// # Panics
+    /// Panics if `len` does not lie on a valid `OsStr` boundary
+    /// (as described in [`OsStr::slice_encoded_bytes`]).
     #[inline]
-    pub(crate) fn truncate(&mut self, len: usize) {
+    #[unstable(feature = "os_string_truncate", issue = "133262")]
+    pub fn truncate(&mut self, len: usize) {
+        self.as_os_str().inner.check_public_boundary(len);
         self.inner.truncate(len);
     }
 
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 555e8804eab..2d5d869630e 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -2804,8 +2804,9 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///
 /// See [`fs::remove_file`] and [`fs::remove_dir`].
 ///
-/// `remove_dir_all` will fail if `remove_dir` or `remove_file` fail on any constituent paths, including the root path.
+/// `remove_dir_all` will fail if `remove_dir` or `remove_file` fail on any constituent paths, including the root `path`.
 /// As a result, the directory you are deleting must exist, meaning that this function is not idempotent.
+/// Additionally, `remove_dir_all` will also fail if the `path` is not a directory.
 ///
 /// Consider ignoring the error if validating the removal is not required for your use case.
 ///
@@ -3019,7 +3020,7 @@ impl DirBuilder {
         match path.parent() {
             Some(p) => self.create_dir_all(p)?,
             None => {
-                return Err(io::const_io_error!(
+                return Err(io::const_error!(
                     io::ErrorKind::Uncategorized,
                     "failed to create whole tree",
                 ));
diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs
index 52fe49985c6..17721090db5 100644
--- a/library/std/src/io/buffered/bufreader/buffer.rs
+++ b/library/std/src/io/buffered/bufreader/buffer.rs
@@ -41,7 +41,7 @@ impl Buffer {
         match Box::try_new_uninit_slice(capacity) {
             Ok(buf) => Ok(Self { buf, pos: 0, filled: 0, initialized: 0 }),
             Err(_) => {
-                Err(io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer"))
+                Err(io::const_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer"))
             }
         }
     }
diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs
index c41bae2aa4e..574eb83dc56 100644
--- a/library/std/src/io/buffered/bufwriter.rs
+++ b/library/std/src/io/buffered/bufwriter.rs
@@ -96,7 +96,7 @@ impl<W: Write> BufWriter<W> {
 
     pub(crate) fn try_new_buffer() -> io::Result<Vec<u8>> {
         Vec::try_with_capacity(DEFAULT_BUF_SIZE).map_err(|_| {
-            io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate write buffer")
+            io::const_error!(ErrorKind::OutOfMemory, "failed to allocate write buffer")
         })
     }
 
@@ -238,7 +238,7 @@ impl<W: ?Sized + Write> BufWriter<W> {
 
             match r {
                 Ok(0) => {
-                    return Err(io::const_io_error!(
+                    return Err(io::const_error!(
                         ErrorKind::WriteZero,
                         "failed to write the buffered data",
                     ));
diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs
index fbfdb4fa023..b2ffeb0f95d 100644
--- a/library/std/src/io/cursor.rs
+++ b/library/std/src/io/cursor.rs
@@ -304,7 +304,7 @@ where
                 self.pos = n;
                 Ok(self.pos)
             }
-            None => Err(io::const_io_error!(
+            None => Err(io::const_error!(
                 ErrorKind::InvalidInput,
                 "invalid seek to a negative or overflowing position",
             )),
@@ -446,7 +446,7 @@ fn reserve_and_pad<A: Allocator>(
     buf_len: usize,
 ) -> io::Result<usize> {
     let pos: usize = (*pos_mut).try_into().map_err(|_| {
-        io::const_io_error!(
+        io::const_error!(
             ErrorKind::InvalidInput,
             "cursor position exceeds maximum possible vector length",
         )
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 5d7adcace52..03f38e220a5 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -76,31 +76,31 @@ impl fmt::Debug for Error {
 #[allow(dead_code)]
 impl Error {
     pub(crate) const INVALID_UTF8: Self =
-        const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8");
+        const_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8");
 
     pub(crate) const READ_EXACT_EOF: Self =
-        const_io_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer");
+        const_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer");
 
-    pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_io_error!(
+    pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_error!(
         ErrorKind::NotFound,
         "The number of hardware threads is not known for the target platform"
     );
 
     pub(crate) const UNSUPPORTED_PLATFORM: Self =
-        const_io_error!(ErrorKind::Unsupported, "operation not supported on this platform");
+        const_error!(ErrorKind::Unsupported, "operation not supported on this platform");
 
     pub(crate) const WRITE_ALL_EOF: Self =
-        const_io_error!(ErrorKind::WriteZero, "failed to write whole buffer");
+        const_error!(ErrorKind::WriteZero, "failed to write whole buffer");
 
     pub(crate) const ZERO_TIMEOUT: Self =
-        const_io_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout");
+        const_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout");
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl From<alloc::ffi::NulError> for Error {
     /// Converts a [`alloc::ffi::NulError`] into a [`Error`].
     fn from(_: alloc::ffi::NulError) -> Error {
-        const_io_error!(ErrorKind::InvalidInput, "data provided contains a nul byte")
+        const_error!(ErrorKind::InvalidInput, "data provided contains a nul byte")
     }
 }
 
@@ -151,27 +151,38 @@ pub type RawOsError = sys::RawOsError;
 // (For the sake of being explicit: the alignment requirement here only matters
 // if `error/repr_bitpacked.rs` is in use — for the unpacked repr it doesn't
 // matter at all)
+#[doc(hidden)]
+#[unstable(feature = "io_const_error_internals", issue = "none")]
 #[repr(align(4))]
 #[derive(Debug)]
-pub(crate) struct SimpleMessage {
-    kind: ErrorKind,
-    message: &'static str,
-}
-
-impl SimpleMessage {
-    pub(crate) const fn new(kind: ErrorKind, message: &'static str) -> Self {
-        Self { kind, message }
-    }
+pub struct SimpleMessage {
+    pub kind: ErrorKind,
+    pub message: &'static str,
 }
 
-/// Creates and returns an `io::Error` for a given `ErrorKind` and constant
-/// message. This doesn't allocate.
-pub(crate) macro const_io_error($kind:expr, $message:expr $(,)?) {
-    $crate::io::error::Error::from_static_message({
-        const MESSAGE_DATA: $crate::io::error::SimpleMessage =
-            $crate::io::error::SimpleMessage::new($kind, $message);
-        &MESSAGE_DATA
-    })
+/// Creates a new I/O error from a known kind of error and a string literal.
+///
+/// Contrary to [`Error::new`], this macro does not allocate and can be used in
+/// `const` contexts.
+///
+/// # Example
+/// ```
+/// #![feature(io_const_error)]
+/// use std::io::{const_error, Error, ErrorKind};
+///
+/// const FAIL: Error = const_error!(ErrorKind::Unsupported, "tried something that never works");
+///
+/// fn not_here() -> Result<(), Error> {
+///     Err(FAIL)
+/// }
+/// ```
+#[rustc_macro_transparency = "semitransparent"]
+#[unstable(feature = "io_const_error", issue = "133448")]
+#[allow_internal_unstable(hint_must_use, io_const_error_internals)]
+pub macro const_error($kind:expr, $message:expr $(,)?) {
+    $crate::hint::must_use($crate::io::Error::from_static_message(
+        const { &$crate::io::SimpleMessage { kind: $kind, message: $message } },
+    ))
 }
 
 // As with `SimpleMessage`: `#[repr(align(4))]` here is just because
@@ -592,13 +603,15 @@ impl Error {
     ///
     /// This function does not allocate.
     ///
-    /// You should not use this directly, and instead use the `const_io_error!`
-    /// macro: `io::const_io_error!(ErrorKind::Something, "some_message")`.
+    /// You should not use this directly, and instead use the `const_error!`
+    /// macro: `io::const_error!(ErrorKind::Something, "some_message")`.
     ///
     /// This function should maybe change to `from_static_message<const MSG: &'static
     /// str>(kind: ErrorKind)` in the future, when const generics allow that.
     #[inline]
-    pub(crate) const fn from_static_message(msg: &'static SimpleMessage) -> Error {
+    #[doc(hidden)]
+    #[unstable(feature = "io_const_error_internals", issue = "none")]
+    pub const fn from_static_message(msg: &'static SimpleMessage) -> Error {
         Self { repr: Repr::new_simple_message(msg) }
     }
 
diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs
index 00d04984a38..edac6563478 100644
--- a/library/std/src/io/error/tests.rs
+++ b/library/std/src/io/error/tests.rs
@@ -1,4 +1,4 @@
-use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_io_error};
+use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error};
 use crate::assert_matches::assert_matches;
 use crate::mem::size_of;
 use crate::sys::decode_error_kind;
@@ -60,7 +60,7 @@ fn test_downcasting() {
 
 #[test]
 fn test_const() {
-    const E: Error = const_io_error!(ErrorKind::NotFound, "hello");
+    const E: Error = const_error!(ErrorKind::NotFound, "hello");
 
     assert_eq!(E.kind(), ErrorKind::NotFound);
     assert_eq!(E.to_string(), "hello");
@@ -110,13 +110,13 @@ fn test_simple_message_packing() {
         }};
     }
 
-    let not_static = const_io_error!(Uncategorized, "not a constant!");
+    let not_static = const_error!(Uncategorized, "not a constant!");
     check_simple_msg!(not_static, Uncategorized, "not a constant!");
 
-    const CONST: Error = const_io_error!(NotFound, "definitely a constant!");
+    const CONST: Error = const_error!(NotFound, "definitely a constant!");
     check_simple_msg!(CONST, NotFound, "definitely a constant!");
 
-    static STATIC: Error = const_io_error!(BrokenPipe, "a constant, sort of!");
+    static STATIC: Error = const_error!(BrokenPipe, "a constant, sort of!");
     check_simple_msg!(STATIC, BrokenPipe, "a constant, sort of!");
 }
 
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 21e70774954..4ffb0463006 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -301,12 +301,15 @@ mod tests;
 pub use core::io::{BorrowedBuf, BorrowedCursor};
 use core::slice::memchr;
 
-pub(crate) use error::const_io_error;
-
 #[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
 pub use self::buffered::WriterPanicked;
 #[unstable(feature = "raw_os_error_ty", issue = "107792")]
 pub use self::error::RawOsError;
+#[doc(hidden)]
+#[unstable(feature = "io_const_error_internals", issue = "none")]
+pub use self::error::SimpleMessage;
+#[unstable(feature = "io_const_error", issue = "133448")]
+pub use self::error::const_error;
 #[stable(feature = "is_terminal", since = "1.70.0")]
 pub use self::stdio::IsTerminal;
 pub(crate) use self::stdio::attempt_print_to_stderr;
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index 89e806c0891..47cbb9614af 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -225,12 +225,12 @@ fn take_eof() {
 
     impl Read for R {
         fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
-            Err(io::const_io_error!(io::ErrorKind::Other, ""))
+            Err(io::const_error!(io::ErrorKind::Other, ""))
         }
     }
     impl BufRead for R {
         fn fill_buf(&mut self) -> io::Result<&[u8]> {
-            Err(io::const_io_error!(io::ErrorKind::Other, ""))
+            Err(io::const_error!(io::ErrorKind::Other, ""))
         }
         fn consume(&mut self, _amt: usize) {}
     }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 5b94f036248..cf99a618e55 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -174,9 +174,6 @@
 //!
 //! - after-main use of thread-locals, which also affects additional features:
 //!   - [`thread::current()`]
-//!   - [`thread::scope()`]
-//!   - [`sync::mpmc`]
-//!   - [`sync::mpsc`]
 //! - before-main stdio file descriptors are not guaranteed to be open on unix platforms
 //!
 //!
@@ -288,7 +285,6 @@
 #![feature(cfg_target_thread_local)]
 #![feature(cfi_encoding)]
 #![feature(concat_idents)]
-#![feature(const_float_methods)]
 #![feature(decl_macro)]
 #![feature(deprecated_suggestion)]
 #![feature(doc_cfg)]
@@ -344,6 +340,7 @@
 #![feature(fmt_internals)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
+#![feature(hint_must_use)]
 #![feature(ip)]
 #![feature(lazy_get)]
 #![feature(maybe_uninit_slice)]
@@ -414,6 +411,7 @@
 // Only for const-ness:
 // tidy-alphabetical-start
 #![feature(const_collections_with_hasher)]
+#![feature(io_const_error)]
 #![feature(thread_local_internals)]
 // tidy-alphabetical-end
 //
@@ -658,6 +656,8 @@ pub mod arch {
     pub use std_detect::is_aarch64_feature_detected;
     #[unstable(feature = "stdarch_arm_feature_detection", issue = "111190")]
     pub use std_detect::is_arm_feature_detected;
+    #[unstable(feature = "is_loongarch_feature_detected", issue = "117425")]
+    pub use std_detect::is_loongarch_feature_detected;
     #[unstable(feature = "is_riscv_feature_detected", issue = "111192")]
     pub use std_detect::is_riscv_feature_detected;
     #[stable(feature = "simd_x86", since = "1.27.0")]
diff --git a/library/std/src/net/mod.rs b/library/std/src/net/mod.rs
index 3b19c743b1e..ddd3b68dd2d 100644
--- a/library/std/src/net/mod.rs
+++ b/library/std/src/net/mod.rs
@@ -84,6 +84,6 @@ where
         }
     }
     Err(last_err.unwrap_or_else(|| {
-        io::const_io_error!(ErrorKind::InvalidInput, "could not resolve to any addresses")
+        io::const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses")
     }))
 }
diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs
index 6df47d7b0e0..674c5fb7d6e 100644
--- a/library/std/src/net/udp.rs
+++ b/library/std/src/net/udp.rs
@@ -203,9 +203,7 @@ impl UdpSocket {
     pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A) -> io::Result<usize> {
         match addr.to_socket_addrs()?.next() {
             Some(addr) => self.0.send_to(buf, &addr),
-            None => {
-                Err(io::const_io_error!(ErrorKind::InvalidInput, "no addresses to send data to"))
-            }
+            None => Err(io::const_error!(ErrorKind::InvalidInput, "no addresses to send data to")),
         }
     }
 
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 2d087c03b04..388b8a88a1a 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -173,16 +173,17 @@ impl Drop for OwnedFd {
     #[inline]
     fn drop(&mut self) {
         unsafe {
-            // Note that errors are ignored when closing a file descriptor. The
-            // reason for this is that if an error occurs we don't actually know if
-            // the file descriptor was closed or not, and if we retried (for
-            // something like EINTR), we might close another valid file descriptor
-            // opened after we closed ours.
-            // However, this is usually justified, as some of the major Unices
-            // do make sure to always close the FD, even when `close()` is interrupted,
-            // and the scenario is rare to begin with.
-            // Helpful link to an epic discussion by POSIX workgroup:
-            // http://austingroupbugs.net/view.php?id=529
+            // Note that errors are ignored when closing a file descriptor. According to POSIX 2024,
+            // we can and indeed should retry `close` on `EINTR`
+            // (https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/close.html),
+            // but it is not clear yet how well widely-used implementations are conforming with this
+            // mandate since older versions of POSIX left the state of the FD after an `EINTR`
+            // unspecified. Ignoring errors is "fine" because some of the major Unices (in
+            // particular, Linux) do make sure to always close the FD, even when `close()` is
+            // interrupted, and the scenario is rare to begin with. If we retried on a
+            // not-POSIX-compliant implementation, the consequences could be really bad since we may
+            // close the wrong FD. Helpful link to an epic discussion by POSIX workgroup that led to
+            // the latest POSIX wording: http://austingroupbugs.net/view.php?id=529
             #[cfg(not(target_os = "hermit"))]
             {
                 #[cfg(unix)]
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index 253e1503cf7..56789f235fd 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -30,14 +30,14 @@ pub(super) fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::s
     let bytes = path.as_os_str().as_bytes();
 
     if bytes.contains(&0) {
-        return Err(io::const_io_error!(
+        return Err(io::const_error!(
             io::ErrorKind::InvalidInput,
             "paths must not contain interior null bytes",
         ));
     }
 
     if bytes.len() >= addr.sun_path.len() {
-        return Err(io::const_io_error!(
+        return Err(io::const_error!(
             io::ErrorKind::InvalidInput,
             "path must be shorter than SUN_LEN",
         ));
@@ -119,7 +119,7 @@ impl SocketAddr {
             // linux returns zero bytes of address
             len = SUN_PATH_OFFSET as libc::socklen_t; // i.e., zero-length address
         } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
                 "file descriptor did not correspond to a Unix socket",
             ));
@@ -273,7 +273,7 @@ impl linux_ext::addr::SocketAddrExt for SocketAddr {
             addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
 
             if name.len() + 1 > addr.sun_path.len() {
-                return Err(io::const_io_error!(
+                return Err(io::const_error!(
                     io::ErrorKind::InvalidInput,
                     "abstract socket name must be shorter than SUN_LEN",
                 ));
diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs
index 9ec3e387e2b..42aada131da 100644
--- a/library/std/src/os/wasi/fs.rs
+++ b/library/std/src/os/wasi/fs.rs
@@ -261,7 +261,7 @@ impl FileExt for fs::File {
             a if a == wasi::ADVICE_DONTNEED.raw() => wasi::ADVICE_DONTNEED,
             a if a == wasi::ADVICE_NOREUSE.raw() => wasi::ADVICE_NOREUSE,
             _ => {
-                return Err(io::const_io_error!(
+                return Err(io::const_error!(
                     io::ErrorKind::InvalidInput,
                     "invalid parameter 'advice'",
                 ));
@@ -560,6 +560,5 @@ pub fn symlink_path<P: AsRef<Path>, U: AsRef<Path>>(old_path: P, new_path: U) ->
 }
 
 fn osstr2str(f: &OsStr) -> io::Result<&str> {
-    f.to_str()
-        .ok_or_else(|| io::const_io_error!(io::ErrorKind::Uncategorized, "input must be utf-8"))
+    f.to_str().ok_or_else(|| io::const_error!(io::ErrorKind::Uncategorized, "input must be utf-8"))
 }
diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs
index 1fcfb6e73ad..272641ea6c7 100644
--- a/library/std/src/os/windows/io/socket.rs
+++ b/library/std/src/os/windows/io/socket.rs
@@ -101,7 +101,7 @@ impl OwnedSocket {
 
     #[cfg(target_vendor = "uwp")]
     pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
-        Err(io::const_io_error!(io::ErrorKind::Unsupported, "Unavailable on UWP"))
+        Err(io::const_error!(io::ErrorKind::Unsupported, "Unavailable on UWP"))
     }
 }
 
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index b0291e3aa19..33a3e4332f3 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -2504,6 +2504,7 @@ impl Path {
     /// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new("")));
     ///
     /// assert!(path.strip_prefix("test").is_err());
+    /// assert!(path.strip_prefix("/te").is_err());
     /// assert!(path.strip_prefix("/haha").is_err());
     ///
     /// let prefix = PathBuf::from("/test/");
@@ -3580,7 +3581,7 @@ impl Error for StripPrefixError {
 pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
     let path = path.as_ref();
     if path.as_os_str().is_empty() {
-        Err(io::const_io_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",))
+        Err(io::const_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",))
     } else {
         sys::path::absolute(path)
     }
diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs
index b231bd871b3..e4731280ffe 100644
--- a/library/std/src/prelude/common.rs
+++ b/library/std/src/prelude/common.rs
@@ -12,6 +12,9 @@ pub use crate::marker::{Send, Sized, Sync, Unpin};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
 pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
+#[unstable(feature = "async_closure", issue = "62290")]
+#[doc(no_inline)]
+pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce};
 
 // Re-exported functions
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/sync/mpmc/array.rs b/library/std/src/sync/mpmc/array.rs
index 2c8ba411f30..a467237fef1 100644
--- a/library/std/src/sync/mpmc/array.rs
+++ b/library/std/src/sync/mpmc/array.rs
@@ -346,7 +346,8 @@ impl<T> Channel<T> {
                 }
 
                 // Block the current thread.
-                let sel = cx.wait_until(deadline);
+                // SAFETY: the context belongs to the current thread.
+                let sel = unsafe { cx.wait_until(deadline) };
 
                 match sel {
                     Selected::Waiting => unreachable!(),
@@ -397,7 +398,8 @@ impl<T> Channel<T> {
                 }
 
                 // Block the current thread.
-                let sel = cx.wait_until(deadline);
+                // SAFETY: the context belongs to the current thread.
+                let sel = unsafe { cx.wait_until(deadline) };
 
                 match sel {
                     Selected::Waiting => unreachable!(),
diff --git a/library/std/src/sync/mpmc/context.rs b/library/std/src/sync/mpmc/context.rs
index 2371d32d4ea..51aa7e82e78 100644
--- a/library/std/src/sync/mpmc/context.rs
+++ b/library/std/src/sync/mpmc/context.rs
@@ -69,7 +69,7 @@ impl Context {
             inner: Arc::new(Inner {
                 select: AtomicUsize::new(Selected::Waiting.into()),
                 packet: AtomicPtr::new(ptr::null_mut()),
-                thread: thread::current(),
+                thread: thread::current_or_unnamed(),
                 thread_id: current_thread_id(),
             }),
         }
@@ -112,8 +112,11 @@ impl Context {
     /// Waits until an operation is selected and returns it.
     ///
     /// If the deadline is reached, `Selected::Aborted` will be selected.
+    ///
+    /// # Safety
+    /// This may only be called from the thread this `Context` belongs to.
     #[inline]
-    pub fn wait_until(&self, deadline: Option<Instant>) -> Selected {
+    pub unsafe fn wait_until(&self, deadline: Option<Instant>) -> Selected {
         loop {
             // Check whether an operation has been selected.
             let sel = Selected::from(self.inner.select.load(Ordering::Acquire));
@@ -126,7 +129,8 @@ impl Context {
                 let now = Instant::now();
 
                 if now < end {
-                    thread::park_timeout(end - now);
+                    // SAFETY: guaranteed by caller.
+                    unsafe { self.inner.thread.park_timeout(end - now) };
                 } else {
                     // The deadline has been reached. Try aborting select.
                     return match self.try_select(Selected::Aborted) {
@@ -135,7 +139,8 @@ impl Context {
                     };
                 }
             } else {
-                thread::park();
+                // SAFETY: guaranteed by caller.
+                unsafe { self.inner.thread.park() };
             }
         }
     }
diff --git a/library/std/src/sync/mpmc/list.rs b/library/std/src/sync/mpmc/list.rs
index 523e6d2f3bb..d88914f5291 100644
--- a/library/std/src/sync/mpmc/list.rs
+++ b/library/std/src/sync/mpmc/list.rs
@@ -444,7 +444,8 @@ impl<T> Channel<T> {
                 }
 
                 // Block the current thread.
-                let sel = cx.wait_until(deadline);
+                // SAFETY: the context belongs to the current thread.
+                let sel = unsafe { cx.wait_until(deadline) };
 
                 match sel {
                     Selected::Waiting => unreachable!(),
diff --git a/library/std/src/sync/mpmc/zero.rs b/library/std/src/sync/mpmc/zero.rs
index 446881291e6..577997c07a6 100644
--- a/library/std/src/sync/mpmc/zero.rs
+++ b/library/std/src/sync/mpmc/zero.rs
@@ -190,7 +190,8 @@ impl<T> Channel<T> {
             drop(inner);
 
             // Block the current thread.
-            let sel = cx.wait_until(deadline);
+            // SAFETY: the context belongs to the current thread.
+            let sel = unsafe { cx.wait_until(deadline) };
 
             match sel {
                 Selected::Waiting => unreachable!(),
@@ -257,7 +258,8 @@ impl<T> Channel<T> {
             drop(inner);
 
             // Block the current thread.
-            let sel = cx.wait_until(deadline);
+            // SAFETY: the context belongs to the current thread.
+            let sel = unsafe { cx.wait_until(deadline) };
 
             match sel {
                 Selected::Waiting => unreachable!(),
diff --git a/library/std/src/sync/rwlock/tests.rs b/library/std/src/sync/rwlock/tests.rs
index 29cad4400f1..48d442921f7 100644
--- a/library/std/src/sync/rwlock/tests.rs
+++ b/library/std/src/sync/rwlock/tests.rs
@@ -511,12 +511,15 @@ fn test_downgrade_basic() {
 }
 
 #[test]
+// FIXME: On macOS we use a provenance-incorrect implementation and Miri catches that issue.
+// See <https://github.com/rust-lang/rust/issues/121950> for details.
+#[cfg_attr(all(miri, target_os = "macos"), ignore)]
 fn test_downgrade_observe() {
     // Taken from the test `test_rwlock_downgrade` from:
     // https://github.com/Amanieu/parking_lot/blob/master/src/rwlock.rs
 
     const W: usize = 20;
-    const N: usize = 100;
+    const N: usize = if cfg!(miri) { 40 } else { 100 };
 
     // This test spawns `W` writer threads, where each will increment a counter `N` times, ensuring
     // that the value they wrote has not changed after downgrading.
diff --git a/library/std/src/sys/pal/common/small_c_string.rs b/library/std/src/sys/pal/common/small_c_string.rs
index 3c96714b5c5..f54505a856e 100644
--- a/library/std/src/sys/pal/common/small_c_string.rs
+++ b/library/std/src/sys/pal/common/small_c_string.rs
@@ -11,7 +11,7 @@ const MAX_STACK_ALLOCATION: usize = 384;
 const MAX_STACK_ALLOCATION: usize = 32;
 
 const NUL_ERR: io::Error =
-    io::const_io_error!(io::ErrorKind::InvalidInput, "file name contained an unexpected NUL byte");
+    io::const_error!(io::ErrorKind::InvalidInput, "file name contained an unexpected NUL byte");
 
 #[inline]
 pub fn run_path_with_cstr<T>(path: &Path, f: &dyn Fn(&CStr) -> io::Result<T>) -> io::Result<T> {
diff --git a/library/std/src/sys/pal/hermit/fs.rs b/library/std/src/sys/pal/hermit/fs.rs
index 17d15ed2e50..11862a07608 100644
--- a/library/std/src/sys/pal/hermit/fs.rs
+++ b/library/std/src/sys/pal/hermit/fs.rs
@@ -294,7 +294,7 @@ impl OpenOptions {
             (false, _, true) => Ok(O_WRONLY | O_APPEND),
             (true, _, true) => Ok(O_RDWR | O_APPEND),
             (false, false, false) => {
-                Err(io::const_io_error!(ErrorKind::InvalidInput, "invalid access mode"))
+                Err(io::const_error!(ErrorKind::InvalidInput, "invalid access mode"))
             }
         }
     }
@@ -304,18 +304,16 @@ impl OpenOptions {
             (true, false) => {}
             (false, false) => {
                 if self.truncate || self.create || self.create_new {
-                    return Err(io::const_io_error!(
-                        ErrorKind::InvalidInput,
-                        "invalid creation mode",
-                    ));
+                    return Err(
+                        io::const_error!(ErrorKind::InvalidInput, "invalid creation mode",),
+                    );
                 }
             }
             (_, true) => {
                 if self.truncate && !self.create_new {
-                    return Err(io::const_io_error!(
-                        ErrorKind::InvalidInput,
-                        "invalid creation mode",
-                    ));
+                    return Err(
+                        io::const_error!(ErrorKind::InvalidInput, "invalid creation mode",),
+                    );
                 }
             }
         }
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index b62afb40a61..f03fca60344 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -42,7 +42,7 @@ pub fn unsupported<T>() -> crate::io::Result<T> {
 }
 
 pub fn unsupported_err() -> crate::io::Error {
-    crate::io::const_io_error!(
+    crate::io::const_error!(
         crate::io::ErrorKind::Unsupported,
         "operation not supported on HermitCore yet",
     )
diff --git a/library/std/src/sys/pal/hermit/net.rs b/library/std/src/sys/pal/hermit/net.rs
index d9baa091a23..4e12374203e 100644
--- a/library/std/src/sys/pal/hermit/net.rs
+++ b/library/std/src/sys/pal/hermit/net.rs
@@ -87,7 +87,7 @@ impl Socket {
         loop {
             let elapsed = start.elapsed();
             if elapsed >= timeout {
-                return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out"));
+                return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out"));
             }
 
             let timeout = timeout - elapsed;
@@ -114,7 +114,7 @@ impl Socket {
                     // for POLLHUP rather than read readiness
                     if pollfd.revents & netc::POLLHUP != 0 {
                         let e = self.take_error()?.unwrap_or_else(|| {
-                            io::const_io_error!(
+                            io::const_error!(
                                 io::ErrorKind::Uncategorized,
                                 "no error set after POLLHUP",
                             )
diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs
index 41f2c3e2123..2a0b8dcb4ed 100644
--- a/library/std/src/sys/pal/hermit/thread.rs
+++ b/library/std/src/sys/pal/hermit/thread.rs
@@ -41,7 +41,7 @@ impl Thread {
             unsafe {
                 drop(Box::from_raw(p));
             }
-            Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Unable to create thread!"))
+            Err(io::const_error!(io::ErrorKind::Uncategorized, "Unable to create thread!"))
         } else {
             Ok(Thread { tid: tid })
         };
diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs
index 586ccd18c2f..ce8a2fed4bc 100644
--- a/library/std/src/sys/pal/sgx/mod.rs
+++ b/library/std/src/sys/pal/sgx/mod.rs
@@ -48,7 +48,7 @@ pub fn unsupported<T>() -> crate::io::Result<T> {
 }
 
 pub fn unsupported_err() -> crate::io::Error {
-    crate::io::const_io_error!(ErrorKind::Unsupported, "operation not supported on SGX yet")
+    crate::io::const_error!(ErrorKind::Unsupported, "operation not supported on SGX yet")
 }
 
 /// This function is used to implement various functions that doesn't exist,
@@ -59,7 +59,7 @@ pub fn unsupported_err() -> crate::io::Error {
 pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> {
     static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
     if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
-        Err(crate::io::const_io_error!(
+        Err(crate::io::const_error!(
             ErrorKind::Uncategorized,
             "operation can't be trusted to have any effect on SGX",
         ))
diff --git a/library/std/src/sys/pal/solid/fs.rs b/library/std/src/sys/pal/solid/fs.rs
index 776a96ff3b7..04dd10ad806 100644
--- a/library/std/src/sys/pal/solid/fs.rs
+++ b/library/std/src/sys/pal/solid/fs.rs
@@ -303,7 +303,7 @@ fn cstr(path: &Path) -> io::Result<CString> {
 
     if !path.starts_with(br"\") {
         // Relative paths aren't supported
-        return Err(crate::io::const_io_error!(
+        return Err(crate::io::const_error!(
             crate::io::ErrorKind::Unsupported,
             "relative path is not supported on this platform",
         ));
@@ -314,10 +314,7 @@ fn cstr(path: &Path) -> io::Result<CString> {
     let wrapped_path = [SAFE_PREFIX, &path, &[0]].concat();
 
     CString::from_vec_with_nul(wrapped_path).map_err(|_| {
-        crate::io::const_io_error!(
-            io::ErrorKind::InvalidInput,
-            "path provided contains a nul byte",
-        )
+        crate::io::const_error!(io::ErrorKind::InvalidInput, "path provided contains a nul byte",)
     })
 }
 
@@ -512,7 +509,7 @@ impl fmt::Debug for File {
 
 pub fn unlink(p: &Path) -> io::Result<()> {
     if stat(p)?.file_type().is_dir() {
-        Err(io::const_io_error!(io::ErrorKind::IsADirectory, "is a directory"))
+        Err(io::const_error!(io::ErrorKind::IsADirectory, "is a directory"))
     } else {
         error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Unlink(cstr(p)?.as_ptr()) })
             .map_err(|e| e.as_io_error())?;
@@ -542,7 +539,7 @@ pub fn rmdir(p: &Path) -> io::Result<()> {
             .map_err(|e| e.as_io_error())?;
         Ok(())
     } else {
-        Err(io::const_io_error!(io::ErrorKind::NotADirectory, "not a directory"))
+        Err(io::const_error!(io::ErrorKind::NotADirectory, "not a directory"))
     }
 }
 
@@ -570,7 +567,7 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> {
 pub fn readlink(p: &Path) -> io::Result<PathBuf> {
     // This target doesn't support symlinks
     stat(p)?;
-    Err(io::const_io_error!(io::ErrorKind::InvalidInput, "not a symbolic link"))
+    Err(io::const_error!(io::ErrorKind::InvalidInput, "not a symbolic link"))
 }
 
 pub fn symlink(_original: &Path, _link: &Path) -> io::Result<()> {
diff --git a/library/std/src/sys/pal/solid/net.rs b/library/std/src/sys/pal/solid/net.rs
index c0818ecd856..5f6436807e2 100644
--- a/library/std/src/sys/pal/solid/net.rs
+++ b/library/std/src/sys/pal/solid/net.rs
@@ -175,7 +175,7 @@ impl Socket {
         };
 
         match n {
-            0 => Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")),
+            0 => Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")),
             _ => {
                 let can_write = writefds.num_fds != 0;
                 if !can_write {
diff --git a/library/std/src/sys/pal/solid/os.rs b/library/std/src/sys/pal/solid/os.rs
index d8afcb91f67..57c28aed3b2 100644
--- a/library/std/src/sys/pal/solid/os.rs
+++ b/library/std/src/sys/pal/solid/os.rs
@@ -204,7 +204,7 @@ pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> {
 /// In kmclib, `setenv` and `unsetenv` don't always set `errno`, so this
 /// function just returns a generic error.
 fn cvt_env(t: c_int) -> io::Result<c_int> {
-    if t == -1 { Err(io::const_io_error!(io::ErrorKind::Uncategorized, "failure")) } else { Ok(t) }
+    if t == -1 { Err(io::const_error!(io::ErrorKind::Uncategorized, "failure")) } else { Ok(t) }
 }
 
 pub fn temp_dir() -> PathBuf {
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index abc8e69a285..47d9add72b5 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -13,7 +13,7 @@ use r_efi::efi::{self, Guid};
 use r_efi::protocols::{device_path, device_path_to_text, shell};
 
 use crate::ffi::{OsStr, OsString};
-use crate::io::{self, const_io_error};
+use crate::io::{self, const_error};
 use crate::mem::{MaybeUninit, size_of};
 use crate::os::uefi::env::boot_services;
 use crate::os::uefi::ffi::{OsStrExt, OsStringExt};
@@ -30,7 +30,7 @@ type BootUninstallMultipleProtocolInterfaces =
     unsafe extern "efiapi" fn(_: r_efi::efi::Handle, _: ...) -> r_efi::efi::Status;
 
 const BOOT_SERVICES_UNAVAILABLE: io::Error =
-    const_io_error!(io::ErrorKind::Other, "Boot Services are no longer available");
+    const_error!(io::ErrorKind::Other, "Boot Services are no longer available");
 
 /// Locates Handles with a particular Protocol GUID.
 ///
@@ -114,7 +114,7 @@ pub(crate) fn open_protocol<T>(
         Err(crate::io::Error::from_raw_os_error(r.as_usize()))
     } else {
         NonNull::new(unsafe { protocol.assume_init() })
-            .ok_or(const_io_error!(io::ErrorKind::Other, "null protocol"))
+            .ok_or(const_error!(io::ErrorKind::Other, "null protocol"))
     }
 }
 
@@ -134,7 +134,7 @@ pub(crate) fn create_event(
     if r.is_error() {
         Err(crate::io::Error::from_raw_os_error(r.as_usize()))
     } else {
-        NonNull::new(event).ok_or(const_io_error!(io::ErrorKind::Other, "null protocol"))
+        NonNull::new(event).ok_or(const_error!(io::ErrorKind::Other, "null protocol"))
     }
 }
 
@@ -155,10 +155,8 @@ pub(crate) unsafe fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result
 ///
 /// Note: Some protocols need to be manually freed. It is the caller's responsibility to do so.
 pub(crate) fn image_handle_protocol<T>(protocol_guid: Guid) -> io::Result<NonNull<T>> {
-    let system_handle = uefi::env::try_image_handle().ok_or(io::const_io_error!(
-        io::ErrorKind::NotFound,
-        "Protocol not found in Image handle"
-    ))?;
+    let system_handle = uefi::env::try_image_handle()
+        .ok_or(io::const_error!(io::ErrorKind::NotFound, "Protocol not found in Image handle"))?;
     open_protocol(system_handle, protocol_guid)
 }
 
@@ -178,7 +176,7 @@ pub(crate) fn device_path_to_text(path: NonNull<device_path::Protocol>) -> io::R
         };
 
         let path = os_string_from_raw(path_ptr)
-            .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?;
+            .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))?;
 
         if let Some(boot_services) = crate::os::uefi::env::boot_services() {
             let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
@@ -213,7 +211,7 @@ pub(crate) fn device_path_to_text(path: NonNull<device_path::Protocol>) -> io::R
         }
     }
 
-    Err(io::const_io_error!(io::ErrorKind::NotFound, "No device path to text protocol found"))
+    Err(io::const_error!(io::ErrorKind::NotFound, "No device path to text protocol found"))
 }
 
 /// Gets RuntimeServices.
@@ -234,7 +232,7 @@ impl DevicePath {
         ) -> io::Result<DevicePath> {
             let path_vec = p.encode_wide().chain(Some(0)).collect::<Vec<u16>>();
             if path_vec[..path_vec.len() - 1].contains(&0) {
-                return Err(const_io_error!(
+                return Err(const_error!(
                     io::ErrorKind::InvalidInput,
                     "strings passed to UEFI cannot contain NULs",
                 ));
@@ -243,9 +241,9 @@ impl DevicePath {
             let path =
                 unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) };
 
-            NonNull::new(path).map(DevicePath).ok_or_else(|| {
-                const_io_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path")
-            })
+            NonNull::new(path)
+                .map(DevicePath)
+                .ok_or_else(|| const_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path"))
         }
 
         static LAST_VALID_HANDLE: AtomicPtr<crate::ffi::c_void> =
@@ -271,7 +269,7 @@ impl DevicePath {
             }
         }
 
-        io::Result::Err(const_io_error!(
+        io::Result::Err(const_error!(
             io::ErrorKind::NotFound,
             "DevicePathFromText Protocol not found"
         ))
@@ -326,7 +324,7 @@ impl<T> OwnedProtocol<T> {
         };
 
         let handle = NonNull::new(handle)
-            .ok_or(io::const_io_error!(io::ErrorKind::Uncategorized, "found null handle"))?;
+            .ok_or(io::const_error!(io::ErrorKind::Uncategorized, "found null handle"))?;
 
         Ok(Self { guid, handle, protocol })
     }
diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
index c0ab52f650a..f29c91f3bfe 100644
--- a/library/std/src/sys/pal/uefi/mod.rs
+++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -95,7 +95,7 @@ pub const fn unsupported<T>() -> std_io::Result<T> {
 
 #[inline]
 pub const fn unsupported_err() -> std_io::Error {
-    std_io::const_io_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI",)
+    std_io::const_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI",)
 }
 
 pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind {
diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs
index 27395f7c3c0..6d23c72ef22 100644
--- a/library/std/src/sys/pal/uefi/os.rs
+++ b/library/std/src/sys/pal/uefi/os.rs
@@ -131,7 +131,7 @@ pub fn getcwd() -> io::Result<PathBuf> {
             let path_ptr = unsafe { ((*shell.as_ptr()).get_cur_dir)(crate::ptr::null_mut()) };
             helpers::os_string_from_raw(path_ptr)
                 .map(PathBuf::from)
-                .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))
+                .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))
         }
         None => {
             let mut t = current_exe()?;
@@ -147,7 +147,7 @@ pub fn chdir(p: &path::Path) -> io::Result<()> {
     let shell = helpers::open_shell().ok_or(unsupported_err())?;
 
     let mut p = helpers::os_string_to_raw(p.as_os_str())
-        .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?;
+        .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))?;
 
     let r = unsafe { ((*shell.as_ptr()).set_cur_dir)(crate::ptr::null_mut(), p.as_mut_ptr()) };
     if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
@@ -290,15 +290,15 @@ mod uefi_env {
 
     pub(crate) fn set(key: &OsStr, val: &OsStr) -> io::Result<()> {
         let mut key_ptr = helpers::os_string_to_raw(key)
-            .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?;
+            .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?;
         let mut val_ptr = helpers::os_string_to_raw(val)
-            .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?;
+            .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?;
         unsafe { set_raw(key_ptr.as_mut_ptr(), val_ptr.as_mut_ptr()) }
     }
 
     pub(crate) fn unset(key: &OsStr) -> io::Result<()> {
         let mut key_ptr = helpers::os_string_to_raw(key)
-            .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?;
+            .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?;
         unsafe { set_raw(key_ptr.as_mut_ptr(), crate::ptr::null_mut()) }
     }
 
@@ -328,7 +328,7 @@ mod uefi_env {
                 });
                 // SAFETY: val.add(start) is always NULL terminated
                 let val = unsafe { get_raw(shell, val.add(start)) }
-                    .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?;
+                    .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?;
 
                 vars.push((key, val));
                 start = i + 1;
diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs
index 1b83f4b0aee..95707ebb7f0 100644
--- a/library/std/src/sys/pal/uefi/process.rs
+++ b/library/std/src/sys/pal/uefi/process.rs
@@ -307,7 +307,7 @@ mod uefi_command_internal {
 
     use super::super::helpers;
     use crate::ffi::{OsStr, OsString};
-    use crate::io::{self, const_io_error};
+    use crate::io::{self, const_error};
     use crate::mem::MaybeUninit;
     use crate::os::uefi::env::{boot_services, image_handle, system_table};
     use crate::os::uefi::ffi::{OsStrExt, OsStringExt};
@@ -328,7 +328,7 @@ mod uefi_command_internal {
         pub fn load_image(p: &OsStr) -> io::Result<Self> {
             let path = helpers::DevicePath::from_text(p)?;
             let boot_services: NonNull<r_efi::efi::BootServices> = boot_services()
-                .ok_or_else(|| const_io_error!(io::ErrorKind::NotFound, "Boot Services not found"))?
+                .ok_or_else(|| const_error!(io::ErrorKind::NotFound, "Boot Services not found"))?
                 .cast();
             let mut child_handle: MaybeUninit<r_efi::efi::Handle> = MaybeUninit::uninit();
             let image_handle = image_handle();
@@ -369,7 +369,7 @@ mod uefi_command_internal {
             }
 
             let boot_services: NonNull<r_efi::efi::BootServices> = boot_services()
-                .ok_or_else(|| const_io_error!(io::ErrorKind::NotFound, "Boot Services not found"))?
+                .ok_or_else(|| const_error!(io::ErrorKind::NotFound, "Boot Services not found"))?
                 .cast();
             let mut exit_data_size: usize = 0;
             let mut exit_data: MaybeUninit<*mut u16> = MaybeUninit::uninit();
@@ -583,7 +583,7 @@ mod uefi_command_internal {
             OsString::from_wide(&self._buffer)
                 .into_string()
                 .map(Into::into)
-                .map_err(|_| const_io_error!(io::ErrorKind::Other, "utf8 conversion failed"))
+                .map_err(|_| const_error!(io::ErrorKind::Other, "utf8 conversion failed"))
         }
 
         extern "efiapi" fn reset(
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 96f99efb21e..37029bcd36e 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -559,7 +559,7 @@ impl FileAttr {
                 return if (ext.stx_mask & libc::STATX_BTIME) != 0 {
                     SystemTime::new(ext.stx_btime.tv_sec, ext.stx_btime.tv_nsec as i64)
                 } else {
-                    Err(io::const_io_error!(
+                    Err(io::const_error!(
                         io::ErrorKind::Unsupported,
                         "creation time is not available for the filesystem",
                     ))
@@ -567,7 +567,7 @@ impl FileAttr {
             }
         }
 
-        Err(io::const_io_error!(
+        Err(io::const_error!(
             io::ErrorKind::Unsupported,
             "creation time is not available on this platform \
                             currently",
@@ -1272,7 +1272,7 @@ impl File {
         target_vendor = "apple",
     )))]
     pub fn lock(&self) -> io::Result<()> {
-        Err(io::const_io_error!(io::ErrorKind::Unsupported, "lock() not supported"))
+        Err(io::const_error!(io::ErrorKind::Unsupported, "lock() not supported"))
     }
 
     #[cfg(any(
@@ -1293,7 +1293,7 @@ impl File {
         target_vendor = "apple",
     )))]
     pub fn lock_shared(&self) -> io::Result<()> {
-        Err(io::const_io_error!(io::ErrorKind::Unsupported, "lock_shared() not supported"))
+        Err(io::const_error!(io::ErrorKind::Unsupported, "lock_shared() not supported"))
     }
 
     #[cfg(any(
@@ -1320,7 +1320,7 @@ impl File {
         target_vendor = "apple",
     )))]
     pub fn try_lock(&self) -> io::Result<bool> {
-        Err(io::const_io_error!(io::ErrorKind::Unsupported, "try_lock() not supported"))
+        Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock() not supported"))
     }
 
     #[cfg(any(
@@ -1347,7 +1347,7 @@ impl File {
         target_vendor = "apple",
     )))]
     pub fn try_lock_shared(&self) -> io::Result<bool> {
-        Err(io::const_io_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported"))
+        Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported"))
     }
 
     #[cfg(any(
@@ -1368,7 +1368,7 @@ impl File {
         target_vendor = "apple",
     )))]
     pub fn unlock(&self) -> io::Result<()> {
-        Err(io::const_io_error!(io::ErrorKind::Unsupported, "unlock() not supported"))
+        Err(io::const_error!(io::ErrorKind::Unsupported, "unlock() not supported"))
     }
 
     pub fn truncate(&self, size: u64) -> io::Result<()> {
@@ -1459,11 +1459,11 @@ impl File {
         )))]
         let to_timespec = |time: Option<SystemTime>| match time {
             Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
-            Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_io_error!(
+            Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
                 "timestamp is too large to set as a file time"
             )),
-            Some(_) => Err(io::const_io_error!(
+            Some(_) => Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
                 "timestamp is too small to set as a file time"
             )),
@@ -1476,7 +1476,7 @@ impl File {
                 // the same as for Redox.
                 // `futimens` and `UTIME_OMIT` are a work in progress for vxworks.
                 let _ = times;
-                Err(io::const_io_error!(
+                Err(io::const_error!(
                     io::ErrorKind::Unsupported,
                     "setting file times not supported",
                 ))
@@ -1515,7 +1515,7 @@ impl File {
                     weak!(fn futimens(c_int, *const libc::timespec) -> c_int);
                     match futimens.get() {
                         Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()),
-                        None => return Err(io::const_io_error!(
+                        None => return Err(io::const_error!(
                             io::ErrorKind::Unsupported,
                             "setting file times requires Android API level >= 19",
                         )),
@@ -2090,7 +2090,7 @@ pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
 #[cfg(target_os = "vxworks")]
 pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> {
     let (_, _, _) = (path, uid, gid);
-    Err(io::const_io_error!(io::ErrorKind::Unsupported, "lchown not supported by vxworks"))
+    Err(io::const_error!(io::ErrorKind::Unsupported, "lchown not supported by vxworks"))
 }
 
 #[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))]
@@ -2101,7 +2101,7 @@ pub fn chroot(dir: &Path) -> io::Result<()> {
 #[cfg(target_os = "vxworks")]
 pub fn chroot(dir: &Path) -> io::Result<()> {
     let _ = dir;
-    Err(io::const_io_error!(io::ErrorKind::Unsupported, "chroot not supported by vxworks"))
+    Err(io::const_error!(io::ErrorKind::Unsupported, "chroot not supported by vxworks"))
 }
 
 pub use remove_dir_impl::remove_dir_all;
diff --git a/library/std/src/sys/pal/unix/l4re.rs b/library/std/src/sys/pal/unix/l4re.rs
index 52d39dcfb16..37dd370c514 100644
--- a/library/std/src/sys/pal/unix/l4re.rs
+++ b/library/std/src/sys/pal/unix/l4re.rs
@@ -1,6 +1,6 @@
 macro_rules! unimpl {
     () => {
-        return Err(io::const_io_error!(
+        return Err(io::const_error!(
             io::ErrorKind::Unsupported,
             "No networking available on L4Re.",
         ));
diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs
index 6a67bb0a101..d140607869c 100644
--- a/library/std/src/sys/pal/unix/net.rs
+++ b/library/std/src/sys/pal/unix/net.rs
@@ -190,7 +190,7 @@ impl Socket {
         loop {
             let elapsed = start.elapsed();
             if elapsed >= timeout {
-                return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out"));
+                return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out"));
             }
 
             let timeout = timeout - elapsed;
@@ -225,7 +225,7 @@ impl Socket {
                         // for POLLHUP or POLLERR rather than read readiness
                         if pollfd.revents & (libc::POLLHUP | libc::POLLERR) != 0 {
                             let e = self.take_error()?.unwrap_or_else(|| {
-                                io::const_io_error!(
+                                io::const_error!(
                                     io::ErrorKind::Uncategorized,
                                     "no error set after POLLHUP",
                                 )
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index f983d174ed6..789a40c13e6 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -258,7 +258,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
     use crate::env;
     use crate::io::ErrorKind;
 
-    let exe_path = env::args().next().ok_or(io::const_io_error!(
+    let exe_path = env::args().next().ok_or(io::const_error!(
         ErrorKind::NotFound,
         "an executable path was not found because no arguments were provided through argv"
     ))?;
@@ -284,7 +284,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
             }
         }
     }
-    Err(io::const_io_error!(ErrorKind::NotFound, "an executable path was not found"))
+    Err(io::const_error!(ErrorKind::NotFound, "an executable path was not found"))
 }
 
 #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
@@ -340,7 +340,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
                 0,
             ))?;
             if path_len <= 1 {
-                return Err(io::const_io_error!(
+                return Err(io::const_error!(
                     io::ErrorKind::Uncategorized,
                     "KERN_PROC_PATHNAME sysctl returned zero-length string",
                 ));
@@ -363,7 +363,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
         if curproc_exe.is_file() {
             return crate::fs::read_link(curproc_exe);
         }
-        Err(io::const_io_error!(
+        Err(io::const_error!(
             io::ErrorKind::Uncategorized,
             "/proc/curproc/exe doesn't point to regular file.",
         ))
@@ -382,10 +382,9 @@ pub fn current_exe() -> io::Result<PathBuf> {
         cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_len, ptr::null_mut(), 0))?;
         argv.set_len(argv_len as usize);
         if argv[0].is_null() {
-            return Err(io::const_io_error!(
-                io::ErrorKind::Uncategorized,
-                "no current exe available",
-            ));
+            return Err(
+                io::const_error!(io::ErrorKind::Uncategorized, "no current exe available",),
+            );
         }
         let argv0 = CStr::from_ptr(argv[0]).to_bytes();
         if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') {
@@ -405,7 +404,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
 ))]
 pub fn current_exe() -> io::Result<PathBuf> {
     match crate::fs::read_link("/proc/self/exe") {
-        Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::const_io_error!(
+        Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::const_error!(
             io::ErrorKind::Uncategorized,
             "no /proc/self/exe available. Is /proc mounted?",
         )),
@@ -476,7 +475,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
         );
         if result != libc::B_OK {
             use crate::io::ErrorKind;
-            Err(io::const_io_error!(ErrorKind::Uncategorized, "Error getting executable path"))
+            Err(io::const_error!(ErrorKind::Uncategorized, "Error getting executable path"))
         } else {
             // find_path adds the null terminator.
             let name = CStr::from_ptr(name.as_ptr()).to_bytes();
@@ -493,7 +492,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
 #[cfg(target_os = "l4re")]
 pub fn current_exe() -> io::Result<PathBuf> {
     use crate::io::ErrorKind;
-    Err(io::const_io_error!(ErrorKind::Unsupported, "Not yet implemented!"))
+    Err(io::const_error!(ErrorKind::Unsupported, "Not yet implemented!"))
 }
 
 #[cfg(target_os = "vxworks")]
@@ -523,7 +522,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
     use crate::env;
     use crate::io::ErrorKind;
 
-    let exe_path = env::args().next().ok_or(io::const_io_error!(
+    let exe_path = env::args().next().ok_or(io::const_error!(
         ErrorKind::Uncategorized,
         "an executable path was not found because no arguments were provided through argv"
     ))?;
@@ -698,12 +697,82 @@ pub fn page_size() -> usize {
     unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
 }
 
+// Returns the value for [`confstr(key, ...)`][posix_confstr]. Currently only
+// used on Darwin, but should work on any unix (in case we need to get
+// `_CS_PATH` or `_CS_V[67]_ENV` in the future).
+//
+// [posix_confstr]:
+//     https://pubs.opengroup.org/onlinepubs/9699919799/functions/confstr.html
+//
+// FIXME: Support `confstr` in Miri.
+#[cfg(all(target_vendor = "apple", not(miri)))]
+fn confstr(key: c_int, size_hint: Option<usize>) -> io::Result<OsString> {
+    let mut buf: Vec<u8> = Vec::with_capacity(0);
+    let mut bytes_needed_including_nul = size_hint
+        .unwrap_or_else(|| {
+            // Treat "None" as "do an extra call to get the length". In theory
+            // we could move this into the loop below, but it's hard to do given
+            // that it isn't 100% clear if it's legal to pass 0 for `len` when
+            // the buffer isn't null.
+            unsafe { libc::confstr(key, core::ptr::null_mut(), 0) }
+        })
+        .max(1);
+    // If the value returned by `confstr` is greater than the len passed into
+    // it, then the value was truncated, meaning we need to retry. Note that
+    // while `confstr` results don't seem to change for a process, it's unclear
+    // if this is guaranteed anywhere, so looping does seem required.
+    while bytes_needed_including_nul > buf.capacity() {
+        // We write into the spare capacity of `buf`. This lets us avoid
+        // changing buf's `len`, which both simplifies `reserve` computation,
+        // allows working with `Vec<u8>` instead of `Vec<MaybeUninit<u8>>`, and
+        // may avoid a copy, since the Vec knows that none of the bytes are needed
+        // when reallocating (well, in theory anyway).
+        buf.reserve(bytes_needed_including_nul);
+        // `confstr` returns
+        // - 0 in the case of errors: we break and return an error.
+        // - The number of bytes written, iff the provided buffer is enough to
+        //   hold the entire value: we break and return the data in `buf`.
+        // - Otherwise, the number of bytes needed (including nul): we go
+        //   through the loop again.
+        bytes_needed_including_nul =
+            unsafe { libc::confstr(key, buf.as_mut_ptr().cast::<c_char>(), buf.capacity()) };
+    }
+    // `confstr` returns 0 in the case of an error.
+    if bytes_needed_including_nul == 0 {
+        return Err(io::Error::last_os_error());
+    }
+    // Safety: `confstr(..., buf.as_mut_ptr(), buf.capacity())` returned a
+    // non-zero value, meaning `bytes_needed_including_nul` bytes were
+    // initialized.
+    unsafe {
+        buf.set_len(bytes_needed_including_nul);
+        // Remove the NUL-terminator.
+        let last_byte = buf.pop();
+        // ... and smoke-check that it *was* a NUL-terminator.
+        assert_eq!(last_byte, Some(0), "`confstr` provided a string which wasn't nul-terminated");
+    };
+    Ok(OsString::from_vec(buf))
+}
+
+#[cfg(all(target_vendor = "apple", not(miri)))]
+fn darwin_temp_dir() -> PathBuf {
+    confstr(libc::_CS_DARWIN_USER_TEMP_DIR, Some(64)).map(PathBuf::from).unwrap_or_else(|_| {
+        // It failed for whatever reason (there are several possible reasons),
+        // so return the global one.
+        PathBuf::from("/tmp")
+    })
+}
+
 pub fn temp_dir() -> PathBuf {
     crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| {
-        if cfg!(target_os = "android") {
-            PathBuf::from("/data/local/tmp")
-        } else {
-            PathBuf::from("/tmp")
+        cfg_if::cfg_if! {
+            if #[cfg(all(target_vendor = "apple", not(miri)))] {
+                darwin_temp_dir()
+            } else if #[cfg(target_os = "android")] {
+                PathBuf::from("/data/local/tmp")
+            } else {
+                PathBuf::from("/tmp")
+            }
         }
     })
 }
diff --git a/library/std/src/sys/pal/unix/os/tests.rs b/library/std/src/sys/pal/unix/os/tests.rs
index efc29955b05..63a1cc1e94a 100644
--- a/library/std/src/sys/pal/unix/os/tests.rs
+++ b/library/std/src/sys/pal/unix/os/tests.rs
@@ -21,3 +21,28 @@ fn test_parse_glibc_version() {
         assert_eq!(parsed, super::parse_glibc_version(version_str));
     }
 }
+
+// Smoke check `confstr`, do it for several hint values, to ensure our resizing
+// logic is correct.
+#[test]
+#[cfg(all(target_vendor = "apple", not(miri)))]
+fn test_confstr() {
+    for key in [libc::_CS_DARWIN_USER_TEMP_DIR, libc::_CS_PATH] {
+        let value_nohint = super::confstr(key, None).unwrap_or_else(|e| {
+            panic!("confstr({key}, None) failed: {e:?}");
+        });
+        let end = (value_nohint.len() + 1) * 2;
+        for hint in 0..end {
+            assert_eq!(
+                super::confstr(key, Some(hint)).as_deref().ok(),
+                Some(&*value_nohint),
+                "confstr({key}, Some({hint})) failed",
+            );
+        }
+    }
+    // Smoke check that we don't loop forever or something if the input was not valid.
+    for hint in [None, Some(0), Some(1)] {
+        let hopefully_invalid = 123456789_i32;
+        assert!(super::confstr(hopefully_invalid, hint).is_err());
+    }
+}
diff --git a/library/std/src/sys/pal/unix/process/process_fuchsia.rs b/library/std/src/sys/pal/unix/process/process_fuchsia.rs
index 8f7d786e32f..b7a35718757 100644
--- a/library/std/src/sys/pal/unix/process/process_fuchsia.rs
+++ b/library/std/src/sys/pal/unix/process/process_fuchsia.rs
@@ -18,7 +18,7 @@ impl Command {
         let envp = self.capture_env();
 
         if self.saw_nul() {
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
                 "nul byte found in provided data",
             ));
@@ -38,7 +38,7 @@ impl Command {
 
     pub fn exec(&mut self, default: Stdio) -> io::Error {
         if self.saw_nul() {
-            return io::const_io_error!(
+            return io::const_error!(
                 io::ErrorKind::InvalidInput,
                 "nul byte found in provided data",
             );
@@ -185,7 +185,7 @@ impl Process {
             ))?;
         }
         if actual != 1 {
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 io::ErrorKind::InvalidData,
                 "Failed to get exit status of process",
             ));
@@ -222,7 +222,7 @@ impl Process {
             ))?;
         }
         if actual != 1 {
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 io::ErrorKind::InvalidData,
                 "Failed to get exit status of process",
             ));
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index 8faf1fda546..ec4965c1d71 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -61,7 +61,7 @@ impl Command {
         let envp = self.capture_env();
 
         if self.saw_nul() {
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 ErrorKind::InvalidInput,
                 "nul byte found in provided data",
             ));
@@ -175,7 +175,7 @@ impl Command {
     // allowed to exist in dead code), but it sounds bad, so we go out of our
     // way to avoid that all-together.
     #[cfg(any(target_os = "tvos", target_os = "watchos"))]
-    const ERR_APPLE_TV_WATCH_NO_FORK_EXEC: Error = io::const_io_error!(
+    const ERR_APPLE_TV_WATCH_NO_FORK_EXEC: Error = io::const_error!(
         ErrorKind::Unsupported,
         "`fork`+`exec`-based process spawning is not supported on this target",
     );
@@ -218,7 +218,7 @@ impl Command {
                 } else if delay < MAX_FORKSPAWN_SLEEP {
                     thread::sleep(delay);
                 } else {
-                    return Err(io::const_io_error!(
+                    return Err(io::const_error!(
                         ErrorKind::WouldBlock,
                         "forking returned EBADF too often",
                     ));
@@ -235,7 +235,7 @@ impl Command {
         let envp = self.capture_env();
 
         if self.saw_nul() {
-            return io::const_io_error!(ErrorKind::InvalidInput, "nul byte found in provided data",);
+            return io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data",);
         }
 
         match self.setup_io(default, true) {
@@ -561,7 +561,7 @@ impl Command {
                         } else if delay < MAX_FORKSPAWN_SLEEP {
                             thread::sleep(delay);
                         } else {
-                            return Err(io::const_io_error!(
+                            return Err(io::const_error!(
                                 ErrorKind::WouldBlock,
                                 "posix_spawnp returned EBADF too often",
                             ));
diff --git a/library/std/src/sys/pal/unix/process/process_vxworks.rs b/library/std/src/sys/pal/unix/process/process_vxworks.rs
index 38daf6af918..e2c1b6a0326 100644
--- a/library/std/src/sys/pal/unix/process/process_vxworks.rs
+++ b/library/std/src/sys/pal/unix/process/process_vxworks.rs
@@ -22,7 +22,7 @@ impl Command {
         let envp = self.capture_env();
 
         if self.saw_nul() {
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 ErrorKind::InvalidInput,
                 "nul byte found in provided data",
             ));
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 04024661836..131a6e81b1e 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -469,7 +469,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
             unsafe {
                 use libc::_syspage_ptr;
                 if _syspage_ptr.is_null() {
-                    Err(io::const_io_error!(io::ErrorKind::NotFound, "No syspage available"))
+                    Err(io::const_error!(io::ErrorKind::NotFound, "No syspage available"))
                 } else {
                     let cpus = (*_syspage_ptr).num_cpu;
                     NonZero::new(cpus as usize)
@@ -509,7 +509,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
             }
         } else {
             // FIXME: implement on Redox, l4re
-            Err(io::const_io_error!(io::ErrorKind::Unsupported, "Getting the number of hardware threads is not supported on the target platform"))
+            Err(io::const_error!(io::ErrorKind::Unsupported, "Getting the number of hardware threads is not supported on the target platform"))
         }
     }
 }
diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs
index 535fe6b27d9..343864d0b3f 100644
--- a/library/std/src/sys/pal/unix/time.rs
+++ b/library/std/src/sys/pal/unix/time.rs
@@ -96,7 +96,7 @@ impl Timespec {
         if tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64 {
             Ok(unsafe { Self::new_unchecked(tv_sec, tv_nsec) })
         } else {
-            Err(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid timestamp"))
+            Err(io::const_error!(io::ErrorKind::InvalidData, "Invalid timestamp"))
         }
     }
 
diff --git a/library/std/src/sys/pal/unsupported/os.rs b/library/std/src/sys/pal/unsupported/os.rs
index 481fd62c04f..48de4312885 100644
--- a/library/std/src/sys/pal/unsupported/os.rs
+++ b/library/std/src/sys/pal/unsupported/os.rs
@@ -96,11 +96,11 @@ pub fn getenv(_: &OsStr) -> Option<OsString> {
 }
 
 pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
-    Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
+    Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
 }
 
 pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> {
-    Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
+    Err(io::const_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
 }
 
 pub fn temp_dir() -> PathBuf {
diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/pal/wasi/fs.rs
index 3296c762cca..0667eb90101 100644
--- a/library/std/src/sys/pal/wasi/fs.rs
+++ b/library/std/src/sys/pal/wasi/fs.rs
@@ -496,7 +496,7 @@ impl File {
     pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
         let to_timestamp = |time: Option<SystemTime>| match time {
             Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts),
-            Some(_) => Err(io::const_io_error!(
+            Some(_) => Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
                 "timestamp is too large to set as a file time"
             )),
@@ -764,8 +764,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
 }
 
 pub fn osstr2str(f: &OsStr) -> io::Result<&str> {
-    f.to_str()
-        .ok_or_else(|| io::const_io_error!(io::ErrorKind::Uncategorized, "input must be utf-8"))
+    f.to_str().ok_or_else(|| io::const_error!(io::ErrorKind::Uncategorized, "input must be utf-8"))
 }
 
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
@@ -811,7 +810,7 @@ fn remove_dir_all_recursive(parent: &WasiFd, path: &Path) -> io::Result<()> {
     for entry in ReadDir::new(fd, dummy_root) {
         let entry = entry?;
         let path = crate::str::from_utf8(&entry.name).map_err(|_| {
-            io::const_io_error!(io::ErrorKind::Uncategorized, "invalid utf-8 file name found")
+            io::const_error!(io::ErrorKind::Uncategorized, "invalid utf-8 file name found")
         })?;
 
         let result: io::Result<()> = try {
diff --git a/library/std/src/sys/pal/wasip2/net.rs b/library/std/src/sys/pal/wasip2/net.rs
index 06e623df843..f009a51821f 100644
--- a/library/std/src/sys/pal/wasip2/net.rs
+++ b/library/std/src/sys/pal/wasip2/net.rs
@@ -117,7 +117,7 @@ impl Socket {
         loop {
             let elapsed = start.elapsed();
             if elapsed >= timeout {
-                return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out"));
+                return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out"));
             }
 
             let timeout = timeout - elapsed;
diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs
index e9fc19bcb99..3447a0157e4 100644
--- a/library/std/src/sys/pal/windows/args.rs
+++ b/library/std/src/sys/pal/windows/args.rs
@@ -327,7 +327,7 @@ pub(crate) fn make_bat_command_line(
     force_quotes: bool,
 ) -> io::Result<Vec<u16>> {
     const INVALID_ARGUMENT_ERROR: io::Error =
-        io::const_io_error!(io::ErrorKind::InvalidInput, r#"batch file arguments are invalid"#);
+        io::const_error!(io::ErrorKind::InvalidInput, r#"batch file arguments are invalid"#);
     // Set the start of the command line to `cmd.exe /c "`
     // It is necessary to surround the command in an extra pair of quotes,
     // hence the trailing quote here. It will be closed after all arguments
@@ -340,7 +340,7 @@ pub(crate) fn make_bat_command_line(
     // Windows file names cannot contain a `"` character or end with `\\`.
     // If the script name does then return an error.
     if script.contains(&(b'"' as u16)) || script.last() == Some(&(b'\\' as u16)) {
-        return Err(io::const_io_error!(
+        return Err(io::const_error!(
             io::ErrorKind::InvalidInput,
             "Windows file names may not contain `\"` or end with `\\`"
         ));
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index 07e4f93a379..5bdd5f81b9c 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -677,7 +677,7 @@ impl File {
                     )
                 }
                 _ => {
-                    return Err(io::const_io_error!(
+                    return Err(io::const_error!(
                         io::ErrorKind::Uncategorized,
                         "Unsupported reparse point type",
                     ));
@@ -718,7 +718,7 @@ impl File {
             || times.modified.map_or(false, is_zero)
             || times.created.map_or(false, is_zero)
         {
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
                 "Cannot set file timestamp to 0",
             ));
@@ -728,7 +728,7 @@ impl File {
             || times.modified.map_or(false, is_max)
             || times.created.map_or(false, is_max)
         {
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
                 "Cannot set file timestamp to 0xFFFF_FFFF_FFFF_FFFF",
             ));
@@ -1305,10 +1305,9 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
 
 #[cfg(target_vendor = "uwp")]
 pub fn link(_original: &Path, _link: &Path) -> io::Result<()> {
-    return Err(io::const_io_error!(
-        io::ErrorKind::Unsupported,
-        "hard link are not supported on UWP",
-    ));
+    return Err(
+        io::const_error!(io::ErrorKind::Unsupported, "hard link are not supported on UWP",),
+    );
 }
 
 pub fn stat(path: &Path) -> io::Result<FileAttr> {
@@ -1495,7 +1494,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> {
             let bytes = unsafe { OsStr::from_encoded_bytes_unchecked(&abs_path[2..]) };
             r"\??\UNC\".encode_utf16().chain(bytes.encode_wide()).collect()
         } else {
-            return Err(io::const_io_error!(io::ErrorKind::InvalidInput, "path is not valid"));
+            return Err(io::const_error!(io::ErrorKind::InvalidInput, "path is not valid"));
         }
     };
     // Defined inline so we don't have to mess about with variable length buffer.
@@ -1512,10 +1511,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> {
     }
     let data_len = 12 + (abs_path.len() * 2);
     if data_len > u16::MAX as usize {
-        return Err(io::const_io_error!(
-            io::ErrorKind::InvalidInput,
-            "`original` path is too long"
-        ));
+        return Err(io::const_error!(io::ErrorKind::InvalidInput, "`original` path is too long"));
     }
     let data_len = data_len as u16;
     let mut header = MountPointBuffer {
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index aca69490d7a..d66ff15e10b 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -183,7 +183,7 @@ pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> crate::io::Result<Vec<u16>> {
         maybe_result.extend(s.encode_wide());
 
         if unrolled_find_u16s(0, &maybe_result).is_some() {
-            return Err(crate::io::const_io_error!(
+            return Err(crate::io::const_error!(
                 ErrorKind::InvalidInput,
                 "strings passed to WinAPI cannot contain NULs",
             ));
diff --git a/library/std/src/sys/pal/windows/net.rs b/library/std/src/sys/pal/windows/net.rs
index fd62d1f407c..a92853c642c 100644
--- a/library/std/src/sys/pal/windows/net.rs
+++ b/library/std/src/sys/pal/windows/net.rs
@@ -267,7 +267,7 @@ impl Socket {
                 };
 
                 match count {
-                    0 => Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")),
+                    0 => Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")),
                     _ => {
                         if writefds.fd_count != 1 {
                             if let Some(e) = self.take_error()? {
diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs
index 17bb03fe7af..da0daacd1dd 100644
--- a/library/std/src/sys/pal/windows/process.rs
+++ b/library/std/src/sys/pal/windows/process.rs
@@ -144,7 +144,7 @@ impl AsRef<OsStr> for EnvKey {
 
 pub(crate) fn ensure_no_nuls<T: AsRef<OsStr>>(str: T) -> io::Result<T> {
     if str.as_ref().encode_wide().any(|b| b == 0) {
-        Err(io::const_io_error!(ErrorKind::InvalidInput, "nul byte found in provided data"))
+        Err(io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data"))
     } else {
         Ok(str)
     }
@@ -439,10 +439,9 @@ fn resolve_exe<'a>(
 ) -> io::Result<Vec<u16>> {
     // Early return if there is no filename.
     if exe_path.is_empty() || path::has_trailing_slash(exe_path) {
-        return Err(io::const_io_error!(
-            io::ErrorKind::InvalidInput,
-            "program path has no file name",
-        ));
+        return Err(
+            io::const_error!(io::ErrorKind::InvalidInput, "program path has no file name",),
+        );
     }
     // Test if the file name has the `exe` extension.
     // This does a case-insensitive `ends_with`.
@@ -492,7 +491,7 @@ fn resolve_exe<'a>(
         }
     }
     // If we get here then the executable cannot be found.
-    Err(io::const_io_error!(io::ErrorKind::NotFound, "program not found"))
+    Err(io::const_error!(io::ErrorKind::NotFound, "program not found"))
 }
 
 // Calls `f` for every path that should be used to find an executable.
@@ -921,7 +920,7 @@ fn make_proc_thread_attribute_list(
     // a null pointer to retrieve the required size.
     let mut required_size = 0;
     let Ok(attribute_count) = attributes.len().try_into() else {
-        return Err(io::const_io_error!(
+        return Err(io::const_error!(
             ErrorKind::InvalidInput,
             "maximum number of ProcThreadAttributes exceeded",
         ));
diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs
index 575f2250eb9..642c8bc4df7 100644
--- a/library/std/src/sys/pal/windows/stdio.rs
+++ b/library/std/src/sys/pal/windows/stdio.rs
@@ -107,7 +107,7 @@ fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> i
         if data[0] >> 6 != 0b10 {
             // not a continuation byte - reject
             incomplete_utf8.len = 0;
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 io::ErrorKind::InvalidData,
                 "Windows stdio in console mode does not support writing non-UTF-8 byte sequences",
             ));
@@ -129,7 +129,7 @@ fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> i
                 return Ok(1);
             }
             Err(_) => {
-                return Err(io::const_io_error!(
+                return Err(io::const_error!(
                     io::ErrorKind::InvalidData,
                     "Windows stdio in console mode does not support writing non-UTF-8 byte sequences",
                 ));
@@ -153,7 +153,7 @@ fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> i
                 incomplete_utf8.len = 1;
                 return Ok(1);
             } else {
-                return Err(io::const_io_error!(
+                return Err(io::const_error!(
                     io::ErrorKind::InvalidData,
                     "Windows stdio in console mode does not support writing non-UTF-8 byte sequences",
                 ));
@@ -392,7 +392,7 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> {
     };
     if result == 0 {
         // We can't really do any better than forget all data and return an error.
-        Err(io::const_io_error!(
+        Err(io::const_error!(
             io::ErrorKind::InvalidData,
             "Windows stdin in console mode does not support non-UTF-16 input; \
             encountered unpaired surrogate",
diff --git a/library/std/src/sys/pal/xous/net/dns.rs b/library/std/src/sys/pal/xous/net/dns.rs
index 1a2b56b4da5..ff6e49ed2d4 100644
--- a/library/std/src/sys/pal/xous/net/dns.rs
+++ b/library/std/src/sys/pal/xous/net/dns.rs
@@ -107,7 +107,7 @@ impl TryFrom<&str> for LookupHost {
             ($e:expr, $msg:expr) => {
                 match $e {
                     Some(r) => r,
-                    None => return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &$msg)),
+                    None => return Err(io::const_error!(io::ErrorKind::InvalidInput, &$msg)),
                 }
             };
         }
@@ -123,7 +123,6 @@ impl TryFrom<(&str, u16)> for LookupHost {
     type Error = io::Error;
 
     fn try_from(v: (&str, u16)) -> io::Result<LookupHost> {
-        lookup(v.0, v.1)
-            .map_err(|_e| io::const_io_error!(io::ErrorKind::InvalidInput, &"DNS failure"))
+        lookup(v.0, v.1).map_err(|_e| io::const_error!(io::ErrorKind::InvalidInput, &"DNS failure"))
     }
 }
diff --git a/library/std/src/sys/pal/xous/net/tcplistener.rs b/library/std/src/sys/pal/xous/net/tcplistener.rs
index ddfb289162b..640a02a64f5 100644
--- a/library/std/src/sys/pal/xous/net/tcplistener.rs
+++ b/library/std/src/sys/pal/xous/net/tcplistener.rs
@@ -9,7 +9,7 @@ use crate::{fmt, io};
 
 macro_rules! unimpl {
     () => {
-        return Err(io::const_io_error!(
+        return Err(io::const_error!(
             io::ErrorKind::Unsupported,
             &"This function is not yet implemented",
         ));
@@ -71,7 +71,7 @@ impl TcpListener {
             0,
             4096,
         ) else {
-            return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Invalid response"));
+            return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response"));
         };
 
         // The first four bytes should be zero upon success, and will be nonzero
@@ -80,16 +80,13 @@ impl TcpListener {
         if response[0] != 0 || valid == 0 {
             let errcode = response[1];
             if errcode == NetError::SocketInUse as u8 {
-                return Err(io::const_io_error!(io::ErrorKind::ResourceBusy, &"Socket in use"));
+                return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use"));
             } else if errcode == NetError::Invalid as u8 {
-                return Err(io::const_io_error!(
-                    io::ErrorKind::AddrNotAvailable,
-                    &"Invalid address"
-                ));
+                return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, &"Invalid address"));
             } else if errcode == NetError::LibraryError as u8 {
-                return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error"));
+                return Err(io::const_error!(io::ErrorKind::Other, &"Library error"));
             } else {
-                return Err(io::const_io_error!(
+                return Err(io::const_error!(
                     io::ErrorKind::Other,
                     &"Unable to connect or internal error"
                 ));
@@ -130,16 +127,15 @@ impl TcpListener {
             if receive_request.raw[0] != 0 {
                 // error case
                 if receive_request.raw[1] == NetError::TimedOut as u8 {
-                    return Err(io::const_io_error!(io::ErrorKind::TimedOut, &"accept timed out",));
+                    return Err(io::const_error!(io::ErrorKind::TimedOut, &"accept timed out",));
                 } else if receive_request.raw[1] == NetError::WouldBlock as u8 {
-                    return Err(io::const_io_error!(
-                        io::ErrorKind::WouldBlock,
-                        &"accept would block",
-                    ));
+                    return Err(
+                        io::const_error!(io::ErrorKind::WouldBlock, &"accept would block",),
+                    );
                 } else if receive_request.raw[1] == NetError::LibraryError as u8 {
-                    return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error"));
+                    return Err(io::const_error!(io::ErrorKind::Other, &"Library error"));
                 } else {
-                    return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",));
+                    return Err(io::const_error!(io::ErrorKind::Other, &"library error",));
                 }
             } else {
                 // accept successful
@@ -163,7 +159,7 @@ impl TcpListener {
                         port,
                     )
                 } else {
-                    return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",));
+                    return Err(io::const_error!(io::ErrorKind::Other, &"library error",));
                 };
 
                 // replenish the listener
@@ -175,7 +171,7 @@ impl TcpListener {
                 Ok((TcpStream::from_listener(stream_fd, self.local.port(), port, addr), addr))
             }
         } else {
-            Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unable to accept"))
+            Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unable to accept"))
         }
     }
 
@@ -192,7 +188,7 @@ impl TcpListener {
             services::net_server(),
             services::NetBlockingScalar::StdSetTtlTcp(self.fd.load(Ordering::Relaxed), ttl).into(),
         )
-        .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
         .map(|_| ())
     }
 
@@ -201,7 +197,7 @@ impl TcpListener {
             services::net_server(),
             services::NetBlockingScalar::StdGetTtlTcp(self.fd.load(Ordering::Relaxed)).into(),
         )
-        .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
         .map(|res| res[0] as _)?)
     }
 
diff --git a/library/std/src/sys/pal/xous/net/tcpstream.rs b/library/std/src/sys/pal/xous/net/tcpstream.rs
index 03442cf2fcd..572dd6b3b63 100644
--- a/library/std/src/sys/pal/xous/net/tcpstream.rs
+++ b/library/std/src/sys/pal/xous/net/tcpstream.rs
@@ -10,7 +10,7 @@ use crate::time::Duration;
 
 macro_rules! unimpl {
     () => {
-        return Err(io::const_io_error!(
+        return Err(io::const_error!(
             io::ErrorKind::Unsupported,
             &"This function is not yet implemented",
         ));
@@ -96,7 +96,7 @@ impl TcpStream {
             0,
             4096,
         ) else {
-            return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Invalid response"));
+            return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response"));
         };
 
         // The first four bytes should be zero upon success, and will be nonzero
@@ -106,14 +106,11 @@ impl TcpStream {
             // errcode is a u8 but stuck in a u16 where the upper byte is invalid. Mask & decode accordingly.
             let errcode = response[0];
             if errcode == NetError::SocketInUse as u8 {
-                return Err(io::const_io_error!(io::ErrorKind::ResourceBusy, &"Socket in use",));
+                return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use",));
             } else if errcode == NetError::Unaddressable as u8 {
-                return Err(io::const_io_error!(
-                    io::ErrorKind::AddrNotAvailable,
-                    &"Invalid address",
-                ));
+                return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, &"Invalid address",));
             } else {
-                return Err(io::const_io_error!(
+                return Err(io::const_error!(
                     io::ErrorKind::InvalidInput,
                     &"Unable to connect or internal error",
                 ));
@@ -199,7 +196,7 @@ impl TcpStream {
             self.read_timeout.load(Ordering::Relaxed) as usize,
             data_to_read,
         ) else {
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
                 &"Library failure: wrong message type or messaging error"
             ));
@@ -215,14 +212,14 @@ impl TcpStream {
             if result[0] != 0 {
                 if result[1] == 8 {
                     // timed out
-                    return Err(io::const_io_error!(io::ErrorKind::TimedOut, &"Timeout",));
+                    return Err(io::const_error!(io::ErrorKind::TimedOut, &"Timeout",));
                 }
                 if result[1] == 9 {
                     // would block
-                    return Err(io::const_io_error!(io::ErrorKind::WouldBlock, &"Would block",));
+                    return Err(io::const_error!(io::ErrorKind::WouldBlock, &"Would block",));
                 }
             }
-            Err(io::const_io_error!(io::ErrorKind::Other, &"recv_slice failure"))
+            Err(io::const_error!(io::ErrorKind::Other, &"recv_slice failure"))
         }
     }
 
@@ -261,23 +258,20 @@ impl TcpStream {
             self.write_timeout.load(Ordering::Relaxed) as usize,
             buf_len,
         )
-        .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Internal error")))?;
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")))?;
 
         if send_request.raw[0] != 0 {
             if send_request.raw[4] == 8 {
                 // timed out
-                return Err(io::const_io_error!(
+                return Err(io::const_error!(
                     io::ErrorKind::BrokenPipe,
                     &"Timeout or connection closed",
                 ));
             } else if send_request.raw[4] == 9 {
                 // would block
-                return Err(io::const_io_error!(io::ErrorKind::WouldBlock, &"Would block",));
+                return Err(io::const_error!(io::ErrorKind::WouldBlock, &"Would block",));
             } else {
-                return Err(io::const_io_error!(
-                    io::ErrorKind::InvalidInput,
-                    &"Error when sending",
-                ));
+                return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Error when sending",));
             }
         }
         Ok(u32::from_le_bytes([
@@ -310,7 +304,7 @@ impl TcpStream {
             0,
             0,
         ) else {
-            return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Internal error"));
+            return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error"));
         };
         let mut i = get_addr.raw.iter();
         match *i.next().unwrap() {
@@ -330,7 +324,7 @@ impl TcpStream {
                 }
                 Ok(SocketAddr::V6(SocketAddrV6::new(new_addr.into(), self.local_port, 0, 0)))
             }
-            _ => Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Internal error")),
+            _ => Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")),
         }
     }
 
@@ -339,7 +333,7 @@ impl TcpStream {
             services::net_server(),
             services::NetBlockingScalar::StdTcpStreamShutdown(self.fd, how).into(),
         )
-        .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
         .map(|_| ())
     }
 
@@ -361,7 +355,7 @@ impl TcpStream {
             services::net_server(),
             services::NetBlockingScalar::StdSetNodelay(self.fd, enabled).into(),
         )
-        .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
         .map(|_| ())
     }
 
@@ -370,7 +364,7 @@ impl TcpStream {
             services::net_server(),
             services::NetBlockingScalar::StdGetNodelay(self.fd).into(),
         )
-        .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
         .map(|res| res[0] != 0)?)
     }
 
@@ -382,7 +376,7 @@ impl TcpStream {
             services::net_server(),
             services::NetBlockingScalar::StdSetTtlTcp(self.fd, ttl).into(),
         )
-        .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
         .map(|_| ())
     }
 
@@ -391,7 +385,7 @@ impl TcpStream {
             services::net_server(),
             services::NetBlockingScalar::StdGetTtlTcp(self.fd).into(),
         )
-        .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
         .map(|res| res[0] as _)?)
     }
 
diff --git a/library/std/src/sys/pal/xous/net/udp.rs b/library/std/src/sys/pal/xous/net/udp.rs
index de5133280ba..1b7ecac6d3a 100644
--- a/library/std/src/sys/pal/xous/net/udp.rs
+++ b/library/std/src/sys/pal/xous/net/udp.rs
@@ -11,7 +11,7 @@ use crate::{fmt, io};
 
 macro_rules! unimpl {
     () => {
-        return Err(io::const_io_error!(
+        return Err(io::const_error!(
             io::ErrorKind::Unsupported,
             &"This function is not yet implemented",
         ));
@@ -72,16 +72,16 @@ impl UdpSocket {
             if response[0] != 0 || valid == 0 {
                 let errcode = response[1];
                 if errcode == NetError::SocketInUse as u8 {
-                    return Err(io::const_io_error!(io::ErrorKind::ResourceBusy, &"Socket in use"));
+                    return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use"));
                 } else if errcode == NetError::Invalid as u8 {
-                    return Err(io::const_io_error!(
+                    return Err(io::const_error!(
                         io::ErrorKind::InvalidInput,
                         &"Port can't be 0 or invalid address"
                     ));
                 } else if errcode == NetError::LibraryError as u8 {
-                    return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error"));
+                    return Err(io::const_error!(io::ErrorKind::Other, &"Library error"));
                 } else {
-                    return Err(io::const_io_error!(
+                    return Err(io::const_error!(
                         io::ErrorKind::Other,
                         &"Unable to connect or internal error"
                     ));
@@ -98,13 +98,13 @@ impl UdpSocket {
                 nonblocking: Cell::new(false),
             });
         }
-        Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Invalid response"))
+        Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response"))
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         match self.remote.get() {
             Some(dest) => Ok(dest),
-            None => Err(io::const_io_error!(io::ErrorKind::NotConnected, &"No peer specified")),
+            None => Err(io::const_error!(io::ErrorKind::NotConnected, &"No peer specified")),
         }
     }
 
@@ -141,16 +141,13 @@ impl UdpSocket {
             if receive_request.raw[0] != 0 {
                 // error case
                 if receive_request.raw[1] == NetError::TimedOut as u8 {
-                    return Err(io::const_io_error!(io::ErrorKind::TimedOut, &"recv timed out",));
+                    return Err(io::const_error!(io::ErrorKind::TimedOut, &"recv timed out",));
                 } else if receive_request.raw[1] == NetError::WouldBlock as u8 {
-                    return Err(io::const_io_error!(
-                        io::ErrorKind::WouldBlock,
-                        &"recv would block",
-                    ));
+                    return Err(io::const_error!(io::ErrorKind::WouldBlock, &"recv would block",));
                 } else if receive_request.raw[1] == NetError::LibraryError as u8 {
-                    return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error"));
+                    return Err(io::const_error!(io::ErrorKind::Other, &"Library error"));
                 } else {
-                    return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",));
+                    return Err(io::const_error!(io::ErrorKind::Other, &"library error",));
                 }
             } else {
                 let rr = &receive_request.raw;
@@ -173,7 +170,7 @@ impl UdpSocket {
                         port,
                     )
                 } else {
-                    return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",));
+                    return Err(io::const_error!(io::ErrorKind::Other, &"library error",));
                 };
                 for (&s, d) in rr[22..22 + rxlen as usize].iter().zip(buf.iter_mut()) {
                     *d = s;
@@ -181,7 +178,7 @@ impl UdpSocket {
                 Ok((rxlen as usize, addr))
             }
         } else {
-            Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unable to recv"))
+            Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unable to recv"))
         }
     }
 
@@ -211,7 +208,7 @@ impl UdpSocket {
         if let Some(addr) = self.remote.get() {
             self.send_to(buf, &addr)
         } else {
-            Err(io::const_io_error!(io::ErrorKind::NotConnected, &"No remote specified"))
+            Err(io::const_error!(io::ErrorKind::NotConnected, &"No remote specified"))
         }
     }
 
@@ -282,22 +279,19 @@ impl UdpSocket {
                     if response[0] != 0 || valid == 0 {
                         let errcode = response[1];
                         if errcode == NetError::SocketInUse as u8 {
-                            return Err(io::const_io_error!(
+                            return Err(io::const_error!(
                                 io::ErrorKind::ResourceBusy,
                                 &"Socket in use"
                             ));
                         } else if errcode == NetError::Invalid as u8 {
-                            return Err(io::const_io_error!(
+                            return Err(io::const_error!(
                                 io::ErrorKind::InvalidInput,
                                 &"Socket not valid"
                             ));
                         } else if errcode == NetError::LibraryError as u8 {
-                            return Err(io::const_io_error!(
-                                io::ErrorKind::Other,
-                                &"Library error"
-                            ));
+                            return Err(io::const_error!(io::ErrorKind::Other, &"Library error"));
                         } else {
-                            return Err(io::const_io_error!(
+                            return Err(io::const_error!(
                                 io::ErrorKind::Other,
                                 &"Unable to connect"
                             ));
@@ -309,7 +303,7 @@ impl UdpSocket {
                 }
                 Err(crate::os::xous::ffi::Error::ServerQueueFull) => {
                     if now.elapsed() >= write_timeout {
-                        return Err(io::const_io_error!(
+                        return Err(io::const_error!(
                             io::ErrorKind::WouldBlock,
                             &"Write timed out"
                         ));
@@ -318,7 +312,7 @@ impl UdpSocket {
                         crate::thread::yield_now();
                     }
                 }
-                _ => return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")),
+                _ => return Err(io::const_error!(io::ErrorKind::Other, &"Library error")),
             }
         }
     }
@@ -372,7 +366,7 @@ impl UdpSocket {
             services::net_server(),
             services::NetBlockingScalar::StdSetTtlUdp(self.fd, ttl).into(),
         )
-        .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
         .map(|_| ())
     }
 
@@ -381,7 +375,7 @@ impl UdpSocket {
             services::net_server(),
             services::NetBlockingScalar::StdGetTtlUdp(self.fd).into(),
         )
-        .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
+        .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value")))
         .map(|res| res[0] as _)?)
     }
 
diff --git a/library/std/src/sys/pal/zkvm/os.rs b/library/std/src/sys/pal/zkvm/os.rs
index 5d224ffd1ba..868b19e33b6 100644
--- a/library/std/src/sys/pal/zkvm/os.rs
+++ b/library/std/src/sys/pal/zkvm/os.rs
@@ -115,11 +115,11 @@ pub fn getenv(varname: &OsStr) -> Option<OsString> {
 }
 
 pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
-    Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
+    Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
 }
 
 pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> {
-    Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
+    Err(io::const_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
 }
 
 pub fn temp_dir() -> PathBuf {
diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs
index 9267602cb97..de042fa3f82 100644
--- a/library/std/src/sys/path/windows.rs
+++ b/library/std/src/sys/path/windows.rs
@@ -328,7 +328,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
     if prefix.map(|x| x.is_verbatim()).unwrap_or(false) {
         // NULs in verbatim paths are rejected for consistency.
         if path.as_encoded_bytes().contains(&0) {
-            return Err(io::const_io_error!(
+            return Err(io::const_error!(
                 io::ErrorKind::InvalidInput,
                 "strings passed to WinAPI cannot contain NULs",
             ));
diff --git a/library/std/src/sys/random/arc4random.rs b/library/std/src/sys/random/arc4random.rs
index ffabaafbee8..32467e9ebaa 100644
--- a/library/std/src/sys/random/arc4random.rs
+++ b/library/std/src/sys/random/arc4random.rs
@@ -12,7 +12,6 @@
 #[cfg(not(any(
     target_os = "haiku",
     target_os = "illumos",
-    target_os = "rtems",
     target_os = "solaris",
     target_os = "vita",
 )))]
@@ -22,7 +21,6 @@ use libc::arc4random_buf;
 #[cfg(any(
     target_os = "haiku", // See https://git.haiku-os.org/haiku/tree/headers/compatibility/bsd/stdlib.h
     target_os = "illumos", // See https://www.illumos.org/man/3C/arc4random
-    target_os = "rtems", // See https://docs.rtems.org/branches/master/bsp-howto/getentropy.html
     target_os = "solaris", // See https://docs.oracle.com/cd/E88353_01/html/E37843/arc4random-3c.html
     target_os = "vita", // See https://github.com/vitasdk/newlib/blob/b89e5bc183b516945f9ee07eef483ecb916e45ff/newlib/libc/include/stdlib.h#L74
 ))]
diff --git a/library/std/src/sys/sync/once/queue.rs b/library/std/src/sys/sync/once/queue.rs
index 177d0d7744a..87837915b39 100644
--- a/library/std/src/sys/sync/once/queue.rs
+++ b/library/std/src/sys/sync/once/queue.rs
@@ -93,7 +93,7 @@ const QUEUE_MASK: usize = !STATE_MASK;
 // use interior mutability.
 #[repr(align(4))] // Ensure the two lower bits are free to use as state bits.
 struct Waiter {
-    thread: Cell<Option<Thread>>,
+    thread: Thread,
     signaled: AtomicBool,
     next: Cell<*const Waiter>,
 }
@@ -238,7 +238,7 @@ fn wait(
     return_on_poisoned: bool,
 ) -> StateAndQueue {
     let node = &Waiter {
-        thread: Cell::new(Some(thread::current())),
+        thread: thread::current_or_unnamed(),
         signaled: AtomicBool::new(false),
         next: Cell::new(ptr::null()),
     };
@@ -277,7 +277,8 @@ fn wait(
             // can park ourselves, the result could be this thread never gets
             // unparked. Luckily `park` comes with the guarantee that if it got
             // an `unpark` just before on an unparked thread it does not park.
-            thread::park();
+            // SAFETY: we retrieved this handle on the current thread above.
+            unsafe { node.thread.park() }
         }
 
         return state_and_queue.load(Acquire);
@@ -309,7 +310,7 @@ impl Drop for WaiterQueue<'_> {
             let mut queue = to_queue(current);
             while !queue.is_null() {
                 let next = (*queue).next.get();
-                let thread = (*queue).thread.take().unwrap();
+                let thread = (*queue).thread.clone();
                 (*queue).signaled.store(true, Release);
                 thread.unpark();
                 queue = next;
diff --git a/library/std/src/sys/sync/rwlock/queue.rs b/library/std/src/sys/sync/rwlock/queue.rs
index 51330f8fafe..bd15f8ee952 100644
--- a/library/std/src/sys/sync/rwlock/queue.rs
+++ b/library/std/src/sys/sync/rwlock/queue.rs
@@ -118,7 +118,7 @@ use crate::mem;
 use crate::ptr::{self, NonNull, null_mut, without_provenance_mut};
 use crate::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release};
 use crate::sync::atomic::{AtomicBool, AtomicPtr};
-use crate::thread::{self, Thread, ThreadId};
+use crate::thread::{self, Thread};
 
 /// The atomic lock state.
 type AtomicState = AtomicPtr<()>;
@@ -217,9 +217,7 @@ impl Node {
     /// Prepare this node for waiting.
     fn prepare(&mut self) {
         // Fall back to creating an unnamed `Thread` handle to allow locking in TLS destructors.
-        self.thread.get_or_init(|| {
-            thread::try_current().unwrap_or_else(|| Thread::new_unnamed(ThreadId::new()))
-        });
+        self.thread.get_or_init(thread::current_or_unnamed);
         self.completed = AtomicBool::new(false);
     }
 
diff --git a/library/std/src/sys_common/fs.rs b/library/std/src/sys_common/fs.rs
index a25a7244660..bfd684d295b 100644
--- a/library/std/src/sys_common/fs.rs
+++ b/library/std/src/sys_common/fs.rs
@@ -5,7 +5,7 @@ use crate::io::{self, Error, ErrorKind};
 use crate::path::Path;
 use crate::sys_common::ignore_notfound;
 
-pub(crate) const NOT_FILE_ERROR: Error = io::const_io_error!(
+pub(crate) const NOT_FILE_ERROR: Error = io::const_error!(
     ErrorKind::InvalidInput,
     "the source path is neither a regular file nor a symlink to a regular file",
 );
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 5a0ad907581..74306978d22 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -122,7 +122,7 @@ pub fn sockaddr_to_addr(storage: &c::sockaddr_storage, len: usize) -> io::Result
                 *(storage as *const _ as *const c::sockaddr_in6)
             })))
         }
-        _ => Err(io::const_io_error!(ErrorKind::InvalidInput, "invalid argument")),
+        _ => Err(io::const_error!(ErrorKind::InvalidInput, "invalid argument")),
     }
 }
 
@@ -185,7 +185,7 @@ impl TryFrom<&str> for LookupHost {
             ($e:expr, $msg:expr) => {
                 match $e {
                     Some(r) => r,
-                    None => return Err(io::const_io_error!(io::ErrorKind::InvalidInput, $msg)),
+                    None => return Err(io::const_error!(io::ErrorKind::InvalidInput, $msg)),
                 }
             };
         }
diff --git a/library/std/src/thread/current.rs b/library/std/src/thread/current.rs
index e6eb90c4c30..1048ef97356 100644
--- a/library/std/src/thread/current.rs
+++ b/library/std/src/thread/current.rs
@@ -165,6 +165,23 @@ pub(crate) fn try_current() -> Option<Thread> {
     }
 }
 
+/// Gets a handle to the thread that invokes it. If the handle stored in thread-
+/// local storage was already destroyed, this creates a new unnamed temporary
+/// handle to allow thread parking in nearly all situations.
+pub(crate) fn current_or_unnamed() -> Thread {
+    let current = CURRENT.get();
+    if current > DESTROYED {
+        unsafe {
+            let current = ManuallyDrop::new(Thread::from_raw(current));
+            (*current).clone()
+        }
+    } else if current == DESTROYED {
+        Thread::new_unnamed(id::get_or_init())
+    } else {
+        init_current(current)
+    }
+}
+
 /// Gets a handle to the thread that invokes it.
 ///
 /// # Examples
@@ -226,17 +243,17 @@ fn init_current(current: *mut ()) -> Thread {
         // a particular API should be entirely allocation-free, feel free to open
         // an issue on the Rust repository, we'll see what we can do.
         rtabort!(
-            "\n
-            Attempted to access thread-local data while allocating said data.\n
-            Do not access functions that allocate in the global allocator!\n
-            This is a bug in the global allocator.\n
-        "
+            "\n\
+            Attempted to access thread-local data while allocating said data.\n\
+            Do not access functions that allocate in the global allocator!\n\
+            This is a bug in the global allocator.\n\
+            "
         )
     } else {
         debug_assert_eq!(current, DESTROYED);
         panic!(
-            "use of std::thread::current() is not possible after the thread's
-         local data has been destroyed"
+            "use of std::thread::current() is not possible after the thread's \
+            local data has been destroyed"
         )
     }
 }
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index 9edb3fa4193..bc5f701e346 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -252,6 +252,19 @@ impl<T: 'static> LocalKey<T> {
     /// This function will `panic!()` if the key currently has its
     /// destructor running, and it **may** panic if the destructor has
     /// previously been run for this thread.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// thread_local! {
+    ///     pub static STATIC: String = String::from("I am");
+    /// }
+    ///
+    /// assert_eq!(
+    ///     STATIC.with(|original_value| format!("{original_value} initialized")),
+    ///     "I am initialized",
+    /// );
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with<F, R>(&'static self, f: F) -> R
     where
@@ -273,6 +286,19 @@ impl<T: 'static> LocalKey<T> {
     ///
     /// This function will still `panic!()` if the key is uninitialized and the
     /// key's initializer panics.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// thread_local! {
+    ///     pub static STATIC: String = String::from("I am");
+    /// }
+    ///
+    /// assert_eq!(
+    ///     STATIC.try_with(|original_value| format!("{original_value} initialized")),
+    ///     Ok(String::from("I am initialized")),
+    /// );
+    /// ```
     #[stable(feature = "thread_local_try_with", since = "1.26.0")]
     #[inline]
     pub fn try_with<F, R>(&'static self, f: F) -> Result<R, AccessError>
@@ -452,7 +478,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     /// Panics if the key currently has its destructor running,
     /// and it **may** panic if the destructor has previously been run for this thread.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::cell::RefCell;
@@ -483,7 +509,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     /// Panics if the key currently has its destructor running,
     /// and it **may** panic if the destructor has previously been run for this thread.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::cell::RefCell;
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 2c2cc58a9dd..2ff44fcd4c6 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -186,7 +186,7 @@ mod current;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use current::current;
-pub(crate) use current::{current_id, drop_current, set_current, try_current};
+pub(crate) use current::{current_id, current_or_unnamed, drop_current, set_current, try_current};
 
 mod spawnhook;
 
@@ -1146,9 +1146,9 @@ pub fn park_timeout_ms(ms: u32) {
 #[stable(feature = "park_timeout", since = "1.4.0")]
 pub fn park_timeout(dur: Duration) {
     let guard = PanicGuard;
-    // SAFETY: park_timeout is called on the parker owned by this thread.
+    // SAFETY: park_timeout is called on a handle owned by this thread.
     unsafe {
-        current().0.parker().park_timeout(dur);
+        current().park_timeout(dur);
     }
     // No panic occurred, do not abort.
     forget(guard);
@@ -1446,6 +1446,15 @@ impl Thread {
         unsafe { self.0.parker().park() }
     }
 
+    /// Like the public [`park_timeout`], but callable on any handle. This is
+    /// used to allow parking in TLS destructors.
+    ///
+    /// # Safety
+    /// May only be called from the thread to which this handle belongs.
+    pub(crate) unsafe fn park_timeout(&self, dur: Duration) {
+        unsafe { self.0.parker().park_timeout(dur) }
+    }
+
     /// Atomically makes the handle's token available if it is not already.
     ///
     /// Every thread is equipped with some basic low-level blocking support, via
diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs
index b2305b1eda7..0033fc3a732 100644
--- a/library/std/src/thread/scoped.rs
+++ b/library/std/src/thread/scoped.rs
@@ -1,4 +1,4 @@
-use super::{Builder, JoinInner, Result, Thread, current, park};
+use super::{Builder, JoinInner, Result, Thread, current_or_unnamed};
 use crate::marker::PhantomData;
 use crate::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
 use crate::sync::Arc;
@@ -140,7 +140,7 @@ where
     let scope = Scope {
         data: Arc::new(ScopeData {
             num_running_threads: AtomicUsize::new(0),
-            main_thread: current(),
+            main_thread: current_or_unnamed(),
             a_thread_panicked: AtomicBool::new(false),
         }),
         env: PhantomData,
@@ -152,7 +152,8 @@ where
 
     // Wait until all the threads are finished.
     while scope.data.num_running_threads.load(Ordering::Acquire) != 0 {
-        park();
+        // SAFETY: this is the main thread, the handle belongs to us.
+        unsafe { scope.data.main_thread.park() };
     }
 
     // Throw any panic from `f`, or the return value of `f` if no thread panicked.
@@ -176,7 +177,7 @@ impl<'scope, 'env> Scope<'scope, 'env> {
     /// thread. If the spawned thread panics, [`join`] will return an [`Err`] containing
     /// the panic payload.
     ///
-    /// If the join handle is dropped, the spawned thread will implicitly joined at the
+    /// If the join handle is dropped, the spawned thread will be implicitly joined at the
     /// end of the scope. In that case, if the spawned thread panics, [`scope`] will
     /// panic after all threads are joined.
     ///
diff --git a/license-metadata.json b/license-metadata.json
new file mode 100644
index 00000000000..09cc3693565
--- /dev/null
+++ b/license-metadata.json
@@ -0,0 +1,269 @@
+{
+  "files": {
+    "children": [
+      {
+        "children": [
+          {
+            "children": [
+              {
+                "children": [
+                  {
+                    "children": [
+                      {
+                        "directories": [],
+                        "files": [
+                          "analyzer-decls.h",
+                          "malloc-macro.h"
+                        ],
+                        "license": {
+                          "copyright": [
+                            "2000-2024 Free Software Foundation, Inc"
+                          ],
+                          "spdx": "GPL-2.0-only"
+                        },
+                        "type": "group"
+                      }
+                    ],
+                    "license": {
+                      "copyright": [
+                        "2007-2011 Atheros Communications Inc",
+                        "2011-2012,2017 Qualcomm Atheros, Inc",
+                        "2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>"
+                      ],
+                      "spdx": "ISC"
+                    },
+                    "name": "c-c++-common/analyzer",
+                    "type": "directory"
+                  }
+                ],
+                "license": {
+                  "copyright": [
+                    "2000-2024 Free Software Foundation, Inc"
+                  ],
+                  "spdx": "GPL-2.0-only"
+                },
+                "name": "gcc/testsuite",
+                "type": "directory"
+              },
+              {
+                "license": {
+                  "copyright": [
+                    "2000-2024 Free Software Foundation, Inc"
+                  ],
+                  "spdx": "GCC-exception-3.1"
+                },
+                "name": "libstdc++-v3/config/os/aix/os_defines.h",
+                "type": "file"
+              }
+            ],
+            "license": {
+              "copyright": [
+                "1997-2024 Free Software Foundation, Inc"
+              ],
+              "spdx": "GPL-3.0-or-later"
+            },
+            "name": "src/gcc",
+            "type": "directory"
+          },
+          {
+            "children": [
+              {
+                "license": {
+                  "copyright": [
+                    "The Rust Project Developers (see https://thanks.rust-lang.org)"
+                  ],
+                  "spdx": "Apache-2.0 OR MIT"
+                },
+                "name": "noscript.css",
+                "type": "file"
+              },
+              {
+                "license": {
+                  "copyright": [
+                    "Nicolas Gallagher and Jonathan Neal"
+                  ],
+                  "spdx": "MIT"
+                },
+                "name": "normalize.css",
+                "type": "file"
+              }
+            ],
+            "license": {
+              "copyright": [
+                "2016 Ike Ku, Jessica Stokes and Leon Guan",
+                "The Rust Project Developers (see https://thanks.rust-lang.org)"
+              ],
+              "spdx": "Apache-2.0 OR MIT"
+            },
+            "name": "src/librustdoc/html/static/css",
+            "type": "directory"
+          },
+          {
+            "children": [
+              {
+                "license": {
+                  "copyright": [
+                    "The Rust Project Developers (see https://thanks.rust-lang.org)"
+                  ],
+                  "spdx": "Apache-2.0 OR MIT"
+                },
+                "name": "README.txt",
+                "type": "file"
+              },
+              {
+                "directories": [],
+                "files": [
+                  "FiraSans-LICENSE.txt",
+                  "FiraSans-Medium.woff2",
+                  "FiraSans-Regular.woff2"
+                ],
+                "license": {
+                  "copyright": [
+                    "2014, Mozilla Foundation",
+                    "2014, Telefonica S.A"
+                  ],
+                  "spdx": "OFL-1.1"
+                },
+                "type": "group"
+              },
+              {
+                "directories": [],
+                "files": [
+                  "NanumBarunGothic-LICENSE.txt",
+                  "NanumBarunGothic.ttf.woff2"
+                ],
+                "license": {
+                  "copyright": [
+                    "2010 NAVER Corporation"
+                  ],
+                  "spdx": "OFL-1.1"
+                },
+                "type": "group"
+              }
+            ],
+            "license": {
+              "copyright": [
+                "2010, 2012, 2014-2023, Adobe Systems Incorporated"
+              ],
+              "spdx": "OFL-1.1"
+            },
+            "name": "src/librustdoc/html/static/fonts",
+            "type": "directory"
+          },
+          {
+            "license": {
+              "copyright": [
+                "2003-2019 University of Illinois at Urbana-Champaign",
+                "The Rust Project Developers (see https://thanks.rust-lang.org)"
+              ],
+              "spdx": "Apache-2.0 WITH LLVM-exception AND (Apache-2.0 OR MIT)"
+            },
+            "name": "compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp",
+            "type": "file"
+          },
+          {
+            "children": [],
+            "license": {
+              "copyright": [
+                "2014 Alex Crichton",
+                "The Rust Project Developers (see https://thanks.rust-lang.org)"
+              ],
+              "spdx": "Apache-2.0 OR MIT"
+            },
+            "name": "library/backtrace",
+            "type": "directory"
+          },
+          {
+            "license": {
+              "copyright": [
+                "1991-2024 Unicode, Inc"
+              ],
+              "spdx": "Unicode-3.0"
+            },
+            "name": "library/core/src/unicode/unicode_data.rs",
+            "type": "file"
+          },
+          {
+            "children": [],
+            "license": {
+              "copyright": [
+                "2019 The Crossbeam Project Developers",
+                "The Rust Project Developers (see https://thanks.rust-lang.org)"
+              ],
+              "spdx": "Apache-2.0 OR MIT"
+            },
+            "name": "library/std/src/sync/mpmc",
+            "type": "directory"
+          },
+          {
+            "license": {
+              "copyright": [
+                "2016 The Fuchsia Authors",
+                "The Rust Project Developers (see https://thanks.rust-lang.org)"
+              ],
+              "spdx": "BSD-2-Clause AND (Apache-2.0 OR MIT)"
+            },
+            "name": "library/std/src/sys/sync/mutex/fuchsia.rs",
+            "type": "file"
+          },
+          {
+            "children": [],
+            "license": {
+              "copyright": [
+                "Rust on Embedded Devices Working Group",
+                "The Rust Project Developers (see https://thanks.rust-lang.org)"
+              ],
+              "spdx": "Apache-2.0 OR CC-BY-SA-4.0 OR MIT"
+            },
+            "name": "src/doc/embedded-book",
+            "type": "directory"
+          },
+          {
+            "children": [],
+            "license": {
+              "copyright": [
+                "2014 Jorge Aparicio",
+                "The Rust Project Developers (see https://thanks.rust-lang.org)"
+              ],
+              "spdx": "Apache-2.0 OR MIT"
+            },
+            "name": "src/doc/rust-by-example",
+            "type": "directory"
+          },
+          {
+            "license": {
+              "copyright": [
+                "2014-2021 Knut Sveidqvist"
+              ],
+              "spdx": "MIT"
+            },
+            "name": "src/doc/rustc-dev-guide/mermaid.min.js",
+            "type": "file"
+          },
+          {
+            "children": [],
+            "license": {
+              "copyright": [
+                "2003-2019 University of Illinois at Urbana-Champaign",
+                "2003-2019 by the contributors listed in CREDITS.TXT (https://github.com/rust-lang/llvm-project/blob/7738295178045041669876bf32b0543ec8319a5c/llvm/CREDITS.TXT)",
+                "2010 Apple Inc"
+              ],
+              "spdx": "Apache-2.0 WITH LLVM-exception AND NCSA"
+            },
+            "name": "src/llvm-project",
+            "type": "directory"
+          }
+        ],
+        "license": {
+          "copyright": [
+            "The Rust Project Developers (see https://thanks.rust-lang.org)"
+          ],
+          "spdx": "Apache-2.0 OR MIT"
+        },
+        "name": ".",
+        "type": "directory"
+      }
+    ],
+    "type": "root"
+  }
+}
\ No newline at end of file
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index efcac4f0953..86d23d9bd02 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -1,6 +1,6 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
+version = 4
 
 [[package]]
 name = "aho-corasick"
@@ -13,9 +13,9 @@ dependencies = [
 
 [[package]]
 name = "anstyle"
-version = "1.0.8"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
 
 [[package]]
 name = "bitflags"
@@ -84,9 +84,9 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.1.22"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0"
+checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8"
 dependencies = [
  "shlex",
 ]
@@ -99,9 +99,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "clap"
-version = "4.5.18"
+version = "4.5.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3"
+checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -109,9 +109,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.18"
+version = "4.5.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b"
+checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
 dependencies = [
  "anstyle",
  "clap_lex",
@@ -119,9 +119,9 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.29"
+version = "4.5.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8937760c3f4c60871870b8c3ee5f9b30771f792a7045c48bcbba999d7d6b3b8e"
+checksum = "11611dca53440593f38e6b25ec629de50b14cdfa63adc0fb856115a2c6d97595"
 dependencies = [
  "clap",
 ]
@@ -161,9 +161,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
 
 [[package]]
 name = "cpufeatures"
-version = "0.2.14"
+version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
+checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6"
 dependencies = [
  "libc",
 ]
@@ -324,9 +324,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.159"
+version = "0.2.162"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
+checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
 
 [[package]]
 name = "libredox"
@@ -379,9 +379,9 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.36.4"
+version = "0.36.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
+checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
 dependencies = [
  "memchr",
 ]
@@ -414,9 +414,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.86"
+version = "1.0.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
 dependencies = [
  "unicode-ident",
 ]
@@ -432,18 +432,18 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.6"
+version = "0.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b"
+checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
 dependencies = [
  "bitflags",
 ]
 
 [[package]]
 name = "regex-automata"
-version = "0.4.7"
+version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -452,15 +452,15 @@ dependencies = [
 
 [[package]]
 name = "regex-syntax"
-version = "0.8.4"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
 
 [[package]]
 name = "rustix"
-version = "0.38.37"
+version = "0.38.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
+checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0"
 dependencies = [
  "bitflags",
  "errno",
@@ -498,18 +498,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
 
 [[package]]
 name = "serde"
-version = "1.0.210"
+version = "1.0.215"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
+checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.210"
+version = "1.0.215"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
+checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -518,9 +518,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.128"
+version = "1.0.132"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
+checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
 dependencies = [
  "itoa",
  "memchr",
@@ -547,9 +547,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
 
 [[package]]
 name = "syn"
-version = "2.0.79"
+version = "2.0.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
+checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -571,9 +571,9 @@ dependencies = [
 
 [[package]]
 name = "tar"
-version = "0.4.42"
+version = "0.4.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020"
+checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6"
 dependencies = [
  "filetime",
  "libc",
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 7950f1004a2..fcd97b7b589 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -37,7 +37,7 @@ test = false
 # Most of the time updating these dependencies requires modifications to the
 # bootstrap codebase(e.g., https://github.com/rust-lang/rust/issues/124565);
 # otherwise, some targets will fail. That's why these dependencies are explicitly pinned.
-cc = "=1.1.22"
+cc = "=1.2.0"
 cmake = "=0.1.48"
 
 build_helper = { path = "../build_helper" }
@@ -47,7 +47,7 @@ fd-lock = "4.0"
 home = "0.5"
 ignore = "0.4"
 libc = "0.2"
-object = { version = "0.36.3", default-features = false, features = ["archive", "coff", "read_core", "unaligned"] }
+object = { version = "0.36.3", default-features = false, features = ["archive", "coff", "read_core", "std", "unaligned"] }
 opener = "0.5"
 semver = "1.0"
 serde = "1.0"
diff --git a/src/bootstrap/defaults/config.compiler.toml b/src/bootstrap/defaults/config.compiler.toml
index 57a0ca5a718..a737de3bd08 100644
--- a/src/bootstrap/defaults/config.compiler.toml
+++ b/src/bootstrap/defaults/config.compiler.toml
@@ -19,6 +19,9 @@ lto = "off"
 # Forces frame pointers to be used with `-Cforce-frame-pointers`.
 # This can be helpful for profiling at a small performance cost.
 frame-pointers = true
+# Compiler contributors often want to build rustc even without any changes to
+# e.g. check that it builds locally and check the baseline behavior of a
+# compiler built from latest `master` commit.
 download-rustc = false
 
 [llvm]
diff --git a/src/bootstrap/defaults/config.dist.toml b/src/bootstrap/defaults/config.dist.toml
index 4346a9c2dd1..7b381b416ca 100644
--- a/src/bootstrap/defaults/config.dist.toml
+++ b/src/bootstrap/defaults/config.dist.toml
@@ -16,6 +16,7 @@ download-ci-llvm = false
 # We have several defaults in bootstrap that depend on whether the channel is `dev` (e.g. `omit-git-hash` and `download-ci-llvm`).
 # Make sure they don't get set when installing from source.
 channel = "nightly"
+# Never download a rustc, distributions must build a fresh compiler.
 download-rustc = false
 lld = true
 # Build the llvm-bitcode-linker
diff --git a/src/bootstrap/defaults/config.library.toml b/src/bootstrap/defaults/config.library.toml
index 67ceb220524..b43796d6f20 100644
--- a/src/bootstrap/defaults/config.library.toml
+++ b/src/bootstrap/defaults/config.library.toml
@@ -10,7 +10,9 @@ bench-stage = 0
 incremental = true
 # Make the compiler and standard library faster to build, at the expense of a ~20% runtime slowdown.
 lto = "off"
-download-rustc = false
+# Download rustc by default for library profile if compiler-affecting
+# directories are not modified. For CI this is disabled.
+download-rustc = "if-unchanged"
 
 [llvm]
 # Will download LLVM from CI if available on your platform.
diff --git a/src/bootstrap/defaults/config.tools.toml b/src/bootstrap/defaults/config.tools.toml
index 76b47a841b3..64097320cab 100644
--- a/src/bootstrap/defaults/config.tools.toml
+++ b/src/bootstrap/defaults/config.tools.toml
@@ -3,6 +3,9 @@
 [rust]
 # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
 incremental = true
+# Most commonly, tools contributors do not need to modify the compiler, so
+# downloading a CI rustc is a good default for tools profile.
+download-rustc = "if-unchanged"
 
 [build]
 # Document with the in-tree rustdoc by default, since `download-rustc` makes it quick to compile.
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 0216ac81162..a636c4a9ef1 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -1023,7 +1023,7 @@ impl Step for PlainSourceTarball {
             let mut cmd = command(&builder.initial_cargo);
             cmd.arg("vendor").arg("--versioned-dirs");
 
-            for p in default_paths_to_vendor(builder) {
+            for (p, _) in default_paths_to_vendor(builder) {
                 cmd.arg("--sync").arg(p);
             }
 
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index a6dff7fde80..c76504761be 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -181,8 +181,7 @@ impl Step for CollectLicenseMetadata {
             panic!("REUSE is required to collect the license metadata");
         };
 
-        // Temporary location, it will be moved to src/etc once it's accurate.
-        let dest = builder.out.join("license-metadata.json");
+        let dest = builder.src.join("license-metadata.json");
 
         let mut cmd = builder.tool_cmd(Tool::CollectLicenseMetadata);
         cmd.env("REUSE_EXE", reuse);
@@ -209,14 +208,14 @@ impl Step for GenerateCopyright {
     }
 
     fn run(self, builder: &Builder<'_>) -> Self::Output {
-        let license_metadata = builder.ensure(CollectLicenseMetadata);
-
-        // Temporary location, it will be moved to the proper one once it's accurate.
+        let license_metadata = builder.src.join("license-metadata.json");
         let dest = builder.out.join("COPYRIGHT.html");
+        let dest_libstd = builder.out.join("COPYRIGHT-library.html");
 
         let mut cmd = builder.tool_cmd(Tool::GenerateCopyright);
         cmd.env("LICENSE_METADATA", &license_metadata);
         cmd.env("DEST", &dest);
+        cmd.env("DEST_LIBSTD", &dest_libstd);
         cmd.env("OUT_DIR", &builder.out);
         cmd.env("CARGO", &builder.initial_cargo);
         cmd.run(builder);
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index dcea9f5f7d1..dd967bca867 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -3,12 +3,14 @@
 //! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules.
 //! However, this contains ~all test parts we expect people to be able to build and run locally.
 
+use std::collections::HashSet;
 use std::ffi::{OsStr, OsString};
 use std::path::{Path, PathBuf};
 use std::{env, fs, iter};
 
 use clap_complete::shells;
 
+use crate::core::build_steps::compile::run_cargo;
 use crate::core::build_steps::doc::DocumentationFormat;
 use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget;
 use crate::core::build_steps::tool::{self, SourceType, Tool};
@@ -2185,6 +2187,7 @@ struct BookTest {
     path: PathBuf,
     name: &'static str,
     is_ext_doc: bool,
+    dependencies: Vec<&'static str>,
 }
 
 impl Step for BookTest {
@@ -2237,6 +2240,57 @@ impl BookTest {
         // Books often have feature-gated example text.
         rustbook_cmd.env("RUSTC_BOOTSTRAP", "1");
         rustbook_cmd.env("PATH", new_path).arg("test").arg(path);
+
+        // Books may also need to build dependencies. For example, `TheBook` has
+        // code samples which use the `trpl` crate. For the `rustdoc` invocation
+        // to find them them successfully, they need to be built first and their
+        // paths used to generate the
+        let libs = if !self.dependencies.is_empty() {
+            let mut lib_paths = vec![];
+            for dep in self.dependencies {
+                let mode = Mode::ToolRustc;
+                let target = builder.config.build;
+                let cargo = tool::prepare_tool_cargo(
+                    builder,
+                    compiler,
+                    mode,
+                    target,
+                    Kind::Build,
+                    dep,
+                    SourceType::Submodule,
+                    &[],
+                );
+
+                let stamp = builder
+                    .cargo_out(compiler, mode, target)
+                    .join(PathBuf::from(dep).file_name().unwrap())
+                    .with_extension("stamp");
+
+                let output_paths = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false);
+                let directories = output_paths
+                    .into_iter()
+                    .filter_map(|p| p.parent().map(ToOwned::to_owned))
+                    .fold(HashSet::new(), |mut set, dir| {
+                        set.insert(dir);
+                        set
+                    });
+
+                lib_paths.extend(directories);
+            }
+            lib_paths
+        } else {
+            vec![]
+        };
+
+        if !libs.is_empty() {
+            let paths = libs
+                .into_iter()
+                .map(|path| path.into_os_string())
+                .collect::<Vec<OsString>>()
+                .join(OsStr::new(","));
+            rustbook_cmd.args([OsString::from("--library-path"), paths]);
+        }
+
         builder.add_rust_test_threads(&mut rustbook_cmd);
         let _guard = builder.msg(
             Kind::Test,
@@ -2295,6 +2349,7 @@ macro_rules! test_book {
         $name:ident, $path:expr, $book_name:expr,
         default=$default:expr
         $(,submodules = $submodules:expr)?
+        $(,dependencies=$dependencies:expr)?
         ;
     )+) => {
         $(
@@ -2324,11 +2379,21 @@ macro_rules! test_book {
                             builder.require_submodule(submodule, None);
                         }
                     )*
+
+                    let dependencies = vec![];
+                    $(
+                        let mut dependencies = dependencies;
+                        for dep in $dependencies {
+                            dependencies.push(dep);
+                        }
+                    )?
+
                     builder.ensure(BookTest {
                         compiler: self.compiler,
                         path: PathBuf::from($path),
                         name: $book_name,
                         is_ext_doc: !$default,
+                        dependencies,
                     });
                 }
             }
@@ -2343,7 +2408,7 @@ test_book!(
     RustcBook, "src/doc/rustc", "rustc", default=true;
     RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false, submodules=["src/doc/rust-by-example"];
     EmbeddedBook, "src/doc/embedded-book", "embedded-book", default=false, submodules=["src/doc/embedded-book"];
-    TheBook, "src/doc/book", "book", default=false, submodules=["src/doc/book"];
+    TheBook, "src/doc/book", "book", default=false, submodules=["src/doc/book"], dependencies=["src/doc/book/packages/trpl"];
     UnstableBook, "src/doc/unstable-book", "unstable-book", default=true;
     EditionGuide, "src/doc/edition-guide", "edition-guide", default=false, submodules=["src/doc/edition-guide"];
 );
@@ -3404,7 +3469,6 @@ impl Step for CodegenCranelift {
             // FIXME remove once vendoring is handled
             .arg("--skip-test")
             .arg("testsuite.extended_sysroot");
-        cargo.args(builder.config.test_args());
 
         cargo.into_cmd().run(builder);
     }
@@ -3599,14 +3663,42 @@ impl Step for TestFloatParse {
             &[],
         );
 
-        cargo_run.arg("--");
-        if builder.config.args().is_empty() {
-            // By default, exclude tests that take longer than ~1m.
-            cargo_run.arg("--skip-huge");
-        } else {
-            cargo_run.args(builder.config.args());
+        if !matches!(env::var("FLOAT_PARSE_TESTS_NO_SKIP_HUGE").as_deref(), Ok("1") | Ok("true")) {
+            cargo_run.args(["--", "--skip-huge"]);
         }
 
         cargo_run.into_cmd().run(builder);
     }
 }
+
+#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
+pub struct CollectLicenseMetadata;
+
+impl Step for CollectLicenseMetadata {
+    type Output = PathBuf;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("src/tools/collect-license-metadata")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(CollectLicenseMetadata);
+    }
+
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let Some(reuse) = &builder.config.reuse else {
+            panic!("REUSE is required to collect the license metadata");
+        };
+
+        let dest = builder.src.join("license-metadata.json");
+
+        let mut cmd = builder.tool_cmd(Tool::CollectLicenseMetadata);
+        cmd.env("REUSE_EXE", reuse);
+        cmd.env("DEST", &dest);
+        cmd.env("ONLY_CHECK", "1");
+        cmd.run(builder);
+
+        dest
+    }
+}
diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs
index 82a6b4d4f28..26d0f100ffd 100644
--- a/src/bootstrap/src/core/build_steps/vendor.rs
+++ b/src/bootstrap/src/core/build_steps/vendor.rs
@@ -4,24 +4,27 @@ use crate::core::build_steps::tool::SUBMODULES_FOR_RUSTBOOK;
 use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::utils::exec::command;
 
-/// List of default paths used for vendoring for `x vendor` and dist tarballs.
-pub fn default_paths_to_vendor(builder: &Builder<'_>) -> Vec<PathBuf> {
-    let mut paths = vec![];
-    for p in [
-        "src/tools/cargo/Cargo.toml",
-        "src/tools/rust-analyzer/Cargo.toml",
-        "compiler/rustc_codegen_cranelift/Cargo.toml",
-        "compiler/rustc_codegen_gcc/Cargo.toml",
-        "library/Cargo.toml",
-        "src/bootstrap/Cargo.toml",
-        "src/tools/rustbook/Cargo.toml",
-        "src/tools/rustc-perf/Cargo.toml",
-        "src/tools/opt-dist/Cargo.toml",
-    ] {
-        paths.push(builder.src.join(p));
-    }
-
-    paths
+/// Returns the cargo workspaces to vendor for `x vendor` and dist tarballs.
+///
+/// Returns a `Vec` of `(path_to_manifest, submodules_required)` where
+/// `path_to_manifest` is the cargo workspace, and `submodules_required` is
+/// the set of submodules that must be available.
+pub fn default_paths_to_vendor(builder: &Builder<'_>) -> Vec<(PathBuf, Vec<&'static str>)> {
+    [
+        ("src/tools/cargo/Cargo.toml", vec!["src/tools/cargo"]),
+        ("src/tools/rust-analyzer/Cargo.toml", vec![]),
+        ("compiler/rustc_codegen_cranelift/Cargo.toml", vec![]),
+        ("compiler/rustc_codegen_gcc/Cargo.toml", vec![]),
+        ("library/Cargo.toml", vec![]),
+        ("src/bootstrap/Cargo.toml", vec![]),
+        ("src/tools/rustbook/Cargo.toml", SUBMODULES_FOR_RUSTBOOK.into()),
+        ("src/tools/rustc-perf/Cargo.toml", vec!["src/tools/rustc-perf"]),
+        ("src/tools/opt-dist/Cargo.toml", vec![]),
+        ("src/doc/book/packages/trpl/Cargo.toml", vec![]),
+    ]
+    .into_iter()
+    .map(|(path, submodules)| (builder.src.join(path), submodules))
+    .collect()
 }
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
@@ -56,13 +59,16 @@ impl Step for Vendor {
             cmd.arg("--versioned-dirs");
         }
 
+        let to_vendor = default_paths_to_vendor(builder);
         // These submodules must be present for `x vendor` to work.
-        for submodule in SUBMODULES_FOR_RUSTBOOK.iter().chain(["src/tools/cargo"].iter()) {
-            builder.build.require_submodule(submodule, None);
+        for (_, submodules) in &to_vendor {
+            for submodule in submodules {
+                builder.build.require_submodule(submodule, None);
+            }
         }
 
         // Sync these paths by default.
-        for p in default_paths_to_vendor(builder) {
+        for (p, _) in &to_vendor {
             cmd.arg("--sync").arg(p);
         }
 
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index d59e0fa7288..e6902bb8cee 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -915,6 +915,7 @@ impl<'a> Builder<'a> {
                 test::HtmlCheck,
                 test::RustInstaller,
                 test::TestFloatParse,
+                test::CollectLicenseMetadata,
                 // Run bootstrap close to the end as it's unlikely to fail
                 test::Bootstrap,
                 // Run run-make last, since these won't pass without make on Windows
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 21c5f7232a1..a1c8bff0db9 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -5,6 +5,10 @@ use crate::Flags;
 use crate::core::build_steps::doc::DocumentationFormat;
 use crate::core::config::Config;
 
+static TEST_TRIPLE_1: &str = "i686-unknown-haiku";
+static TEST_TRIPLE_2: &str = "i686-unknown-hurd-gnu";
+static TEST_TRIPLE_3: &str = "i686-unknown-netbsd";
+
 fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
     configure_with_args(&[cmd.to_owned()], host, target)
 }
@@ -37,7 +41,7 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config
         .join(&thread::current().name().unwrap_or("unknown").replace(":", "-"));
     t!(fs::create_dir_all(&dir));
     config.out = dir;
-    config.build = TargetSelection::from_user("A-A");
+    config.build = TargetSelection::from_user(TEST_TRIPLE_1);
     config.hosts = host.iter().map(|s| TargetSelection::from_user(s)).collect();
     config.targets = target.iter().map(|s| TargetSelection::from_user(s)).collect();
     config
@@ -58,48 +62,28 @@ fn run_build(paths: &[PathBuf], config: Config) -> Cache {
 fn check_cli<const N: usize>(paths: [&str; N]) {
     run_build(
         &paths.map(PathBuf::from),
-        configure_with_args(&paths.map(String::from), &["A-A"], &["A-A"]),
+        configure_with_args(&paths.map(String::from), &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]),
     );
 }
 
 macro_rules! std {
     ($host:ident => $target:ident, stage = $stage:literal) => {
         compile::Std::new(
-            Compiler {
-                host: TargetSelection::from_user(concat!(
-                    stringify!($host),
-                    "-",
-                    stringify!($host)
-                )),
-                stage: $stage,
-            },
-            TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))),
+            Compiler { host: TargetSelection::from_user($host), stage: $stage },
+            TargetSelection::from_user($target),
         )
     };
 }
 
 macro_rules! doc_std {
-    ($host:ident => $target:ident, stage = $stage:literal) => {{
-        doc::Std::new(
-            $stage,
-            TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))),
-            DocumentationFormat::Html,
-        )
-    }};
+    ($host:ident => $target:ident, stage = $stage:literal) => {{ doc::Std::new($stage, TargetSelection::from_user($target), DocumentationFormat::Html) }};
 }
 
 macro_rules! rustc {
     ($host:ident => $target:ident, stage = $stage:literal) => {
         compile::Rustc::new(
-            Compiler {
-                host: TargetSelection::from_user(concat!(
-                    stringify!($host),
-                    "-",
-                    stringify!($host)
-                )),
-                stage: $stage,
-            },
-            TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))),
+            Compiler { host: TargetSelection::from_user($host), stage: $stage },
+            TargetSelection::from_user($target),
         )
     };
 }
@@ -135,7 +119,7 @@ fn test_intersection() {
 
 #[test]
 fn validate_path_remap() {
-    let build = Build::new(configure("test", &["A-A"], &["A-A"]));
+    let build = Build::new(configure("test", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]));
 
     PATH_REMAP
         .iter()
@@ -148,7 +132,7 @@ fn validate_path_remap() {
 
 #[test]
 fn check_missing_paths_for_x_test_tests() {
-    let build = Build::new(configure("test", &["A-A"], &["A-A"]));
+    let build = Build::new(configure("test", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]));
 
     let (_, tests_remap_paths) =
         PATH_REMAP.iter().find(|(target_path, _)| *target_path == "tests").unwrap();
@@ -172,7 +156,7 @@ fn check_missing_paths_for_x_test_tests() {
 
 #[test]
 fn test_exclude() {
-    let mut config = configure("test", &["A-A"], &["A-A"]);
+    let mut config = configure("test", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]);
     config.skip = vec!["src/tools/tidy".into()];
     let cache = run_build(&[], config);
 
@@ -187,7 +171,7 @@ fn test_exclude() {
 fn test_exclude_kind() {
     let path = PathBuf::from("compiler/rustc_data_structures");
 
-    let mut config = configure("test", &["A-A"], &["A-A"]);
+    let mut config = configure("test", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]);
     // Ensure our test is valid, and `test::Rustc` would be run without the exclude.
     assert!(run_build(&[], config.clone()).contains::<test::CrateLibrustc>());
     // Ensure tests for rustc are not skipped.
@@ -200,16 +184,22 @@ fn test_exclude_kind() {
 /// Ensure that if someone passes both a single crate and `library`, all library crates get built.
 #[test]
 fn alias_and_path_for_library() {
-    let mut cache =
-        run_build(&["library".into(), "core".into()], configure("build", &["A-A"], &["A-A"]));
+    let mut cache = run_build(
+        &["library".into(), "core".into()],
+        configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]),
+    );
     assert_eq!(first(cache.all::<compile::Std>()), &[
-        std!(A => A, stage = 0),
-        std!(A => A, stage = 1)
+        std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+        std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1)
     ]);
 
-    let mut cache =
-        run_build(&["library".into(), "core".into()], configure("doc", &["A-A"], &["A-A"]));
-    assert_eq!(first(cache.all::<doc::Std>()), &[doc_std!(A => A, stage = 0)]);
+    let mut cache = run_build(
+        &["library".into(), "core".into()],
+        configure("doc", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]),
+    );
+    assert_eq!(first(cache.all::<doc::Std>()), &[
+        doc_std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0)
+    ]);
 }
 
 #[test]
@@ -248,18 +238,18 @@ fn ci_rustc_if_unchanged_logic() {
 mod defaults {
     use pretty_assertions::assert_eq;
 
-    use super::{configure, first, run_build};
+    use super::{TEST_TRIPLE_1, TEST_TRIPLE_2, configure, first, run_build};
     use crate::Config;
     use crate::core::builder::*;
 
     #[test]
     fn build_default() {
-        let mut cache = run_build(&[], configure("build", &["A-A"], &["A-A"]));
+        let mut cache = run_build(&[], configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]));
 
-        let a = TargetSelection::from_user("A-A");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
         assert_eq!(first(cache.all::<compile::Std>()), &[
-            std!(A => A, stage = 0),
-            std!(A => A, stage = 1),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
         ]);
         assert!(!cache.all::<compile::Assemble>().is_empty());
         // Make sure rustdoc is only built once.
@@ -269,16 +259,20 @@ mod defaults {
             // - this is the compiler it's _linked_ to, not built with.
             &[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }],
         );
-        assert_eq!(first(cache.all::<compile::Rustc>()), &[rustc!(A => A, stage = 0)],);
+        assert_eq!(first(cache.all::<compile::Rustc>()), &[
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0)
+        ],);
     }
 
     #[test]
     fn build_stage_0() {
-        let config = Config { stage: 0, ..configure("build", &["A-A"], &["A-A"]) };
+        let config = Config { stage: 0, ..configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]) };
         let mut cache = run_build(&[], config);
 
-        let a = TargetSelection::from_user("A-A");
-        assert_eq!(first(cache.all::<compile::Std>()), &[std!(A => A, stage = 0)]);
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
+        assert_eq!(first(cache.all::<compile::Std>()), &[
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0)
+        ]);
         assert!(!cache.all::<compile::Assemble>().is_empty());
         assert_eq!(
             first(cache.all::<tool::Rustdoc>()),
@@ -291,11 +285,14 @@ mod defaults {
 
     #[test]
     fn build_cross_compile() {
-        let config = Config { stage: 1, ..configure("build", &["A-A", "B-B"], &["A-A", "B-B"]) };
+        let config = Config {
+            stage: 1,
+            ..configure("build", &[TEST_TRIPLE_1, TEST_TRIPLE_2], &[TEST_TRIPLE_1, TEST_TRIPLE_2])
+        };
         let mut cache = run_build(&[], config);
 
-        let a = TargetSelection::from_user("A-A");
-        let b = TargetSelection::from_user("B-B");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
+        let b = TargetSelection::from_user(TEST_TRIPLE_2);
 
         // Ideally, this build wouldn't actually have `target: a`
         // rustdoc/rustcc/std here (the user only requested a host=B build, so
@@ -303,10 +300,10 @@ mod defaults {
         // (since we're producing stage 1 libraries/binaries).  But currently
         // bootstrap is just a bit buggy here; this should be fixed though.
         assert_eq!(first(cache.all::<compile::Std>()), &[
-            std!(A => A, stage = 0),
-            std!(A => A, stage = 1),
-            std!(A => B, stage = 0),
-            std!(A => B, stage = 1),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 0),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
         ]);
         assert_eq!(first(cache.all::<compile::Assemble>()), &[
             compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
@@ -318,18 +315,18 @@ mod defaults {
             tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } },
         ],);
         assert_eq!(first(cache.all::<compile::Rustc>()), &[
-            rustc!(A => A, stage = 0),
-            rustc!(A => B, stage = 0),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 0),
         ]);
     }
 
     #[test]
     fn doc_default() {
-        let mut config = configure("doc", &["A-A"], &["A-A"]);
+        let mut config = configure("doc", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]);
         config.compiler_docs = true;
         config.cmd = Subcommand::Doc { open: false, json: false };
         let mut cache = run_build(&[], config);
-        let a = TargetSelection::from_user("A-A");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
 
         // error_index_generator uses stage 0 to share rustdoc artifacts with the
         // rustdoc tool.
@@ -349,7 +346,7 @@ mod defaults {
 mod dist {
     use pretty_assertions::assert_eq;
 
-    use super::{Config, first, run_build};
+    use super::{Config, TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, first, run_build};
     use crate::core::builder::*;
 
     fn configure(host: &[&str], target: &[&str]) -> Config {
@@ -358,9 +355,9 @@ mod dist {
 
     #[test]
     fn dist_baseline() {
-        let mut cache = run_build(&[], configure(&["A-A"], &["A-A"]));
+        let mut cache = run_build(&[], configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_1]));
 
-        let a = TargetSelection::from_user("A-A");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
 
         assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a },]);
         assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]);
@@ -380,10 +377,11 @@ mod dist {
 
     #[test]
     fn dist_with_targets() {
-        let mut cache = run_build(&[], configure(&["A-A"], &["A-A", "B-B"]));
+        let mut cache =
+            run_build(&[], configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_1, TEST_TRIPLE_2]));
 
-        let a = TargetSelection::from_user("A-A");
-        let b = TargetSelection::from_user("B-B");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
+        let b = TargetSelection::from_user(TEST_TRIPLE_2);
 
         assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a }, dist::Docs {
             host: b
@@ -403,10 +401,13 @@ mod dist {
 
     #[test]
     fn dist_with_hosts() {
-        let mut cache = run_build(&[], configure(&["A-A", "B-B"], &["A-A", "B-B"]));
+        let mut cache = run_build(
+            &[],
+            configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[TEST_TRIPLE_1, TEST_TRIPLE_2]),
+        );
 
-        let a = TargetSelection::from_user("A-A");
-        let b = TargetSelection::from_user("B-B");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
+        let b = TargetSelection::from_user(TEST_TRIPLE_2);
 
         assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a }, dist::Docs {
             host: b
@@ -423,19 +424,20 @@ mod dist {
             dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
         ]);
         assert_eq!(first(cache.all::<compile::Std>()), &[
-            std!(A => A, stage = 0),
-            std!(A => A, stage = 1),
-            std!(A => A, stage = 2),
-            std!(A => B, stage = 1),
-            std!(A => B, stage = 2),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
         ],);
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
     }
 
     #[test]
     fn dist_only_cross_host() {
-        let b = TargetSelection::from_user("B-B");
-        let mut config = configure(&["A-A", "B-B"], &["A-A", "B-B"]);
+        let b = TargetSelection::from_user(TEST_TRIPLE_2);
+        let mut config =
+            configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[TEST_TRIPLE_1, TEST_TRIPLE_2]);
         config.docs = false;
         config.extended = true;
         config.hosts = vec![b];
@@ -445,18 +447,25 @@ mod dist {
             compiler: Compiler { host: b, stage: 2 }
         },]);
         assert_eq!(first(cache.all::<compile::Rustc>()), &[
-            rustc!(A => A, stage = 0),
-            rustc!(A => B, stage = 1),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
         ]);
     }
 
     #[test]
     fn dist_with_targets_and_hosts() {
-        let mut cache = run_build(&[], configure(&["A-A", "B-B"], &["A-A", "B-B", "C-C"]));
+        let mut cache = run_build(
+            &[],
+            configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[
+                TEST_TRIPLE_1,
+                TEST_TRIPLE_2,
+                TEST_TRIPLE_3,
+            ]),
+        );
 
-        let a = TargetSelection::from_user("A-A");
-        let b = TargetSelection::from_user("B-B");
-        let c = TargetSelection::from_user("C-C");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
+        let b = TargetSelection::from_user(TEST_TRIPLE_2);
+        let c = TargetSelection::from_user(TEST_TRIPLE_3);
 
         assert_eq!(first(cache.all::<dist::Docs>()), &[
             dist::Docs { host: a },
@@ -482,11 +491,11 @@ mod dist {
 
     #[test]
     fn dist_with_empty_host() {
-        let config = configure(&[], &["C-C"]);
+        let config = configure(&[], &[TEST_TRIPLE_3]);
         let mut cache = run_build(&[], config);
 
-        let a = TargetSelection::from_user("A-A");
-        let c = TargetSelection::from_user("C-C");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
+        let c = TargetSelection::from_user(TEST_TRIPLE_3);
 
         assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: c },]);
         assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: c },]);
@@ -498,10 +507,13 @@ mod dist {
 
     #[test]
     fn dist_with_same_targets_and_hosts() {
-        let mut cache = run_build(&[], configure(&["A-A", "B-B"], &["A-A", "B-B"]));
+        let mut cache = run_build(
+            &[],
+            configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[TEST_TRIPLE_1, TEST_TRIPLE_2]),
+        );
 
-        let a = TargetSelection::from_user("A-A");
-        let b = TargetSelection::from_user("B-B");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
+        let b = TargetSelection::from_user(TEST_TRIPLE_2);
 
         assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a }, dist::Docs {
             host: b
@@ -519,11 +531,11 @@ mod dist {
         ]);
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
         assert_eq!(first(cache.all::<compile::Std>()), &[
-            std!(A => A, stage = 0),
-            std!(A => A, stage = 1),
-            std!(A => A, stage = 2),
-            std!(A => B, stage = 1),
-            std!(A => B, stage = 2),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
         ]);
         assert_eq!(first(cache.all::<compile::Assemble>()), &[
             compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
@@ -535,7 +547,11 @@ mod dist {
 
     #[test]
     fn build_all() {
-        let build = Build::new(configure(&["A-A", "B-B"], &["A-A", "B-B", "C-C"]));
+        let build = Build::new(configure(&[TEST_TRIPLE_1, TEST_TRIPLE_2], &[
+            TEST_TRIPLE_1,
+            TEST_TRIPLE_2,
+            TEST_TRIPLE_3,
+        ]));
         let mut builder = Builder::new(&build);
         builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[
             "compiler/rustc".into(),
@@ -543,53 +559,53 @@ mod dist {
         ]);
 
         assert_eq!(first(builder.cache.all::<compile::Std>()), &[
-            std!(A => A, stage = 0),
-            std!(A => A, stage = 1),
-            std!(A => A, stage = 2),
-            std!(A => B, stage = 1),
-            std!(A => B, stage = 2),
-            std!(A => C, stage = 2),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2),
         ]);
         assert_eq!(builder.cache.all::<compile::Assemble>().len(), 5);
         assert_eq!(first(builder.cache.all::<compile::Rustc>()), &[
-            rustc!(A => A, stage = 0),
-            rustc!(A => A, stage = 1),
-            rustc!(A => A, stage = 2),
-            rustc!(A => B, stage = 1),
-            rustc!(A => B, stage = 2),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
         ]);
     }
 
     #[test]
     fn llvm_out_behaviour() {
-        let mut config = configure(&["A-A"], &["B-B"]);
+        let mut config = configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_2]);
         config.llvm_from_ci = true;
         let build = Build::new(config.clone());
 
-        let target = TargetSelection::from_user("A-A");
+        let target = TargetSelection::from_user(TEST_TRIPLE_1);
         assert!(build.llvm_out(target).ends_with("ci-llvm"));
-        let target = TargetSelection::from_user("B-B");
+        let target = TargetSelection::from_user(TEST_TRIPLE_2);
         assert!(build.llvm_out(target).ends_with("llvm"));
 
         config.llvm_from_ci = false;
         let build = Build::new(config.clone());
-        let target = TargetSelection::from_user("A-A");
+        let target = TargetSelection::from_user(TEST_TRIPLE_1);
         assert!(build.llvm_out(target).ends_with("llvm"));
     }
 
     #[test]
     fn build_with_empty_host() {
-        let config = configure(&[], &["C-C"]);
+        let config = configure(&[], &[TEST_TRIPLE_3]);
         let build = Build::new(config);
         let mut builder = Builder::new(&build);
         builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
 
-        let a = TargetSelection::from_user("A-A");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
 
         assert_eq!(first(builder.cache.all::<compile::Std>()), &[
-            std!(A => A, stage = 0),
-            std!(A => A, stage = 1),
-            std!(A => C, stage = 2),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+            std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2),
         ]);
         assert_eq!(first(builder.cache.all::<compile::Assemble>()), &[
             compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
@@ -597,14 +613,14 @@ mod dist {
             compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
         ]);
         assert_eq!(first(builder.cache.all::<compile::Rustc>()), &[
-            rustc!(A => A, stage = 0),
-            rustc!(A => A, stage = 1),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+            rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
         ]);
     }
 
     #[test]
     fn test_with_no_doc_stage0() {
-        let mut config = configure(&["A-A"], &["A-A"]);
+        let mut config = configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_1]);
         config.stage = 0;
         config.paths = vec!["library/std".into()];
         config.cmd = Subcommand::Test {
@@ -626,7 +642,7 @@ mod dist {
         let build = Build::new(config);
         let mut builder = Builder::new(&build);
 
-        let host = TargetSelection::from_user("A-A");
+        let host = TargetSelection::from_user(TEST_TRIPLE_1);
 
         builder.run_step_descriptions(&[StepDescription::from::<test::Crate>(Kind::Test)], &[
             "library/std".into(),
@@ -644,13 +660,13 @@ mod dist {
 
     #[test]
     fn doc_ci() {
-        let mut config = configure(&["A-A"], &["A-A"]);
+        let mut config = configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_1]);
         config.compiler_docs = true;
         config.cmd = Subcommand::Doc { open: false, json: false };
         let build = Build::new(config);
         let mut builder = Builder::new(&build);
         builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]);
-        let a = TargetSelection::from_user("A-A");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
 
         // error_index_generator uses stage 1 to share rustdoc artifacts with the
         // rustdoc tool.
@@ -671,7 +687,7 @@ mod dist {
     #[test]
     fn test_docs() {
         // Behavior of `x.py test` doing various documentation tests.
-        let mut config = configure(&["A-A"], &["A-A"]);
+        let mut config = configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_1]);
         config.cmd = Subcommand::Test {
             test_args: vec![],
             compiletest_rustc_args: vec![],
@@ -693,7 +709,7 @@ mod dist {
         let mut builder = Builder::new(&build);
 
         builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]);
-        let a = TargetSelection::from_user("A-A");
+        let a = TargetSelection::from_user(TEST_TRIPLE_1);
 
         // error_index_generator uses stage 1 to share rustdoc artifacts with the
         // rustdoc tool.
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index e706aba977b..9b2d49e7620 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -1771,8 +1771,37 @@ impl Config {
                 std_features: std_features_toml,
             } = rust;
 
-            config.download_rustc_commit =
-                config.download_ci_rustc_commit(download_rustc, config.llvm_assertions);
+            // FIXME(#133381): alt rustc builds currently do *not* have rustc debug assertions
+            // enabled. We should not download a CI alt rustc if we need rustc to have debug
+            // assertions (e.g. for crashes test suite). This can be changed once something like
+            // [Enable debug assertions on alt
+            // builds](https://github.com/rust-lang/rust/pull/131077) lands.
+            //
+            // Note that `rust.debug = true` currently implies `rust.debug-assertions = true`!
+            //
+            // This relies also on the fact that the global default for `download-rustc` will be
+            // `false` if it's not explicitly set.
+            let debug_assertions_requested = matches!(rustc_debug_assertions_toml, Some(true))
+                || (matches!(debug_toml, Some(true))
+                    && !matches!(rustc_debug_assertions_toml, Some(false)));
+
+            if debug_assertions_requested {
+                if let Some(ref opt) = download_rustc {
+                    if opt.is_string_or_true() {
+                        eprintln!(
+                            "WARN: currently no CI rustc builds have rustc debug assertions \
+                            enabled. Please either set `rust.debug-assertions` to `false` if you \
+                            want to use download CI rustc or set `rust.download-rustc` to `false`."
+                        );
+                    }
+                }
+            }
+
+            config.download_rustc_commit = config.download_ci_rustc_commit(
+                download_rustc,
+                debug_assertions_requested,
+                config.llvm_assertions,
+            );
 
             debug = debug_toml;
             rustc_debug_assertions = rustc_debug_assertions_toml;
@@ -2778,6 +2807,7 @@ impl Config {
     fn download_ci_rustc_commit(
         &self,
         download_rustc: Option<StringOrBool>,
+        debug_assertions_requested: bool,
         llvm_assertions: bool,
     ) -> Option<String> {
         if !is_download_ci_available(&self.build.triple, llvm_assertions) {
@@ -2786,8 +2816,12 @@ impl Config {
 
         // If `download-rustc` is not set, default to rebuilding.
         let if_unchanged = match download_rustc {
-            None => self.rust_info.is_managed_git_subrepository(),
-            Some(StringOrBool::Bool(false)) => return None,
+            // Globally default `download-rustc` to `false`, because some contributors don't use
+            // profiles for reasons such as:
+            // - They need to seamlessly switch between compiler/library work.
+            // - They don't want to use compiler profile because they need to override too many
+            //   things and it's easier to not use a profile.
+            None | Some(StringOrBool::Bool(false)) => return None,
             Some(StringOrBool::Bool(true)) => false,
             Some(StringOrBool::String(s)) if s == "if-unchanged" => {
                 if !self.rust_info.is_managed_git_subrepository() {
@@ -2845,6 +2879,14 @@ impl Config {
             return None;
         }
 
+        if debug_assertions_requested {
+            eprintln!(
+                "WARN: `rust.debug-assertions = true` will prevent downloading CI rustc as alt CI \
+                rustc is not currently built with debug assertions."
+            );
+            return None;
+        }
+
         Some(commit)
     }
 
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 7f62ffb20db..41a541d7269 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -305,4 +305,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "`rust.llvm-tools` is now enabled by default when no `config.toml` is provided.",
     },
+    ChangeInfo {
+        change_id: 133068,
+        severity: ChangeSeverity::Warning,
+        summary: "Revert `rust.download-rustc` global default to `false` and only use `rust.download-rustc = \"if-unchanged\"` default for library and tools profile. As alt CI rustc is built without debug assertions, `rust.debug-assertions = true` will now inhibit downloading CI rustc.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 9ca036a2afd..079213e8c3d 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -61,18 +61,18 @@ pub fn is_dylib(path: &Path) -> bool {
 }
 
 fn is_aix_shared_archive(path: &Path) -> bool {
-    // FIXME(#133268): reading the entire file as &[u8] into memory seems excessive
-    // look into either mmap it or use the ReadCache
-    let data = match fs::read(path) {
-        Ok(data) => data,
+    let file = match fs::File::open(path) {
+        Ok(file) => file,
         Err(_) => return false,
     };
-    let file = match ArchiveFile::parse(&*data) {
-        Ok(file) => file,
+    let reader = object::ReadCache::new(file);
+    let archive = match ArchiveFile::parse(&reader) {
+        Ok(result) => result,
         Err(_) => return false,
     };
 
-    file.members()
+    archive
+        .members()
         .filter_map(Result::ok)
         .any(|entry| String::from_utf8_lossy(entry.name()).contains(".so"))
 }
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index f0afb570cc4..d408cd518a0 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -63,6 +63,7 @@ ENV SCRIPT \
            /scripts/validate-toolstate.sh && \
            /scripts/validate-error-codes.sh && \
            reuse --include-submodules lint && \
+           python3 ../x.py test collect-license-metadata && \
            # Runs checks to ensure that there are no issues in our JS code.
            es-check es2019 ../src/librustdoc/html/static/js/*.js && \
            eslint -c ../src/librustdoc/html/static/.eslintrc.js ../src/librustdoc/html/static/js/*.js && \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
index 17fc1a57492..2a09cd54b13 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
@@ -84,7 +84,10 @@ ENV RUST_CONFIGURE_ARGS \
   --enable-new-symbol-mangling
 
 ENV HOST_TARGET x86_64-unknown-linux-gnu
-ENV FORCE_CI_RUSTC 1
+
+# FIXME(#133381): currently rustc alt builds do *not* have rustc debug
+# assertions enabled! Therefore, we cannot force download CI rustc.
+#ENV FORCE_CI_RUSTC 1
 
 COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
 COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 9a51a3f4268..2f59892acf6 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -48,7 +48,7 @@ runners:
 
 envs:
   env-x86_64-apple-tests: &env-x86_64-apple-tests
-    SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc
+    SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact
     RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc
     RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
     MACOSX_DEPLOYMENT_TARGET: 10.12
@@ -384,13 +384,12 @@ auto:
       SCRIPT: make ci-msvc
     <<: *job-windows-8c
 
-  - image: x86_64-msvc-ext
+  # x86_64-msvc-ext is split into multiple jobs to run tests in parallel.
+  - image: x86_64-msvc-ext1
     env:
-      SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo && src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows
-      HOST_TARGET: x86_64-pc-windows-msvc
-      RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json
-      DEPLOY_TOOLSTATES_JSON: toolstates-windows.json
-    <<: *job-windows-8c
+      SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo
+      RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld
+    <<: *job-windows
 
   # Temporary builder to workaround CI issues
   # See <https://github.com/rust-lang/rust/issues/127883>
@@ -406,6 +405,15 @@ auto:
       RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld
     <<: *job-windows
 
+  # Run `checktools.sh` and upload the toolstate file.
+  - image: x86_64-msvc-ext3
+    env:
+      SCRIPT: src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows
+      HOST_TARGET: x86_64-pc-windows-msvc
+      RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json
+      DEPLOY_TOOLSTATES_JSON: toolstates-windows.json
+    <<: *job-windows
+
   # 32/64-bit MinGW builds.
   #
   # We are using MinGW with POSIX threads since LLVM requires
diff --git a/src/doc/book b/src/doc/book
-Subproject f38ce8baef98cb20229e56f1be2d50e345f1179
+Subproject e16dd73690a6cc3ecdc5f5d94bbc3ce158a42e1
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 915f9b319c2823f310430ecdecd86264a7870d7
+Subproject f48b0e842a3911c63240e955d042089e9e0894c
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject eac89a3cbe6c4714e5029ae8b5a1c556fd4e8c4
+Subproject 0674321898cd454764ab69702819d39a919afd6
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 41ccb0e6478305401dad92e8fd3d04a4304edb4
+Subproject 5c86c739ec71b8bc839310ff47fa94e94635bba
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject b679e71c2d66c6fe13e06b99ac61773b866213f
+Subproject 787b4166ccc67bd8f72a6e3ef6685ce9ce82909
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index cb43feca758..e987d06b0f3 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -119,17 +119,14 @@ files. It takes one of the following values:
 * `n`, `no`, `off` or `false`: omit bitcode from rlibs.
 
 LLVM bitcode is required when rustc is performing link-time optimization (LTO).
-It is also required on some targets like iOS ones where vendors look for LLVM
-bitcode. Embedded bitcode will appear in rustc-generated object files inside of
-a section whose name is defined by the target platform. Most of the time this is
-`.llvmbc`.
+Embedded bitcode will appear in rustc-generated object files inside of a section
+whose name is defined by the target platform. Most of the time this is `.llvmbc`.
 
 The use of `-C embed-bitcode=no` can significantly improve compile times and
 reduce generated file sizes if your compilation does not actually need bitcode
-(e.g. if you're not compiling for iOS or you're not performing LTO). For these
-reasons, Cargo uses `-C embed-bitcode=no` whenever possible. Likewise, if you
-are building directly with `rustc` we recommend using `-C embed-bitcode=no`
-whenever you are not using LTO.
+(e.g. if you're not performing LTO). For these reasons, Cargo uses `-C embed-bitcode=no`
+whenever possible. Likewise, if you are building directly with `rustc` we recommend
+using `-C embed-bitcode=no` whenever you are not using LTO.
 
 If combined with `-C lto`, `-C embed-bitcode=no` will cause `rustc` to abort
 at start-up, because the combination is invalid.
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index f38d34fccd4..0942b5ebfee 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -179,7 +179,7 @@ This informs `rustc` of the name of your crate.
 <a id="option-edition"></a>
 ## `--edition`: specify the edition to use
 
-This flag takes a value of `2015`, `2018` or `2021`. The default is `2015`. More
+This flag takes a value of `2015`, `2018`,`2021`, or `2024`. The default is `2015`. More
 information about editions may be found in the [edition guide].
 
 [edition guide]: ../edition-guide/introduction.html
diff --git a/src/doc/rustdoc/src/write-documentation/documentation-tests.md b/src/doc/rustdoc/src/write-documentation/documentation-tests.md
index c93893b5ada..e02c26bd42b 100644
--- a/src/doc/rustdoc/src/write-documentation/documentation-tests.md
+++ b/src/doc/rustdoc/src/write-documentation/documentation-tests.md
@@ -360,7 +360,7 @@ are added.
 # fn foo() {}
 ```
 
-`edition2015`, `edition2018` and `edition2021` tell `rustdoc`
+`edition2015`, `edition2018`, `edition2021`, and `edition2024` tell `rustdoc`
 that the code sample should be compiled using the respective edition of Rust.
 
 ```rust
diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-reg.md b/src/doc/unstable-book/src/language-features/asm-experimental-reg.md
new file mode 100644
index 00000000000..a251573d276
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/asm-experimental-reg.md
@@ -0,0 +1,40 @@
+# `asm_experimental_arch`
+
+The tracking issue for this feature is: [#133416]
+
+[#133416]: https://github.com/rust-lang/rust/issues/133416
+
+------------------------
+
+This tracks support for additional registers in architectures where inline assembly is already stable.
+
+## Register classes
+
+| Architecture | Register class | Registers | LLVM constraint code |
+| ------------ | -------------- | --------- | -------------------- |
+| s390x | `vreg` | `v[0-31]` | `v` |
+
+> **Notes**:
+> - s390x `vreg` is clobber-only in stable.
+
+## Register class supported types
+
+| Architecture | Register class | Target feature | Allowed types |
+| ------------ | -------------- | -------------- | ------------- |
+| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
+
+## Register aliases
+
+| Architecture | Base register | Aliases |
+| ------------ | ------------- | ------- |
+
+## Unsupported registers
+
+| Architecture | Unsupported register | Reason |
+| ------------ | -------------------- | ------ |
+
+## Template modifiers
+
+| Architecture | Register class | Modifier | Example output | LLVM modifier |
+| ------------ | -------------- | -------- | -------------- | ------------- |
+| s390x | `vreg` | None | `%v0` | None |
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index c47937a3b73..415fe09718c 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -17,27 +17,27 @@ _x.py() {
     _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -53,7 +53,7 @@ _x.py() {
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '::paths -- paths for the subcommand:_files' \
-'::free_args -- arguments passed to subcommands:' \
+'::free_args -- arguments passed to subcommands:_default' \
 ":: :_x.py_commands" \
 "*::: :->bootstrap" \
 && ret=0
@@ -67,27 +67,27 @@ _x.py() {
 _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -109,27 +109,27 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '--all-targets[Check all targets]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -150,33 +150,33 @@ _arguments "${_arguments_options[@]}" : \
 ;;
 (clippy)
 _arguments "${_arguments_options[@]}" : \
-'*-A+[clippy lints to allow]:LINT: ' \
-'*-D+[clippy lints to deny]:LINT: ' \
-'*-W+[clippy lints to warn on]:LINT: ' \
-'*-F+[clippy lints to forbid]:LINT: ' \
+'*-A+[clippy lints to allow]:LINT:_default' \
+'*-D+[clippy lints to deny]:LINT:_default' \
+'*-W+[clippy lints to warn on]:LINT:_default' \
+'*-F+[clippy lints to forbid]:LINT:_default' \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '--fix[]' \
 '--allow-dirty[]' \
 '--allow-staged[]' \
@@ -201,27 +201,27 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -243,27 +243,27 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '--check[check formatting instead of applying]' \
 '--all[apply to all appropriate files, not just those that have been modified]' \
 '*-v[use verbose output (-vv for very verbose)]' \
@@ -287,27 +287,27 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '--open[open the docs in a browser]' \
 '--json[render the documentation in JSON format in addition to the usual HTML format]' \
 '*-v[use verbose output (-vv for very verbose)]' \
@@ -329,35 +329,35 @@ _arguments "${_arguments_options[@]}" : \
 ;;
 (test)
 _arguments "${_arguments_options[@]}" : \
-'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \
-'*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS: ' \
-'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell)]:EXTRA_CHECKS: ' \
-'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE: ' \
-'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run: ' \
-'--run=[whether to execute run-* tests]:auto | always | never: ' \
+'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \
+'*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS:_default' \
+'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell)]:EXTRA_CHECKS:_default' \
+'--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
+'--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
+'--run=[whether to execute run-* tests]:auto | always | never:_default' \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '--no-fail-fast[run all tests regardless of failure]' \
 '--no-doc[do not run doc tests]' \
 '--doc[only run doc tests]' \
@@ -384,30 +384,30 @@ _arguments "${_arguments_options[@]}" : \
 ;;
 (miri)
 _arguments "${_arguments_options[@]}" : \
-'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \
+'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '--no-fail-fast[run all tests regardless of failure]' \
 '--no-doc[do not run doc tests]' \
 '--doc[only run doc tests]' \
@@ -430,30 +430,30 @@ _arguments "${_arguments_options[@]}" : \
 ;;
 (bench)
 _arguments "${_arguments_options[@]}" : \
-'*--test-args=[]:TEST_ARGS: ' \
+'*--test-args=[]:TEST_ARGS:_default' \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -473,29 +473,29 @@ _arguments "${_arguments_options[@]}" : \
 ;;
 (clean)
 _arguments "${_arguments_options[@]}" : \
-'--stage=[Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used]:N: ' \
+'--stage=[Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used]:N:_default' \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '--all[Clean the entire build directory (not used by default)]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -518,27 +518,27 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -560,27 +560,27 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -600,30 +600,30 @@ _arguments "${_arguments_options[@]}" : \
 ;;
 (run)
 _arguments "${_arguments_options[@]}" : \
-'*--args=[arguments for the tool]:ARGS: ' \
+'*--args=[arguments for the tool]:ARGS:_default' \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -645,27 +645,27 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -688,27 +688,27 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '--run[run suggested tests]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -732,27 +732,27 @@ _arguments "${_arguments_options[@]}" : \
 '*--sync=[Additional \`Cargo.toml\` to sync and vendor]:SYNC:_files' \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '--versioned-dirs[Always include version in subdir name]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -775,27 +775,27 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '--config=[TOML configuration file for build]:FILE:_files' \
 '--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
-'--build=[build target of the stage0 compiler]:BUILD:( )' \
-'--host=[host targets to build]:HOST:( )' \
-'--target=[target targets to build]:TARGET:( )' \
+'--build=[build target of the stage0 compiler]:BUILD:' \
+'--host=[host targets to build]:HOST:' \
+'--target=[target targets to build]:TARGET:' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
 '*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
 '--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:( )' \
-'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'-j+[number of jobs to run in parallel]:JOBS:' \
+'--jobs=[number of jobs to run in parallel]:JOBS:' \
 '--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--error-format=[rustc error format]:FORMAT:( )' \
+'--error-format=[rustc error format]:FORMAT:' \
 '--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
 '--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
 '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
-'*--set=[override options in config.toml]:section.option=value:( )' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
+'*--set=[override options in config.toml]:section.option=value:' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py
index bace228454e..a42ce111ebc 100644
--- a/src/etc/lldb_providers.py
+++ b/src/etc/lldb_providers.py
@@ -32,7 +32,7 @@ from lldb import SBData, SBError, eBasicTypeLong, eBasicTypeUnsignedLong, \
 # You can find more information and examples here:
 #   1. https://lldb.llvm.org/varformats.html
 #   2. https://lldb.llvm.org/use/python-reference.html
-#   3. https://lldb.llvm.org/python_reference/lldb.formatters.cpp.libcxx-pysrc.html
+#   3. https://github.com/llvm/llvm-project/blob/llvmorg-8.0.1/lldb/www/python_reference/lldb.formatters.cpp-pysrc.html
 #   4. https://github.com/llvm-mirror/lldb/tree/master/examples/summaries/cocoa
 ####################################################################################################
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 031696d445d..97a2c331012 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -325,11 +325,11 @@ fn clean_where_predicate<'tcx>(
     predicate: &hir::WherePredicate<'tcx>,
     cx: &mut DocContext<'tcx>,
 ) -> Option<WherePredicate> {
-    if !predicate.in_where_clause() {
+    if !predicate.kind.in_where_clause() {
         return None;
     }
-    Some(match *predicate {
-        hir::WherePredicate::BoundPredicate(ref wbp) => {
+    Some(match *predicate.kind {
+        hir::WherePredicateKind::BoundPredicate(ref wbp) => {
             let bound_params = wbp
                 .bound_generic_params
                 .iter()
@@ -342,12 +342,12 @@ fn clean_where_predicate<'tcx>(
             }
         }
 
-        hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
+        hir::WherePredicateKind::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
             lifetime: clean_lifetime(wrp.lifetime, cx),
             bounds: wrp.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
         },
 
-        hir::WherePredicate::EqPredicate(ref wrp) => WherePredicate::EqPredicate {
+        hir::WherePredicateKind::EqPredicate(ref wrp) => WherePredicate::EqPredicate {
             lhs: clean_ty(wrp.lhs_ty, cx),
             rhs: clean_ty(wrp.rhs_ty, cx).into(),
         },
@@ -2516,14 +2516,6 @@ fn clean_generic_args<'tcx>(
                     }
                     hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
                     hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)),
-                    // Checking for `is_desugared_from_effects` on the `AnonConst` not only accounts for the case
-                    // where the argument is `host` but for all possible cases (e.g., `true`, `false`).
-                    hir::GenericArg::Const(hir::ConstArg {
-                        is_desugared_from_effects: true,
-                        ..
-                    }) => {
-                        return None;
-                    }
                     hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))),
                     hir::GenericArg::Infer(_inf) => GenericArg::Infer,
                 })
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 2f9e7976ca1..46bc2915d0a 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1296,7 +1296,7 @@ impl clean::Impl {
                         self.print_type(inner_type, f, use_absolute, cx)?;
                         write!(f, ">")?;
                     } else {
-                        write!(f, "{}&lt;", anchor(ty.def_id(), last, cx).to_string())?;
+                        write!(f, "{}&lt;", anchor(ty.def_id(), last, cx))?;
                         self.print_type(inner_type, f, use_absolute, cx)?;
                         write!(f, "&gt;")?;
                     }
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 29f6f92a6b2..b2fc1a47f78 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -181,6 +181,9 @@ impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> {
             // current parent tag is not the same as our pending content.
             let close_tag = if self.pending_elems.len() > 1
                 && let Some(current_class) = current_class
+                // `PreludeTy` can never include more than an ident so it should not generate
+                // a wrapping `span`.
+                && !matches!(current_class, Class::PreludeTy(_))
             {
                 Some(enter_span(self.out, current_class, &self.href_context))
             } else {
@@ -333,7 +336,7 @@ enum Class {
     /// `Ident` isn't rendered in the HTML but we still need it for the `Span` it contains.
     Ident(Span),
     Lifetime,
-    PreludeTy,
+    PreludeTy(Span),
     PreludeVal,
     QuestionMark,
     Decoration(&'static str),
@@ -381,7 +384,7 @@ impl Class {
             Class::Bool => "bool-val",
             Class::Ident(_) => "",
             Class::Lifetime => "lifetime",
-            Class::PreludeTy => "prelude-ty",
+            Class::PreludeTy(_) => "prelude-ty",
             Class::PreludeVal => "prelude-val",
             Class::QuestionMark => "question-mark",
             Class::Decoration(kind) => kind,
@@ -392,7 +395,7 @@ impl Class {
     /// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`).
     fn get_span(self) -> Option<Span> {
         match self {
-            Self::Ident(sp) | Self::Self_(sp) | Self::Macro(sp) => Some(sp),
+            Self::Ident(sp) | Self::Self_(sp) | Self::Macro(sp) | Self::PreludeTy(sp) => Some(sp),
             Self::Comment
             | Self::DocComment
             | Self::Attribute
@@ -403,7 +406,6 @@ impl Class {
             | Self::Number
             | Self::Bool
             | Self::Lifetime
-            | Self::PreludeTy
             | Self::PreludeVal
             | Self::QuestionMark
             | Self::Decoration(_) => None,
@@ -411,6 +413,7 @@ impl Class {
     }
 }
 
+#[derive(Debug)]
 enum Highlight<'a> {
     Token { text: &'a str, class: Option<Class> },
     EnterSpan { class: Class },
@@ -847,7 +850,7 @@ impl<'src> Classifier<'src> {
             }
             TokenKind::Ident => match get_real_ident_class(text, false) {
                 None => match text {
-                    "Option" | "Result" => Class::PreludeTy,
+                    "Option" | "Result" => Class::PreludeTy(self.new_span(before, text)),
                     "Some" | "None" | "Ok" | "Err" => Class::PreludeVal,
                     // "union" is a weak keyword and is only considered as a keyword when declaring
                     // a union type.
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 66221abdeca2002d318fde6efff516aab091df0
+Subproject 4c39aaff66862cc0da52fe529aa1990bb8bb9a2
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index fce7f9985ea..1eebfc22af2 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -963,7 +963,7 @@ fn report<'tcx>(
             // expr_str (the suggestion) is never shown if is_final_ufcs is true, since it's
             // `expr.kind == ExprKind::Call`. Therefore, this is, afaik, always unnecessary.
             /*
-            expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence().order() < PREC_PREFIX {
+            expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence() < PREC_PREFIX {
                 Cow::Owned(format!("({expr_str})"))
             } else {
                 expr_str
@@ -1003,7 +1003,7 @@ fn report<'tcx>(
                         Node::Expr(e) => match e.kind {
                             ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false),
                             ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))),
-                            _ => (e.precedence().order(), false),
+                            _ => (e.precedence(), false),
                         },
                         _ => (0, false),
                     };
@@ -1016,7 +1016,7 @@ fn report<'tcx>(
                     );
 
                     let sugg = if !snip_is_macro
-                        && (calls_field || expr.precedence().order() < precedence)
+                        && (calls_field || expr.precedence() < precedence)
                         && !has_enclosing_paren(&snip)
                         && !is_in_tuple
                     {
@@ -1071,7 +1071,7 @@ fn report<'tcx>(
                     let (snip, snip_is_macro) =
                         snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app);
                     let sugg =
-                        if !snip_is_macro && expr.precedence().order() < precedence && !has_enclosing_paren(&snip) {
+                        if !snip_is_macro && expr.precedence() < precedence && !has_enclosing_paren(&snip) {
                             format!("{prefix}({snip})")
                         } else {
                             format!("{prefix}{snip}")
@@ -1158,7 +1158,7 @@ impl<'tcx> Dereferencing<'tcx> {
                         },
                         Some(parent) if !parent.span.from_expansion() => {
                             // Double reference might be needed at this point.
-                            if parent.precedence().order() == PREC_UNAMBIGUOUS {
+                            if parent.precedence() == PREC_UNAMBIGUOUS {
                                 // Parentheses would be needed here, don't lint.
                                 *outer_pat = None;
                             } else {
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 3b6b3c89858..1a34b87e42a 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -11,7 +11,6 @@ use rustc_hir::{
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::traits::Reveal;
 use rustc_middle::ty::{
     self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, TraitPredicate, Ty, TyCtxt, Upcast,
 };
@@ -516,7 +515,6 @@ fn typing_env_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId
                 .upcast(tcx)
             }),
         )),
-        Reveal::UserFacing,
     );
     ty::TypingEnv {
         typing_mode: ty::TypingMode::non_body_analysis(),
diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
index 6ad879b9fe7..81152da8c85 100644
--- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty};
 use rustc_hir::{
     BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind,
-    PredicateOrigin, Ty, WherePredicate,
+    PredicateOrigin, Ty, WherePredicate, WherePredicateKind
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
@@ -205,12 +205,13 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
     }
 
     fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) {
-        if let WherePredicate::BoundPredicate(predicate) = predicate {
+        let span = predicate.span;
+        if let WherePredicateKind::BoundPredicate(predicate) = predicate.kind {
             // Collect spans for any bounds on type parameters.
             if let Some((def_id, _)) = predicate.bounded_ty.peel_refs().as_generic_param() {
                 match predicate.origin {
                     PredicateOrigin::GenericParam => {
-                        self.inline_bounds.insert(def_id, predicate.span);
+                        self.inline_bounds.insert(def_id, span);
                     },
                     PredicateOrigin::WhereClause => {
                         self.where_bounds.insert(def_id);
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
index 65fdc93e0ed..4427edb752e 100644
--- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -4,7 +4,7 @@ use rustc_errors::{Applicability, SuggestionStyle};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{
     AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifiers, TyKind,
-    WherePredicate,
+    WherePredicateKind,
 };
 use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
@@ -324,7 +324,7 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
 impl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls {
     fn check_generics(&mut self, cx: &LateContext<'tcx>, generics: &rustc_hir::Generics<'tcx>) {
         for predicate in generics.predicates {
-            if let WherePredicate::BoundPredicate(predicate) = predicate
+            if let WherePredicateKind::BoundPredicate(predicate) = predicate.kind
                 // In theory, the origin doesn't really matter,
                 // we *could* also lint on explicit where clauses written out by the user,
                 // not just impl trait desugared ones, but that contradicts with the lint name...
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index ce0e1a24a7b..6ff1a1e5ec7 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -12,7 +12,7 @@ use rustc_hir::intravisit::{
 use rustc_hir::{
     BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics,
     Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef,
-    PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate, lang_items,
+    PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate, WherePredicateKind, lang_items,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::map::Map;
@@ -442,9 +442,9 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
 /// reason about elision.
 fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) -> bool {
     for predicate in generics.predicates {
-        match *predicate {
-            WherePredicate::RegionPredicate(..) => return true,
-            WherePredicate::BoundPredicate(ref pred) => {
+        match *predicate.kind {
+            WherePredicateKind::RegionPredicate(..) => return true,
+            WherePredicateKind::BoundPredicate(ref pred) => {
                 // a predicate like F: Trait or F: for<'a> Trait<'a>
                 let mut visitor = RefVisitor::new(cx);
                 // walk the type F, it may not contain LT refs
@@ -467,7 +467,7 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_
                     }
                 }
             },
-            WherePredicate::EqPredicate(ref pred) => {
+            WherePredicateKind::EqPredicate(ref pred) => {
                 let mut visitor = RefVisitor::new(cx);
                 walk_ty(&mut visitor, pred.lhs_ty);
                 walk_ty(&mut visitor, pred.rhs_ty);
diff --git a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
index 70f76ced09a..35dc8e9aa4e 100644
--- a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
@@ -84,7 +84,7 @@ pub(super) fn check<'tcx>(
         if !prefix.is_empty()
             && (
                 // Precedence of internal expression is less than or equal to precedence of `&expr`.
-                arg_expression.precedence().order() <= PREC_PREFIX || is_range_literal(arg_expression)
+                arg_expression.precedence() <= PREC_PREFIX || is_range_literal(arg_expression)
             )
         {
             arg_snip = format!("({arg_snip})").into();
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
index d38560998a5..9c6df4d8ac0 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
@@ -117,7 +117,7 @@ where
     // it's being passed by value.
     let scrutinee = peel_hir_expr_refs(scrutinee).0;
     let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app);
-    let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence().order() < PREC_UNAMBIGUOUS {
+    let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < PREC_UNAMBIGUOUS {
         format!("({scrutinee_str})")
     } else {
         scrutinee_str.into()
diff --git a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
index d276e29bace..882ab2dda7a 100644
--- a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
+++ b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
@@ -1,5 +1,5 @@
 use rustc_ast::visit::FnKind;
-use rustc_ast::{NodeId, WherePredicate};
+use rustc_ast::{NodeId, WherePredicateKind};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::declare_lint_pass;
@@ -51,8 +51,8 @@ impl EarlyLintPass for MultipleBoundLocations {
                 }
             }
             for clause in &generics.where_clause.predicates {
-                match clause {
-                    WherePredicate::BoundPredicate(pred) => {
+                match &clause.kind {
+                    WherePredicateKind::BoundPredicate(pred) => {
                         if (!pred.bound_generic_params.is_empty() || !pred.bounds.is_empty())
                             && let Some(Some(bound_span)) = pred
                                 .bounded_ty
@@ -62,14 +62,14 @@ impl EarlyLintPass for MultipleBoundLocations {
                             emit_lint(cx, *bound_span, pred.bounded_ty.span);
                         }
                     },
-                    WherePredicate::RegionPredicate(pred) => {
+                    WherePredicateKind::RegionPredicate(pred) => {
                         if !pred.bounds.is_empty()
                             && let Some(bound_span) = generic_params_with_bounds.get(&pred.lifetime.ident.name.as_str())
                         {
                             emit_lint(cx, *bound_span, pred.lifetime.ident.span);
                         }
                     },
-                    WherePredicate::EqPredicate(_) => {},
+                    WherePredicateKind::EqPredicate(_) => {},
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
index 852a0ce8c6d..ad6313e391b 100644
--- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::{DefId, DefIdMap};
-use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicate};
+use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicateKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{ClauseKind, PredicatePolarity};
 use rustc_session::declare_lint_pass;
@@ -52,7 +52,7 @@ fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator<Item
         .iter()
         .enumerate()
         .filter_map(|(predicate_pos, predicate)| {
-            let WherePredicate::BoundPredicate(bound_predicate) = predicate else {
+            let WherePredicateKind::BoundPredicate(bound_predicate) = &predicate.kind else {
                 return None;
             };
 
diff --git a/src/tools/clippy/clippy_lints/src/neg_multiply.rs b/src/tools/clippy/clippy_lints/src/neg_multiply.rs
index f84d9fadb85..a0ba2aaf552 100644
--- a/src/tools/clippy/clippy_lints/src/neg_multiply.rs
+++ b/src/tools/clippy/clippy_lints/src/neg_multiply.rs
@@ -58,7 +58,7 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
     {
         let mut applicability = Applicability::MachineApplicable;
         let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability);
-        let suggestion = if !from_macro && exp.precedence().order() < PREC_PREFIX && !has_enclosing_paren(&snip) {
+        let suggestion = if !from_macro && exp.precedence() < PREC_PREFIX && !has_enclosing_paren(&snip) {
             format!("-({snip})")
         } else {
             format!("-{snip}")
diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
index 0ac818c21d9..79baa914b03 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
@@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
             let (expr_ty, expr_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(expr));
             let (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed));
             let parent_expr = get_parent_expr(cx, expr);
-            let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence().order() > PREC_PREFIX);
+            let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence() > PREC_PREFIX);
 
             if expr_ty == indexed_ty {
                 if expr_ref_count > indexed_ref_count {
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 07bf4319ff0..6f3c6682305 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -11,7 +11,7 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{
     BoundPolarity, GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath,
-    TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicate,
+    TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicateKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
@@ -124,9 +124,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
         let mut self_bounds_map = FxHashMap::default();
 
         for predicate in item.generics.predicates {
-            if let WherePredicate::BoundPredicate(bound_predicate) = predicate
+            if let WherePredicateKind::BoundPredicate(bound_predicate) = predicate.kind
                 && bound_predicate.origin != PredicateOrigin::ImplTrait
-                && !bound_predicate.span.from_expansion()
+                && !predicate.span.from_expansion()
                 && let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind
                 && let Some(PathSegment {
                     res: Res::SelfTyParam { trait_: def_id },
@@ -268,10 +268,10 @@ impl TraitBounds {
         let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default();
         let mut applicability = Applicability::MaybeIncorrect;
         for bound in generics.predicates {
-            if let WherePredicate::BoundPredicate(p) = bound
+            if let WherePredicateKind::BoundPredicate(p) = bound.kind
                 && p.origin != PredicateOrigin::ImplTrait
                 && p.bounds.len() as u64 <= self.max_trait_bounds
-                && !p.span.from_expansion()
+                && !bound.span.from_expansion()
                 && let bounds = p
                     .bounds
                     .iter()
@@ -295,7 +295,7 @@ impl TraitBounds {
                 span_lint_and_help(
                     cx,
                     TYPE_REPETITION_IN_BOUNDS,
-                    p.span,
+                    bound.span,
                     "this type has already been used as a bound predicate",
                     None,
                     hint_string,
@@ -322,8 +322,8 @@ fn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Gen
         .predicates
         .iter()
         .filter_map(|pred| {
-            if pred.in_where_clause()
-                && let WherePredicate::BoundPredicate(bound_predicate) = pred
+            if pred.kind.in_where_clause()
+                && let WherePredicateKind::BoundPredicate(bound_predicate) = pred.kind
                 && let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind
             {
                 return Some(
@@ -347,10 +347,10 @@ fn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Gen
     //            |
     // compare trait bounds keyed by generic name and comparable trait to collected where
     // predicates eg. (T, Clone)
-    for predicate in generics.predicates.iter().filter(|pred| !pred.in_where_clause()) {
-        if let WherePredicate::BoundPredicate(bound_predicate) = predicate
+    for predicate in generics.predicates.iter().filter(|pred| !pred.kind.in_where_clause()) {
+        if let WherePredicateKind::BoundPredicate(bound_predicate) = predicate.kind
             && bound_predicate.origin != PredicateOrigin::ImplTrait
-            && !bound_predicate.span.from_expansion()
+            && !predicate.span.from_expansion()
             && let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind
         {
             let traits = rollup_traits(cx, bound_predicate.bounds, "these bounds contain repeated elements");
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
index fca332dba40..cad15b1e982 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
@@ -1,7 +1,7 @@
 use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::sugg::Sugg;
-use rustc_ast::ExprPrecedence;
+use rustc_ast::util::parser::AssocOp;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Node};
 use rustc_hir_typeck::cast::check_cast;
@@ -44,7 +44,7 @@ pub(super) fn check<'tcx>(
     };
 
     if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)
-        && parent.precedence().order() > ExprPrecedence::Cast.order()
+        && parent.precedence() > AssocOp::As.precedence() as i8
     {
         sugg = format!("({sugg})");
     }
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 0be6dc15a8e..c90f4a6ebfe 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -661,8 +661,8 @@ pub fn eq_generics(l: &Generics, r: &Generics) -> bool {
 }
 
 pub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool {
-    use WherePredicate::*;
-    match (l, r) {
+    use WherePredicateKind::*;
+    match (&l.kind, &r.kind) {
         (BoundPredicate(l), BoundPredicate(r)) => {
             over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
                 eq_generic_param(l, r)
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 345c46f944a..3c9ea4bfaf4 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -404,12 +404,11 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
     // FIXME(const_trait_impl, fee1-dead) revert to const destruct once it works again
     #[expect(unused)]
     fn is_ty_const_destruct_unused<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {
-        // Avoid selecting for simple cases, such as builtin types.
-        if ty::util::is_trivially_const_drop(ty) {
-            return true;
+        // If this doesn't need drop at all, then don't select `~const Destruct`.
+        if !ty.needs_drop(tcx, body.typing_env(tcx)) {
+            return false;
         }
 
-
         let (infcx, param_env) =
             tcx.infer_ctxt().build_with_typing_env(body.typing_env(tcx));
         // FIXME(const_trait_impl) constness
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 3498606dfd3..03e1a814a86 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -575,7 +575,7 @@ pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
 
 /// Checks if a given type looks safe to be uninitialized.
 pub fn is_uninit_value_valid_for_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
-    let typing_env = cx.typing_env().with_reveal_all_normalized(cx.tcx);
+    let typing_env = cx.typing_env().with_post_analysis_normalized(cx.tcx);
     cx.tcx
         .check_validity_requirement((ValidityRequirement::Uninit, typing_env.as_query_input(ty)))
         .unwrap_or_else(|_| is_uninit_value_valid_for_ty_fallback(cx, ty))
diff --git a/src/tools/collect-license-metadata/src/main.rs b/src/tools/collect-license-metadata/src/main.rs
index dce36bb17b6..08a30d0b899 100644
--- a/src/tools/collect-license-metadata/src/main.rs
+++ b/src/tools/collect-license-metadata/src/main.rs
@@ -4,7 +4,7 @@ mod reuse;
 
 use std::path::PathBuf;
 
-use anyhow::Error;
+use anyhow::{Context, Error};
 
 use crate::licenses::LicensesInterner;
 
@@ -12,10 +12,12 @@ use crate::licenses::LicensesInterner;
 ///
 /// You should probably let `bootstrap` execute this program instead of running it directly.
 ///
-/// Run `x.py run collect-license-metadata`
+/// * Run `x.py run collect-license-metadata` to re-regenerate the file.
+/// * Run `x.py test collect-license-metadata` to check if the file you have is correct.
 fn main() -> Result<(), Error> {
     let reuse_exe: PathBuf = std::env::var_os("REUSE_EXE").expect("Missing REUSE_EXE").into();
     let dest: PathBuf = std::env::var_os("DEST").expect("Missing DEST").into();
+    let only_check = std::env::var_os("ONLY_CHECK").is_some();
 
     let mut interner = LicensesInterner::new();
     let paths = crate::reuse::collect(&reuse_exe, &mut interner)?;
@@ -23,15 +25,32 @@ fn main() -> Result<(), Error> {
     let mut tree = crate::path_tree::build(paths);
     tree.simplify();
 
-    if let Some(parent) = dest.parent() {
-        std::fs::create_dir_all(parent)?;
+    let output = serde_json::json!({
+        "files": crate::path_tree::expand_interned_licenses(tree, &interner)
+    });
+
+    if only_check {
+        println!("loading existing license information");
+        let existing = std::fs::read_to_string(&dest).with_context(|| {
+            format!("Failed to read existing license JSON at {}", dest.display())
+        })?;
+        let existing_json: serde_json::Value =
+            serde_json::from_str(&existing).with_context(|| {
+                format!("Failed to read existing license JSON at {}", dest.display())
+            })?;
+        if existing_json != output {
+            eprintln!("The existing {} file is out of date.", dest.display());
+            eprintln!("Run ./x run collect-license-metadata to update it.");
+            anyhow::bail!("The existing {} file doesn't match what REUSE reports.", dest.display());
+        }
+        println!("license information matches");
+    } else {
+        if let Some(parent) = dest.parent() {
+            std::fs::create_dir_all(parent)?;
+        }
+        std::fs::write(&dest, &serde_json::to_vec_pretty(&output)?)?;
+        println!("license information written to {}", dest.display());
     }
-    std::fs::write(
-        &dest,
-        &serde_json::to_vec_pretty(&serde_json::json!({
-            "files": crate::path_tree::expand_interned_licenses(tree, &interner),
-        }))?,
-    )?;
 
     Ok(())
 }
diff --git a/src/tools/collect-license-metadata/src/reuse.rs b/src/tools/collect-license-metadata/src/reuse.rs
index e5ee8f0da5e..dbe46781b7c 100644
--- a/src/tools/collect-license-metadata/src/reuse.rs
+++ b/src/tools/collect-license-metadata/src/reuse.rs
@@ -10,10 +10,10 @@ pub(crate) fn collect(
     reuse_exe: &Path,
     interner: &mut LicensesInterner,
 ) -> Result<Vec<(PathBuf, LicenseId)>, Error> {
-    eprintln!("gathering license information from REUSE");
+    println!("gathering license information from REUSE (this might take a minute...)");
     let start = Instant::now();
     let raw = &obtain_spdx_document(reuse_exe)?;
-    eprintln!("finished gathering the license information from REUSE in {:.2?}", start.elapsed());
+    println!("finished gathering the license information from REUSE in {:.2?}", start.elapsed());
 
     let document = spdx_rs::parsers::spdx_from_tag_value(&raw)?;
 
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs
index bdd0b80b395..0c47ef871d2 100644
--- a/src/tools/compiletest/src/directive-list.rs
+++ b/src/tools/compiletest/src/directive-list.rs
@@ -214,7 +214,6 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "only-x86_64-unknown-linux-gnu",
     "pp-exact",
     "pretty-compare-only",
-    "pretty-expanded",
     "pretty-mode",
     "reference",
     "regex-error-pattern",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 3539e85ba63..e945797647e 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -124,8 +124,6 @@ pub struct TestProps {
     // a proc-macro and needs `#![crate_type = "proc-macro"]`. This ensures
     // that the aux file is compiled as a `proc-macro` and not as a `dylib`.
     pub no_prefer_dynamic: bool,
-    // Run -Zunpretty expanded when running pretty printing tests
-    pub pretty_expanded: bool,
     // Which pretty mode are we testing with, default to 'normal'
     pub pretty_mode: String,
     // Only compare pretty output and don't try compiling
@@ -218,7 +216,6 @@ mod directives {
     pub const DONT_CHECK_COMPILER_STDOUT: &'static str = "dont-check-compiler-stdout";
     pub const DONT_CHECK_COMPILER_STDERR: &'static str = "dont-check-compiler-stderr";
     pub const NO_PREFER_DYNAMIC: &'static str = "no-prefer-dynamic";
-    pub const PRETTY_EXPANDED: &'static str = "pretty-expanded";
     pub const PRETTY_MODE: &'static str = "pretty-mode";
     pub const PRETTY_COMPARE_ONLY: &'static str = "pretty-compare-only";
     pub const AUX_BIN: &'static str = "aux-bin";
@@ -278,7 +275,6 @@ impl TestProps {
             dont_check_compiler_stderr: false,
             compare_output_lines_by_subset: false,
             no_prefer_dynamic: false,
-            pretty_expanded: false,
             pretty_mode: "normal".to_string(),
             pretty_compare_only: false,
             forbid_output: vec![],
@@ -425,7 +421,6 @@ impl TestProps {
                         &mut self.dont_check_compiler_stderr,
                     );
                     config.set_name_directive(ln, NO_PREFER_DYNAMIC, &mut self.no_prefer_dynamic);
-                    config.set_name_directive(ln, PRETTY_EXPANDED, &mut self.pretty_expanded);
 
                     if let Some(m) = config.parse_name_value_directive(ln, PRETTY_MODE) {
                         self.pretty_mode = m;
diff --git a/src/tools/compiletest/src/runtest/pretty.rs b/src/tools/compiletest/src/runtest/pretty.rs
index 40e767e84ef..e3b07f1d63d 100644
--- a/src/tools/compiletest/src/runtest/pretty.rs
+++ b/src/tools/compiletest/src/runtest/pretty.rs
@@ -84,21 +84,5 @@ impl TestCx<'_> {
         if !proc_res.status.success() {
             self.fatal_proc_rec("pretty-printed source does not typecheck", &proc_res);
         }
-
-        if !self.props.pretty_expanded {
-            return;
-        }
-
-        // additionally, run `-Zunpretty=expanded` and try to build it.
-        let proc_res = self.print_source(ReadFrom::Path, "expanded");
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("pretty-printing (expanded) failed", &proc_res);
-        }
-
-        let ProcRes { stdout: expanded_src, .. } = proc_res;
-        let proc_res = self.typecheck_source(expanded_src);
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("pretty-printed source (expanded) does not typecheck", &proc_res);
-        }
     }
 }
diff --git a/src/tools/generate-copyright/src/cargo_metadata.rs b/src/tools/generate-copyright/src/cargo_metadata.rs
index 31b18c3dc10..420579372ac 100644
--- a/src/tools/generate-copyright/src/cargo_metadata.rs
+++ b/src/tools/generate-copyright/src/cargo_metadata.rs
@@ -45,21 +45,20 @@ pub struct PackageMetadata {
 
 /// Use `cargo metadata` and `cargo vendor` to get a list of dependencies and their license data.
 ///
-/// This will involve running `cargo vendor` into `${BUILD}/vendor` so we can
+/// This will involve running `cargo vendor` into `vendor_path` so we can
 /// grab the license files.
 ///
 /// Any dependency with a path beginning with `root_path` is ignored, as we
 /// assume `reuse` has covered it already.
 pub fn get_metadata_and_notices(
     cargo: &Path,
-    dest: &Path,
+    vendor_path: &Path,
     root_path: &Path,
     manifest_paths: &[&Path],
 ) -> Result<BTreeMap<Package, PackageMetadata>, Error> {
     let mut output = get_metadata(cargo, root_path, manifest_paths)?;
 
     // Now do a cargo-vendor and grab everything
-    let vendor_path = dest.join("vendor");
     println!("Vendoring deps into {}...", vendor_path.display());
     run_cargo_vendor(cargo, &vendor_path, manifest_paths)?;
 
diff --git a/src/tools/generate-copyright/src/main.rs b/src/tools/generate-copyright/src/main.rs
index afa75d0d671..f83d16d0cab 100644
--- a/src/tools/generate-copyright/src/main.rs
+++ b/src/tools/generate-copyright/src/main.rs
@@ -6,13 +6,6 @@ use rinja::Template;
 
 mod cargo_metadata;
 
-#[derive(Template)]
-#[template(path = "COPYRIGHT.html")]
-struct CopyrightTemplate {
-    in_tree: Node,
-    dependencies: BTreeMap<cargo_metadata::Package, cargo_metadata::PackageMetadata>,
-}
-
 /// The entry point to the binary.
 ///
 /// You should probably let `bootstrap` execute this program instead of running it directly.
@@ -20,49 +13,97 @@ struct CopyrightTemplate {
 /// Run `x.py run generate-copyright`
 fn main() -> Result<(), Error> {
     let dest_file = env_path("DEST")?;
+    let libstd_dest_file = env_path("DEST_LIBSTD")?;
     let out_dir = env_path("OUT_DIR")?;
     let cargo = env_path("CARGO")?;
     let license_metadata = env_path("LICENSE_METADATA")?;
 
-    let collected_tree_metadata: Metadata =
-        serde_json::from_slice(&std::fs::read(&license_metadata)?)?;
-
     let root_path = std::path::absolute(".")?;
-    let workspace_paths = [
-        Path::new("./Cargo.toml"),
-        Path::new("./src/tools/cargo/Cargo.toml"),
-        Path::new("./library/Cargo.toml"),
-    ];
-    let mut collected_cargo_metadata =
-        cargo_metadata::get_metadata_and_notices(&cargo, &out_dir, &root_path, &workspace_paths)?;
 
-    let stdlib_set =
-        cargo_metadata::get_metadata(&cargo, &root_path, &[Path::new("./library/std/Cargo.toml")])?;
+    // Scan Cargo dependencies
+    let mut collected_cargo_metadata =
+        cargo_metadata::get_metadata_and_notices(&cargo, &out_dir.join("vendor"), &root_path, &[
+            Path::new("./Cargo.toml"),
+            Path::new("./src/tools/cargo/Cargo.toml"),
+            Path::new("./library/Cargo.toml"),
+        ])?;
+
+    let library_collected_cargo_metadata = cargo_metadata::get_metadata_and_notices(
+        &cargo,
+        &out_dir.join("library-vendor"),
+        &root_path,
+        &[Path::new("./library/Cargo.toml")],
+    )?;
 
     for (key, value) in collected_cargo_metadata.iter_mut() {
-        value.is_in_libstd = Some(stdlib_set.contains_key(key));
+        value.is_in_libstd = Some(library_collected_cargo_metadata.contains_key(key));
     }
 
+    // Load JSON output by reuse
+    let collected_tree_metadata: Metadata =
+        serde_json::from_slice(&std::fs::read(&license_metadata)?)?;
+
+    // Find libstd sub-set
+    let library_collected_tree_metadata = Metadata {
+        files: collected_tree_metadata
+            .files
+            .trim_clone(&Path::new("./library"), &Path::new("."))
+            .unwrap(),
+    };
+
+    // Output main file
     let template = CopyrightTemplate {
         in_tree: collected_tree_metadata.files,
         dependencies: collected_cargo_metadata,
     };
-
     let output = template.render()?;
-
+    // Git stores text files with \n, but this file may contain \r\n in files
+    // copied from dependencies. Normalise them before we write them out, for
+    // consistency.
+    let output = output.replace("\r\n", "\n");
     std::fs::write(&dest_file, output)?;
 
+    // Output libstd subset file
+    let template = LibraryCopyrightTemplate {
+        in_tree: library_collected_tree_metadata.files,
+        dependencies: library_collected_cargo_metadata,
+    };
+    let output = template.render()?;
+    // Git stores text files with \n, but this file may contain \r\n in files
+    // copied from dependencies. Normalise them before we write them out, for
+    // consistency.
+    let output = output.replace("\r\n", "\n");
+    std::fs::write(&libstd_dest_file, output)?;
+
     Ok(())
 }
 
+/// The HTML template for the toolchain copyright file
+#[derive(Template)]
+#[template(path = "COPYRIGHT.html")]
+struct CopyrightTemplate {
+    in_tree: Node,
+    dependencies: BTreeMap<cargo_metadata::Package, cargo_metadata::PackageMetadata>,
+}
+
+/// The HTML template for the library copyright file
+#[derive(Template)]
+#[template(path = "COPYRIGHT-library.html")]
+struct LibraryCopyrightTemplate {
+    in_tree: Node,
+    dependencies: BTreeMap<cargo_metadata::Package, cargo_metadata::PackageMetadata>,
+}
+
 /// Describes a tree of metadata for our filesystem tree
-#[derive(serde::Deserialize)]
+///
+/// Must match the JSON emitted by the `CollectLicenseMetadata` bootstrap tool.
+#[derive(serde::Deserialize, Clone, Debug, PartialEq, Eq)]
 struct Metadata {
     files: Node,
 }
 
 /// Describes one node in our metadata tree
-#[derive(serde::Deserialize, rinja::Template)]
+#[derive(serde::Deserialize, rinja::Template, Clone, Debug, PartialEq, Eq)]
 #[serde(rename_all = "kebab-case", tag = "type")]
 #[template(path = "Node.html")]
 pub(crate) enum Node {
@@ -72,8 +113,74 @@ pub(crate) enum Node {
     Group { files: Vec<String>, directories: Vec<String>, license: License },
 }
 
+impl Node {
+    /// Clone, this node, but only if the path to the item is within the match path
+    fn trim_clone(&self, match_path: &Path, parent_path: &Path) -> Option<Node> {
+        match self {
+            Node::Root { children } => {
+                let mut filtered_children = Vec::new();
+                for node in children {
+                    if let Some(child_node) = node.trim_clone(match_path, parent_path) {
+                        filtered_children.push(child_node);
+                    }
+                }
+                if filtered_children.is_empty() {
+                    None
+                } else {
+                    Some(Node::Root { children: filtered_children })
+                }
+            }
+            Node::Directory { name, children, license } => {
+                let child_name = parent_path.join(name);
+                if !(child_name.starts_with(match_path) || match_path.starts_with(&child_name)) {
+                    return None;
+                }
+                let mut filtered_children = Vec::new();
+                for node in children {
+                    if let Some(child_node) = node.trim_clone(match_path, &child_name) {
+                        filtered_children.push(child_node);
+                    }
+                }
+                Some(Node::Directory {
+                    name: name.clone(),
+                    children: filtered_children,
+                    license: license.clone(),
+                })
+            }
+            Node::File { name, license } => {
+                let child_name = parent_path.join(name);
+                if !(child_name.starts_with(match_path) || match_path.starts_with(&child_name)) {
+                    return None;
+                }
+                Some(Node::File { name: name.clone(), license: license.clone() })
+            }
+            Node::Group { files, directories, license } => {
+                let mut filtered_child_files = Vec::new();
+                for child in files {
+                    let child_name = parent_path.join(child);
+                    if child_name.starts_with(match_path) || match_path.starts_with(&child_name) {
+                        filtered_child_files.push(child.clone());
+                    }
+                }
+                let mut filtered_child_dirs = Vec::new();
+                for child in directories {
+                    let child_name = parent_path.join(child);
+                    if child_name.starts_with(match_path) || match_path.starts_with(&child_name) {
+                        filtered_child_dirs.push(child.clone());
+                    }
+                }
+                Some(Node::Group {
+                    files: filtered_child_files,
+                    directories: filtered_child_dirs,
+                    license: license.clone(),
+                })
+            }
+        }
+    }
+}
+
 /// A License has an SPDX license name and a list of copyright holders.
-#[derive(serde::Deserialize)]
+#[derive(serde::Deserialize, Clone, Debug, PartialEq, Eq)]
 struct License {
     spdx: String,
     copyright: Vec<String>,
diff --git a/src/tools/generate-copyright/templates/COPYRIGHT-library.html b/src/tools/generate-copyright/templates/COPYRIGHT-library.html
new file mode 100644
index 00000000000..2c1eba741db
--- /dev/null
+++ b/src/tools/generate-copyright/templates/COPYRIGHT-library.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>Copyright notices for The Rust Standard Library</title>
+</head>
+<body>
+
+<h1>Copyright notices for The Rust Standard Library</h1>
+
+<p>This file describes the copyright and licensing information for the Rust
+Standard Library source code within The Rust Project git tree, and the
+third-party dependencies used when building the Rust Standard Library.</p>
+
+<h2>Table of Contents</h2>
+<ul>
+    <li><a href="#in-tree-files">In-tree files</a></li>
+    <li><a href="#out-of-tree-dependencies">Out-of-tree dependencies</a></li>
+</ul>
+
+<h2 id="in-tree-files">In-tree files</h2>
+
+<p>The following licenses cover the in-tree source files that were used in this
+release:</p>
+
+{{ in_tree|safe }}
+
+<h2 id="out-of-tree-dependencies">Out-of-tree dependencies</h2>
+
+<p>The following licenses cover the out-of-tree crates that were used in the
+Rust Standard Library in this release:</p>
+
+{% for (key, value) in dependencies %}
+    <h3>📦 {{key.name}}-{{key.version}}</h3>
+    <p><b>URL:</b> <a href="https://crates.io/crates/{{ key.name }}/{{ key.version }}">https://crates.io/crates/{{ key.name }}/{{ key.version }}</a></p>
+    <p><b>Authors:</b> {{ value.authors|join(", ") }}</p>
+    <p><b>License:</b> {{ value.license }}</p>
+    {% let len = value.notices.len() %}
+    {% if len > 0 %}
+        <p><b>Notices:</b>
+        {% for (notice_name, notice_text) in value.notices %}
+            <details>
+                <summary><code>{{ notice_name }}</code></summary>
+                <pre>
+{{ notice_text }}
+                </pre>
+            </details>
+        {% endfor %}
+        </p>
+    {% endif %}
+{% endfor %}
+</body>
+</html>
\ No newline at end of file
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index e5812ae2603..e193c786eff 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-5d3c6ee9b34989595d2a72b79e61ca37e949d757
+eddb717281a9031f645d88dd3b8323a7e25632cc
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 357c50889c4..15f05ba909c 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -3,6 +3,7 @@
     clippy::manual_range_contains,
     clippy::useless_format,
     clippy::field_reassign_with_default,
+    clippy::needless_lifetimes,
     rustc::diagnostic_outside_of_impl,
     rustc::untranslatable_diagnostic
 )]
@@ -73,51 +74,47 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
     fn after_analysis<'tcx>(
         &mut self,
         _: &rustc_interface::interface::Compiler,
-        queries: &'tcx rustc_interface::Queries<'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> Compilation {
-        queries.global_ctxt().unwrap().enter(|tcx| {
-            if tcx.sess.dcx().has_errors_or_delayed_bugs().is_some() {
-                tcx.dcx().fatal("miri cannot be run on programs that fail compilation");
-            }
+        if tcx.sess.dcx().has_errors_or_delayed_bugs().is_some() {
+            tcx.dcx().fatal("miri cannot be run on programs that fail compilation");
+        }
 
-            let early_dcx = EarlyDiagCtxt::new(tcx.sess.opts.error_format);
-            init_late_loggers(&early_dcx, tcx);
-            if !tcx.crate_types().contains(&CrateType::Executable) {
-                tcx.dcx().fatal("miri only makes sense on bin crates");
-            }
+        let early_dcx = EarlyDiagCtxt::new(tcx.sess.opts.error_format);
+        init_late_loggers(&early_dcx, tcx);
+        if !tcx.crate_types().contains(&CrateType::Executable) {
+            tcx.dcx().fatal("miri only makes sense on bin crates");
+        }
 
-            let (entry_def_id, entry_type) = entry_fn(tcx);
-            let mut config = self.miri_config.clone();
+        let (entry_def_id, entry_type) = entry_fn(tcx);
+        let mut config = self.miri_config.clone();
 
-            // Add filename to `miri` arguments.
-            config.args.insert(0, tcx.sess.io.input.filestem().to_string());
+        // Add filename to `miri` arguments.
+        config.args.insert(0, tcx.sess.io.input.filestem().to_string());
 
-            // Adjust working directory for interpretation.
-            if let Some(cwd) = env::var_os("MIRI_CWD") {
-                env::set_current_dir(cwd).unwrap();
-            }
+        // Adjust working directory for interpretation.
+        if let Some(cwd) = env::var_os("MIRI_CWD") {
+            env::set_current_dir(cwd).unwrap();
+        }
 
-            if tcx.sess.opts.optimize != OptLevel::No {
-                tcx.dcx().warn("Miri does not support optimizations: the opt-level is ignored. The only effect \
+        if tcx.sess.opts.optimize != OptLevel::No {
+            tcx.dcx().warn("Miri does not support optimizations: the opt-level is ignored. The only effect \
                     of selecting a Cargo profile that enables optimizations (such as --release) is to apply \
                     its remaining settings, such as whether debug assertions and overflow checks are enabled.");
-            }
-            if tcx.sess.mir_opt_level() > 0 {
-                tcx.dcx().warn("You have explicitly enabled MIR optimizations, overriding Miri's default \
+        }
+        if tcx.sess.mir_opt_level() > 0 {
+            tcx.dcx().warn("You have explicitly enabled MIR optimizations, overriding Miri's default \
                     which is to completely disable them. Any optimizations may hide UB that Miri would \
                     otherwise detect, and it is not necessarily possible to predict what kind of UB will \
                     be missed. If you are enabling optimizations to make Miri run faster, we advise using \
                     cfg(miri) to shrink your workload instead. The performance benefit of enabling MIR \
                     optimizations is usually marginal at best.");
-            }
+        }
 
-            if let Some(return_code) = miri::eval_entry(tcx, entry_def_id, entry_type, config) {
-                std::process::exit(
-                    i32::try_from(return_code).expect("Return value was too large!"),
-                );
-            }
-            tcx.dcx().abort_if_errors();
-        });
+        if let Some(return_code) = miri::eval_entry(tcx, entry_def_id, entry_type, config) {
+            std::process::exit(i32::try_from(return_code).expect("Return value was too large!"));
+        }
+        tcx.dcx().abort_if_errors();
 
         Compilation::Stop
     }
@@ -193,20 +190,18 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls {
     fn after_analysis<'tcx>(
         &mut self,
         _: &rustc_interface::interface::Compiler,
-        queries: &'tcx rustc_interface::Queries<'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> Compilation {
-        queries.global_ctxt().unwrap().enter(|tcx| {
-            if self.target_crate {
-                // cargo-miri has patched the compiler flags to make these into check-only builds,
-                // but we are still emulating regular rustc builds, which would perform post-mono
-                // const-eval during collection. So let's also do that here, even if we might be
-                // running with `--emit=metadata`. In particular this is needed to make
-                // `compile_fail` doc tests trigger post-mono errors.
-                // In general `collect_and_partition_mono_items` is not safe to call in check-only
-                // builds, but we are setting `-Zalways-encode-mir` which avoids those issues.
-                let _ = tcx.collect_and_partition_mono_items(());
-            }
-        });
+        if self.target_crate {
+            // cargo-miri has patched the compiler flags to make these into check-only builds,
+            // but we are still emulating regular rustc builds, which would perform post-mono
+            // const-eval during collection. So let's also do that here, even if we might be
+            // running with `--emit=metadata`. In particular this is needed to make
+            // `compile_fail` doc tests trigger post-mono errors.
+            // In general `collect_and_partition_mono_items` is not safe to call in check-only
+            // builds, but we are setting `-Zalways-encode-mir` which avoids those issues.
+            let _ = tcx.collect_and_partition_mono_items(());
+        }
         Compilation::Continue
     }
 }
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index c145cf3ceb8..d6a180451d7 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -382,6 +382,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Return success (`1`).
                 this.write_int(1, dest)?;
             }
+            "TlsFree" => {
+                let [key] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
+                let key = u128::from(this.read_scalar(key)?.to_u32()?);
+                this.machine.tls.delete_tls_key(key)?;
+
+                // Return success (`1`).
+                this.write_int(1, dest)?;
+            }
 
             // Access to command-line arguments
             "GetCommandLineW" => {
diff --git a/src/tools/miri/tests/pass/tls/windows-tls.rs b/src/tools/miri/tests/pass/tls/windows-tls.rs
new file mode 100644
index 00000000000..58131be1903
--- /dev/null
+++ b/src/tools/miri/tests/pass/tls/windows-tls.rs
@@ -0,0 +1,18 @@
+//@only-target: windows # this directly tests windows-only functions
+
+use std::ffi::c_void;
+use std::ptr;
+
+extern "system" {
+    fn TlsAlloc() -> u32;
+    fn TlsSetValue(key: u32, val: *mut c_void) -> bool;
+    fn TlsGetValue(key: u32) -> *mut c_void;
+    fn TlsFree(key: u32) -> bool;
+}
+
+fn main() {
+    let key = unsafe { TlsAlloc() };
+    assert!(unsafe { TlsSetValue(key, ptr::without_provenance_mut(1)) });
+    assert_eq!(unsafe { TlsGetValue(key).addr() }, 1);
+    assert!(unsafe { TlsFree(key) });
+}
diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock
index 9e549348da3..400eb7c5e0d 100644
--- a/src/tools/rustbook/Cargo.lock
+++ b/src/tools/rustbook/Cargo.lock
@@ -161,9 +161,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "cc"
-version = "1.1.34"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9"
+checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8"
 dependencies = [
  "shlex",
 ]
diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml
index 2c29a2848b7..854c4547337 100644
--- a/src/tools/rustbook/Cargo.toml
+++ b/src/tools/rustbook/Cargo.toml
@@ -12,7 +12,7 @@ env_logger = "0.11"
 mdbook-trpl-listing = { path = "../../doc/book/packages/mdbook-trpl-listing" }
 mdbook-trpl-note = { path = "../../doc/book/packages/mdbook-trpl-note" }
 mdbook-i18n-helpers = "0.3.3"
-mdbook-spec = { path = "../../doc/reference/mdbook-spec"}
+mdbook-spec = { path = "../../doc/reference/mdbook-spec" }
 
 [dependencies.mdbook]
 version = "0.4.37"
diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs
index f905b9277ff..a1ef18610b0 100644
--- a/src/tools/rustbook/src/main.rs
+++ b/src/tools/rustbook/src/main.rs
@@ -31,6 +31,20 @@ fn main() {
                               (Defaults to the current directory when omitted)")
     .value_parser(clap::value_parser!(PathBuf));
 
+    // Note: we don't parse this into a `PathBuf` because it is comma separated
+    // strings *and* we will ultimately pass it into `MDBook::test()`, which
+    // accepts `Vec<&str>`. Although it is a bit annoying that `-l/--lang` and
+    // `-L/--library-path` are so close, this is the same set of arguments we
+    // would pass when invoking mdbook on the CLI, so making them match when
+    // invoking rustbook makes for good consistency.
+    let library_path_arg = arg!(
+        -L --"library-path" <PATHS>
+        "A comma-separated list of directories to add to the crate search\n\
+        path when building tests"
+    )
+    .required(false)
+    .value_parser(parse_library_paths);
+
     let matches = Command::new("rustbook")
         .about("Build a book with mdBook")
         .author("Steve Klabnik <steve@steveklabnik.com>")
@@ -48,11 +62,12 @@ fn main() {
         .subcommand(
             Command::new("test")
                 .about("Tests that a book's Rust code samples compile")
-                .arg(dir_arg),
+                .arg(dir_arg)
+                .arg(library_path_arg),
         )
         .get_matches();
 
-    // Check which subcomamnd the user ran...
+    // Check which subcommand the user ran...
     match matches.subcommand() {
         Some(("build", sub_matches)) => {
             if let Err(e) = build(sub_matches) {
@@ -113,8 +128,12 @@ pub fn build(args: &ArgMatches) -> Result3<()> {
 
 fn test(args: &ArgMatches) -> Result3<()> {
     let book_dir = get_book_dir(args);
+    let library_paths = args
+        .try_get_one::<Vec<String>>("library-path")?
+        .map(|v| v.iter().map(|s| s.as_str()).collect::<Vec<&str>>())
+        .unwrap_or_default();
     let mut book = load_book(&book_dir)?;
-    book.test(vec![])
+    book.test(library_paths)
 }
 
 fn get_book_dir(args: &ArgMatches) -> PathBuf {
@@ -132,6 +151,10 @@ fn load_book(book_dir: &Path) -> Result3<MDBook> {
     Ok(book)
 }
 
+fn parse_library_paths(input: &str) -> Result<Vec<String>, String> {
+    Ok(input.split(",").map(String::from).collect())
+}
+
 fn handle_error(error: mdbook::errors::Error) -> ! {
     eprintln!("Error: {}", error);
 
@@ -139,5 +162,5 @@ fn handle_error(error: mdbook::errors::Error) -> ! {
         eprintln!("\tCaused By: {}", cause);
     }
 
-    ::std::process::exit(101);
+    std::process::exit(101);
 }
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index 68c481bda6e..18932587f1f 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -1916,15 +1916,15 @@ pub(crate) fn rewrite_struct_field_prefix(
     field: &ast::FieldDef,
 ) -> RewriteResult {
     let vis = format_visibility(context, &field.vis);
+    let safety = format_safety(field.safety);
     let type_annotation_spacing = type_annotation_spacing(context.config);
     Ok(match field.ident {
         Some(name) => format!(
-            "{}{}{}:",
-            vis,
+            "{vis}{safety}{}{}:",
             rewrite_ident(context, name),
             type_annotation_spacing.0
         ),
-        None => vis.to_string(),
+        None => format!("{vis}{safety}"),
     })
 }
 
diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs
index 4d684f3c635..db7c3486e71 100644
--- a/src/tools/rustfmt/src/spanned.rs
+++ b/src/tools/rustfmt/src/spanned.rs
@@ -150,11 +150,7 @@ impl Spanned for ast::FieldDef {
 
 impl Spanned for ast::WherePredicate {
     fn span(&self) -> Span {
-        match *self {
-            ast::WherePredicate::BoundPredicate(ref p) => p.span,
-            ast::WherePredicate::RegionPredicate(ref p) => p.span,
-            ast::WherePredicate::EqPredicate(ref p) => p.span,
-        }
+        self.span
     }
 }
 
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index e237662f5aa..dd4a788c002 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -463,8 +463,8 @@ impl Rewrite for ast::WherePredicate {
 
     fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         // FIXME: dead spans?
-        let result = match *self {
-            ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
+        let result = match self.kind {
+            ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
                 ref bound_generic_params,
                 ref bounded_ty,
                 ref bounds,
@@ -482,12 +482,11 @@ impl Rewrite for ast::WherePredicate {
 
                 rewrite_assign_rhs(context, lhs, bounds, &RhsAssignKind::Bounds, shape)?
             }
-            ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
+            ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
                 ref lifetime,
                 ref bounds,
-                span,
-            }) => rewrite_bounded_lifetime(lifetime, bounds, span, context, shape)?,
-            ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
+            }) => rewrite_bounded_lifetime(lifetime, bounds, self.span, context, shape)?,
+            ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate {
                 ref lhs_ty,
                 ref rhs_ty,
                 ..
diff --git a/src/tools/rustfmt/tests/source/unsafe-field.rs b/src/tools/rustfmt/tests/source/unsafe-field.rs
new file mode 100644
index 00000000000..35cf40a22d3
--- /dev/null
+++ b/src/tools/rustfmt/tests/source/unsafe-field.rs
@@ -0,0 +1,16 @@
+struct Foo {
+    unsafe
+    field: (),
+}
+
+enum Bar {
+    Variant {
+        unsafe
+        field: (),
+    },
+}
+
+union Baz {
+    unsafe
+    field: (),
+}
diff --git a/src/tools/rustfmt/tests/target/unsafe-field.rs b/src/tools/rustfmt/tests/target/unsafe-field.rs
new file mode 100644
index 00000000000..fc7fd3750c6
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/unsafe-field.rs
@@ -0,0 +1,11 @@
+struct Foo {
+    unsafe field: (),
+}
+
+enum Bar {
+    Variant { unsafe field: () },
+}
+
+union Baz {
+    unsafe field: (),
+}
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 932a58788e0..ac82a17e145 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -2756,7 +2756,6 @@ ui/lint/issue-57410-1.rs
 ui/lint/issue-57410.rs
 ui/lint/issue-63364.rs
 ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs
-ui/lint/issue-79546-fuel-ice.rs
 ui/lint/issue-79744.rs
 ui/lint/issue-81218.rs
 ui/lint/issue-83477.rs
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 6394a1463b0..35cda17e168 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -337,12 +337,16 @@ pub fn check(path: &Path, bad: &mut bool) {
         .case_insensitive(true)
         .build()
         .unwrap();
-    let style_file = Path::new(file!());
+
+    // In some cases, a style check would be triggered by its own implementation
+    // or comments. A simple workaround is to just allowlist this file.
+    let this_file = Path::new(file!());
+
     walk(path, skip, &mut |entry, contents| {
         let file = entry.path();
         let filename = file.file_name().unwrap().to_string_lossy();
 
-        let is_style_file = filename.ends_with(".css");
+        let is_css_file = filename.ends_with(".css");
         let under_rustfmt = filename.ends_with(".rs") &&
             // This list should ideally be sourced from rustfmt.toml but we don't want to add a toml
             // parser to tidy.
@@ -405,13 +409,13 @@ pub fn check(path: &Path, bad: &mut bool) {
         let mut comment_block: Option<(usize, usize)> = None;
         let is_test = file.components().any(|c| c.as_os_str() == "tests")
             || file.file_stem().unwrap() == "tests";
-        let is_style = file.ends_with(style_file) || style_file.ends_with(file);
-        let is_style_test =
-            is_test && file.parent().unwrap().ends_with(style_file.with_extension(""));
+        let is_this_file = file.ends_with(this_file) || this_file.ends_with(file);
+        let is_test_for_this_file =
+            is_test && file.parent().unwrap().ends_with(this_file.with_extension(""));
         // scanning the whole file for multiple needles at once is more efficient than
         // executing lines times needles separate searches.
         let any_problematic_line =
-            !is_style && !is_style_test && problematic_regex.is_match(contents);
+            !is_this_file && !is_test_for_this_file && problematic_regex.is_match(contents);
         for (i, line) in contents.split('\n').enumerate() {
             if line.is_empty() {
                 if i == 0 {
@@ -458,19 +462,19 @@ pub fn check(path: &Path, bad: &mut bool) {
                     "line longer than {max_columns} chars"
                 );
             }
-            if !is_style_file && line.contains('\t') {
+            if !is_css_file && line.contains('\t') {
                 suppressible_tidy_err!(err, skip_tab, "tab character");
             }
             if line.ends_with(' ') || line.ends_with('\t') {
                 suppressible_tidy_err!(err, skip_end_whitespace, "trailing whitespace");
             }
-            if is_style_file && line.starts_with(' ') {
+            if is_css_file && line.starts_with(' ') {
                 err("CSS files use tabs for indent");
             }
             if line.contains('\r') {
                 suppressible_tidy_err!(err, skip_cr, "CR character");
             }
-            if !is_style {
+            if !is_this_file {
                 // Allow using TODO in diagnostic suggestions by marking the
                 // relevant line with `// ignore-tidy-todo`.
                 if trimmed.contains("TODO") && !trimmed.contains("ignore-tidy-todo") {
diff --git a/src/version b/src/version
index bd0f9e6c28f..f288d11142d 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.84.0
+1.85.0
diff --git a/tests/assembly/asm/s390x-types.rs b/tests/assembly/asm/s390x-types.rs
index b1522198a08..3da22d6c77b 100644
--- a/tests/assembly/asm/s390x-types.rs
+++ b/tests/assembly/asm/s390x-types.rs
@@ -1,10 +1,13 @@
-//@ revisions: s390x
+//@ revisions: s390x s390x_vector
 //@ assembly-output: emit-asm
 //@[s390x] compile-flags: --target s390x-unknown-linux-gnu
 //@[s390x] needs-llvm-components: systemz
+//@[s390x_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector
+//@[s390x_vector] needs-llvm-components: systemz
 //@ compile-flags: -Zmerge-functions=disabled
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, f128)]
+#![cfg_attr(s390x_vector, feature(asm_experimental_reg))]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
@@ -27,16 +30,39 @@ trait Sized {}
 #[lang = "copy"]
 trait Copy {}
 
+impl<T: Copy, const N: usize> Copy for [T; N] {}
+
 type ptr = *const i32;
 
+#[repr(simd)]
+pub struct i8x16([i8; 16]);
+#[repr(simd)]
+pub struct i16x8([i16; 8]);
+#[repr(simd)]
+pub struct i32x4([i32; 4]);
+#[repr(simd)]
+pub struct i64x2([i64; 2]);
+#[repr(simd)]
+pub struct f32x4([f32; 4]);
+#[repr(simd)]
+pub struct f64x2([f64; 2]);
+
 impl Copy for i8 {}
 impl Copy for u8 {}
 impl Copy for i16 {}
 impl Copy for i32 {}
 impl Copy for i64 {}
+impl Copy for i128 {}
 impl Copy for f32 {}
 impl Copy for f64 {}
+impl Copy for f128 {}
 impl Copy for ptr {}
+impl Copy for i8x16 {}
+impl Copy for i16x8 {}
+impl Copy for i32x4 {}
+impl Copy for i64x2 {}
+impl Copy for f32x4 {}
+impl Copy for f64x2 {}
 
 extern "C" {
     fn extern_func();
@@ -65,7 +91,6 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
 // CHECK: #APP
 // CHECK: brasl %r14, extern_func
 // CHECK: #NO_APP
-#[cfg(s390x)]
 #[no_mangle]
 pub unsafe fn sym_fn_32() {
     asm!("brasl %r14, {}", sym extern_func);
@@ -146,6 +171,90 @@ check!(reg_f64, f64, freg, "ldr");
 // CHECK: #NO_APP
 check!(reg_ptr, ptr, reg, "lgr");
 
+// s390x_vector-LABEL: vreg_i8x16:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_i8x16, i8x16, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_i16x8:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_i16x8, i16x8, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_i32x4:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_i32x4, i32x4, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_i64x2:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_i64x2, i64x2, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_f32x4:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_f32x4, f32x4, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_f64x2:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_f64x2, f64x2, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_i32:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_i32, i32, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_i64:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_i64, i64, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_i128:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_i128, i128, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_f32:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_f32, f32, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_f64:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_f64, f64, vreg, "vlr");
+
+// s390x_vector-LABEL: vreg_f128:
+// s390x_vector: #APP
+// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check!(vreg_f128, f128, vreg, "vlr");
+
 // CHECK-LABEL: r0_i8:
 // CHECK: #APP
 // CHECK: lr %r0, %r0
@@ -181,3 +290,87 @@ check_reg!(f0_f32, f32, "f0", "ler");
 // CHECK: ldr %f0, %f0
 // CHECK: #NO_APP
 check_reg!(f0_f64, f64, "f0", "ldr");
+
+// s390x_vector-LABEL: v0_i8x16:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_i8x16, i8x16, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_i16x8:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_i16x8, i16x8, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_i32x4:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_i32x4, i32x4, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_i64x2:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_i64x2, i64x2, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_f32x4:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_f32x4, f32x4, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_f64x2:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_f64x2, f64x2, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_i32:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_i32, i32, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_i64:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_i64, i64, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_i128:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_i128, i128, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_f32:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_f32, f32, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_f64:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_f64, f64, "v0", "vlr");
+
+// s390x_vector-LABEL: v0_f128:
+// s390x_vector: #APP
+// s390x_vector: vlr %v0, %v0
+// s390x_vector: #NO_APP
+#[cfg(s390x_vector)]
+check_reg!(v0_f128, f128, "v0", "vlr");
diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs
index 1e9f2ee59b4..c4317752920 100644
--- a/tests/auxiliary/minicore.rs
+++ b/tests/auxiliary/minicore.rs
@@ -45,6 +45,7 @@ impl_marker_trait!(
 impl<'a, T: ?Sized> Copy for &'a T {}
 impl<T: ?Sized> Copy for *const T {}
 impl<T: ?Sized> Copy for *mut T {}
+impl<T: Copy, const N: usize> Copy for [T; N] {}
 
 #[lang = "phantom_data"]
 pub struct PhantomData<T: ?Sized>;
diff --git a/tests/codegen/aarch64-softfloat.rs b/tests/codegen/aarch64-softfloat.rs
new file mode 100644
index 00000000000..85380a6c472
--- /dev/null
+++ b/tests/codegen/aarch64-softfloat.rs
@@ -0,0 +1,48 @@
+//@ compile-flags: --target aarch64-unknown-none-softfloat -Zmerge-functions=disabled
+//@ needs-llvm-components: aarch64
+#![crate_type = "lib"]
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+impl Copy for f32 {}
+impl Copy for f64 {}
+
+// CHECK: i64 @pass_f64_C(i64 {{[^,]*}})
+#[no_mangle]
+extern "C" fn pass_f64_C(x: f64) -> f64 {
+    x
+}
+
+// CHECK: i64 @pass_f32_pair_C(i64 {{[^,]*}})
+#[no_mangle]
+extern "C" fn pass_f32_pair_C(x: (f32, f32)) -> (f32, f32) {
+    x
+}
+
+// CHECK: [2 x i64] @pass_f64_pair_C([2 x i64] {{[^,]*}})
+#[no_mangle]
+extern "C" fn pass_f64_pair_C(x: (f64, f64)) -> (f64, f64) {
+    x
+}
+
+// CHECK: i64 @pass_f64_Rust(i64 {{[^,]*}})
+#[no_mangle]
+fn pass_f64_Rust(x: f64) -> f64 {
+    x
+}
+
+// CHECK: i64 @pass_f32_pair_Rust(i64 {{[^,]*}})
+#[no_mangle]
+fn pass_f32_pair_Rust(x: (f32, f32)) -> (f32, f32) {
+    x
+}
+
+// CHECK: void @pass_f64_pair_Rust(ptr {{.*}}%{{[^ ]+}}, ptr {{.*}}%{{[^ ]+}})
+#[no_mangle]
+fn pass_f64_pair_Rust(x: (f64, f64)) -> (f64, f64) {
+    x
+}
diff --git a/tests/codegen/asm/goto.rs b/tests/codegen/asm/goto.rs
index e522d0da5b4..c40a43fbe1b 100644
--- a/tests/codegen/asm/goto.rs
+++ b/tests/codegen/asm/goto.rs
@@ -2,21 +2,10 @@
 //@ only-x86_64
 
 #![crate_type = "rlib"]
-#![feature(asm_goto)]
+#![feature(asm_goto, asm_goto_with_outputs)]
 
 use std::arch::asm;
 
-#[no_mangle]
-pub extern "C" fn panicky() {}
-
-struct Foo;
-
-impl Drop for Foo {
-    fn drop(&mut self) {
-        println!();
-    }
-}
-
 // CHECK-LABEL: @asm_goto
 #[no_mangle]
 pub unsafe fn asm_goto() {
@@ -38,14 +27,37 @@ pub unsafe fn asm_goto_with_outputs() -> u64 {
     out
 }
 
+// CHECK-LABEL: @asm_goto_with_outputs_use_in_label
+#[no_mangle]
+pub unsafe fn asm_goto_with_outputs_use_in_label() -> u64 {
+    let out: u64;
+    // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect "
+    // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]]
+    asm!("{} /* {} */", out(reg) out, label { return out; });
+    // CHECK: [[JUMPBB]]:
+    // CHECK-NEXT: [[RET:%.+]] = phi i64 [ 1, %[[FALLTHROUGHBB]] ], [ [[RES]], %start ]
+    // CHECK-NEXT: ret i64 [[RET]]
+    1
+}
+
 // CHECK-LABEL: @asm_goto_noreturn
 #[no_mangle]
 pub unsafe fn asm_goto_noreturn() -> u64 {
-    let out: u64;
     // CHECK: callbr void asm sideeffect alignstack inteldialect "
     // CHECK-NEXT: to label %unreachable [label %[[JUMPBB:[a-b0-9]+]]]
     asm!("jmp {}", label { return 1; }, options(noreturn));
     // CHECK: [[JUMPBB]]:
     // CHECK-NEXT: ret i64 1
+}
+
+// CHECK-LABEL: @asm_goto_noreturn_with_outputs
+#[no_mangle]
+pub unsafe fn asm_goto_noreturn_with_outputs() -> u64 {
+    let out: u64;
+    // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect "
+    // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]]
+    asm!("mov {}, 1", "jmp {}", out(reg) out, label { return out; });
+    // CHECK: [[JUMPBB]]:
+    // CHECK-NEXT: ret i64 [[RES]]
     out
 }
diff --git a/tests/codegen/sanitizer/no-sanitize.rs b/tests/codegen/sanitizer/no-sanitize.rs
index 47d3fd83f11..2a309f6b9c6 100644
--- a/tests/codegen/sanitizer/no-sanitize.rs
+++ b/tests/codegen/sanitizer/no-sanitize.rs
@@ -7,6 +7,16 @@
 #![crate_type = "lib"]
 #![feature(no_sanitize)]
 
+// CHECK:     @UNSANITIZED = constant{{.*}} no_sanitize_address
+// CHECK-NOT: @__asan_global_UNSANITIZED
+#[no_mangle]
+#[no_sanitize(address)]
+pub static UNSANITIZED: u32 = 0;
+
+// CHECK: @__asan_global_SANITIZED
+#[no_mangle]
+pub static SANITIZED: u32 = 0;
+
 // CHECK-LABEL: ; no_sanitize::unsanitized
 // CHECK-NEXT:  ; Function Attrs:
 // CHECK-NOT:   sanitize_address
diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map
index adf4aba0c23..fa20c8cf6d7 100644
--- a/tests/coverage/closure.cov-map
+++ b/tests/coverage/closure.cov-map
@@ -140,17 +140,19 @@ Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
 Highest counter ID seen: c1
 
-Function name: closure::main::{closure#18} (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 0d, 02, 1c, 00, 02, 1d, 02, 12, 00, 02, 11, 00, 12, 00, 01, 11, 01, 0e]
+Function name: closure::main::{closure#18}
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 19, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 0
+Number of expressions: 1
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 4
-- Code(Zero) at (prev + 25, 13) to (start + 2, 28)
-- Code(Zero) at (prev + 2, 29) to (start + 2, 18)
-- Code(Zero) at (prev + 2, 17) to (start + 0, 18)
-- Code(Zero) at (prev + 1, 17) to (start + 1, 14)
-Highest counter ID seen: (none)
+- Code(Counter(0)) at (prev + 25, 13) to (start + 2, 28)
+- Code(Counter(1)) at (prev + 2, 29) to (start + 2, 18)
+- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 18)
+    = (c0 - c1)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 14)
+Highest counter ID seen: c1
 
 Function name: closure::main::{closure#19}
 Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 43, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e]
diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map
index a8ad17574ba..64870c434b3 100644
--- a/tests/coverage/issue-84561.cov-map
+++ b/tests/coverage/issue-84561.cov-map
@@ -59,59 +59,69 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: issue_84561::test3
-Raw bytes (375): 0x[01, 01, 31, 05, 09, 0d, 00, 15, 19, 12, 00, 15, 19, 21, 00, 1e, 00, 21, 00, 31, 00, 3d, 00, 2e, 45, 3d, 00, 42, 49, 45, 00, 3f, 51, 42, 49, 45, 00, 7a, 55, 51, 00, 7a, 55, 51, 00, 77, 5d, 7a, 55, 51, 00, 77, 61, 7a, 55, 51, 00, 72, 65, 77, 61, 7a, 55, 51, 00, 75, be, 01, c2, 01, 79, 69, 6d, 69, 6d, 69, 6d, c2, 01, 00, 69, 6d, c2, 01, 79, 69, 6d, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, b6, 01, 00, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 12, 02, 05, 00, 1f, 0e, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 1e, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 1a, 04, 09, 05, 06, 31, 06, 05, 03, 06, 22, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 2e, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 2a, 05, 09, 03, 0a, 3f, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 3a, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 77, 03, 05, 00, 0f, 77, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 56, 02, 0d, 00, 13, 72, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 6e, 02, 0d, 00, 13, bb, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, c2, 01, 02, 0d, 00, 17, c2, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 92, 01, 02, 15, 00, 1b, be, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, b6, 01, 02, 05, 00, 0f, b2, 01, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02]
+Raw bytes (414): 0x[01, 01, 3b, 05, 09, 0d, 11, 15, 19, 1e, 1d, 15, 19, 1a, 21, 1e, 1d, 15, 19, 25, 2d, 21, 25, 29, 35, 32, 29, 21, 25, 31, 39, 3d, 41, 42, 45, 3d, 41, 66, 49, 45, 4d, 63, 51, 66, 49, 45, 4d, 5e, 55, 63, 51, 66, 49, 45, 4d, 9e, 01, 55, 51, 59, 9e, 01, 55, 51, 59, 9b, 01, 5d, 9e, 01, 55, 51, 59, 9b, 01, 61, 9e, 01, 55, 51, 59, 96, 01, 65, 9b, 01, 61, 9e, 01, 55, 51, 59, 75, e2, 01, e6, 01, 79, 69, 6d, 69, 6d, 69, 6d, e6, 01, 00, 69, 6d, e6, 01, 79, 69, 6d, df, 01, 7d, 75, e2, 01, e6, 01, 79, 69, 6d, da, 01, 81, 01, df, 01, 7d, 75, e2, 01, e6, 01, 79, 69, 6d, 81, 01, 85, 01, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 1e, 02, 05, 00, 1f, 1a, 01, 05, 00, 0f, 16, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 25, 03, 20, 00, 30, 2d, 00, 33, 00, 41, 22, 00, 4b, 00, 5a, 32, 01, 05, 00, 0f, 29, 05, 09, 03, 10, 35, 05, 0d, 00, 1b, 2a, 02, 0d, 00, 1c, 2e, 04, 09, 05, 06, 31, 06, 05, 03, 06, 36, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 42, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 3e, 05, 09, 03, 0a, 63, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 59, 03, 0d, 00, 1d, 5e, 03, 09, 00, 13, 5a, 03, 0d, 00, 1d, 9b, 01, 03, 05, 00, 0f, 9b, 01, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 7a, 02, 0d, 00, 13, 96, 01, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 92, 01, 02, 0d, 00, 13, df, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, e6, 01, 02, 0d, 00, 17, e6, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, b6, 01, 02, 15, 00, 1b, e2, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, da, 01, 02, 05, 00, 0f, d6, 01, 03, 09, 00, 22, 81, 01, 02, 05, 00, 0f, ea, 01, 03, 09, 00, 2c, 85, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 49
+Number of expressions: 59
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(3), rhs = Zero
+- expression 1 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 2 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 3 operands: lhs = Expression(4, Sub), rhs = Zero
+- expression 3 operands: lhs = Expression(7, Sub), rhs = Counter(7)
 - expression 4 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 5 operands: lhs = Counter(8), rhs = Zero
-- expression 6 operands: lhs = Expression(7, Sub), rhs = Zero
-- expression 7 operands: lhs = Counter(8), rhs = Zero
-- expression 8 operands: lhs = Counter(12), rhs = Zero
-- expression 9 operands: lhs = Counter(15), rhs = Zero
-- expression 10 operands: lhs = Expression(11, Sub), rhs = Counter(17)
-- expression 11 operands: lhs = Counter(15), rhs = Zero
-- expression 12 operands: lhs = Expression(16, Sub), rhs = Counter(18)
-- expression 13 operands: lhs = Counter(17), rhs = Zero
-- expression 14 operands: lhs = Expression(15, Add), rhs = Counter(20)
-- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(18)
-- expression 16 operands: lhs = Counter(17), rhs = Zero
-- expression 17 operands: lhs = Expression(30, Sub), rhs = Counter(21)
-- expression 18 operands: lhs = Counter(20), rhs = Zero
-- expression 19 operands: lhs = Expression(30, Sub), rhs = Counter(21)
-- expression 20 operands: lhs = Counter(20), rhs = Zero
-- expression 21 operands: lhs = Expression(29, Add), rhs = Counter(23)
-- expression 22 operands: lhs = Expression(30, Sub), rhs = Counter(21)
-- expression 23 operands: lhs = Counter(20), rhs = Zero
-- expression 24 operands: lhs = Expression(29, Add), rhs = Counter(24)
-- expression 25 operands: lhs = Expression(30, Sub), rhs = Counter(21)
-- expression 26 operands: lhs = Counter(20), rhs = Zero
-- expression 27 operands: lhs = Expression(28, Sub), rhs = Counter(25)
-- expression 28 operands: lhs = Expression(29, Add), rhs = Counter(24)
-- expression 29 operands: lhs = Expression(30, Sub), rhs = Counter(21)
-- expression 30 operands: lhs = Counter(20), rhs = Zero
-- expression 31 operands: lhs = Counter(29), rhs = Expression(47, Sub)
-- expression 32 operands: lhs = Expression(48, Sub), rhs = Counter(30)
-- expression 33 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 34 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 35 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 36 operands: lhs = Expression(48, Sub), rhs = Zero
-- expression 37 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 38 operands: lhs = Expression(48, Sub), rhs = Counter(30)
-- expression 39 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 40 operands: lhs = Expression(46, Add), rhs = Counter(31)
-- expression 41 operands: lhs = Counter(29), rhs = Expression(47, Sub)
-- expression 42 operands: lhs = Expression(48, Sub), rhs = Counter(30)
+- expression 5 operands: lhs = Expression(6, Sub), rhs = Counter(8)
+- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(7)
+- expression 7 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 8 operands: lhs = Counter(9), rhs = Counter(11)
+- expression 9 operands: lhs = Counter(8), rhs = Counter(9)
+- expression 10 operands: lhs = Counter(10), rhs = Counter(13)
+- expression 11 operands: lhs = Expression(12, Sub), rhs = Counter(10)
+- expression 12 operands: lhs = Counter(8), rhs = Counter(9)
+- expression 13 operands: lhs = Counter(12), rhs = Counter(14)
+- expression 14 operands: lhs = Counter(15), rhs = Counter(16)
+- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(17)
+- expression 16 operands: lhs = Counter(15), rhs = Counter(16)
+- expression 17 operands: lhs = Expression(25, Sub), rhs = Counter(18)
+- expression 18 operands: lhs = Counter(17), rhs = Counter(19)
+- expression 19 operands: lhs = Expression(24, Add), rhs = Counter(20)
+- expression 20 operands: lhs = Expression(25, Sub), rhs = Counter(18)
+- expression 21 operands: lhs = Counter(17), rhs = Counter(19)
+- expression 22 operands: lhs = Expression(23, Sub), rhs = Counter(21)
+- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(20)
+- expression 24 operands: lhs = Expression(25, Sub), rhs = Counter(18)
+- expression 25 operands: lhs = Counter(17), rhs = Counter(19)
+- expression 26 operands: lhs = Expression(39, Sub), rhs = Counter(21)
+- expression 27 operands: lhs = Counter(20), rhs = Counter(22)
+- expression 28 operands: lhs = Expression(39, Sub), rhs = Counter(21)
+- expression 29 operands: lhs = Counter(20), rhs = Counter(22)
+- expression 30 operands: lhs = Expression(38, Add), rhs = Counter(23)
+- expression 31 operands: lhs = Expression(39, Sub), rhs = Counter(21)
+- expression 32 operands: lhs = Counter(20), rhs = Counter(22)
+- expression 33 operands: lhs = Expression(38, Add), rhs = Counter(24)
+- expression 34 operands: lhs = Expression(39, Sub), rhs = Counter(21)
+- expression 35 operands: lhs = Counter(20), rhs = Counter(22)
+- expression 36 operands: lhs = Expression(37, Sub), rhs = Counter(25)
+- expression 37 operands: lhs = Expression(38, Add), rhs = Counter(24)
+- expression 38 operands: lhs = Expression(39, Sub), rhs = Counter(21)
+- expression 39 operands: lhs = Counter(20), rhs = Counter(22)
+- expression 40 operands: lhs = Counter(29), rhs = Expression(56, Sub)
+- expression 41 operands: lhs = Expression(57, Sub), rhs = Counter(30)
+- expression 42 operands: lhs = Counter(26), rhs = Counter(27)
 - expression 43 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 44 operands: lhs = Expression(45, Sub), rhs = Zero
-- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(31)
-- expression 46 operands: lhs = Counter(29), rhs = Expression(47, Sub)
-- expression 47 operands: lhs = Expression(48, Sub), rhs = Counter(30)
+- expression 44 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 45 operands: lhs = Expression(57, Sub), rhs = Zero
+- expression 46 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 47 operands: lhs = Expression(57, Sub), rhs = Counter(30)
 - expression 48 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 49 operands: lhs = Expression(55, Add), rhs = Counter(31)
+- expression 50 operands: lhs = Counter(29), rhs = Expression(56, Sub)
+- expression 51 operands: lhs = Expression(57, Sub), rhs = Counter(30)
+- expression 52 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 53 operands: lhs = Expression(54, Sub), rhs = Counter(32)
+- expression 54 operands: lhs = Expression(55, Add), rhs = Counter(31)
+- expression 55 operands: lhs = Counter(29), rhs = Expression(56, Sub)
+- expression 56 operands: lhs = Expression(57, Sub), rhs = Counter(30)
+- expression 57 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 58 operands: lhs = Counter(32), rhs = Counter(33)
 Number of file 0 mappings: 51
 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28)
 - Code(Counter(1)) at (prev + 4, 9) to (start + 1, 28)
@@ -119,73 +129,78 @@ Number of file 0 mappings: 51
     = (c1 - c2)
 - Code(Counter(3)) at (prev + 5, 5) to (start + 0, 31)
 - Code(Expression(1, Sub)) at (prev + 1, 5) to (start + 0, 31)
-    = (c3 - Zero)
+    = (c3 - c4)
 - Code(Counter(5)) at (prev + 1, 9) to (start + 1, 28)
-- Code(Expression(4, Sub)) at (prev + 2, 5) to (start + 0, 31)
+- Code(Expression(7, Sub)) at (prev + 2, 5) to (start + 0, 31)
     = (c5 - c6)
-- Code(Expression(3, Sub)) at (prev + 1, 5) to (start + 0, 15)
-    = ((c5 - c6) - Zero)
-- Code(Zero) at (prev + 0, 32) to (start + 0, 48)
+- Code(Expression(6, Sub)) at (prev + 1, 5) to (start + 0, 15)
+    = ((c5 - c6) - c7)
+- Code(Expression(5, Sub)) at (prev + 0, 32) to (start + 0, 48)
+    = (((c5 - c6) - c7) - c8)
 - Code(Counter(8)) 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(Expression(7, Sub)) at (prev + 1, 5) to (start + 0, 15)
-    = (c8 - Zero)
-- 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(Expression(6, Sub)) at (prev + 4, 9) to (start + 5, 6)
-    = ((c8 - Zero) - Zero)
+- Code(Counter(9)) at (prev + 3, 32) to (start + 0, 48)
+- Code(Counter(11)) at (prev + 0, 51) to (start + 0, 65)
+- Code(Expression(8, Sub)) at (prev + 0, 75) to (start + 0, 90)
+    = (c9 - c11)
+- Code(Expression(12, Sub)) at (prev + 1, 5) to (start + 0, 15)
+    = (c8 - c9)
+- Code(Counter(10)) at (prev + 5, 9) to (start + 3, 16)
+- Code(Counter(13)) at (prev + 5, 13) to (start + 0, 27)
+- Code(Expression(10, Sub)) at (prev + 2, 13) to (start + 0, 28)
+    = (c10 - c13)
+- Code(Expression(11, Sub)) at (prev + 4, 9) to (start + 5, 6)
+    = ((c8 - c9) - c10)
 - Code(Counter(12)) at (prev + 6, 5) to (start + 3, 6)
-- Code(Expression(8, Sub)) at (prev + 4, 5) to (start + 3, 6)
-    = (c12 - Zero)
+- Code(Expression(13, Sub)) at (prev + 4, 5) to (start + 3, 6)
+    = (c12 - c14)
 - Code(Counter(15)) at (prev + 4, 9) to (start + 4, 6)
-- Code(Expression(11, Sub)) at (prev + 5, 8) to (start + 0, 15)
-    = (c15 - Zero)
+- Code(Expression(16, Sub)) at (prev + 5, 8) to (start + 0, 15)
+    = (c15 - c16)
 - Code(Counter(17)) at (prev + 1, 9) to (start + 3, 10)
-- Code(Expression(10, Sub)) at (prev + 5, 9) to (start + 3, 10)
-    = ((c15 - Zero) - c17)
-- Code(Expression(15, Add)) at (prev + 5, 8) to (start + 0, 15)
-    = ((c17 - Zero) + c18)
+- Code(Expression(15, Sub)) at (prev + 5, 9) to (start + 3, 10)
+    = ((c15 - c16) - c17)
+- Code(Expression(24, Add)) at (prev + 5, 8) to (start + 0, 15)
+    = ((c17 - c19) + c18)
 - Code(Counter(20)) at (prev + 1, 9) to (start + 0, 19)
-- Code(Zero) at (prev + 3, 13) to (start + 0, 29)
-- Code(Expression(14, Sub)) at (prev + 3, 9) to (start + 0, 19)
-    = (((c17 - Zero) + c18) - c20)
-- Code(Zero) at (prev + 3, 13) to (start + 0, 29)
-- Code(Expression(29, Add)) at (prev + 3, 5) to (start + 0, 15)
-    = ((c20 - Zero) + c21)
-- Code(Expression(29, Add)) at (prev + 1, 12) to (start + 0, 19)
-    = ((c20 - Zero) + c21)
+- Code(Counter(22)) at (prev + 3, 13) to (start + 0, 29)
+- Code(Expression(23, Sub)) at (prev + 3, 9) to (start + 0, 19)
+    = (((c17 - c19) + c18) - c20)
+- Code(Expression(22, Sub)) at (prev + 3, 13) to (start + 0, 29)
+    = ((((c17 - c19) + c18) - c20) - c21)
+- Code(Expression(38, Add)) at (prev + 3, 5) to (start + 0, 15)
+    = ((c20 - c22) + c21)
+- Code(Expression(38, Add)) at (prev + 1, 12) to (start + 0, 19)
+    = ((c20 - c22) + c21)
 - Code(Counter(23)) at (prev + 1, 13) to (start + 0, 19)
-- Code(Expression(21, Sub)) at (prev + 2, 13) to (start + 0, 19)
-    = (((c20 - Zero) + c21) - c23)
-- Code(Expression(28, Sub)) at (prev + 4, 5) to (start + 2, 19)
-    = (((c20 - Zero) + c21) - c24)
+- Code(Expression(30, Sub)) at (prev + 2, 13) to (start + 0, 19)
+    = (((c20 - c22) + c21) - c23)
+- Code(Expression(37, Sub)) at (prev + 4, 5) to (start + 2, 19)
+    = (((c20 - c22) + c21) - c24)
 - Code(Counter(25)) at (prev + 3, 13) to (start + 0, 19)
-- Code(Expression(27, Sub)) at (prev + 2, 13) to (start + 0, 19)
-    = ((((c20 - Zero) + c21) - c24) - c25)
-- Code(Expression(46, Add)) at (prev + 3, 5) to (start + 0, 15)
+- Code(Expression(36, Sub)) at (prev + 2, 13) to (start + 0, 19)
+    = ((((c20 - c22) + c21) - c24) - c25)
+- Code(Expression(55, Add)) at (prev + 3, 5) to (start + 0, 15)
     = (c29 + ((c26 - c27) - c30))
 - Code(Counter(26)) at (prev + 1, 12) to (start + 0, 19)
 - Code(Counter(27)) at (prev + 1, 13) to (start + 3, 14)
 - Code(Counter(29)) at (prev + 4, 13) to (start + 0, 19)
-- Code(Expression(48, Sub)) at (prev + 2, 13) to (start + 0, 23)
+- Code(Expression(57, Sub)) at (prev + 2, 13) to (start + 0, 23)
     = (c26 - c27)
-- Code(Expression(48, Sub)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Expression(57, Sub)) at (prev + 1, 20) to (start + 0, 27)
     = (c26 - c27)
 - Code(Zero) at (prev + 1, 21) to (start + 0, 27)
-- Code(Expression(36, Sub)) at (prev + 2, 21) to (start + 0, 27)
+- Code(Expression(45, Sub)) at (prev + 2, 21) to (start + 0, 27)
     = ((c26 - c27) - Zero)
-- Code(Expression(47, Sub)) at (prev + 4, 13) to (start + 0, 19)
+- Code(Expression(56, Sub)) at (prev + 4, 13) to (start + 0, 19)
     = ((c26 - c27) - c30)
 - Code(Counter(31)) at (prev + 3, 9) to (start + 0, 25)
-- Code(Expression(45, Sub)) at (prev + 2, 5) to (start + 0, 15)
+- Code(Expression(54, Sub)) at (prev + 2, 5) to (start + 0, 15)
     = ((c29 + ((c26 - c27) - c30)) - c31)
-- Code(Expression(44, Sub)) at (prev + 3, 9) to (start + 0, 34)
-    = (((c29 + ((c26 - c27) - c30)) - c31) - Zero)
-- 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: c31
+- Code(Expression(53, Sub)) at (prev + 3, 9) to (start + 0, 34)
+    = (((c29 + ((c26 - c27) - c30)) - c31) - c32)
+- Code(Counter(32)) at (prev + 2, 5) to (start + 0, 15)
+- Code(Expression(58, Sub)) at (prev + 3, 9) to (start + 0, 44)
+    = (c32 - c33)
+- Code(Counter(33)) at (prev + 2, 1) to (start + 0, 2)
+Highest counter ID seen: c33
 
diff --git a/tests/coverage/no-core.cov-map b/tests/coverage/no-core.cov-map
new file mode 100644
index 00000000000..3a1ca4745c7
--- /dev/null
+++ b/tests/coverage/no-core.cov-map
@@ -0,0 +1,9 @@
+Function name: no_core::main
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 01, 00, 0d]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 13)
+Highest counter ID seen: c0
+
diff --git a/tests/coverage/no-core.coverage b/tests/coverage/no-core.coverage
new file mode 100644
index 00000000000..8b890609568
--- /dev/null
+++ b/tests/coverage/no-core.coverage
@@ -0,0 +1,13 @@
+   LL|       |#![feature(no_core)]
+   LL|       |#![no_core]
+   LL|       |//@ edition: 2021
+   LL|       |
+   LL|       |// Test that coverage instrumentation works for `#![no_core]` crates.
+   LL|       |
+   LL|       |// For this test, we pull in std anyway, to avoid having to set up our own
+   LL|       |// no-core or no-std environment. What's important is that the compiler allows
+   LL|       |// coverage for a crate with the `#![no_core]` annotation.
+   LL|       |extern crate std;
+   LL|       |
+   LL|      1|fn main() {}
+
diff --git a/tests/coverage/no-core.rs b/tests/coverage/no-core.rs
new file mode 100644
index 00000000000..206222902fc
--- /dev/null
+++ b/tests/coverage/no-core.rs
@@ -0,0 +1,12 @@
+#![feature(no_core)]
+#![no_core]
+//@ edition: 2021
+
+// Test that coverage instrumentation works for `#![no_core]` crates.
+
+// For this test, we pull in std anyway, to avoid having to set up our own
+// no-core or no-std environment. What's important is that the compiler allows
+// coverage for a crate with the `#![no_core]` annotation.
+extern crate std;
+
+fn main() {}
diff --git a/tests/crashes/124350.rs b/tests/crashes/124350.rs
deleted file mode 100644
index d6038f280cf..00000000000
--- a/tests/crashes/124350.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: #124350
-
-struct Node<const D: usize> {}
-
-impl Node<D>
-where
-    SmallVec<{ D * 2 }>:,
-{
-    fn new() -> Self {
-        let mut node = Node::new();
-        (&a, 0)();
-
-        node
-    }
-}
-
-struct SmallVec<T1, T2> {}
diff --git a/tests/crashes/124751.rs b/tests/crashes/124751.rs
index f15e39965d3..1372b97233d 100644
--- a/tests/crashes/124751.rs
+++ b/tests/crashes/124751.rs
@@ -1,5 +1,5 @@
 //@ known-bug: rust-lang/rust#124751
-//@ compile-flags: -Zunstable-options --edition=2024
+//@ edition: 2024
 
 #![feature(gen_blocks)]
 
diff --git a/tests/crashes/125758.rs b/tests/crashes/125758.rs
deleted file mode 100644
index 86c3b80abab..00000000000
--- a/tests/crashes/125758.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-//@ known-bug: rust-lang/rust#125758
-#![feature(impl_trait_in_assoc_type)]
-
-trait Trait: Sized {
-    type Assoc2;
-}
-
-impl Trait for Bar {
-    type Assoc2 = impl std::fmt::Debug;
-}
-
-struct Foo {
-    field: <Bar as Trait>::Assoc2,
-}
-
-enum Bar {
-    C = 42,
-    D = 99,
-}
-
-static BAR: u8 = 42;
-
-static FOO2: (&Foo, &<Bar as Trait>::Assoc2) =
-    unsafe { (std::mem::transmute(&BAR), std::mem::transmute(&BAR)) };
-
-fn main() {}
diff --git a/tests/crashes/126359.rs b/tests/crashes/126359.rs
deleted file mode 100644
index 4b28c466b55..00000000000
--- a/tests/crashes/126359.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: rust-lang/rust#126359
-
-struct OppOrder<const N: u8 = 3, T = u32> {
-    arr: [T; N],
-}
-
-fn main() {
-    let _ = OppOrder::<3, u32> { arr: [0, 0, 0] };
-}
diff --git a/tests/crashes/127351.rs b/tests/crashes/127351.rs
deleted file mode 100644
index e3f41594885..00000000000
--- a/tests/crashes/127351.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: #127351
-#![feature(lazy_type_alias)]
-#![allow(incomplete_features)]
-
-struct Outer0<'a, T>(ExplicitTypeOutlives<'a, T>);
-type ExplicitTypeOutlives<'a, T: 'a> = (&'a (), T);
-
-pub struct Warns {
-    _significant_drop: ExplicitTypeOutlives,
-    field: String,
-}
-
-pub fn test(w: Warns) {
-    _ = || drop(w.field);
-}
-
-fn main() {}
diff --git a/tests/crashes/127353.rs b/tests/crashes/127353.rs
deleted file mode 100644
index 9bcb90b5c57..00000000000
--- a/tests/crashes/127353.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-//@ known-bug: #127353
-#![feature(type_alias_impl_trait)]
-trait Trait<T> {}
-type Alias<'a, U> = impl Trait<U>;
-
-fn f<'a>() -> Alias<'a, ()> {}
-
-pub enum UninhabitedVariants {
-    Tuple(Alias),
-}
-
-struct A;
-
-fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
-    match x {}
-}
-
-fn main() {}
diff --git a/tests/crashes/127742.rs b/tests/crashes/127742.rs
deleted file mode 100644
index 24add454135..00000000000
--- a/tests/crashes/127742.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ known-bug: #127742
-struct Vtable(dyn Cap);  // missing lifetime
-
-trait Cap<'a> {}
-
-union Transmute {
-    t: u64,  // ICEs with u64, u128, or usize. Correctly errors with u32.
-    u: &'static Vtable,
-}
-
-const G: &'static Vtable = unsafe { Transmute { t: 1 }.u };
diff --git a/tests/crashes/129444.rs b/tests/crashes/129444.rs
deleted file mode 100644
index b1b547b5191..00000000000
--- a/tests/crashes/129444.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ known-bug: rust-lang/rust#129444
-
-//@ compile-flags: -Znext-solver=coherence
-
-trait Trait {
-    type Assoc;
-}
-
-struct W<T: Trait>(*mut T);
-impl<T: ?Trait> Trait for W<W<W<T>>> {}
-
-trait NoOverlap {}
-impl<T: Trait<W<T>>> NoOverlap for T {}
-
-impl<T: Trait<Assoc = u32>> NoOverlap for W<T> {}
diff --git a/tests/crashes/130521.rs b/tests/crashes/130521.rs
index 7c078ab5790..ebcfacf9623 100644
--- a/tests/crashes/130521.rs
+++ b/tests/crashes/130521.rs
@@ -1,12 +1,12 @@
 //@ known-bug: #130521
 
 #![feature(dyn_compatible_for_dispatch)]
-struct Vtable(dyn Cap);
+struct Vtable(dyn Cap<'static>);
 
 trait Cap<'a> {}
 
 union Transmute {
-    t: u64,
+    t: u128,
     u: &'static Vtable,
 }
 
diff --git a/tests/crashes/131101.rs b/tests/crashes/131101.rs
deleted file mode 100644
index 3ec441101b7..00000000000
--- a/tests/crashes/131101.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: #131101
-trait Foo<const N: u8> {
-    fn do_x(&self) -> [u8; N];
-}
-
-struct Bar;
-
-impl Foo<const 3> for Bar {
-    fn do_x(&self) -> [u8; 3] {
-        [0u8; 3]
-    }
-}
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 8df262b351f..23928337bf7 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,23 +14,19 @@
   
       bb0: {
           StorageLive(_1);
--         StorageLive(_2);
+          StorageLive(_2);
 -         StorageLive(_3);
 +         nop;
-+         nop;
           _3 = const {ALLOC0: &u8};
--         _2 = copy (*_3);
-+         _2 = const 2_u8;
+          _2 = copy (*_3);
           StorageLive(_4);
           StorageLive(_5);
           _5 = const {ALLOC0: &u8};
 -         _4 = copy (*_5);
--         _1 = Add(move _2, move _4);
-+         _4 = const 2_u8;
-+         _1 = const 4_u8;
++         _4 = copy (*_3);
+          _1 = Add(move _2, move _4);
           StorageDead(_4);
--         StorageDead(_2);
-+         nop;
+          StorageDead(_2);
           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 05fec2f3303..98ba76fb765 100644
--- a/tests/mir-opt/const_prop/read_immutable_static.rs
+++ b/tests/mir-opt/const_prop/read_immutable_static.rs
@@ -6,6 +6,7 @@ static FOO: u8 = 2;
 fn main() {
     // CHECK-LABEL: fn main(
     // CHECK: debug x => [[x:_.*]];
-    // CHECK: [[x]] = const 4_u8;
+    // Disabled due to <https://github.com/rust-lang/rust/issues/130853>
+    // COM: 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 b9e269266b0..4477b4b005b 100644
--- a/tests/mir-opt/const_prop/ref_deref.main.GVN.diff
+++ b/tests/mir-opt/const_prop/ref_deref.main.GVN.diff
@@ -16,8 +16,7 @@
           StorageLive(_2);
           _4 = const main::promoted[0];
           _2 = &(*_4);
--         _1 = copy (*_2);
-+         _1 = const 4_i32;
+          _1 = copy (*_2);
           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 dcc13c9251c..bbfd70bea16 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,8 +16,7 @@
           StorageLive(_2);
           _4 = const main::promoted[0];
           _2 = &((*_4).1: i32);
--         _1 = copy (*_2);
-+         _1 = const 5_i32;
+          _1 = copy (*_2);
           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 5a48a887f93..31108e1a57f 100644
--- a/tests/mir-opt/const_prop/ref_deref_project.rs
+++ b/tests/mir-opt/const_prop/ref_deref_project.rs
@@ -5,6 +5,7 @@
 fn main() {
     // CHECK-LABEL: fn main(
     // CHECK: debug a => [[a:_.*]];
-    // CHECK: [[a]] = const 5_i32;
+    // Disabled due to <https://github.com/rust-lang/rust/issues/130853>
+    // COM: 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 41ce94eda75..8a8ea5b7e20 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
@@ -30,17 +30,16 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = Len((*_2));
+          _7 = Len((*_2));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
++         _8 = Lt(const 1_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
 -         _1 = copy (*_2)[_6];
-+         _1 = const 2_u32;
++         _1 = copy (*_2)[1 of 2];
           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 8cced96cd43..f0c844884f6 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
@@ -30,17 +30,16 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = Len((*_2));
+          _7 = Len((*_2));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
++         _8 = Lt(const 1_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
 -         _1 = copy (*_2)[_6];
-+         _1 = const 2_u32;
++         _1 = copy (*_2)[1 of 2];
           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 41ce94eda75..8a8ea5b7e20 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
@@ -30,17 +30,16 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = Len((*_2));
+          _7 = Len((*_2));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
++         _8 = Lt(const 1_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
 -         _1 = copy (*_2)[_6];
-+         _1 = const 2_u32;
++         _1 = copy (*_2)[1 of 2];
           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 8cced96cd43..f0c844884f6 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
@@ -30,17 +30,16 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = Len((*_2));
+          _7 = Len((*_2));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
++         _8 = Lt(const 1_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
 -         _1 = copy (*_2)[_6];
-+         _1 = const 2_u32;
++         _1 = copy (*_2)[1 of 2];
           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 ebd3c9e792d..498e09fbb65 100644
--- a/tests/mir-opt/const_prop/slice_len.rs
+++ b/tests/mir-opt/const_prop/slice_len.rs
@@ -8,7 +8,8 @@ fn main() {
     // CHECK-LABEL: fn main(
     // CHECK: debug a => [[a:_.*]];
     // CHECK: [[slice:_.*]] = copy {{.*}} as &[u32] (PointerCoercion(Unsize, AsCast));
-    // CHECK: assert(const true,
-    // CHECK: [[a]] = const 2_u32;
+    // Disabled due to <https://github.com/rust-lang/rust/issues/130853>
+    // COM: CHECK: assert(const true,
+    // COM: CHECK: [[a]] = const 2_u32;
     let a = (&[1u32, 2, 3] as &[u32])[1];
 }
diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
index cbb11d50f79..39d52ba698a 100644
--- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
@@ -33,12 +33,12 @@
 +     coverage ExpressionId(3) => Expression { lhs: Counter(3), op: Add, rhs: Counter(2) };
 +     coverage ExpressionId(4) => Expression { lhs: Expression(3), op: Add, rhs: Counter(1) };
 +     coverage ExpressionId(5) => Expression { lhs: Expression(4), op: Add, rhs: Expression(2) };
-+     coverage Code(Counter(0)) => 14:1 - 15:21;
-+     coverage Code(Counter(3)) => 16:17 - 16:33;
-+     coverage Code(Counter(2)) => 17:17 - 17:33;
-+     coverage Code(Counter(1)) => 18:17 - 18:33;
-+     coverage Code(Expression(2)) => 19:17 - 19:33;
-+     coverage Code(Expression(5)) => 21:1 - 21:2;
++     coverage Code(Counter(0)) => $DIR/branch_match_arms.rs:14:1: 15:21 (#0);
++     coverage Code(Counter(3)) => $DIR/branch_match_arms.rs:16:17: 16:33 (#0);
++     coverage Code(Counter(2)) => $DIR/branch_match_arms.rs:17:17: 17:33 (#0);
++     coverage Code(Counter(1)) => $DIR/branch_match_arms.rs:18:17: 18:33 (#0);
++     coverage Code(Expression(2)) => $DIR/branch_match_arms.rs:19:17: 19:33 (#0);
++     coverage Code(Expression(5)) => $DIR/branch_match_arms.rs:21:2: 21:2 (#0);
 + 
       bb0: {
 +         Coverage::CounterIncrement(0);
diff --git a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
index 2efb1fd0a17..148ff86354b 100644
--- a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
@@ -5,7 +5,7 @@
       let mut _0: bool;
   
 +     coverage body span: $DIR/instrument_coverage.rs:19:18: 21:2 (#0)
-+     coverage Code(Counter(0)) => 19:1 - 21:2;
++     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:19:1: 21:2 (#0);
 + 
       bb0: {
 +         Coverage::CounterIncrement(0);
diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
index a179824d6c7..b480d1ac13a 100644
--- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
@@ -9,11 +9,11 @@
   
 +     coverage body span: $DIR/instrument_coverage.rs:10:11: 16:2 (#0)
 +     coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Add, rhs: Counter(1) };
-+     coverage Code(Counter(0)) => 10:1 - 10:11;
-+     coverage Code(Expression(0)) => 12:12 - 12:17;
-+     coverage Code(Counter(0)) => 13:13 - 13:18;
-+     coverage Code(Counter(1)) => 14:9 - 14:10;
-+     coverage Code(Counter(0)) => 16:1 - 16:2;
++     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:10:1: 10:11 (#0);
++     coverage Code(Expression(0)) => $DIR/instrument_coverage.rs:12:12: 12:17 (#0);
++     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:13:13: 13:18 (#0);
++     coverage Code(Counter(1)) => $DIR/instrument_coverage.rs:14:10: 14:10 (#0);
++     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:16:2: 16:2 (#0);
 + 
       bb0: {
 +         Coverage::CounterIncrement(0);
diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
index 082539369f7..2c7ec6e85eb 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
@@ -9,11 +9,11 @@
   
       coverage body span: $DIR/instrument_coverage_cleanup.rs:13:11: 15:2 (#0)
       coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Subtract, rhs: Counter(1) };
-      coverage Code(Counter(0)) => 13:1 - 14:36;
-      coverage Code(Expression(0)) => 14:37 - 14:39;
-      coverage Code(Counter(1)) => 14:38 - 14:39;
-      coverage Code(Counter(0)) => 15:1 - 15:2;
-      coverage Branch { true_term: Expression(0), false_term: Counter(1) } => 14:8 - 14:36;
+      coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0);
+      coverage Code(Expression(0)) => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0);
+      coverage Code(Counter(1)) => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0);
+      coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0);
+      coverage Branch { true_term: Expression(0), false_term: Counter(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0);
   
       bb0: {
           Coverage::CounterIncrement(0);
diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
index 8635818c6a7..c08265eb0e9 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
@@ -9,11 +9,11 @@
   
 +     coverage body span: $DIR/instrument_coverage_cleanup.rs:13:11: 15:2 (#0)
 +     coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Subtract, rhs: Counter(1) };
-+     coverage Code(Counter(0)) => 13:1 - 14:36;
-+     coverage Code(Expression(0)) => 14:37 - 14:39;
-+     coverage Code(Counter(1)) => 14:38 - 14:39;
-+     coverage Code(Counter(0)) => 15:1 - 15:2;
-+     coverage Branch { true_term: Expression(0), false_term: Counter(1) } => 14:8 - 14:36;
++     coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0);
++     coverage Code(Expression(0)) => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0);
++     coverage Code(Counter(1)) => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0);
++     coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0);
++     coverage Branch { true_term: Expression(0), false_term: Counter(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0);
 + 
       bb0: {
 +         Coverage::CounterIncrement(0);
diff --git a/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff b/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff
index b0702696e18..acbea13642c 100644
--- a/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.borrowed.GVN.panic-abort.diff
@@ -18,8 +18,7 @@
       }
   
       bb2: {
--         _0 = opaque::<T>(copy (*_3)) -> [return: bb3, unwind unreachable];
-+         _0 = opaque::<T>(copy _1) -> [return: bb3, unwind unreachable];
+          _0 = opaque::<T>(copy (*_3)) -> [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 fe05d4deeed..ba080bfdb07 100644
--- a/tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.borrowed.GVN.panic-unwind.diff
@@ -18,8 +18,7 @@
       }
   
       bb2: {
--         _0 = opaque::<T>(copy (*_3)) -> [return: bb3, unwind continue];
-+         _0 = opaque::<T>(copy _1) -> [return: bb3, unwind continue];
+          _0 = opaque::<T>(copy (*_3)) -> [return: bb3, unwind continue];
       }
   
       bb3: {
diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
index a763614dc64..ecd7bdc433c 100644
--- a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
@@ -107,23 +107,18 @@
           StorageLive(_18);
           _18 = &(*_1);
           StorageLive(_19);
--         StorageLive(_20);
-+         nop;
+          StorageLive(_20);
           _20 = copy (*_18);
--         _19 = opaque::<u32>(move _20) -> [return: bb7, unwind unreachable];
-+         _19 = opaque::<u32>(copy _20) -> [return: bb7, unwind unreachable];
+          _19 = opaque::<u32>(move _20) -> [return: bb7, unwind unreachable];
       }
   
       bb7: {
--         StorageDead(_20);
-+         nop;
+          StorageDead(_20);
           StorageDead(_19);
           StorageLive(_21);
           StorageLive(_22);
--         _22 = copy (*_18);
--         _21 = opaque::<u32>(move _22) -> [return: bb8, unwind unreachable];
-+         _22 = copy _20;
-+         _21 = opaque::<u32>(copy _20) -> [return: bb8, unwind unreachable];
+          _22 = copy (*_18);
+          _21 = opaque::<u32>(move _22) -> [return: bb8, unwind unreachable];
       }
   
       bb8: {
@@ -157,23 +152,18 @@
           StorageDead(_28);
           StorageDead(_27);
           StorageLive(_29);
--         StorageLive(_30);
-+         nop;
+          StorageLive(_30);
           _30 = copy ((*_3).0: u32);
--         _29 = opaque::<u32>(move _30) -> [return: bb12, unwind unreachable];
-+         _29 = opaque::<u32>(copy _30) -> [return: bb12, unwind unreachable];
+          _29 = opaque::<u32>(move _30) -> [return: bb12, unwind unreachable];
       }
   
       bb12: {
--         StorageDead(_30);
-+         nop;
+          StorageDead(_30);
           StorageDead(_29);
           StorageLive(_31);
           StorageLive(_32);
--         _32 = copy ((*_3).0: u32);
--         _31 = opaque::<u32>(move _32) -> [return: bb13, unwind unreachable];
-+         _32 = copy _30;
-+         _31 = opaque::<u32>(copy _30) -> [return: bb13, unwind unreachable];
+          _32 = copy ((*_3).0: u32);
+          _31 = opaque::<u32>(move _32) -> [return: bb13, unwind unreachable];
       }
   
       bb13: {
diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
index ca6fda48364..bbca6bc3c75 100644
--- a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
@@ -107,23 +107,18 @@
           StorageLive(_18);
           _18 = &(*_1);
           StorageLive(_19);
--         StorageLive(_20);
-+         nop;
+          StorageLive(_20);
           _20 = copy (*_18);
--         _19 = opaque::<u32>(move _20) -> [return: bb7, unwind continue];
-+         _19 = opaque::<u32>(copy _20) -> [return: bb7, unwind continue];
+          _19 = opaque::<u32>(move _20) -> [return: bb7, unwind continue];
       }
   
       bb7: {
--         StorageDead(_20);
-+         nop;
+          StorageDead(_20);
           StorageDead(_19);
           StorageLive(_21);
           StorageLive(_22);
--         _22 = copy (*_18);
--         _21 = opaque::<u32>(move _22) -> [return: bb8, unwind continue];
-+         _22 = copy _20;
-+         _21 = opaque::<u32>(copy _20) -> [return: bb8, unwind continue];
+          _22 = copy (*_18);
+          _21 = opaque::<u32>(move _22) -> [return: bb8, unwind continue];
       }
   
       bb8: {
@@ -157,23 +152,18 @@
           StorageDead(_28);
           StorageDead(_27);
           StorageLive(_29);
--         StorageLive(_30);
-+         nop;
+          StorageLive(_30);
           _30 = copy ((*_3).0: u32);
--         _29 = opaque::<u32>(move _30) -> [return: bb12, unwind continue];
-+         _29 = opaque::<u32>(copy _30) -> [return: bb12, unwind continue];
+          _29 = opaque::<u32>(move _30) -> [return: bb12, unwind continue];
       }
   
       bb12: {
--         StorageDead(_30);
-+         nop;
+          StorageDead(_30);
           StorageDead(_29);
           StorageLive(_31);
           StorageLive(_32);
--         _32 = copy ((*_3).0: u32);
--         _31 = opaque::<u32>(move _32) -> [return: bb13, unwind continue];
-+         _32 = copy _30;
-+         _31 = opaque::<u32>(copy _30) -> [return: bb13, unwind continue];
+          _32 = copy ((*_3).0: u32);
+          _31 = opaque::<u32>(move _32) -> [return: bb13, unwind continue];
       }
   
       bb13: {
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 130b011630c..7f99b83d937 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:614:19: 614:21};
+      let mut _9: {closure@$DIR/gvn.rs:615:19: 615:21};
       let _10: ();
       let mut _11: fn();
-      let mut _13: {closure@$DIR/gvn.rs:614:19: 614:21};
+      let mut _13: {closure@$DIR/gvn.rs:615:19: 615: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:614:19: 614:21};
+              let _7: {closure@$DIR/gvn.rs:615:19: 615:21};
               scope 3 {
                   debug closure => _7;
                   let _8: fn();
@@ -62,16 +62,16 @@
           StorageDead(_6);
           StorageDead(_5);
 -         StorageLive(_7);
--         _7 = {closure@$DIR/gvn.rs:614:19: 614:21};
+-         _7 = {closure@$DIR/gvn.rs:615:19: 615:21};
 -         StorageLive(_8);
 +         nop;
-+         _7 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
++         _7 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
 +         nop;
           StorageLive(_9);
 -         _9 = copy _7;
 -         _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
-+         _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
-+         _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} 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));
           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:614:19: 614:21};
-+         _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} 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));
           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 372a08d5473..06dd0502f30 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:614:19: 614:21};
+      let mut _9: {closure@$DIR/gvn.rs:615:19: 615:21};
       let _10: ();
       let mut _11: fn();
-      let mut _13: {closure@$DIR/gvn.rs:614:19: 614:21};
+      let mut _13: {closure@$DIR/gvn.rs:615:19: 615: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:614:19: 614:21};
+              let _7: {closure@$DIR/gvn.rs:615:19: 615:21};
               scope 3 {
                   debug closure => _7;
                   let _8: fn();
@@ -62,16 +62,16 @@
           StorageDead(_6);
           StorageDead(_5);
 -         StorageLive(_7);
--         _7 = {closure@$DIR/gvn.rs:614:19: 614:21};
+-         _7 = {closure@$DIR/gvn.rs:615:19: 615:21};
 -         StorageLive(_8);
 +         nop;
-+         _7 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
++         _7 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
 +         nop;
           StorageLive(_9);
 -         _9 = copy _7;
 -         _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast));
-+         _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
-+         _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} 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));
           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:614:19: 614:21};
-+         _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} 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));
           StorageDead(_13);
           StorageLive(_14);
           StorageLive(_15);
diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs
index faa6faa7017..97513248e23 100644
--- a/tests/mir-opt/gvn.rs
+++ b/tests/mir-opt/gvn.rs
@@ -99,17 +99,18 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) {
     opaque((x * y) - y);
     opaque((x * y) - y);
 
-    // We can substitute through an immutable reference too.
+    // 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]]);
-    // CHECK: [[addref:_.*]] = Add(copy [[deref]], copy _1);
-    // CHECK: opaque::<u64>(copy [[addref]])
-    // CHECK: opaque::<u64>(copy [[addref]])
+    // COM: CHECK: [[addref:_.*]] = Add(copy [[deref]], copy _1);
+    // COM: CHECK: opaque::<u64>(copy [[addref]])
+    // COM: CHECK: opaque::<u64>(copy [[addref]])
     let a = &z;
     opaque(*a + x);
     opaque(*a + x);
 
-    // But not through a mutable reference or a pointer.
+    // And certainly not through a mutable reference or a pointer.
     // CHECK: [[mut:_.*]] = &mut _3;
     // CHECK: [[addmut:_.*]] = Add(
     // CHECK: opaque::<u64>(move [[addmut]])
@@ -137,13 +138,13 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) {
         opaque(*d + x);
     }
 
-    // We can substitute again, but not with the earlier computations.
+    // We still cannot substitute again, and never with the earlier computations.
     // Important: `e` is not `a`!
     // CHECK: [[ref2:_.*]] = &_3;
     // CHECK: [[deref2:_.*]] = copy (*[[ref2]]);
-    // CHECK: [[addref2:_.*]] = Add(copy [[deref2]], copy _1);
-    // CHECK: opaque::<u64>(copy [[addref2]])
-    // CHECK: opaque::<u64>(copy [[addref2]])
+    // COM: CHECK: [[addref2:_.*]] = Add(copy [[deref2]], copy _1);
+    // COM: CHECK: opaque::<u64>(copy [[addref2]])
+    // COM: CHECK: opaque::<u64>(copy [[addref2]])
     let e = &z;
     opaque(*e + x);
     opaque(*e + x);
@@ -495,15 +496,15 @@ fn dereferences(t: &mut u32, u: &impl Copy, s: &S<u32>) {
     unsafe { opaque(*z) };
     unsafe { opaque(*z) };
 
-    // We can reuse dereferences of `&Freeze`.
+    // Do not reuse dereferences of `&Freeze`.
     // CHECK: [[ref:_.*]] = &(*_1);
     // CHECK: [[st7:_.*]] = copy (*[[ref]]);
-    // CHECK: opaque::<u32>(copy [[st7]])
-    // CHECK: opaque::<u32>(copy [[st7]])
+    // COM: CHECK: opaque::<u32>(copy [[st7]])
+    // COM: CHECK: opaque::<u32>(copy [[st7]])
     let z = &*t;
     opaque(*z);
     opaque(*z);
-    // But not in reborrows.
+    // Not in reborrows either.
     // CHECK: [[reborrow:_.*]] = &(*[[ref]]);
     // CHECK: opaque::<&u32>(move [[reborrow]])
     opaque(&*z);
@@ -516,10 +517,10 @@ fn dereferences(t: &mut u32, u: &impl Copy, s: &S<u32>) {
     opaque(*u);
     opaque(*u);
 
-    // `*s` is not Copy, but `(*s).0` is, so we can reuse.
+    // `*s` is not Copy, but `(*s).0` is, but we still cannot reuse.
     // CHECK: [[st10:_.*]] = copy ((*_3).0: u32);
-    // CHECK: opaque::<u32>(copy [[st10]])
-    // CHECK: opaque::<u32>(copy [[st10]])
+    // COM: CHECK: opaque::<u32>(copy [[st10]])
+    // COM: CHECK: opaque::<u32>(copy [[st10]])
     opaque(s.0);
     opaque(s.0);
 }
@@ -736,7 +737,7 @@ fn borrowed<T: Copy + Freeze>(x: T) {
     // CHECK: bb1: {
     // CHECK-NEXT: _0 = opaque::<T>(copy _1)
     // CHECK: bb2: {
-    // CHECK-NEXT: _0 = opaque::<T>(copy _1)
+    // COM: 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 e8e99b44e72..43efcbdfb1e 100644
--- a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
@@ -111,9 +111,8 @@
           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];
@@ -123,9 +122,8 @@
           StorageDead(_11);
           _9 = &_10;
 -         StorageLive(_12);
--         StorageLive(_13);
-+         nop;
 +         nop;
+          StorageLive(_13);
           StorageLive(_14);
 -         _14 = &(*_4);
 +         _14 = &(*_1);
@@ -150,12 +148,11 @@
           StorageLive(_17);
           StorageLive(_18);
 -         _18 = copy (*_15);
-+         _18 = copy _10;
++         _18 = copy (*_9);
           StorageLive(_19);
 -         _19 = copy (*_16);
--         _17 = Eq(move _18, move _19);
-+         _19 = copy _13;
-+         _17 = Eq(copy _10, copy _13);
++         _19 = copy (*_12);
+          _17 = Eq(move _18, move _19);
           switchInt(move _17) -> [0: bb6, otherwise: bb5];
       }
   
@@ -166,10 +163,8 @@
           StorageDead(_17);
           StorageDead(_16);
           StorageDead(_15);
--         StorageDead(_13);
--         StorageDead(_10);
-+         nop;
-+         nop;
+          StorageDead(_13);
+          StorageDead(_10);
           StorageDead(_8);
           StorageDead(_7);
 -         StorageLive(_29);
@@ -218,9 +213,8 @@
           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];
@@ -230,9 +224,8 @@
           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];
@@ -256,12 +249,11 @@
           StorageLive(_43);
           StorageLive(_44);
 -         _44 = copy (*_41);
-+         _44 = copy _36;
++         _44 = copy (*_35);
           StorageLive(_45);
 -         _45 = copy (*_42);
--         _43 = Eq(move _44, move _45);
-+         _45 = copy _39;
-+         _43 = Eq(copy _36, copy _39);
++         _45 = copy (*_38);
+          _43 = Eq(move _44, move _45);
           switchInt(move _43) -> [0: bb11, otherwise: bb10];
       }
   
@@ -272,10 +264,8 @@
           StorageDead(_43);
           StorageDead(_42);
           StorageDead(_41);
--         StorageDead(_39);
--         StorageDead(_36);
-+         nop;
-+         nop;
+          StorageDead(_39);
+          StorageDead(_36);
           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 4296d4d4a59..8572f538c0f 100644
--- a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
@@ -111,9 +111,8 @@
           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];
@@ -123,9 +122,8 @@
           StorageDead(_11);
           _9 = &_10;
 -         StorageLive(_12);
--         StorageLive(_13);
-+         nop;
 +         nop;
+          StorageLive(_13);
           StorageLive(_14);
 -         _14 = &(*_4);
 +         _14 = &(*_1);
@@ -150,12 +148,11 @@
           StorageLive(_17);
           StorageLive(_18);
 -         _18 = copy (*_15);
-+         _18 = copy _10;
++         _18 = copy (*_9);
           StorageLive(_19);
 -         _19 = copy (*_16);
--         _17 = Eq(move _18, move _19);
-+         _19 = copy _13;
-+         _17 = Eq(copy _10, copy _13);
++         _19 = copy (*_12);
+          _17 = Eq(move _18, move _19);
           switchInt(move _17) -> [0: bb6, otherwise: bb5];
       }
   
@@ -166,10 +163,8 @@
           StorageDead(_17);
           StorageDead(_16);
           StorageDead(_15);
--         StorageDead(_13);
--         StorageDead(_10);
-+         nop;
-+         nop;
+          StorageDead(_13);
+          StorageDead(_10);
           StorageDead(_8);
           StorageDead(_7);
 -         StorageLive(_29);
@@ -218,9 +213,8 @@
           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];
@@ -230,9 +224,8 @@
           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];
@@ -256,12 +249,11 @@
           StorageLive(_43);
           StorageLive(_44);
 -         _44 = copy (*_41);
-+         _44 = copy _36;
++         _44 = copy (*_35);
           StorageLive(_45);
 -         _45 = copy (*_42);
--         _43 = Eq(move _44, move _45);
-+         _45 = copy _39;
-+         _43 = Eq(copy _36, copy _39);
++         _45 = copy (*_38);
+          _43 = Eq(move _44, move _45);
           switchInt(move _43) -> [0: bb11, otherwise: bb10];
       }
   
@@ -272,10 +264,8 @@
           StorageDead(_43);
           StorageDead(_42);
           StorageDead(_41);
--         StorageDead(_39);
--         StorageDead(_36);
-+         nop;
-+         nop;
+          StorageDead(_39);
+          StorageDead(_36);
           StorageDead(_34);
           StorageDead(_33);
           _0 = const ();
diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
index 7a479bc55da..e872e011542 100644
--- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
@@ -758,39 +758,32 @@
           StorageLive(_126);
           _126 = &_3;
           StorageLive(_127);
--         StorageLive(_128);
--         StorageLive(_129);
-+         nop;
-+         nop;
+          StorageLive(_128);
+          StorageLive(_129);
           _129 = copy (*_126);
           StorageLive(_130);
           _130 = copy _1;
 -         _128 = Add(move _129, move _130);
-+         _128 = Add(copy _129, copy _1);
++         _128 = Add(move _129, copy _1);
           StorageDead(_130);
--         StorageDead(_129);
--         _127 = opaque::<u64>(move _128) -> [return: bb35, unwind unreachable];
-+         nop;
-+         _127 = opaque::<u64>(copy _128) -> [return: bb35, unwind unreachable];
+          StorageDead(_129);
+          _127 = opaque::<u64>(move _128) -> [return: bb35, unwind unreachable];
       }
   
       bb35: {
--         StorageDead(_128);
-+         nop;
+          StorageDead(_128);
           StorageDead(_127);
           StorageLive(_131);
           StorageLive(_132);
           StorageLive(_133);
--         _133 = copy (*_126);
-+         _133 = copy _129;
+          _133 = copy (*_126);
           StorageLive(_134);
           _134 = copy _1;
 -         _132 = Add(move _133, move _134);
-+         _132 = copy _128;
++         _132 = Add(move _133, copy _1);
           StorageDead(_134);
           StorageDead(_133);
--         _131 = opaque::<u64>(move _132) -> [return: bb36, unwind unreachable];
-+         _131 = opaque::<u64>(copy _128) -> [return: bb36, unwind unreachable];
+          _131 = opaque::<u64>(move _132) -> [return: bb36, unwind unreachable];
       }
   
       bb36: {
@@ -906,39 +899,32 @@
           StorageLive(_163);
           _163 = &_3;
           StorageLive(_164);
--         StorageLive(_165);
--         StorageLive(_166);
-+         nop;
-+         nop;
+          StorageLive(_165);
+          StorageLive(_166);
           _166 = copy (*_163);
           StorageLive(_167);
           _167 = copy _1;
 -         _165 = Add(move _166, move _167);
-+         _165 = Add(copy _166, copy _1);
++         _165 = Add(move _166, copy _1);
           StorageDead(_167);
--         StorageDead(_166);
--         _164 = opaque::<u64>(move _165) -> [return: bb43, unwind unreachable];
-+         nop;
-+         _164 = opaque::<u64>(copy _165) -> [return: bb43, unwind unreachable];
+          StorageDead(_166);
+          _164 = opaque::<u64>(move _165) -> [return: bb43, unwind unreachable];
       }
   
       bb43: {
--         StorageDead(_165);
-+         nop;
+          StorageDead(_165);
           StorageDead(_164);
           StorageLive(_168);
           StorageLive(_169);
           StorageLive(_170);
--         _170 = copy (*_163);
-+         _170 = copy _166;
+          _170 = copy (*_163);
           StorageLive(_171);
           _171 = copy _1;
 -         _169 = Add(move _170, move _171);
-+         _169 = copy _165;
++         _169 = Add(move _170, copy _1);
           StorageDead(_171);
           StorageDead(_170);
--         _168 = opaque::<u64>(move _169) -> [return: bb44, unwind unreachable];
-+         _168 = opaque::<u64>(copy _165) -> [return: bb44, unwind unreachable];
+          _168 = opaque::<u64>(move _169) -> [return: bb44, unwind unreachable];
       }
   
       bb44: {
diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
index 3ca5238663c..3996dab27a3 100644
--- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
@@ -758,39 +758,32 @@
           StorageLive(_126);
           _126 = &_3;
           StorageLive(_127);
--         StorageLive(_128);
--         StorageLive(_129);
-+         nop;
-+         nop;
+          StorageLive(_128);
+          StorageLive(_129);
           _129 = copy (*_126);
           StorageLive(_130);
           _130 = copy _1;
 -         _128 = Add(move _129, move _130);
-+         _128 = Add(copy _129, copy _1);
++         _128 = Add(move _129, copy _1);
           StorageDead(_130);
--         StorageDead(_129);
--         _127 = opaque::<u64>(move _128) -> [return: bb35, unwind continue];
-+         nop;
-+         _127 = opaque::<u64>(copy _128) -> [return: bb35, unwind continue];
+          StorageDead(_129);
+          _127 = opaque::<u64>(move _128) -> [return: bb35, unwind continue];
       }
   
       bb35: {
--         StorageDead(_128);
-+         nop;
+          StorageDead(_128);
           StorageDead(_127);
           StorageLive(_131);
           StorageLive(_132);
           StorageLive(_133);
--         _133 = copy (*_126);
-+         _133 = copy _129;
+          _133 = copy (*_126);
           StorageLive(_134);
           _134 = copy _1;
 -         _132 = Add(move _133, move _134);
-+         _132 = copy _128;
++         _132 = Add(move _133, copy _1);
           StorageDead(_134);
           StorageDead(_133);
--         _131 = opaque::<u64>(move _132) -> [return: bb36, unwind continue];
-+         _131 = opaque::<u64>(copy _128) -> [return: bb36, unwind continue];
+          _131 = opaque::<u64>(move _132) -> [return: bb36, unwind continue];
       }
   
       bb36: {
@@ -906,39 +899,32 @@
           StorageLive(_163);
           _163 = &_3;
           StorageLive(_164);
--         StorageLive(_165);
--         StorageLive(_166);
-+         nop;
-+         nop;
+          StorageLive(_165);
+          StorageLive(_166);
           _166 = copy (*_163);
           StorageLive(_167);
           _167 = copy _1;
 -         _165 = Add(move _166, move _167);
-+         _165 = Add(copy _166, copy _1);
++         _165 = Add(move _166, copy _1);
           StorageDead(_167);
--         StorageDead(_166);
--         _164 = opaque::<u64>(move _165) -> [return: bb43, unwind continue];
-+         nop;
-+         _164 = opaque::<u64>(copy _165) -> [return: bb43, unwind continue];
+          StorageDead(_166);
+          _164 = opaque::<u64>(move _165) -> [return: bb43, unwind continue];
       }
   
       bb43: {
--         StorageDead(_165);
-+         nop;
+          StorageDead(_165);
           StorageDead(_164);
           StorageLive(_168);
           StorageLive(_169);
           StorageLive(_170);
--         _170 = copy (*_163);
-+         _170 = copy _166;
+          _170 = copy (*_163);
           StorageLive(_171);
           _171 = copy _1;
 -         _169 = Add(move _170, move _171);
-+         _169 = copy _165;
++         _169 = Add(move _170, copy _1);
           StorageDead(_171);
           StorageDead(_170);
--         _168 = opaque::<u64>(move _169) -> [return: bb44, unwind continue];
-+         _168 = opaque::<u64>(copy _165) -> [return: bb44, unwind continue];
+          _168 = opaque::<u64>(move _169) -> [return: bb44, unwind continue];
       }
   
       bb44: {
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 37b7b0d2c9d..881b629803a 100644
--- a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
@@ -17,16 +17,15 @@
           StorageLive(_3);
           _5 = const f::promoted[0];
           _3 = &(*_5);
--         _2 = copy ((*_3).1: E);
-+         _2 = copy ((*_5).1: E);
-          StorageLive(_1);
--         _1 = copy ((_2 as A).1: u32);
-+         _1 = const 0_u32;
+          _2 = copy ((*_3).1: E);
+-         StorageLive(_1);
++         nop;
+          _1 = copy ((_2 as A).1: u32);
           StorageDead(_3);
           StorageDead(_2);
--         _0 = copy _1;
-+         _0 = const 0_u32;
-          StorageDead(_1);
+          _0 = copy _1;
+-         StorageDead(_1);
++         nop;
           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 37b7b0d2c9d..881b629803a 100644
--- a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
@@ -17,16 +17,15 @@
           StorageLive(_3);
           _5 = const f::promoted[0];
           _3 = &(*_5);
--         _2 = copy ((*_3).1: E);
-+         _2 = copy ((*_5).1: E);
-          StorageLive(_1);
--         _1 = copy ((_2 as A).1: u32);
-+         _1 = const 0_u32;
+          _2 = copy ((*_3).1: E);
+-         StorageLive(_1);
++         nop;
+          _1 = copy ((_2 as A).1: u32);
           StorageDead(_3);
           StorageDead(_2);
--         _0 = copy _1;
-+         _0 = const 0_u32;
-          StorageDead(_1);
+          _0 = copy _1;
+-         StorageDead(_1);
++         nop;
           return;
       }
   }
diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-abort.diff
index b532b133a83..95c52925401 100644
--- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-abort.diff
@@ -1,5 +1,5 @@
-- // MIR for `bar` before RevealAll
-+ // MIR for `bar` after RevealAll
+- // MIR for `bar` before PostAnalysisNormalize
++ // MIR for `bar` after PostAnalysisNormalize
   
   fn bar(_1: P) -> () {
       debug _baz => _1;
diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-unwind.diff
index bcebcf297c2..1b710a78cb1 100644
--- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.PostAnalysisNormalize.panic-unwind.diff
@@ -1,5 +1,5 @@
-- // MIR for `bar` before RevealAll
-+ // MIR for `bar` after RevealAll
+- // MIR for `bar` before PostAnalysisNormalize
++ // MIR for `bar` after PostAnalysisNormalize
   
   fn bar(_1: P) -> () {
       debug _baz => _1;
diff --git a/tests/mir-opt/inline/issue_78442.rs b/tests/mir-opt/inline/issue_78442.rs
index 6dc875f9a40..4eb5c142034 100644
--- a/tests/mir-opt/inline/issue_78442.rs
+++ b/tests/mir-opt/inline/issue_78442.rs
@@ -2,7 +2,7 @@
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 #![crate_type = "lib"]
 
-// EMIT_MIR issue_78442.bar.RevealAll.diff
+// EMIT_MIR issue_78442.bar.PostAnalysisNormalize.diff
 // EMIT_MIR issue_78442.bar.Inline.diff
 pub fn bar<P>(
     // Error won't happen if "bar" is not generic
diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.rs b/tests/mir-opt/pre-codegen/deref_nested_borrows.rs
new file mode 100644
index 00000000000..4f70ec36bc9
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.rs
@@ -0,0 +1,25 @@
+//! Regression test for <https://github.com/rust-lang/rust/issues/130853>
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+
+fn src(x: &&u8) -> bool {
+    // CHECK-LABEL: fn src(
+    // CHECK-NOT: _0 = const true;
+    // CHECK: _0 = Eq({{.*}}, {{.*}});
+    // CHECK-NOT: _0 = const true;
+    let y = **x;
+    unsafe { unknown() };
+    **x == y
+}
+
+#[inline(never)]
+unsafe fn unknown() {
+    // CHECK-LABEL: fn unknown(
+}
+
+fn main() {
+    // CHECK-LABEL: fn main(
+    src(&&0);
+}
+
+// EMIT_MIR deref_nested_borrows.src.GVN.diff
+// EMIT_MIR deref_nested_borrows.src.PreCodegen.after.mir
diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff
new file mode 100644
index 00000000000..993857f225a
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff
@@ -0,0 +1,42 @@
+- // MIR for `src` before GVN
++ // MIR for `src` after GVN
+  
+  fn src(_1: &&u8) -> bool {
+      debug x => _1;
+      let mut _0: bool;
+      let _2: u8;
+      let _3: ();
+      let mut _4: u8;
+      let mut _5: u8;
+      let mut _6: &u8;
+      let mut _7: &u8;
+      scope 1 {
+          debug y => _2;
+      }
+  
+      bb0: {
+-         StorageLive(_2);
+-         _6 = deref_copy (*_1);
++         nop;
++         _6 = copy (*_1);
+          _2 = copy (*_6);
+          _3 = unknown() -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageLive(_4);
+-         _7 = deref_copy (*_1);
++         _7 = copy (*_1);
+          _4 = copy (*_7);
+          StorageLive(_5);
+          _5 = copy _2;
+-         _0 = Eq(move _4, move _5);
++         _0 = Eq(move _4, copy _2);
+          StorageDead(_5);
+          StorageDead(_4);
+-         StorageDead(_2);
++         nop;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..d81bfa9310b
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff
@@ -0,0 +1,42 @@
+- // MIR for `src` before GVN
++ // MIR for `src` after GVN
+  
+  fn src(_1: &&u8) -> bool {
+      debug x => _1;
+      let mut _0: bool;
+      let _2: u8;
+      let _3: ();
+      let mut _4: u8;
+      let mut _5: u8;
+      let mut _6: &u8;
+      let mut _7: &u8;
+      scope 1 {
+          debug y => _2;
+      }
+  
+      bb0: {
+-         StorageLive(_2);
+-         _6 = deref_copy (*_1);
++         nop;
++         _6 = copy (*_1);
+          _2 = copy (*_6);
+          _3 = unknown() -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+          StorageLive(_4);
+-         _7 = deref_copy (*_1);
++         _7 = copy (*_1);
+          _4 = copy (*_7);
+          StorageLive(_5);
+          _5 = copy _2;
+-         _0 = Eq(move _4, move _5);
++         _0 = Eq(move _4, copy _2);
+          StorageDead(_5);
+          StorageDead(_4);
+-         StorageDead(_2);
++         nop;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir
new file mode 100644
index 00000000000..23b1c3f3f43
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-abort.mir
@@ -0,0 +1,29 @@
+// MIR for `src` after PreCodegen
+
+fn src(_1: &&u8) -> bool {
+    debug x => _1;
+    let mut _0: bool;
+    let mut _2: &u8;
+    let _3: u8;
+    let _4: ();
+    let mut _5: &u8;
+    let mut _6: u8;
+    scope 1 {
+        debug y => _3;
+    }
+
+    bb0: {
+        _2 = copy (*_1);
+        _3 = copy (*_2);
+        _4 = unknown() -> [return: bb1, unwind unreachable];
+    }
+
+    bb1: {
+        StorageLive(_6);
+        _5 = copy (*_1);
+        _6 = copy (*_5);
+        _0 = Eq(move _6, copy _3);
+        StorageDead(_6);
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir
new file mode 100644
index 00000000000..4c01e9464bf
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,29 @@
+// MIR for `src` after PreCodegen
+
+fn src(_1: &&u8) -> bool {
+    debug x => _1;
+    let mut _0: bool;
+    let mut _2: &u8;
+    let _3: u8;
+    let _4: ();
+    let mut _5: &u8;
+    let mut _6: u8;
+    scope 1 {
+        debug y => _3;
+    }
+
+    bb0: {
+        _2 = copy (*_1);
+        _3 = copy (*_2);
+        _4 = unknown() -> [return: bb1, unwind continue];
+    }
+
+    bb1: {
+        StorageLive(_6);
+        _5 = copy (*_1);
+        _6 = copy (*_5);
+        _0 = Eq(move _6, copy _3);
+        StorageDead(_6);
+        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 cbdd194afd3..5a269717f82 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,65 +4,70 @@ 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 _5: &usize;
+    let mut _5: &(usize, usize, usize, usize);
     let _6: &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;
+    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;
     scope 1 {
         debug a => _4;
-        debug b => _5;
-        debug c => _6;
-        debug d => _7;
+        debug b => _6;
+        debug c => _8;
+        debug d => _10;
         scope 2 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _8;
-            debug other => _10;
+            debug self => _11;
+            debug other => _13;
             scope 3 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
                 debug self => _4;
-                debug other => _6;
-                let mut _11: usize;
-                let mut _12: usize;
+                debug other => _8;
+                let mut _14: usize;
+                let mut _15: usize;
             }
         }
         scope 4 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _14;
-            debug other => _16;
+            debug self => _17;
+            debug other => _19;
             scope 5 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
-                debug self => _7;
-                debug other => _5;
-                let mut _17: usize;
-                let mut _18: usize;
+                debug self => _10;
+                debug other => _6;
+                let mut _20: usize;
+                let mut _21: usize;
             }
         }
         scope 6 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _20;
-            debug other => _22;
+            debug self => _23;
+            debug other => _25;
             scope 7 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
-                debug self => _6;
+                debug self => _8;
                 debug other => _4;
+                let mut _26: usize;
+                let mut _27: usize;
             }
         }
         scope 8 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
-            debug self => _24;
-            debug other => _26;
+            debug self => _29;
+            debug other => _31;
             scope 9 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
-                debug self => _5;
-                debug other => _7;
-                let mut _27: usize;
-                let mut _28: usize;
+                debug self => _6;
+                debug other => _10;
+                let mut _32: usize;
+                let mut _33: usize;
             }
         }
     }
@@ -70,116 +75,129 @@ 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 = &((*_3).1: usize);
-        _6 = &((*_3).2: usize);
-        _7 = &((*_3).3: 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;
         StorageLive(_13);
-        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];
+        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];
     }
 
     bb1: {
-        StorageDead(_9);
-        StorageDead(_10);
-        StorageDead(_8);
+        StorageDead(_12);
+        StorageDead(_13);
+        StorageDead(_11);
         goto -> bb4;
     }
 
     bb2: {
-        StorageDead(_9);
-        StorageDead(_10);
-        StorageDead(_8);
-        StorageLive(_19);
-        StorageLive(_14);
-        _14 = &_7;
-        StorageLive(_16);
-        StorageLive(_15);
-        _15 = copy _5;
-        _16 = &_15;
+        StorageDead(_12);
+        StorageDead(_13);
+        StorageDead(_11);
+        StorageLive(_22);
         StorageLive(_17);
-        _17 = copy ((*_3).3: usize);
+        _17 = &_10;
+        StorageLive(_19);
         StorageLive(_18);
-        _18 = copy ((*_3).1: usize);
-        _19 = Le(move _17, move _18);
-        StorageDead(_18);
-        StorageDead(_17);
-        switchInt(move _19) -> [0: bb3, otherwise: bb8];
+        _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];
     }
 
     bb3: {
-        StorageDead(_15);
-        StorageDead(_16);
-        StorageDead(_14);
+        StorageDead(_18);
+        StorageDead(_19);
+        StorageDead(_17);
         goto -> bb4;
     }
 
     bb4: {
+        StorageLive(_28);
         StorageLive(_23);
-        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];
+        _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];
     }
 
     bb5: {
-        StorageDead(_21);
-        StorageDead(_22);
-        StorageDead(_20);
+        StorageDead(_24);
+        StorageDead(_25);
+        StorageDead(_23);
         _0 = const false;
         goto -> bb7;
     }
 
     bb6: {
-        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(_26);
         StorageDead(_24);
+        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);
         goto -> bb7;
     }
 
     bb7: {
-        StorageDead(_23);
+        StorageDead(_28);
         goto -> bb9;
     }
 
     bb8: {
-        StorageDead(_15);
-        StorageDead(_16);
-        StorageDead(_14);
+        StorageDead(_18);
+        StorageDead(_19);
+        StorageDead(_17);
         _0 = const true;
         goto -> bb9;
     }
 
     bb9: {
-        StorageDead(_19);
-        StorageDead(_13);
+        StorageDead(_22);
+        StorageDead(_16);
         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 bc7a31d5219..f93f7264dec 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,40 +4,46 @@ 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 _5: usize;
+    let mut _5: &(usize, usize, usize, usize);
     let _6: usize;
-    let _7: usize;
-    let mut _8: bool;
-    let mut _9: bool;
-    let mut _10: bool;
+    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;
     scope 1 {
         debug a => _4;
-        debug b => _5;
-        debug c => _6;
-        debug d => _7;
+        debug b => _6;
+        debug c => _8;
+        debug d => _10;
     }
 
     bb0: {
         _3 = copy (*_2);
         _4 = copy ((*_3).0: usize);
-        _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];
+        _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];
     }
 
     bb1: {
-        StorageLive(_9);
-        _9 = Le(copy _7, copy _5);
-        switchInt(move _9) -> [0: bb2, otherwise: bb6];
+        StorageLive(_12);
+        _12 = Le(copy _10, copy _6);
+        switchInt(move _12) -> [0: bb2, otherwise: bb6];
     }
 
     bb2: {
-        StorageLive(_10);
-        _10 = Le(copy _6, copy _4);
-        switchInt(move _10) -> [0: bb3, otherwise: bb4];
+        StorageLive(_13);
+        _13 = Le(copy _8, copy _4);
+        switchInt(move _13) -> [0: bb3, otherwise: bb4];
     }
 
     bb3: {
@@ -46,12 +52,12 @@ fn variant_b::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:11:25: 11:41},
     }
 
     bb4: {
-        _0 = Le(copy _5, copy _7);
+        _0 = Le(copy _6, copy _10);
         goto -> bb5;
     }
 
     bb5: {
-        StorageDead(_10);
+        StorageDead(_13);
         goto -> bb7;
     }
 
@@ -61,8 +67,8 @@ fn variant_b::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:11:25: 11:41},
     }
 
     bb7: {
-        StorageDead(_9);
-        StorageDead(_8);
+        StorageDead(_12);
+        StorageDead(_11);
         return;
     }
 }
diff --git a/tests/run-make/avr-rjmp-offset/rmake.rs b/tests/run-make/avr-rjmp-offset/rmake.rs
index 89cbca309be..de64b724eed 100644
--- a/tests/run-make/avr-rjmp-offset/rmake.rs
+++ b/tests/run-make/avr-rjmp-offset/rmake.rs
@@ -10,6 +10,11 @@
 //! wrong output is only produced with direct assembly generation, but not when
 //! "emit-asm" is used, as described in the issue description of #129301:
 //! https://github.com/rust-lang/rust/issues/129301#issue-2475070770
+
+// FIXME(#133480): this has been randomly failing on `x86_64-mingw` due to linker hangs or
+// crashes... so I'm going to disable this test for windows for now.
+//@ ignore-windows-gnu
+
 use run_make_support::{llvm_objdump, rustc};
 
 fn main() {
diff --git a/tests/run-make/crate-loading/rmake.rs b/tests/run-make/crate-loading/rmake.rs
index 2d5913c4bcb..544bf9ab957 100644
--- a/tests/run-make/crate-loading/rmake.rs
+++ b/tests/run-make/crate-loading/rmake.rs
@@ -18,31 +18,37 @@ fn main() {
         .extern_("dependency", rust_lib_name("dependency"))
         .extern_("dep_2_reexport", rust_lib_name("foo"))
         .run_fail()
-        .assert_stderr_contains(r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied because the trait comes from a different crate version
- --> multiple-dep-versions.rs:7:18
-  |
-7 |     do_something(Type);
-  |                  ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
-  |
+        .assert_stderr_contains(r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied
+  --> multiple-dep-versions.rs:7:18
+   |
+7  |     do_something(Type);
+   |     ------------ ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
+   |     |
+   |     required by a bound introduced by this call
+   |
 note: there are multiple different versions of crate `dependency` in the dependency graph"#)
         .assert_stderr_contains(r#"
-3 | pub struct Type(pub i32);
-  | --------------- this type implements the required trait
-4 | pub trait Trait {
-  | ^^^^^^^^^^^^^^^ this is the required trait
+3  | pub struct Type(pub i32);
+   | --------------- this type implements the required trait
+4  | pub trait Trait {
+   | ^^^^^^^^^^^^^^^ this is the required trait
 "#)
         .assert_stderr_contains(r#"
-1 | extern crate dep_2_reexport;
-  | ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
-2 | extern crate dependency;
-  | ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate"#)
+1  | extern crate dep_2_reexport;
+   | ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
+2  | extern crate dependency;
+   | ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate"#)
         .assert_stderr_contains(r#"
-3 | pub struct Type;
-  | --------------- this type doesn't implement the required trait
-4 | pub trait Trait {
-  | --------------- this is the found trait
-  = note: two types coming from two different versions of the same crate are different types even if they look the same
-  = help: you can use `cargo tree` to explore your dependency tree"#)
+3  | pub struct Type;
+   | --------------- this type doesn't implement the required trait
+4  | pub trait Trait {
+   | --------------- this is the found trait
+   = note: two types coming from two different versions of the same crate are different types even if they look the same
+   = help: you can use `cargo tree` to explore your dependency tree"#)
+        .assert_stderr_contains(r#"note: required by a bound in `do_something`"#)
+        .assert_stderr_contains(r#"
+12 | pub fn do_something<X: Trait>(_: X) {}
+   |                        ^^^^^ required by this bound in `do_something`"#)
         .assert_stderr_contains(r#"error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
  --> multiple-dep-versions.rs:8:10
   |
diff --git a/tests/run-make/diagnostics-traits-from-duplicate-crates/minibevy.rs b/tests/run-make/diagnostics-traits-from-duplicate-crates/minibevy.rs
new file mode 100644
index 00000000000..1bc8473e08e
--- /dev/null
+++ b/tests/run-make/diagnostics-traits-from-duplicate-crates/minibevy.rs
@@ -0,0 +1,2 @@
+pub trait Resource {}
+pub struct Ray2d;
diff --git a/tests/run-make/diagnostics-traits-from-duplicate-crates/minirapier.rs b/tests/run-make/diagnostics-traits-from-duplicate-crates/minirapier.rs
new file mode 100644
index 00000000000..2b84332aa51
--- /dev/null
+++ b/tests/run-make/diagnostics-traits-from-duplicate-crates/minirapier.rs
@@ -0,0 +1 @@
+pub type Ray = minibevy::Ray2d;
diff --git a/tests/run-make/diagnostics-traits-from-duplicate-crates/repro.rs b/tests/run-make/diagnostics-traits-from-duplicate-crates/repro.rs
new file mode 100644
index 00000000000..90a6dfc2e15
--- /dev/null
+++ b/tests/run-make/diagnostics-traits-from-duplicate-crates/repro.rs
@@ -0,0 +1,14 @@
+extern crate minibevy;
+extern crate minirapier;
+
+use minibevy::Resource;
+use minirapier::Ray;
+
+fn insert_resource<R: Resource>(_resource: R) {}
+
+struct Res;
+impl Resource for Res {}
+
+fn main() {
+    insert_resource(Res.into());
+}
diff --git a/tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs b/tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs
new file mode 100644
index 00000000000..32c4cf33896
--- /dev/null
+++ b/tests/run-make/diagnostics-traits-from-duplicate-crates/rmake.rs
@@ -0,0 +1,45 @@
+// Non-regression test for issue #132920 where multiple versions of the same crate are present in
+// the dependency graph, and an unexpected error in a dependent crate caused an ICE in the
+// unsatisfied bounds diagnostics for traits present in multiple crate versions.
+//
+// Setup:
+// - two versions of the same crate: minibevy_a and minibevy_b
+// - minirapier: depends on minibevy_a
+// - repro: depends on minirapier and minibevy_b
+
+use run_make_support::rustc;
+
+fn main() {
+    // Prepare dependencies, mimicking a check build with cargo.
+    rustc()
+        .input("minibevy.rs")
+        .crate_name("minibevy")
+        .crate_type("lib")
+        .emit("metadata")
+        .metadata("a")
+        .extra_filename("-a")
+        .run();
+    rustc()
+        .input("minibevy.rs")
+        .crate_name("minibevy")
+        .crate_type("lib")
+        .emit("metadata")
+        .metadata("b")
+        .extra_filename("-b")
+        .run();
+    rustc()
+        .input("minirapier.rs")
+        .crate_name("minirapier")
+        .crate_type("lib")
+        .emit("metadata")
+        .extern_("minibevy", "libminibevy-a.rmeta")
+        .run();
+
+    // Building the main crate used to ICE here when printing the `type annotations needed` error.
+    rustc()
+        .input("repro.rs")
+        .extern_("minibevy", "libminibevy-b.rmeta")
+        .extern_("minirapier", "libminirapier.rmeta")
+        .run_fail()
+        .assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug");
+}
diff --git a/tests/run-make/libstd-no-protected/rmake.rs b/tests/run-make/libstd-no-protected/rmake.rs
new file mode 100644
index 00000000000..3bba59a8f4d
--- /dev/null
+++ b/tests/run-make/libstd-no-protected/rmake.rs
@@ -0,0 +1,63 @@
+// If libstd was compiled to use protected symbols, then linking would fail if GNU ld < 2.40 were
+// used. This might not be noticed, since usually we use LLD for linking, so we could end up
+// distributing a version of libstd that would cause link errors for such users.
+
+//@ only-x86_64-unknown-linux-gnu
+
+use run_make_support::object::Endianness;
+use run_make_support::object::read::archive::ArchiveFile;
+use run_make_support::object::read::elf::{FileHeader as _, SectionHeader as _};
+use run_make_support::rfs::{read, read_dir};
+use run_make_support::{has_prefix, has_suffix, object, path, rustc, shallow_find_files, target};
+
+type FileHeader = run_make_support::object::elf::FileHeader64<Endianness>;
+type SymbolTable<'data> = run_make_support::object::read::elf::SymbolTable<'data, FileHeader>;
+
+fn main() {
+    // Find libstd-...rlib
+    let sysroot = rustc().print("sysroot").run().stdout_utf8();
+    let sysroot = sysroot.trim();
+    let target_sysroot = path(sysroot).join("lib/rustlib").join(target()).join("lib");
+    let mut libs = shallow_find_files(&target_sysroot, |path| {
+        has_prefix(path, "libstd-") && has_suffix(path, ".rlib")
+    });
+    assert_eq!(libs.len(), 1);
+    let libstd_path = libs.pop().unwrap();
+    let archive_data = read(libstd_path);
+
+    // Parse all the object files within the libstd archive, checking defined symbols.
+    let mut num_protected = 0;
+    let mut num_symbols = 0;
+
+    let archive = ArchiveFile::parse(&*archive_data).unwrap();
+    for member in archive.members() {
+        let member = member.unwrap();
+        if member.name() == b"lib.rmeta" {
+            continue;
+        }
+        let data = member.data(&*archive_data).unwrap();
+
+        let header = FileHeader::parse(data).unwrap();
+        let endian = header.endian().unwrap();
+        let sections = header.sections(endian, data).unwrap();
+
+        for (section_index, section) in sections.enumerate() {
+            if section.sh_type(endian) == object::elf::SHT_SYMTAB {
+                let symbols =
+                    SymbolTable::parse(endian, data, &sections, section_index, section).unwrap();
+                for symbol in symbols.symbols() {
+                    if symbol.st_visibility() == object::elf::STV_PROTECTED {
+                        num_protected += 1;
+                    }
+                    num_symbols += 1;
+                }
+            }
+        }
+    }
+
+    // If there were no symbols at all, then something is wrong with the test.
+    assert_ne!(num_symbols, 0);
+
+    // The purpose of this test - check that no symbols have protected visibility.
+    assert_eq!(num_protected, 0);
+}
diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout
index dbd67b57df2..8f6fde69c29 100644
--- a/tests/run-make/rustc-help/help-v.stdout
+++ b/tests/run-make/rustc-help/help-v.stdout
@@ -25,7 +25,7 @@ Options:
         --edition 2015|2018|2021|2024
                         Specify which edition of the compiler to use when
                         compiling code. The default is 2015 and the latest
-                        stable edition is 2021.
+                        stable edition is 2024.
         --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
                         Comma separated list of types of output for the
                         compiler to emit
diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout
index a7d07162799..131efa93282 100644
--- a/tests/run-make/rustc-help/help.stdout
+++ b/tests/run-make/rustc-help/help.stdout
@@ -25,7 +25,7 @@ Options:
         --edition 2015|2018|2021|2024
                         Specify which edition of the compiler to use when
                         compiling code. The default is 2015 and the latest
-                        stable edition is 2021.
+                        stable edition is 2024.
         --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
                         Comma separated list of types of output for the
                         compiler to emit
diff --git a/tests/rustdoc-ui/2024-doctests-checks.rs b/tests/rustdoc-ui/2024-doctests-checks.rs
index 464cf5b200d..f3e4e10f571 100644
--- a/tests/rustdoc-ui/2024-doctests-checks.rs
+++ b/tests/rustdoc-ui/2024-doctests-checks.rs
@@ -1,5 +1,6 @@
 //@ check-pass
-//@ compile-flags: --test --test-args=--test-threads=1 -Zunstable-options --edition 2024
+//@ edition: 2024
+//@ compile-flags: --test --test-args=--test-threads=1
 //@ normalize-stdout-test: "tests/rustdoc-ui" -> "$$DIR"
 //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
 //@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
diff --git a/tests/rustdoc-ui/2024-doctests-checks.stdout b/tests/rustdoc-ui/2024-doctests-checks.stdout
index d1064084a85..534fe466fe7 100644
--- a/tests/rustdoc-ui/2024-doctests-checks.stdout
+++ b/tests/rustdoc-ui/2024-doctests-checks.stdout
@@ -1,12 +1,12 @@
 
 running 1 test
-test $DIR/2024-doctests-checks.rs - Foo (line 7) ... ok
+test $DIR/2024-doctests-checks.rs - Foo (line 8) ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
 
 running 1 test
-test $DIR/2024-doctests-checks.rs - Foo (line 14) ... ok
+test $DIR/2024-doctests-checks.rs - Foo (line 15) ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
diff --git a/tests/rustdoc-ui/2024-doctests-crate-attribute.rs b/tests/rustdoc-ui/2024-doctests-crate-attribute.rs
index 4984fdfe194..a353fc7cc44 100644
--- a/tests/rustdoc-ui/2024-doctests-crate-attribute.rs
+++ b/tests/rustdoc-ui/2024-doctests-crate-attribute.rs
@@ -1,5 +1,6 @@
 //@ check-pass
-//@ compile-flags: --test --test-args=--test-threads=1 -Zunstable-options --edition 2024
+//@ edition: 2024
+//@ compile-flags: --test --test-args=--test-threads=1
 //@ normalize-stdout-test: "tests/rustdoc-ui" -> "$$DIR"
 //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
 //@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
diff --git a/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout b/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout
index 29702ce8929..c084ac4522e 100644
--- a/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout
+++ b/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout
@@ -1,12 +1,12 @@
 
 running 1 test
-test $DIR/2024-doctests-crate-attribute.rs - Foo (line 19) ... ok
+test $DIR/2024-doctests-crate-attribute.rs - Foo (line 20) ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
 
 running 1 test
-test $DIR/2024-doctests-crate-attribute.rs - Foo (line 10) ... ok
+test $DIR/2024-doctests-crate-attribute.rs - Foo (line 11) ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
diff --git a/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs b/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs
index 354427000bf..388b8f310ae 100644
--- a/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs
+++ b/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs
@@ -1,5 +1,4 @@
 //@ edition:2024
-//@ compile-flags:-Z unstable-options
 #![crate_name="extern_macros"]
 #[macro_export]
 macro_rules! attrs_on_struct {
diff --git a/tests/rustdoc-ui/doctest/dead-code-2024.rs b/tests/rustdoc-ui/doctest/dead-code-2024.rs
index 4c77112e61a..41459c5e651 100644
--- a/tests/rustdoc-ui/doctest/dead-code-2024.rs
+++ b/tests/rustdoc-ui/doctest/dead-code-2024.rs
@@ -1,6 +1,7 @@
 // This test ensures that the 2024 edition merged doctest will not use `#[allow(unused)]`.
 
-//@ compile-flags:--test -Zunstable-options --edition 2024
+//@ edition: 2024
+//@ compile-flags:--test
 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
 //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
 //@ failure-status: 101
diff --git a/tests/rustdoc-ui/doctest/dead-code-2024.stdout b/tests/rustdoc-ui/doctest/dead-code-2024.stdout
index 69dd4e2ede1..a943a177e10 100644
--- a/tests/rustdoc-ui/doctest/dead-code-2024.stdout
+++ b/tests/rustdoc-ui/doctest/dead-code-2024.stdout
@@ -1,18 +1,18 @@
 
 running 1 test
-test $DIR/dead-code-2024.rs - f (line 12) - compile ... FAILED
+test $DIR/dead-code-2024.rs - f (line 13) - compile ... FAILED
 
 failures:
 
----- $DIR/dead-code-2024.rs - f (line 12) stdout ----
+---- $DIR/dead-code-2024.rs - f (line 13) stdout ----
 error: trait `T` is never used
-  --> $DIR/dead-code-2024.rs:13:7
+  --> $DIR/dead-code-2024.rs:14:7
    |
 LL | trait T { fn f(); }
    |       ^
    |
 note: the lint level is defined here
-  --> $DIR/dead-code-2024.rs:11:9
+  --> $DIR/dead-code-2024.rs:12:9
    |
 LL | #![deny(warnings)]
    |         ^^^^^^^^
@@ -23,7 +23,7 @@ error: aborting due to 1 previous error
 Couldn't compile the test.
 
 failures:
-    $DIR/dead-code-2024.rs - f (line 12)
+    $DIR/dead-code-2024.rs - f (line 13)
 
 test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs
index 4018e37105f..d057218688c 100644
--- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs
+++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs
@@ -1,7 +1,8 @@
 // FIXME: if/when the output of the test harness can be tested on its own, this test should be
 // adapted to use that, and that normalize line can go away
 
-//@ compile-flags:--test -Z unstable-options --edition 2024
+//@ edition: 2024
+//@ compile-flags:--test
 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
 //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
 //@ failure-status: 101
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout
index cb3456e087e..90c0463d832 100644
--- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout
+++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout
@@ -1,14 +1,14 @@
 
 running 1 test
-test $DIR/failed-doctest-should-panic.rs - Foo (line 9) - should panic ... FAILED
+test $DIR/failed-doctest-should-panic.rs - Foo (line 10) - should panic ... FAILED
 
 failures:
 
----- $DIR/failed-doctest-should-panic.rs - Foo (line 9) stdout ----
+---- $DIR/failed-doctest-should-panic.rs - Foo (line 10) stdout ----
 note: test did not panic as expected
 
 failures:
-    $DIR/failed-doctest-should-panic.rs - Foo (line 9)
+    $DIR/failed-doctest-should-panic.rs - Foo (line 10)
 
 test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs
index 4c21d542951..754791361e8 100644
--- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs
+++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs
@@ -1,4 +1,5 @@
-//@ compile-flags:--test --test-args=--test-threads=1 -Zunstable-options --edition 2024
+//@ edition: 2024
+//@ compile-flags:--test --test-args=--test-threads=1
 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
 //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
 //@ check-pass
diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout
index f2cb1e7e72f..a32da0aeb96 100644
--- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout
+++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout
@@ -1,7 +1,7 @@
 
 running 2 tests
-test $DIR/merged-ignore-no_run.rs - ignored (line 6) ... ignored
-test $DIR/merged-ignore-no_run.rs - no_run (line 11) - compile ... ok
+test $DIR/merged-ignore-no_run.rs - ignored (line 7) ... ignored
+test $DIR/merged-ignore-no_run.rs - no_run (line 12) - compile ... ok
 
 test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME
 
diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs
index aac43031546..35d1c738bb1 100644
--- a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs
+++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs
@@ -1,6 +1,7 @@
 // This test checks that it will output warnings for usage of `standalone` or `standalone_crate`.
 
-//@ compile-flags:--test -Zunstable-options --edition 2024
+//@ edition: 2024
+//@ compile-flags:--test
 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
 //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
 //@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr b/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr
index d69d03d8657..bfc1e919404 100644
--- a/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr
+++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr
@@ -1,34 +1,34 @@
 error: unknown attribute `standalone`
-  --> $DIR/standalone-warning-2024.rs:10:1
+  --> $DIR/standalone-warning-2024.rs:11:1
    |
-10 | / //! ```standalone
-11 | | //! bla
-12 | | //! ```
-13 | | //!
-14 | | //! ```standalone-crate
-15 | | //! bla
-16 | | //! ```
+11 | / //! ```standalone
+12 | | //! bla
+13 | | //! ```
+14 | | //!
+15 | | //! ```standalone-crate
+16 | | //! bla
+17 | | //! ```
    | |_______^
    |
    = help: use `standalone_crate` to compile this code block separately
    = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
 note: the lint level is defined here
-  --> $DIR/standalone-warning-2024.rs:8:9
+  --> $DIR/standalone-warning-2024.rs:9:9
    |
-8  | #![deny(warnings)]
+9  | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]`
 
 error: unknown attribute `standalone-crate`
-  --> $DIR/standalone-warning-2024.rs:10:1
+  --> $DIR/standalone-warning-2024.rs:11:1
    |
-10 | / //! ```standalone
-11 | | //! bla
-12 | | //! ```
-13 | | //!
-14 | | //! ```standalone-crate
-15 | | //! bla
-16 | | //! ```
+11 | / //! ```standalone
+12 | | //! bla
+13 | | //! ```
+14 | | //!
+15 | | //! ```standalone-crate
+16 | | //! bla
+17 | | //! ```
    | |_______^
    |
    = help: use `standalone_crate` to compile this code block separately
diff --git a/tests/rustdoc-ui/doctest/wrong-ast-2024.rs b/tests/rustdoc-ui/doctest/wrong-ast-2024.rs
index 7b4fa8fd2c9..a1455c01bc6 100644
--- a/tests/rustdoc-ui/doctest/wrong-ast-2024.rs
+++ b/tests/rustdoc-ui/doctest/wrong-ast-2024.rs
@@ -1,4 +1,5 @@
-//@ compile-flags:--test --test-args=--test-threads=1 -Zunstable-options --edition 2024
+//@ edition: 2024
+//@ compile-flags:--test --test-args=--test-threads=1
 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
 //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
 //@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
diff --git a/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout b/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout
index 22c8ce468fd..62e1fb10b9f 100644
--- a/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout
+++ b/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout
@@ -1,17 +1,17 @@
 
 running 1 test
-test $DIR/wrong-ast-2024.rs - three (line 17) - should panic ... ok
+test $DIR/wrong-ast-2024.rs - three (line 18) - should panic ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
 
 running 2 tests
-test $DIR/wrong-ast-2024.rs - one (line 7) ... FAILED
-test $DIR/wrong-ast-2024.rs - two (line 12) ... FAILED
+test $DIR/wrong-ast-2024.rs - one (line 8) ... FAILED
+test $DIR/wrong-ast-2024.rs - two (line 13) ... FAILED
 
 failures:
 
----- $DIR/wrong-ast-2024.rs - one (line 7) stdout ----
+---- $DIR/wrong-ast-2024.rs - one (line 8) stdout ----
 error[E0758]: unterminated block comment
   --> $DIR/wrong-ast-2024.rs:$LINE:$COL
    |
@@ -22,7 +22,7 @@ error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0758`.
 Couldn't compile the test.
----- $DIR/wrong-ast-2024.rs - two (line 12) stdout ----
+---- $DIR/wrong-ast-2024.rs - two (line 13) stdout ----
 error: unexpected closing delimiter: `}`
   --> $DIR/wrong-ast-2024.rs:$LINE:$COL
    |
@@ -34,8 +34,8 @@ error: aborting due to 1 previous error
 Couldn't compile the test.
 
 failures:
-    $DIR/wrong-ast-2024.rs - one (line 7)
-    $DIR/wrong-ast-2024.rs - two (line 12)
+    $DIR/wrong-ast-2024.rs - one (line 8)
+    $DIR/wrong-ast-2024.rs - two (line 13)
 
 test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs b/tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs
new file mode 100644
index 00000000000..5d3d3c196e1
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs
@@ -0,0 +1,20 @@
+//@ force-host
+//@ no-prefer-dynamic
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+mod view {}
+
+/// [`view`]
+#[proc_macro]
+pub fn f(_: TokenStream) -> TokenStream {
+    todo!()
+}
+
+/// [`f()`]
+#[proc_macro]
+pub fn g(_: TokenStream) -> TokenStream {
+    todo!()
+}
diff --git a/tests/rustdoc-ui/intra-doc/pub-proc-item.rs b/tests/rustdoc-ui/intra-doc/pub-proc-item.rs
new file mode 100644
index 00000000000..413efb40b0d
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/pub-proc-item.rs
@@ -0,0 +1,8 @@
+//@ aux-build:in-proc-item-comment.rs
+//@ check-pass
+
+// issue#132743
+
+extern crate in_proc_item_comment;
+
+pub use in_proc_item_comment::{f, g};
diff --git a/tests/rustdoc-ui/unable-fulfill-trait.rs b/tests/rustdoc-ui/unable-fulfill-trait.rs
index 4edc7ab76c1..49dce32072b 100644
--- a/tests/rustdoc-ui/unable-fulfill-trait.rs
+++ b/tests/rustdoc-ui/unable-fulfill-trait.rs
@@ -3,7 +3,6 @@
 pub struct Foo<'a, 'b, T> {
     field1: dyn Bar<'a, 'b>,
     //~^ ERROR
-    //~| ERROR
 }
 
 pub trait Bar<'x, 's, U>
diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr
index 12e53546cda..2786a005cd1 100644
--- a/tests/rustdoc-ui/unable-fulfill-trait.stderr
+++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr
@@ -5,7 +5,7 @@ LL |     field1: dyn Bar<'a, 'b>,
    |                 ^^^ expected 1 generic argument
    |
 note: trait defined here, with 1 generic parameter: `U`
-  --> $DIR/unable-fulfill-trait.rs:9:11
+  --> $DIR/unable-fulfill-trait.rs:8:11
    |
 LL | pub trait Bar<'x, 's, U>
    |           ^^^         -
@@ -14,13 +14,6 @@ help: add missing generic argument
 LL |     field1: dyn Bar<'a, 'b, U>,
    |                           +++
 
-error[E0227]: ambiguous lifetime bound, explicit lifetime bound required
-  --> $DIR/unable-fulfill-trait.rs:4:13
-   |
-LL |     field1: dyn Bar<'a, 'b>,
-   |             ^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0107, E0227.
-For more information about an error, try `rustc --explain E0107`.
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/rustdoc/jump-to-def-prelude-types.rs b/tests/rustdoc/jump-to-def-prelude-types.rs
new file mode 100644
index 00000000000..43617b1bc9d
--- /dev/null
+++ b/tests/rustdoc/jump-to-def-prelude-types.rs
@@ -0,0 +1,23 @@
+// This test checks that prelude types like `Result` and `Option` still get a link generated.
+
+//@ compile-flags: -Zunstable-options --generate-link-to-definition
+
+#![crate_name = "foo"]
+
+//@ has 'src/foo/jump-to-def-prelude-types.rs.html'
+// FIXME: would be nice to be able to check both the class and the href at the same time so
+// we could check the text as well...
+//@ has - '//a[@class="prelude-ty"]/@href' '{{channel}}/core/result/enum.Result.html'
+//@ has - '//a[@class="prelude-ty"]/@href' '{{channel}}/core/option/enum.Option.html'
+pub fn foo() -> Result<Option<()>, ()> { Err(()) }
+
+// This part is to ensure that they are not linking to the actual prelude ty.
+pub mod bar {
+    struct Result;
+    struct Option;
+
+    //@ has - '//a[@href="#16"]' 'Result'
+    pub fn bar() -> Result { Result }
+    //@ has - '//a[@href="#17"]' 'Option'
+    pub fn bar2() -> Option { Option }
+}
diff --git a/tests/ui-fulldeps/obtain-borrowck.rs b/tests/ui-fulldeps/obtain-borrowck.rs
index e6c703addd9..af98f93297b 100644
--- a/tests/ui-fulldeps/obtain-borrowck.rs
+++ b/tests/ui-fulldeps/obtain-borrowck.rs
@@ -25,19 +25,20 @@ extern crate rustc_interface;
 extern crate rustc_middle;
 extern crate rustc_session;
 
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::thread_local;
+
 use rustc_borrowck::consumers::{self, BodyWithBorrowckFacts, ConsumerOptions};
 use rustc_driver::Compilation;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
+use rustc_interface::Config;
 use rustc_interface::interface::Compiler;
-use rustc_interface::{Config, Queries};
 use rustc_middle::query::queries::mir_borrowck::ProvidedValue;
 use rustc_middle::ty::TyCtxt;
 use rustc_middle::util::Providers;
 use rustc_session::Session;
-use std::cell::RefCell;
-use std::collections::HashMap;
-use std::thread_local;
 
 fn main() {
     let exit_code = rustc_driver::catch_with_exit_code(move || {
@@ -63,55 +64,49 @@ impl rustc_driver::Callbacks for CompilerCalls {
 
     // In this callback we trigger borrow checking of all functions and obtain
     // the result.
-    fn after_analysis<'tcx>(
-        &mut self,
-        compiler: &Compiler,
-        queries: &'tcx Queries<'tcx>,
-    ) -> Compilation {
-        compiler.sess.dcx().abort_if_errors();
-        queries.global_ctxt().unwrap().enter(|tcx| {
-            // Collect definition ids of MIR bodies.
-            let hir = tcx.hir();
-            let mut bodies = Vec::new();
-
-            let crate_items = tcx.hir_crate_items(());
-            for id in crate_items.free_items() {
-                if matches!(tcx.def_kind(id.owner_id), DefKind::Fn) {
-                    bodies.push(id.owner_id);
-                }
+    fn after_analysis<'tcx>(&mut self, _compiler: &Compiler, tcx: TyCtxt<'tcx>) -> Compilation {
+        tcx.sess.dcx().abort_if_errors();
+        // Collect definition ids of MIR bodies.
+        let hir = tcx.hir();
+        let mut bodies = Vec::new();
+
+        let crate_items = tcx.hir_crate_items(());
+        for id in crate_items.free_items() {
+            if matches!(tcx.def_kind(id.owner_id), DefKind::Fn) {
+                bodies.push(id.owner_id);
             }
-
-            for id in crate_items.trait_items() {
-                if matches!(tcx.def_kind(id.owner_id), DefKind::AssocFn) {
-                    let trait_item = hir.trait_item(id);
-                    if let rustc_hir::TraitItemKind::Fn(_, trait_fn) = &trait_item.kind {
-                        if let rustc_hir::TraitFn::Provided(_) = trait_fn {
-                            bodies.push(trait_item.owner_id);
-                        }
+        }
+
+        for id in crate_items.trait_items() {
+            if matches!(tcx.def_kind(id.owner_id), DefKind::AssocFn) {
+                let trait_item = hir.trait_item(id);
+                if let rustc_hir::TraitItemKind::Fn(_, trait_fn) = &trait_item.kind {
+                    if let rustc_hir::TraitFn::Provided(_) = trait_fn {
+                        bodies.push(trait_item.owner_id);
                     }
                 }
             }
+        }
 
-            for id in crate_items.impl_items() {
-                if matches!(tcx.def_kind(id.owner_id), DefKind::AssocFn) {
-                    bodies.push(id.owner_id);
-                }
-            }
-
-            // Trigger borrow checking of all bodies.
-            for def_id in bodies {
-                let _ = tcx.optimized_mir(def_id);
-            }
-
-            // See what bodies were borrow checked.
-            let mut bodies = get_bodies(tcx);
-            bodies.sort_by(|(def_id1, _), (def_id2, _)| def_id1.cmp(def_id2));
-            println!("Bodies retrieved for:");
-            for (def_id, body) in bodies {
-                println!("{}", def_id);
-                assert!(body.input_facts.unwrap().cfg_edge.len() > 0);
+        for id in crate_items.impl_items() {
+            if matches!(tcx.def_kind(id.owner_id), DefKind::AssocFn) {
+                bodies.push(id.owner_id);
             }
-        });
+        }
+
+        // Trigger borrow checking of all bodies.
+        for def_id in bodies {
+            let _ = tcx.optimized_mir(def_id);
+        }
+
+        // See what bodies were borrow checked.
+        let mut bodies = get_bodies(tcx);
+        bodies.sort_by(|(def_id1, _), (def_id2, _)| def_id1.cmp(def_id2));
+        println!("Bodies retrieved for:");
+        for (def_id, body) in bodies {
+            println!("{}", def_id);
+            assert!(body.input_facts.unwrap().cfg_edge.len() > 0);
+        }
 
         Compilation::Continue
     }
diff --git a/tests/ui-fulldeps/stable-mir/check_abi.rs b/tests/ui-fulldeps/stable-mir/check_abi.rs
index 5b7da7bb129..8caf3032afc 100644
--- a/tests/ui-fulldeps/stable-mir/check_abi.rs
+++ b/tests/ui-fulldeps/stable-mir/check_abi.rs
@@ -11,6 +11,7 @@
 #![feature(ascii_char, ascii_char_variants)]
 
 extern crate rustc_hir;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_allocation.rs b/tests/ui-fulldeps/stable-mir/check_allocation.rs
index 1e2f640f39f..072c8ba6a44 100644
--- a/tests/ui-fulldeps/stable-mir/check_allocation.rs
+++ b/tests/ui-fulldeps/stable-mir/check_allocation.rs
@@ -13,6 +13,7 @@
 #![feature(ascii_char, ascii_char_variants)]
 
 extern crate rustc_hir;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_attribute.rs b/tests/ui-fulldeps/stable-mir/check_attribute.rs
index 131fd99ebaa..22481e275a9 100644
--- a/tests/ui-fulldeps/stable-mir/check_attribute.rs
+++ b/tests/ui-fulldeps/stable-mir/check_attribute.rs
@@ -9,6 +9,7 @@
 #![feature(rustc_private)]
 
 extern crate rustc_hir;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_binop.rs b/tests/ui-fulldeps/stable-mir/check_binop.rs
index 3b52d88de3c..8c44e285108 100644
--- a/tests/ui-fulldeps/stable-mir/check_binop.rs
+++ b/tests/ui-fulldeps/stable-mir/check_binop.rs
@@ -9,6 +9,7 @@
 #![feature(rustc_private)]
 
 extern crate rustc_hir;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_crate_defs.rs b/tests/ui-fulldeps/stable-mir/check_crate_defs.rs
index e039ca07dd4..ed093903381 100644
--- a/tests/ui-fulldeps/stable-mir/check_crate_defs.rs
+++ b/tests/ui-fulldeps/stable-mir/check_crate_defs.rs
@@ -10,6 +10,7 @@
 #![feature(assert_matches)]
 
 extern crate rustc_hir;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_def_ty.rs b/tests/ui-fulldeps/stable-mir/check_def_ty.rs
index ec3cf1753e2..482dbd22d5f 100644
--- a/tests/ui-fulldeps/stable-mir/check_def_ty.rs
+++ b/tests/ui-fulldeps/stable-mir/check_def_ty.rs
@@ -11,6 +11,7 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_defs.rs b/tests/ui-fulldeps/stable-mir/check_defs.rs
index 3402b345818..bf1f1a2ceab 100644
--- a/tests/ui-fulldeps/stable-mir/check_defs.rs
+++ b/tests/ui-fulldeps/stable-mir/check_defs.rs
@@ -10,6 +10,7 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_instance.rs b/tests/ui-fulldeps/stable-mir/check_instance.rs
index 7d63e202fa6..464350b1045 100644
--- a/tests/ui-fulldeps/stable-mir/check_instance.rs
+++ b/tests/ui-fulldeps/stable-mir/check_instance.rs
@@ -10,6 +10,7 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
index 3534228f73e..6edebaf756c 100644
--- a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
+++ b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
@@ -13,6 +13,7 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 
+extern crate rustc_middle;
 extern crate rustc_hir;
 #[macro_use]
 extern crate rustc_smir;
diff --git a/tests/ui-fulldeps/stable-mir/check_item_kind.rs b/tests/ui-fulldeps/stable-mir/check_item_kind.rs
index 91baa074c10..23b54e6c60b 100644
--- a/tests/ui-fulldeps/stable-mir/check_item_kind.rs
+++ b/tests/ui-fulldeps/stable-mir/check_item_kind.rs
@@ -10,6 +10,7 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_normalization.rs b/tests/ui-fulldeps/stable-mir/check_normalization.rs
index 72e410f8080..928173b154b 100644
--- a/tests/ui-fulldeps/stable-mir/check_normalization.rs
+++ b/tests/ui-fulldeps/stable-mir/check_normalization.rs
@@ -9,6 +9,7 @@
 
 #![feature(rustc_private)]
 
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_trait_queries.rs b/tests/ui-fulldeps/stable-mir/check_trait_queries.rs
index 8721f243587..304a7ce9255 100644
--- a/tests/ui-fulldeps/stable-mir/check_trait_queries.rs
+++ b/tests/ui-fulldeps/stable-mir/check_trait_queries.rs
@@ -10,6 +10,7 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_transform.rs b/tests/ui-fulldeps/stable-mir/check_transform.rs
index 40217b9aa95..bcf79c456b0 100644
--- a/tests/ui-fulldeps/stable-mir/check_transform.rs
+++ b/tests/ui-fulldeps/stable-mir/check_transform.rs
@@ -11,6 +11,7 @@
 #![feature(ascii_char, ascii_char_variants)]
 
 extern crate rustc_hir;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
index 0715e0cfc52..e21508c9b46 100644
--- a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
+++ b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
@@ -11,6 +11,7 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/compilation-result.rs b/tests/ui-fulldeps/stable-mir/compilation-result.rs
index 286bbd7c594..d921de73f43 100644
--- a/tests/ui-fulldeps/stable-mir/compilation-result.rs
+++ b/tests/ui-fulldeps/stable-mir/compilation-result.rs
@@ -10,6 +10,7 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index 6b458c5d923..53be8eb10c1 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -11,6 +11,7 @@
 #![feature(assert_matches)]
 
 extern crate rustc_hir;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/projections.rs b/tests/ui-fulldeps/stable-mir/projections.rs
index a8bf4c1d399..fdb7eeed1b0 100644
--- a/tests/ui-fulldeps/stable-mir/projections.rs
+++ b/tests/ui-fulldeps/stable-mir/projections.rs
@@ -11,6 +11,7 @@
 #![feature(assert_matches)]
 
 extern crate rustc_hir;
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui-fulldeps/stable-mir/smir_visitor.rs b/tests/ui-fulldeps/stable-mir/smir_visitor.rs
index f1bc03781b9..666000d3b07 100644
--- a/tests/ui-fulldeps/stable-mir/smir_visitor.rs
+++ b/tests/ui-fulldeps/stable-mir/smir_visitor.rs
@@ -10,6 +10,7 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 
+extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_smir;
 extern crate rustc_driver;
diff --git a/tests/ui/abi/anon-extern-mod.rs b/tests/ui/abi/anon-extern-mod.rs
index bb3739bc4af..134542b9cff 100644
--- a/tests/ui/abi/anon-extern-mod.rs
+++ b/tests/ui/abi/anon-extern-mod.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #[link(name = "rust_test_helpers", kind = "static")]
 extern "C" {
diff --git a/tests/ui/abi/c-stack-as-value.rs b/tests/ui/abi/c-stack-as-value.rs
index 401bc132b6e..10933bdb278 100644
--- a/tests/ui/abi/c-stack-as-value.rs
+++ b/tests/ui/abi/c-stack-as-value.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 mod rustrt {
     #[link(name = "rust_test_helpers", kind = "static")]
diff --git a/tests/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs b/tests/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
index 95bf4df68df..b2d06444c13 100644
--- a/tests/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
+++ b/tests/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 //@ aux-build:anon-extern-mod-cross-crate-1.rs
-//@ pretty-expanded FIXME #23616
 
 extern crate anonexternmod;
 
diff --git a/tests/ui/abi/cross-crate/duplicated-external-mods.rs b/tests/ui/abi/cross-crate/duplicated-external-mods.rs
index 2a3875d2773..19a9b07d65c 100644
--- a/tests/ui/abi/cross-crate/duplicated-external-mods.rs
+++ b/tests/ui/abi/cross-crate/duplicated-external-mods.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:anon-extern-mod-cross-crate-1.rs
 //@ aux-build:anon-extern-mod-cross-crate-1.rs
-//@ pretty-expanded FIXME #23616
 
 extern crate anonexternmod;
 
diff --git a/tests/ui/abi/extern/extern-pass-empty.rs b/tests/ui/abi/extern/extern-pass-empty.rs
index f168f5faa17..1ad52b128ad 100644
--- a/tests/ui/abi/extern/extern-pass-empty.rs
+++ b/tests/ui/abi/extern/extern-pass-empty.rs
@@ -3,7 +3,6 @@
 
 // Test a foreign function that accepts empty struct.
 
-//@ pretty-expanded FIXME #23616
 //@ ignore-msvc
 //@ ignore-emscripten emcc asserts on an empty struct as an argument
 
diff --git a/tests/ui/abi/foreign/invoke-external-foreign.rs b/tests/ui/abi/foreign/invoke-external-foreign.rs
index 78cc84804bf..a22b12af672 100644
--- a/tests/ui/abi/foreign/invoke-external-foreign.rs
+++ b/tests/ui/abi/foreign/invoke-external-foreign.rs
@@ -5,7 +5,6 @@
 // successfully (and safely) invoke external, cdecl
 // functions from outside the crate.
 
-//@ pretty-expanded FIXME #23616
 
 extern crate foreign_lib;
 
diff --git a/tests/ui/alias-uninit-value.rs b/tests/ui/alias-uninit-value.rs
index 3223bac1820..0084a98e627 100644
--- a/tests/ui/alias-uninit-value.rs
+++ b/tests/ui/alias-uninit-value.rs
@@ -7,7 +7,6 @@
 
 // Regression test for issue #374
 
-//@ pretty-expanded FIXME #23616
 
 enum sty { ty_nil, }
 
diff --git a/tests/ui/array-slice-vec/cast-in-array-size.rs b/tests/ui/array-slice-vec/cast-in-array-size.rs
index cb5072564b2..5276288f819 100644
--- a/tests/ui/array-slice-vec/cast-in-array-size.rs
+++ b/tests/ui/array-slice-vec/cast-in-array-size.rs
@@ -2,7 +2,6 @@
 
 
 // issues #10618 and #16382
-//@ pretty-expanded FIXME #23616
 
 const SIZE: isize = 25;
 
diff --git a/tests/ui/array-slice-vec/empty-mutable-vec.rs b/tests/ui/array-slice-vec/empty-mutable-vec.rs
index 663071bf613..1785b1aa39e 100644
--- a/tests/ui/array-slice-vec/empty-mutable-vec.rs
+++ b/tests/ui/array-slice-vec/empty-mutable-vec.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_mut)]
 
diff --git a/tests/ui/array-slice-vec/issue-15730.rs b/tests/ui/array-slice-vec/issue-15730.rs
index fe9d908a1ff..2a69417819d 100644
--- a/tests/ui/array-slice-vec/issue-15730.rs
+++ b/tests/ui/array-slice-vec/issue-15730.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_mut)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let mut array = [1, 2, 3];
diff --git a/tests/ui/array-slice-vec/issue-18425.rs b/tests/ui/array-slice-vec/issue-18425.rs
index 22345718ad8..e74a20de726 100644
--- a/tests/ui/array-slice-vec/issue-18425.rs
+++ b/tests/ui/array-slice-vec/issue-18425.rs
@@ -2,7 +2,6 @@
 // Check that codegen doesn't ICE when codegenning an array repeat
 // expression with a count of 1 and a non-Copy element type.
 
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let _ = [Box::new(1_usize); 1];
diff --git a/tests/ui/array-slice-vec/match_arr_unknown_len.stderr b/tests/ui/array-slice-vec/match_arr_unknown_len.stderr
index 3ed0d6bdf3a..f617ff33938 100644
--- a/tests/ui/array-slice-vec/match_arr_unknown_len.stderr
+++ b/tests/ui/array-slice-vec/match_arr_unknown_len.stderr
@@ -2,10 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/match_arr_unknown_len.rs:3:9
    |
 LL |         [1, 2] => true,
-   |         ^^^^^^ expected `2`, found `N`
-   |
-   = note: expected array `[u32; 2]`
-              found array `[u32; N]`
+   |         ^^^^^^ expected an array with a size of 2, found one with a size of N
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/array-slice-vec/mut-vstore-expr.rs b/tests/ui/array-slice-vec/mut-vstore-expr.rs
index 809c001b079..9553aed9a00 100644
--- a/tests/ui/array-slice-vec/mut-vstore-expr.rs
+++ b/tests/ui/array-slice-vec/mut-vstore-expr.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let _x: &mut [isize] = &mut [ 1, 2, 3 ];
diff --git a/tests/ui/array-slice-vec/vec-macro-with-brackets.rs b/tests/ui/array-slice-vec/vec-macro-with-brackets.rs
index 65ca182b615..b62e294f9d1 100644
--- a/tests/ui/array-slice-vec/vec-macro-with-brackets.rs
+++ b/tests/ui/array-slice-vec/vec-macro-with-brackets.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_variables)]
 
-//@ pretty-expanded FIXME #23616
 
 macro_rules! vec [
     ($($e:expr),*) => ({
diff --git a/tests/ui/array-slice-vec/vec-repeat-with-cast.rs b/tests/ui/array-slice-vec/vec-repeat-with-cast.rs
index 4af38d9cf32..1f1fd4cd0d2 100644
--- a/tests/ui/array-slice-vec/vec-repeat-with-cast.rs
+++ b/tests/ui/array-slice-vec/vec-repeat-with-cast.rs
@@ -1,5 +1,4 @@
 //@ run-pass
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() { let _a = [0; 1 as usize]; }
diff --git a/tests/ui/array-slice-vec/vector-no-ann-2.rs b/tests/ui/array-slice-vec/vector-no-ann-2.rs
index b130c6bc2ff..63828551af1 100644
--- a/tests/ui/array-slice-vec/vector-no-ann-2.rs
+++ b/tests/ui/array-slice-vec/vector-no-ann-2.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let _quux: Box<Vec<usize>> = Box::new(Vec::new());
diff --git a/tests/ui/asm/s390x/bad-reg.rs b/tests/ui/asm/s390x/bad-reg.rs
index 6de43fdfe5e..144215b1a3d 100644
--- a/tests/ui/asm/s390x/bad-reg.rs
+++ b/tests/ui/asm/s390x/bad-reg.rs
@@ -1,19 +1,31 @@
 //@ add-core-stubs
 //@ needs-asm-support
-//@ revisions: s390x
+//@ revisions: s390x s390x_vector s390x_vector_stable
 //@[s390x] compile-flags: --target s390x-unknown-linux-gnu
 //@[s390x] needs-llvm-components: systemz
+//@[s390x_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector
+//@[s390x_vector] needs-llvm-components: systemz
+//@[s390x_vector_stable] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector
+//@[s390x_vector_stable] needs-llvm-components: systemz
 
 #![crate_type = "rlib"]
-#![feature(no_core, rustc_attrs)]
-#![feature(asm_experimental_arch)]
+#![feature(no_core, rustc_attrs, repr_simd)]
+#![cfg_attr(not(s390x_vector_stable), feature(asm_experimental_reg))]
 #![no_core]
+#![allow(non_camel_case_types)]
 
 extern crate minicore;
 use minicore::*;
 
+#[repr(simd)]
+pub struct i64x2([i64; 2]);
+
+impl Copy for i64x2 {}
+
 fn f() {
     let mut x = 0;
+    let mut b = 0u8;
+    let mut v = i64x2([0; 2]);
     unsafe {
         // Unsupported registers
         asm!("", out("r11") _);
@@ -57,6 +69,51 @@ fn f() {
         asm!("", out("a1") _);
         //~^ ERROR invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
 
+        // vreg
+        asm!("", out("v0") _); // always ok
+        asm!("", in("v0") v); // requires vector & asm_experimental_reg
+        //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
+        //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658]
+        //[s390x_vector_stable]~| ERROR type `i64x2` cannot be used with this register class in stable [E0658]
+        asm!("", out("v0") v); // requires vector & asm_experimental_reg
+        //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
+        //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658]
+        //[s390x_vector_stable]~| ERROR type `i64x2` cannot be used with this register class in stable [E0658]
+        asm!("", in("v0") x); // requires vector & asm_experimental_reg
+        //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
+        //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658]
+        //[s390x_vector_stable]~| ERROR type `i32` cannot be used with this register class in stable [E0658]
+        asm!("", out("v0") x); // requires vector & asm_experimental_reg
+        //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
+        //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658]
+        //[s390x_vector_stable]~| ERROR type `i32` cannot be used with this register class in stable [E0658]
+        asm!("", in("v0") b);
+        //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
+        //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class
+        //[s390x_vector_stable]~^^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658]
+        //[s390x_vector_stable]~| ERROR type `u8` cannot be used with this register class
+        asm!("", out("v0") b);
+        //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
+        //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class
+        //[s390x_vector_stable]~^^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658]
+        //[s390x_vector_stable]~| ERROR type `u8` cannot be used with this register class
+        asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg
+        //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
+        //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658]
+        //[s390x_vector_stable]~| ERROR type `i64x2` cannot be used with this register class in stable [E0658]
+        asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg
+        //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
+        //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658]
+        //[s390x_vector_stable]~| ERROR type `i32` cannot be used with this register class in stable [E0658]
+        asm!("/* {} */", in(vreg) b);
+        //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
+        //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class
+        //[s390x_vector_stable]~^^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658]
+        //[s390x_vector_stable]~| ERROR type `u8` cannot be used with this register class
+        asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg
+        //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
+        //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658]
+
         // Clobber-only registers
         // areg
         asm!("", out("a2") _); // ok
@@ -72,21 +129,6 @@ fn f() {
         asm!("/* {} */", out(areg) _);
         //~^ ERROR can only be used as a clobber
 
-        // vreg
-        asm!("", out("v0") _); // ok
-        // FIXME: will be supported in https://github.com/rust-lang/rust/pull/131664
-        asm!("", in("v0") x);
-        //~^ ERROR can only be used as a clobber
-        //~| ERROR type `i32` cannot be used with this register class
-        asm!("", out("v0") x);
-        //~^ ERROR can only be used as a clobber
-        //~| ERROR type `i32` cannot be used with this register class
-        asm!("/* {} */", in(vreg) x);
-        //~^ ERROR can only be used as a clobber
-        //~| ERROR type `i32` cannot be used with this register class
-        asm!("/* {} */", out(vreg) _);
-        //~^ ERROR can only be used as a clobber
-
         // Overlapping registers
         // vreg/freg
         asm!("", out("v0") _, out("f0") _);
diff --git a/tests/ui/asm/s390x/bad-reg.s390x.stderr b/tests/ui/asm/s390x/bad-reg.s390x.stderr
index 460d7c15de1..238419b376b 100644
--- a/tests/ui/asm/s390x/bad-reg.s390x.stderr
+++ b/tests/ui/asm/s390x/bad-reg.s390x.stderr
@@ -1,173 +1,149 @@
 error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:19:18
+  --> $DIR/bad-reg.rs:31:18
    |
 LL |         asm!("", out("r11") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:21:18
+  --> $DIR/bad-reg.rs:33:18
    |
 LL |         asm!("", out("r15") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:23:18
+  --> $DIR/bad-reg.rs:35:18
    |
 LL |         asm!("", out("c0") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:25:18
+  --> $DIR/bad-reg.rs:37:18
    |
 LL |         asm!("", out("c1") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:27:18
+  --> $DIR/bad-reg.rs:39:18
    |
 LL |         asm!("", out("c2") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:29:18
+  --> $DIR/bad-reg.rs:41:18
    |
 LL |         asm!("", out("c3") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:31:18
+  --> $DIR/bad-reg.rs:43:18
    |
 LL |         asm!("", out("c4") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:33:18
+  --> $DIR/bad-reg.rs:45:18
    |
 LL |         asm!("", out("c5") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:35:18
+  --> $DIR/bad-reg.rs:47:18
    |
 LL |         asm!("", out("c6") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:37:18
+  --> $DIR/bad-reg.rs:49:18
    |
 LL |         asm!("", out("c7") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:39:18
+  --> $DIR/bad-reg.rs:51:18
    |
 LL |         asm!("", out("c8") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:41:18
+  --> $DIR/bad-reg.rs:53:18
    |
 LL |         asm!("", out("c9") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:43:18
+  --> $DIR/bad-reg.rs:55:18
    |
 LL |         asm!("", out("c10") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:45:18
+  --> $DIR/bad-reg.rs:57:18
    |
 LL |         asm!("", out("c11") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:47:18
+  --> $DIR/bad-reg.rs:59:18
    |
 LL |         asm!("", out("c12") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:49:18
+  --> $DIR/bad-reg.rs:61:18
    |
 LL |         asm!("", out("c13") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:51:18
+  --> $DIR/bad-reg.rs:63:18
    |
 LL |         asm!("", out("c14") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:53:18
+  --> $DIR/bad-reg.rs:65:18
    |
 LL |         asm!("", out("c15") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:55:18
+  --> $DIR/bad-reg.rs:67:18
    |
 LL |         asm!("", out("a0") _);
    |                  ^^^^^^^^^^^
 
 error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
-  --> $DIR/bad-reg.rs:57:18
+  --> $DIR/bad-reg.rs:69:18
    |
 LL |         asm!("", out("a1") _);
    |                  ^^^^^^^^^^^
 
 error: register class `areg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:63:18
+  --> $DIR/bad-reg.rs:120:18
    |
 LL |         asm!("", in("a2") x);
    |                  ^^^^^^^^^^
 
 error: register class `areg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:66:18
+  --> $DIR/bad-reg.rs:123:18
    |
 LL |         asm!("", out("a2") x);
    |                  ^^^^^^^^^^^
 
 error: register class `areg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:69:26
+  --> $DIR/bad-reg.rs:126:26
    |
 LL |         asm!("/* {} */", in(areg) x);
    |                          ^^^^^^^^^^
 
 error: register class `areg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:72:26
+  --> $DIR/bad-reg.rs:129:26
    |
 LL |         asm!("/* {} */", out(areg) _);
    |                          ^^^^^^^^^^^
 
-error: register class `vreg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:78:18
-   |
-LL |         asm!("", in("v0") x);
-   |                  ^^^^^^^^^^
-
-error: register class `vreg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:81:18
-   |
-LL |         asm!("", out("v0") x);
-   |                  ^^^^^^^^^^^
-
-error: register class `vreg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:84:26
-   |
-LL |         asm!("/* {} */", in(vreg) x);
-   |                          ^^^^^^^^^^
-
-error: register class `vreg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:87:26
-   |
-LL |         asm!("/* {} */", out(vreg) _);
-   |                          ^^^^^^^^^^^
-
 error: register `f0` conflicts with register `v0`
-  --> $DIR/bad-reg.rs:92:31
+  --> $DIR/bad-reg.rs:134:31
    |
 LL |         asm!("", out("v0") _, out("f0") _);
    |                  -----------  ^^^^^^^^^^^ register `f0`
@@ -175,7 +151,7 @@ LL |         asm!("", out("v0") _, out("f0") _);
    |                  register `v0`
 
 error: register `f1` conflicts with register `v1`
-  --> $DIR/bad-reg.rs:94:31
+  --> $DIR/bad-reg.rs:136:31
    |
 LL |         asm!("", out("v1") _, out("f1") _);
    |                  -----------  ^^^^^^^^^^^ register `f1`
@@ -183,7 +159,7 @@ LL |         asm!("", out("v1") _, out("f1") _);
    |                  register `v1`
 
 error: register `f2` conflicts with register `v2`
-  --> $DIR/bad-reg.rs:96:31
+  --> $DIR/bad-reg.rs:138:31
    |
 LL |         asm!("", out("v2") _, out("f2") _);
    |                  -----------  ^^^^^^^^^^^ register `f2`
@@ -191,7 +167,7 @@ LL |         asm!("", out("v2") _, out("f2") _);
    |                  register `v2`
 
 error: register `f3` conflicts with register `v3`
-  --> $DIR/bad-reg.rs:98:31
+  --> $DIR/bad-reg.rs:140:31
    |
 LL |         asm!("", out("v3") _, out("f3") _);
    |                  -----------  ^^^^^^^^^^^ register `f3`
@@ -199,7 +175,7 @@ LL |         asm!("", out("v3") _, out("f3") _);
    |                  register `v3`
 
 error: register `f4` conflicts with register `v4`
-  --> $DIR/bad-reg.rs:100:31
+  --> $DIR/bad-reg.rs:142:31
    |
 LL |         asm!("", out("v4") _, out("f4") _);
    |                  -----------  ^^^^^^^^^^^ register `f4`
@@ -207,7 +183,7 @@ LL |         asm!("", out("v4") _, out("f4") _);
    |                  register `v4`
 
 error: register `f5` conflicts with register `v5`
-  --> $DIR/bad-reg.rs:102:31
+  --> $DIR/bad-reg.rs:144:31
    |
 LL |         asm!("", out("v5") _, out("f5") _);
    |                  -----------  ^^^^^^^^^^^ register `f5`
@@ -215,7 +191,7 @@ LL |         asm!("", out("v5") _, out("f5") _);
    |                  register `v5`
 
 error: register `f6` conflicts with register `v6`
-  --> $DIR/bad-reg.rs:104:31
+  --> $DIR/bad-reg.rs:146:31
    |
 LL |         asm!("", out("v6") _, out("f6") _);
    |                  -----------  ^^^^^^^^^^^ register `f6`
@@ -223,7 +199,7 @@ LL |         asm!("", out("v6") _, out("f6") _);
    |                  register `v6`
 
 error: register `f7` conflicts with register `v7`
-  --> $DIR/bad-reg.rs:106:31
+  --> $DIR/bad-reg.rs:148:31
    |
 LL |         asm!("", out("v7") _, out("f7") _);
    |                  -----------  ^^^^^^^^^^^ register `f7`
@@ -231,7 +207,7 @@ LL |         asm!("", out("v7") _, out("f7") _);
    |                  register `v7`
 
 error: register `f8` conflicts with register `v8`
-  --> $DIR/bad-reg.rs:108:31
+  --> $DIR/bad-reg.rs:150:31
    |
 LL |         asm!("", out("v8") _, out("f8") _);
    |                  -----------  ^^^^^^^^^^^ register `f8`
@@ -239,7 +215,7 @@ LL |         asm!("", out("v8") _, out("f8") _);
    |                  register `v8`
 
 error: register `f9` conflicts with register `v9`
-  --> $DIR/bad-reg.rs:110:31
+  --> $DIR/bad-reg.rs:152:31
    |
 LL |         asm!("", out("v9") _, out("f9") _);
    |                  -----------  ^^^^^^^^^^^ register `f9`
@@ -247,7 +223,7 @@ LL |         asm!("", out("v9") _, out("f9") _);
    |                  register `v9`
 
 error: register `f10` conflicts with register `v10`
-  --> $DIR/bad-reg.rs:112:32
+  --> $DIR/bad-reg.rs:154:32
    |
 LL |         asm!("", out("v10") _, out("f10") _);
    |                  ------------  ^^^^^^^^^^^^ register `f10`
@@ -255,7 +231,7 @@ LL |         asm!("", out("v10") _, out("f10") _);
    |                  register `v10`
 
 error: register `f11` conflicts with register `v11`
-  --> $DIR/bad-reg.rs:114:32
+  --> $DIR/bad-reg.rs:156:32
    |
 LL |         asm!("", out("v11") _, out("f11") _);
    |                  ------------  ^^^^^^^^^^^^ register `f11`
@@ -263,7 +239,7 @@ LL |         asm!("", out("v11") _, out("f11") _);
    |                  register `v11`
 
 error: register `f12` conflicts with register `v12`
-  --> $DIR/bad-reg.rs:116:32
+  --> $DIR/bad-reg.rs:158:32
    |
 LL |         asm!("", out("v12") _, out("f12") _);
    |                  ------------  ^^^^^^^^^^^^ register `f12`
@@ -271,7 +247,7 @@ LL |         asm!("", out("v12") _, out("f12") _);
    |                  register `v12`
 
 error: register `f13` conflicts with register `v13`
-  --> $DIR/bad-reg.rs:118:32
+  --> $DIR/bad-reg.rs:160:32
    |
 LL |         asm!("", out("v13") _, out("f13") _);
    |                  ------------  ^^^^^^^^^^^^ register `f13`
@@ -279,7 +255,7 @@ LL |         asm!("", out("v13") _, out("f13") _);
    |                  register `v13`
 
 error: register `f14` conflicts with register `v14`
-  --> $DIR/bad-reg.rs:120:32
+  --> $DIR/bad-reg.rs:162:32
    |
 LL |         asm!("", out("v14") _, out("f14") _);
    |                  ------------  ^^^^^^^^^^^^ register `f14`
@@ -287,7 +263,7 @@ LL |         asm!("", out("v14") _, out("f14") _);
    |                  register `v14`
 
 error: register `f15` conflicts with register `v15`
-  --> $DIR/bad-reg.rs:122:32
+  --> $DIR/bad-reg.rs:164:32
    |
 LL |         asm!("", out("v15") _, out("f15") _);
    |                  ------------  ^^^^^^^^^^^^ register `f15`
@@ -295,58 +271,94 @@ LL |         asm!("", out("v15") _, out("f15") _);
    |                  register `v15`
 
 error: invalid register `f16`: unknown register
-  --> $DIR/bad-reg.rs:125:32
+  --> $DIR/bad-reg.rs:167:32
    |
 LL |         asm!("", out("v16") _, out("f16") _);
    |                                ^^^^^^^^^^^^
 
-error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:63:27
+error: register class `vreg` requires the `vector` target feature
+  --> $DIR/bad-reg.rs:74:18
    |
-LL |         asm!("", in("a2") x);
-   |                           ^
+LL |         asm!("", in("v0") v); // requires vector & asm_experimental_reg
+   |                  ^^^^^^^^^^
+
+error: register class `vreg` requires the `vector` target feature
+  --> $DIR/bad-reg.rs:78:18
    |
-   = note: register class `areg` supports these types: 
+LL |         asm!("", out("v0") v); // requires vector & asm_experimental_reg
+   |                  ^^^^^^^^^^^
 
-error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:66:28
+error: register class `vreg` requires the `vector` target feature
+  --> $DIR/bad-reg.rs:82:18
    |
-LL |         asm!("", out("a2") x);
-   |                            ^
+LL |         asm!("", in("v0") x); // requires vector & asm_experimental_reg
+   |                  ^^^^^^^^^^
+
+error: register class `vreg` requires the `vector` target feature
+  --> $DIR/bad-reg.rs:86:18
    |
-   = note: register class `areg` supports these types: 
+LL |         asm!("", out("v0") x); // requires vector & asm_experimental_reg
+   |                  ^^^^^^^^^^^
 
-error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:69:35
+error: register class `vreg` requires the `vector` target feature
+  --> $DIR/bad-reg.rs:90:18
    |
-LL |         asm!("/* {} */", in(areg) x);
-   |                                   ^
+LL |         asm!("", in("v0") b);
+   |                  ^^^^^^^^^^
+
+error: register class `vreg` requires the `vector` target feature
+  --> $DIR/bad-reg.rs:95:18
    |
-   = note: register class `areg` supports these types: 
+LL |         asm!("", out("v0") b);
+   |                  ^^^^^^^^^^^
+
+error: register class `vreg` requires the `vector` target feature
+  --> $DIR/bad-reg.rs:100:26
+   |
+LL |         asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg
+   |                          ^^^^^^^^^^
+
+error: register class `vreg` requires the `vector` target feature
+  --> $DIR/bad-reg.rs:104:26
+   |
+LL |         asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg
+   |                          ^^^^^^^^^^
+
+error: register class `vreg` requires the `vector` target feature
+  --> $DIR/bad-reg.rs:108:26
+   |
+LL |         asm!("/* {} */", in(vreg) b);
+   |                          ^^^^^^^^^^
+
+error: register class `vreg` requires the `vector` target feature
+  --> $DIR/bad-reg.rs:113:26
+   |
+LL |         asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg
+   |                          ^^^^^^^^^^^
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:78:27
+  --> $DIR/bad-reg.rs:120:27
    |
-LL |         asm!("", in("v0") x);
+LL |         asm!("", in("a2") x);
    |                           ^
    |
-   = note: register class `vreg` supports these types: 
+   = note: register class `areg` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:81:28
+  --> $DIR/bad-reg.rs:123:28
    |
-LL |         asm!("", out("v0") x);
+LL |         asm!("", out("a2") x);
    |                            ^
    |
-   = note: register class `vreg` supports these types: 
+   = note: register class `areg` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:84:35
+  --> $DIR/bad-reg.rs:126:35
    |
-LL |         asm!("/* {} */", in(vreg) x);
+LL |         asm!("/* {} */", in(areg) x);
    |                                   ^
    |
-   = note: register class `vreg` supports these types: 
+   = note: register class `areg` supports these types: 
 
-error: aborting due to 51 previous errors
+error: aborting due to 54 previous errors
 
diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr
new file mode 100644
index 00000000000..897f872ae72
--- /dev/null
+++ b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr
@@ -0,0 +1,328 @@
+error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:31:18
+   |
+LL |         asm!("", out("r11") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:33:18
+   |
+LL |         asm!("", out("r15") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:35:18
+   |
+LL |         asm!("", out("c0") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:37:18
+   |
+LL |         asm!("", out("c1") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:39:18
+   |
+LL |         asm!("", out("c2") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:41:18
+   |
+LL |         asm!("", out("c3") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:43:18
+   |
+LL |         asm!("", out("c4") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:45:18
+   |
+LL |         asm!("", out("c5") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:47:18
+   |
+LL |         asm!("", out("c6") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:49:18
+   |
+LL |         asm!("", out("c7") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:51:18
+   |
+LL |         asm!("", out("c8") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:53:18
+   |
+LL |         asm!("", out("c9") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:55:18
+   |
+LL |         asm!("", out("c10") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:57:18
+   |
+LL |         asm!("", out("c11") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:59:18
+   |
+LL |         asm!("", out("c12") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:61:18
+   |
+LL |         asm!("", out("c13") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:63:18
+   |
+LL |         asm!("", out("c14") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:65:18
+   |
+LL |         asm!("", out("c15") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:67:18
+   |
+LL |         asm!("", out("a0") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:69:18
+   |
+LL |         asm!("", out("a1") _);
+   |                  ^^^^^^^^^^^
+
+error: register class `areg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:120:18
+   |
+LL |         asm!("", in("a2") x);
+   |                  ^^^^^^^^^^
+
+error: register class `areg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:123:18
+   |
+LL |         asm!("", out("a2") x);
+   |                  ^^^^^^^^^^^
+
+error: register class `areg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:126:26
+   |
+LL |         asm!("/* {} */", in(areg) x);
+   |                          ^^^^^^^^^^
+
+error: register class `areg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:129:26
+   |
+LL |         asm!("/* {} */", out(areg) _);
+   |                          ^^^^^^^^^^^
+
+error: register `f0` conflicts with register `v0`
+  --> $DIR/bad-reg.rs:134:31
+   |
+LL |         asm!("", out("v0") _, out("f0") _);
+   |                  -----------  ^^^^^^^^^^^ register `f0`
+   |                  |
+   |                  register `v0`
+
+error: register `f1` conflicts with register `v1`
+  --> $DIR/bad-reg.rs:136:31
+   |
+LL |         asm!("", out("v1") _, out("f1") _);
+   |                  -----------  ^^^^^^^^^^^ register `f1`
+   |                  |
+   |                  register `v1`
+
+error: register `f2` conflicts with register `v2`
+  --> $DIR/bad-reg.rs:138:31
+   |
+LL |         asm!("", out("v2") _, out("f2") _);
+   |                  -----------  ^^^^^^^^^^^ register `f2`
+   |                  |
+   |                  register `v2`
+
+error: register `f3` conflicts with register `v3`
+  --> $DIR/bad-reg.rs:140:31
+   |
+LL |         asm!("", out("v3") _, out("f3") _);
+   |                  -----------  ^^^^^^^^^^^ register `f3`
+   |                  |
+   |                  register `v3`
+
+error: register `f4` conflicts with register `v4`
+  --> $DIR/bad-reg.rs:142:31
+   |
+LL |         asm!("", out("v4") _, out("f4") _);
+   |                  -----------  ^^^^^^^^^^^ register `f4`
+   |                  |
+   |                  register `v4`
+
+error: register `f5` conflicts with register `v5`
+  --> $DIR/bad-reg.rs:144:31
+   |
+LL |         asm!("", out("v5") _, out("f5") _);
+   |                  -----------  ^^^^^^^^^^^ register `f5`
+   |                  |
+   |                  register `v5`
+
+error: register `f6` conflicts with register `v6`
+  --> $DIR/bad-reg.rs:146:31
+   |
+LL |         asm!("", out("v6") _, out("f6") _);
+   |                  -----------  ^^^^^^^^^^^ register `f6`
+   |                  |
+   |                  register `v6`
+
+error: register `f7` conflicts with register `v7`
+  --> $DIR/bad-reg.rs:148:31
+   |
+LL |         asm!("", out("v7") _, out("f7") _);
+   |                  -----------  ^^^^^^^^^^^ register `f7`
+   |                  |
+   |                  register `v7`
+
+error: register `f8` conflicts with register `v8`
+  --> $DIR/bad-reg.rs:150:31
+   |
+LL |         asm!("", out("v8") _, out("f8") _);
+   |                  -----------  ^^^^^^^^^^^ register `f8`
+   |                  |
+   |                  register `v8`
+
+error: register `f9` conflicts with register `v9`
+  --> $DIR/bad-reg.rs:152:31
+   |
+LL |         asm!("", out("v9") _, out("f9") _);
+   |                  -----------  ^^^^^^^^^^^ register `f9`
+   |                  |
+   |                  register `v9`
+
+error: register `f10` conflicts with register `v10`
+  --> $DIR/bad-reg.rs:154:32
+   |
+LL |         asm!("", out("v10") _, out("f10") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f10`
+   |                  |
+   |                  register `v10`
+
+error: register `f11` conflicts with register `v11`
+  --> $DIR/bad-reg.rs:156:32
+   |
+LL |         asm!("", out("v11") _, out("f11") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f11`
+   |                  |
+   |                  register `v11`
+
+error: register `f12` conflicts with register `v12`
+  --> $DIR/bad-reg.rs:158:32
+   |
+LL |         asm!("", out("v12") _, out("f12") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f12`
+   |                  |
+   |                  register `v12`
+
+error: register `f13` conflicts with register `v13`
+  --> $DIR/bad-reg.rs:160:32
+   |
+LL |         asm!("", out("v13") _, out("f13") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f13`
+   |                  |
+   |                  register `v13`
+
+error: register `f14` conflicts with register `v14`
+  --> $DIR/bad-reg.rs:162:32
+   |
+LL |         asm!("", out("v14") _, out("f14") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f14`
+   |                  |
+   |                  register `v14`
+
+error: register `f15` conflicts with register `v15`
+  --> $DIR/bad-reg.rs:164:32
+   |
+LL |         asm!("", out("v15") _, out("f15") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f15`
+   |                  |
+   |                  register `v15`
+
+error: invalid register `f16`: unknown register
+  --> $DIR/bad-reg.rs:167:32
+   |
+LL |         asm!("", out("v16") _, out("f16") _);
+   |                                ^^^^^^^^^^^^
+
+error: type `u8` cannot be used with this register class
+  --> $DIR/bad-reg.rs:90:27
+   |
+LL |         asm!("", in("v0") b);
+   |                           ^
+   |
+   = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
+
+error: type `u8` cannot be used with this register class
+  --> $DIR/bad-reg.rs:95:28
+   |
+LL |         asm!("", out("v0") b);
+   |                            ^
+   |
+   = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
+
+error: type `u8` cannot be used with this register class
+  --> $DIR/bad-reg.rs:108:35
+   |
+LL |         asm!("/* {} */", in(vreg) b);
+   |                                   ^
+   |
+   = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:120:27
+   |
+LL |         asm!("", in("a2") x);
+   |                           ^
+   |
+   = note: register class `areg` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:123:28
+   |
+LL |         asm!("", out("a2") x);
+   |                            ^
+   |
+   = note: register class `areg` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:126:35
+   |
+LL |         asm!("/* {} */", in(areg) x);
+   |                                   ^
+   |
+   = note: register class `areg` supports these types: 
+
+error: aborting due to 47 previous errors
+
diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr
new file mode 100644
index 00000000000..e2b3eeef4e9
--- /dev/null
+++ b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr
@@ -0,0 +1,489 @@
+error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:31:18
+   |
+LL |         asm!("", out("r11") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm
+  --> $DIR/bad-reg.rs:33:18
+   |
+LL |         asm!("", out("r15") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:35:18
+   |
+LL |         asm!("", out("c0") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:37:18
+   |
+LL |         asm!("", out("c1") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:39:18
+   |
+LL |         asm!("", out("c2") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:41:18
+   |
+LL |         asm!("", out("c3") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:43:18
+   |
+LL |         asm!("", out("c4") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:45:18
+   |
+LL |         asm!("", out("c5") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:47:18
+   |
+LL |         asm!("", out("c6") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:49:18
+   |
+LL |         asm!("", out("c7") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:51:18
+   |
+LL |         asm!("", out("c8") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:53:18
+   |
+LL |         asm!("", out("c9") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:55:18
+   |
+LL |         asm!("", out("c10") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:57:18
+   |
+LL |         asm!("", out("c11") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:59:18
+   |
+LL |         asm!("", out("c12") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:61:18
+   |
+LL |         asm!("", out("c13") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:63:18
+   |
+LL |         asm!("", out("c14") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:65:18
+   |
+LL |         asm!("", out("c15") _);
+   |                  ^^^^^^^^^^^^
+
+error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:67:18
+   |
+LL |         asm!("", out("a0") _);
+   |                  ^^^^^^^^^^^
+
+error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
+  --> $DIR/bad-reg.rs:69:18
+   |
+LL |         asm!("", out("a1") _);
+   |                  ^^^^^^^^^^^
+
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/bad-reg.rs:74:18
+   |
+LL |         asm!("", in("v0") v); // requires vector & asm_experimental_reg
+   |                  ^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/bad-reg.rs:78:18
+   |
+LL |         asm!("", out("v0") v); // requires vector & asm_experimental_reg
+   |                  ^^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/bad-reg.rs:82:18
+   |
+LL |         asm!("", in("v0") x); // requires vector & asm_experimental_reg
+   |                  ^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/bad-reg.rs:86:18
+   |
+LL |         asm!("", out("v0") x); // requires vector & asm_experimental_reg
+   |                  ^^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/bad-reg.rs:90:18
+   |
+LL |         asm!("", in("v0") b);
+   |                  ^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/bad-reg.rs:95:18
+   |
+LL |         asm!("", out("v0") b);
+   |                  ^^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/bad-reg.rs:100:26
+   |
+LL |         asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg
+   |                          ^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/bad-reg.rs:104:26
+   |
+LL |         asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg
+   |                          ^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/bad-reg.rs:108:26
+   |
+LL |         asm!("/* {} */", in(vreg) b);
+   |                          ^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/bad-reg.rs:113:26
+   |
+LL |         asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg
+   |                          ^^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` 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: register class `areg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:120:18
+   |
+LL |         asm!("", in("a2") x);
+   |                  ^^^^^^^^^^
+
+error: register class `areg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:123:18
+   |
+LL |         asm!("", out("a2") x);
+   |                  ^^^^^^^^^^^
+
+error: register class `areg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:126:26
+   |
+LL |         asm!("/* {} */", in(areg) x);
+   |                          ^^^^^^^^^^
+
+error: register class `areg` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:129:26
+   |
+LL |         asm!("/* {} */", out(areg) _);
+   |                          ^^^^^^^^^^^
+
+error: register `f0` conflicts with register `v0`
+  --> $DIR/bad-reg.rs:134:31
+   |
+LL |         asm!("", out("v0") _, out("f0") _);
+   |                  -----------  ^^^^^^^^^^^ register `f0`
+   |                  |
+   |                  register `v0`
+
+error: register `f1` conflicts with register `v1`
+  --> $DIR/bad-reg.rs:136:31
+   |
+LL |         asm!("", out("v1") _, out("f1") _);
+   |                  -----------  ^^^^^^^^^^^ register `f1`
+   |                  |
+   |                  register `v1`
+
+error: register `f2` conflicts with register `v2`
+  --> $DIR/bad-reg.rs:138:31
+   |
+LL |         asm!("", out("v2") _, out("f2") _);
+   |                  -----------  ^^^^^^^^^^^ register `f2`
+   |                  |
+   |                  register `v2`
+
+error: register `f3` conflicts with register `v3`
+  --> $DIR/bad-reg.rs:140:31
+   |
+LL |         asm!("", out("v3") _, out("f3") _);
+   |                  -----------  ^^^^^^^^^^^ register `f3`
+   |                  |
+   |                  register `v3`
+
+error: register `f4` conflicts with register `v4`
+  --> $DIR/bad-reg.rs:142:31
+   |
+LL |         asm!("", out("v4") _, out("f4") _);
+   |                  -----------  ^^^^^^^^^^^ register `f4`
+   |                  |
+   |                  register `v4`
+
+error: register `f5` conflicts with register `v5`
+  --> $DIR/bad-reg.rs:144:31
+   |
+LL |         asm!("", out("v5") _, out("f5") _);
+   |                  -----------  ^^^^^^^^^^^ register `f5`
+   |                  |
+   |                  register `v5`
+
+error: register `f6` conflicts with register `v6`
+  --> $DIR/bad-reg.rs:146:31
+   |
+LL |         asm!("", out("v6") _, out("f6") _);
+   |                  -----------  ^^^^^^^^^^^ register `f6`
+   |                  |
+   |                  register `v6`
+
+error: register `f7` conflicts with register `v7`
+  --> $DIR/bad-reg.rs:148:31
+   |
+LL |         asm!("", out("v7") _, out("f7") _);
+   |                  -----------  ^^^^^^^^^^^ register `f7`
+   |                  |
+   |                  register `v7`
+
+error: register `f8` conflicts with register `v8`
+  --> $DIR/bad-reg.rs:150:31
+   |
+LL |         asm!("", out("v8") _, out("f8") _);
+   |                  -----------  ^^^^^^^^^^^ register `f8`
+   |                  |
+   |                  register `v8`
+
+error: register `f9` conflicts with register `v9`
+  --> $DIR/bad-reg.rs:152:31
+   |
+LL |         asm!("", out("v9") _, out("f9") _);
+   |                  -----------  ^^^^^^^^^^^ register `f9`
+   |                  |
+   |                  register `v9`
+
+error: register `f10` conflicts with register `v10`
+  --> $DIR/bad-reg.rs:154:32
+   |
+LL |         asm!("", out("v10") _, out("f10") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f10`
+   |                  |
+   |                  register `v10`
+
+error: register `f11` conflicts with register `v11`
+  --> $DIR/bad-reg.rs:156:32
+   |
+LL |         asm!("", out("v11") _, out("f11") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f11`
+   |                  |
+   |                  register `v11`
+
+error: register `f12` conflicts with register `v12`
+  --> $DIR/bad-reg.rs:158:32
+   |
+LL |         asm!("", out("v12") _, out("f12") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f12`
+   |                  |
+   |                  register `v12`
+
+error: register `f13` conflicts with register `v13`
+  --> $DIR/bad-reg.rs:160:32
+   |
+LL |         asm!("", out("v13") _, out("f13") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f13`
+   |                  |
+   |                  register `v13`
+
+error: register `f14` conflicts with register `v14`
+  --> $DIR/bad-reg.rs:162:32
+   |
+LL |         asm!("", out("v14") _, out("f14") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f14`
+   |                  |
+   |                  register `v14`
+
+error: register `f15` conflicts with register `v15`
+  --> $DIR/bad-reg.rs:164:32
+   |
+LL |         asm!("", out("v15") _, out("f15") _);
+   |                  ------------  ^^^^^^^^^^^^ register `f15`
+   |                  |
+   |                  register `v15`
+
+error: invalid register `f16`: unknown register
+  --> $DIR/bad-reg.rs:167:32
+   |
+LL |         asm!("", out("v16") _, out("f16") _);
+   |                                ^^^^^^^^^^^^
+
+error[E0658]: type `i64x2` cannot be used with this register class in stable
+  --> $DIR/bad-reg.rs:74:27
+   |
+LL |         asm!("", in("v0") v); // requires vector & asm_experimental_reg
+   |                           ^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: type `i64x2` cannot be used with this register class in stable
+  --> $DIR/bad-reg.rs:78:28
+   |
+LL |         asm!("", out("v0") v); // requires vector & asm_experimental_reg
+   |                            ^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: type `i32` cannot be used with this register class in stable
+  --> $DIR/bad-reg.rs:82:27
+   |
+LL |         asm!("", in("v0") x); // requires vector & asm_experimental_reg
+   |                           ^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: type `i32` cannot be used with this register class in stable
+  --> $DIR/bad-reg.rs:86:28
+   |
+LL |         asm!("", out("v0") x); // requires vector & asm_experimental_reg
+   |                            ^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` 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: type `u8` cannot be used with this register class
+  --> $DIR/bad-reg.rs:90:27
+   |
+LL |         asm!("", in("v0") b);
+   |                           ^
+   |
+   = note: register class `vreg` supports these types: 
+
+error: type `u8` cannot be used with this register class
+  --> $DIR/bad-reg.rs:95:28
+   |
+LL |         asm!("", out("v0") b);
+   |                            ^
+   |
+   = note: register class `vreg` supports these types: 
+
+error[E0658]: type `i64x2` cannot be used with this register class in stable
+  --> $DIR/bad-reg.rs:100:35
+   |
+LL |         asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg
+   |                                   ^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: type `i32` cannot be used with this register class in stable
+  --> $DIR/bad-reg.rs:104:35
+   |
+LL |         asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg
+   |                                   ^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` 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: type `u8` cannot be used with this register class
+  --> $DIR/bad-reg.rs:108:35
+   |
+LL |         asm!("/* {} */", in(vreg) b);
+   |                                   ^
+   |
+   = note: register class `vreg` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:120:27
+   |
+LL |         asm!("", in("a2") x);
+   |                           ^
+   |
+   = note: register class `areg` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:123:28
+   |
+LL |         asm!("", out("a2") x);
+   |                            ^
+   |
+   = note: register class `areg` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:126:35
+   |
+LL |         asm!("/* {} */", in(areg) x);
+   |                                   ^
+   |
+   = note: register class `areg` supports these types: 
+
+error: aborting due to 63 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/asm/x86_64/goto.rs b/tests/ui/asm/x86_64/goto.rs
index 6c14bb57ac6..50e7441509a 100644
--- a/tests/ui/asm/x86_64/goto.rs
+++ b/tests/ui/asm/x86_64/goto.rs
@@ -3,7 +3,7 @@
 //@ needs-asm-support
 
 #![deny(unreachable_code)]
-#![feature(asm_goto)]
+#![feature(asm_goto, asm_goto_with_outputs)]
 
 use std::arch::asm;
 
@@ -31,10 +31,6 @@ fn goto_jump() {
     }
 }
 
-// asm goto with outputs cause miscompilation in LLVM. UB can be triggered
-// when outputs are used inside the label block when optimisation is enabled.
-// See: https://github.com/llvm/llvm-project/issues/74483
-/*
 fn goto_out_fallthrough() {
     unsafe {
         let mut out: usize;
@@ -68,7 +64,57 @@ fn goto_out_jump() {
         assert!(value);
     }
 }
-*/
+
+fn goto_out_jump_noreturn() {
+    unsafe {
+        let mut value = false;
+        let mut out: usize;
+        asm!(
+            "lea {}, [{} + 1]",
+            "jmp {}",
+            out(reg) out,
+            in(reg) 0x12345678usize,
+            label {
+                value = true;
+                assert_eq!(out, 0x12345679);
+            },
+            options(noreturn)
+        );
+        assert!(value);
+    }
+}
+
+// asm goto with outputs cause miscompilation in LLVM when multiple outputs are present.
+// The code sample below is adapted from https://github.com/llvm/llvm-project/issues/74483
+// and does not work with `-C opt-level=0`
+#[expect(unused)]
+fn goto_multi_out() {
+    #[inline(never)]
+    #[allow(unused)]
+    fn goto_multi_out(a: usize, b: usize) -> usize {
+        let mut x: usize;
+        let mut y: usize;
+        let mut z: usize;
+        unsafe {
+            core::arch::asm!(
+                "mov {x}, {a}",
+                "test {a}, {a}",
+                "jnz {label1}",
+                "/* {y} {z} {b} {label2} */",
+                x = out(reg) x,
+                y = out(reg) y,
+                z = out(reg) z,
+                a = in(reg) a,
+                b = in(reg) b,
+                label1 = label { return x },
+                label2 = label { return 1 },
+            );
+            0
+        }
+    }
+
+    assert_eq!(goto_multi_out(11, 22), 11);
+}
 
 fn goto_noreturn() {
     unsafe {
@@ -102,8 +148,10 @@ fn goto_noreturn_diverge() {
 fn main() {
     goto_fallthough();
     goto_jump();
-    // goto_out_fallthrough();
-    // goto_out_jump();
+    goto_out_fallthrough();
+    goto_out_jump();
+    goto_out_jump_noreturn();
+    // goto_multi_out();
     goto_noreturn();
     goto_noreturn_diverge();
 }
diff --git a/tests/ui/asm/x86_64/goto.stderr b/tests/ui/asm/x86_64/goto.stderr
index 27e227d71a5..8f89e2b1290 100644
--- a/tests/ui/asm/x86_64/goto.stderr
+++ b/tests/ui/asm/x86_64/goto.stderr
@@ -1,5 +1,5 @@
 warning: unreachable statement
-  --> $DIR/goto.rs:97:9
+  --> $DIR/goto.rs:143:9
    |
 LL | /         asm!(
 LL | |             "jmp {}",
@@ -13,7 +13,7 @@ LL |           unreachable!();
    |           ^^^^^^^^^^^^^^ unreachable statement
    |
 note: the lint level is defined here
-  --> $DIR/goto.rs:87:8
+  --> $DIR/goto.rs:133:8
    |
 LL | #[warn(unreachable_code)]
    |        ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs
index 8fe79b97d9b..977ef604b34 100644
--- a/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs
+++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.rs
@@ -15,6 +15,7 @@ impl Foo for Def {
 pub fn test<A: Foo, B: Foo>() {
     let _array = [4; <A as Foo>::Y];
     //~^ ERROR constant expression depends on a generic parameter
+    //~| ERROR constant expression depends on a generic parameter
 }
 
 fn main() {
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr
index cd830394285..8202342c65d 100644
--- a/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr
+++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays-2.stderr
@@ -6,5 +6,13 @@ LL |     let _array = [4; <A as Foo>::Y];
    |
    = note: this may fail depending on what value the parameter takes
 
-error: aborting due to 1 previous error
+error: constant expression depends on a generic parameter
+  --> $DIR/associated-const-type-parameter-arrays-2.rs:16:18
+   |
+LL |     let _array = [4; <A as Foo>::Y];
+   |                  ^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/associated-types/associated-types-binding-in-where-clause.rs b/tests/ui/associated-types/associated-types-binding-in-where-clause.rs
index ed2cebb5f7e..b82656945a2 100644
--- a/tests/ui/associated-types/associated-types-binding-in-where-clause.rs
+++ b/tests/ui/associated-types/associated-types-binding-in-where-clause.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Test equality constraints on associated types in a where clause.
 
-//@ pretty-expanded FIXME #23616
 
 pub trait Foo {
     type A;
diff --git a/tests/ui/associated-types/associated-types-conditional-dispatch.rs b/tests/ui/associated-types/associated-types-conditional-dispatch.rs
index d30ea66e9b9..3ec835ccbc3 100644
--- a/tests/ui/associated-types/associated-types-conditional-dispatch.rs
+++ b/tests/ui/associated-types/associated-types-conditional-dispatch.rs
@@ -5,7 +5,6 @@
 // `Target=[A]`, then the impl marked with `(*)` is seen to conflict
 // with all the others.
 
-//@ pretty-expanded FIXME #23616
 
 use std::marker::PhantomData;
 use std::ops::Deref;
diff --git a/tests/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs b/tests/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs
index e2c13716a69..9bf7570534c 100644
--- a/tests/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs
+++ b/tests/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs
@@ -4,7 +4,6 @@
 // (modulo bound lifetime names) appears in the environment
 // twice. Issue #21965.
 
-//@ pretty-expanded FIXME #23616
 
 fn foo<T>(t: T) -> i32
     where T : for<'a> Fn(&'a u8) -> i32,
diff --git a/tests/ui/associated-types/associated-types-duplicate-binding-in-env.rs b/tests/ui/associated-types/associated-types-duplicate-binding-in-env.rs
index d1ff4b222b7..44c5634f4ef 100644
--- a/tests/ui/associated-types/associated-types-duplicate-binding-in-env.rs
+++ b/tests/ui/associated-types/associated-types-duplicate-binding-in-env.rs
@@ -3,7 +3,6 @@
 // Check that we do not report ambiguities when the same predicate
 // appears in the environment twice. Issue #21965.
 
-//@ pretty-expanded FIXME #23616
 
 trait Foo {
     type B;
diff --git a/tests/ui/associated-types/associated-types-eq-obj.rs b/tests/ui/associated-types/associated-types-eq-obj.rs
index 1236d770b95..c1ca8bbd739 100644
--- a/tests/ui/associated-types/associated-types-eq-obj.rs
+++ b/tests/ui/associated-types/associated-types-eq-obj.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Test equality constraints on associated types inside of an object type
 
-//@ pretty-expanded FIXME #23616
 
 pub trait Foo {
     type A;
diff --git a/tests/ui/associated-types/associated-types-issue-20371.rs b/tests/ui/associated-types/associated-types-issue-20371.rs
index 32fe1ca1c00..d2e056a57b2 100644
--- a/tests/ui/associated-types/associated-types-issue-20371.rs
+++ b/tests/ui/associated-types/associated-types-issue-20371.rs
@@ -2,7 +2,6 @@
 // Test that we are able to have an impl that defines an associated type
 // before the actual trait.
 
-//@ pretty-expanded FIXME #23616
 
 impl X for f64 { type Y = isize; }
 trait X { type Y; }
diff --git a/tests/ui/associated-types/associated-types-nested-projections.rs b/tests/ui/associated-types/associated-types-nested-projections.rs
index 90ff170a6a7..659016b4644 100644
--- a/tests/ui/associated-types/associated-types-nested-projections.rs
+++ b/tests/ui/associated-types/associated-types-nested-projections.rs
@@ -2,7 +2,6 @@
 #![allow(unused_variables)]
 // Test that we can resolve nested projection types. Issue #20666.
 
-//@ pretty-expanded FIXME #23616
 
 use std::slice;
 
diff --git a/tests/ui/associated-types/associated-types-nested-projections.stderr b/tests/ui/associated-types/associated-types-nested-projections.stderr
index 97d5a758573..1b69fcfacf5 100644
--- a/tests/ui/associated-types/associated-types-nested-projections.stderr
+++ b/tests/ui/associated-types/associated-types-nested-projections.stderr
@@ -1,5 +1,5 @@
 warning: method `into_iter` is never used
-  --> $DIR/associated-types-nested-projections.rs:16:8
+  --> $DIR/associated-types-nested-projections.rs:15:8
    |
 LL | trait IntoIterator {
    |       ------------ method in this trait
diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds-binding.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds-binding.rs
index bd9b91b002e..a6e426df1c9 100644
--- a/tests/ui/associated-types/associated-types-normalize-in-bounds-binding.rs
+++ b/tests/ui/associated-types/associated-types-normalize-in-bounds-binding.rs
@@ -3,7 +3,6 @@
 // Test that we normalize associated types that appear in a bound that
 // contains a binding. Issue #21664.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
index 884b1a17a2c..f15de0d9a28 100644
--- a/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
+++ b/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
@@ -3,7 +3,6 @@
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-//@ pretty-expanded FIXME #23616
 
 use std::marker::PhantomData;
 
diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds.rs
index 8da60e1d9cb..7e94d3a011f 100644
--- a/tests/ui/associated-types/associated-types-normalize-in-bounds.rs
+++ b/tests/ui/associated-types/associated-types-normalize-in-bounds.rs
@@ -3,7 +3,6 @@
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-//@ pretty-expanded FIXME #23616
 
 use std::marker::PhantomData;
 
diff --git a/tests/ui/associated-types/associated-types-projection-in-object-type.rs b/tests/ui/associated-types/associated-types-projection-in-object-type.rs
index 4cf1c256f3d..d5d7a294dfd 100644
--- a/tests/ui/associated-types/associated-types-projection-in-object-type.rs
+++ b/tests/ui/associated-types/associated-types-projection-in-object-type.rs
@@ -6,7 +6,6 @@
 // appear in associated type bindings in object types, which were not
 // being properly flagged.
 
-//@ pretty-expanded FIXME #23616
 
 use std::ops::{Shl, Shr};
 use std::cell::RefCell;
diff --git a/tests/ui/associated-types/associated-types-projection-in-where-clause.rs b/tests/ui/associated-types/associated-types-projection-in-where-clause.rs
index ed8259396d1..6f4ee8bf177 100644
--- a/tests/ui/associated-types/associated-types-projection-in-where-clause.rs
+++ b/tests/ui/associated-types/associated-types-projection-in-where-clause.rs
@@ -3,7 +3,6 @@
 #![allow(unused_variables)]
 // Test a where clause that uses a non-normalized projection type.
 
-//@ pretty-expanded FIXME #23616
 
 trait Int
 {
diff --git a/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs b/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs
index f0a34325196..c2550c930d3 100644
--- a/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs
+++ b/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Foo<T> {
     type Bar;
diff --git a/tests/ui/associated-types/associated-types-ref-from-struct.rs b/tests/ui/associated-types/associated-types-ref-from-struct.rs
index c16bb8651c3..bdff76e86a3 100644
--- a/tests/ui/associated-types/associated-types-ref-from-struct.rs
+++ b/tests/ui/associated-types/associated-types-ref-from-struct.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Test associated type references in structure fields.
 
-//@ pretty-expanded FIXME #23616
 
 trait Test {
     type V;
diff --git a/tests/ui/associated-types/associated-types-region-erasure-issue-20582.rs b/tests/ui/associated-types/associated-types-region-erasure-issue-20582.rs
index dec3a3c9245..7c556005f2d 100644
--- a/tests/ui/associated-types/associated-types-region-erasure-issue-20582.rs
+++ b/tests/ui/associated-types/associated-types-region-erasure-issue-20582.rs
@@ -3,7 +3,6 @@
 // Regression test for #20582. This test caused an ICE related to
 // inconsistent region erasure in codegen.
 
-//@ pretty-expanded FIXME #23616
 
 struct Foo<'a> {
     buf: &'a[u8]
diff --git a/tests/ui/associated-types/associated-types-resolve-lifetime.rs b/tests/ui/associated-types/associated-types-resolve-lifetime.rs
index 6be2fa6f2ab..a75488cf843 100644
--- a/tests/ui/associated-types/associated-types-resolve-lifetime.rs
+++ b/tests/ui/associated-types/associated-types-resolve-lifetime.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Get<T> {
     fn get(&self) -> T;
diff --git a/tests/ui/associated-types/issue-19129-1.rs b/tests/ui/associated-types/issue-19129-1.rs
index 65340b413e9..e4d8082c05a 100644
--- a/tests/ui/associated-types/issue-19129-1.rs
+++ b/tests/ui/associated-types/issue-19129-1.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Trait<Input> {
     type Output;
diff --git a/tests/ui/associated-types/issue-19129-2.rs b/tests/ui/associated-types/issue-19129-2.rs
index 6562c54b0b7..15e73bfc532 100644
--- a/tests/ui/associated-types/issue-19129-2.rs
+++ b/tests/ui/associated-types/issue-19129-2.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 trait Trait<Input> {
     type Output;
diff --git a/tests/ui/associated-types/issue-20763-1.rs b/tests/ui/associated-types/issue-20763-1.rs
index ea2e696767d..0abd2317fa9 100644
--- a/tests/ui/associated-types/issue-20763-1.rs
+++ b/tests/ui/associated-types/issue-20763-1.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait T0 {
     type O;
diff --git a/tests/ui/associated-types/issue-20763-2.rs b/tests/ui/associated-types/issue-20763-2.rs
index 149bfcb8c99..9e7f3e15fe0 100644
--- a/tests/ui/associated-types/issue-20763-2.rs
+++ b/tests/ui/associated-types/issue-20763-2.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait T0 {
     type O;
diff --git a/tests/ui/associated-types/issue-21363.rs b/tests/ui/associated-types/issue-21363.rs
index 0dcebafd95b..96d4c202349 100644
--- a/tests/ui/associated-types/issue-21363.rs
+++ b/tests/ui/associated-types/issue-21363.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 #![no_implicit_prelude]
 
diff --git a/tests/ui/associated-types/issue-21726.rs b/tests/ui/associated-types/issue-21726.rs
index f014c644786..9611423b9f0 100644
--- a/tests/ui/associated-types/issue-21726.rs
+++ b/tests/ui/associated-types/issue-21726.rs
@@ -4,7 +4,6 @@
 // subtyping of projection types that resulted in an unconstrained
 // region, yielding region inference failures.
 
-//@ pretty-expanded FIXME #23616
 
 fn main() { }
 
diff --git a/tests/ui/associated-types/issue-22560.rs b/tests/ui/associated-types/issue-22560.rs
index 44be8817b08..465aea515ee 100644
--- a/tests/ui/associated-types/issue-22560.rs
+++ b/tests/ui/associated-types/issue-22560.rs
@@ -7,9 +7,6 @@ trait Sub<Rhs=Self> {
 }
 
 type Test = dyn Add + Sub;
-//~^ ERROR E0393
-//~| ERROR E0191
-//~| ERROR E0393
-//~| ERROR E0225
+//~^ ERROR E0225
 
 fn main() { }
diff --git a/tests/ui/associated-types/issue-22560.stderr b/tests/ui/associated-types/issue-22560.stderr
index 834040490f9..d0b6adc520c 100644
--- a/tests/ui/associated-types/issue-22560.stderr
+++ b/tests/ui/associated-types/issue-22560.stderr
@@ -9,56 +9,6 @@ LL | type Test = dyn Add + Sub;
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
-error[E0191]: the value of the associated types `Output` in `Add`, `Output` in `Sub` must be specified
-  --> $DIR/issue-22560.rs:9:17
-   |
-LL |     type Output;
-   |     ----------- `Output` defined here
-...
-LL |     type Output;
-   |     ----------- `Output` defined here
-...
-LL | type Test = dyn Add + Sub;
-   |                 ^^^   ^^^ associated type `Output` must be specified
-   |                 |
-   |                 associated type `Output` must be specified
-   |
-help: specify the associated types
-   |
-LL | type Test = dyn Add<Output = Type> + Sub<Output = Type>;
-   |                 ~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~
-
-error[E0393]: the type parameter `Rhs` must be explicitly specified
-  --> $DIR/issue-22560.rs:9:17
-   |
-LL | trait Add<Rhs=Self> {
-   | ------------------- type parameter `Rhs` must be specified for this
-...
-LL | type Test = dyn Add + Sub;
-   |                 ^^^
-   |
-   = note: because of the default `Self` reference, type parameters must be specified on object types
-help: set the type parameter to the desired type
-   |
-LL | type Test = dyn Add<Rhs> + Sub;
-   |                    +++++
-
-error[E0393]: the type parameter `Rhs` must be explicitly specified
-  --> $DIR/issue-22560.rs:9:23
-   |
-LL | trait Sub<Rhs=Self> {
-   | ------------------- type parameter `Rhs` must be specified for this
-...
-LL | type Test = dyn Add + Sub;
-   |                       ^^^
-   |
-   = note: because of the default `Self` reference, type parameters must be specified on object types
-help: set the type parameter to the desired type
-   |
-LL | type Test = dyn Add + Sub<Rhs>;
-   |                          +++++
-
-error: aborting due to 4 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0191, E0225, E0393.
-For more information about an error, try `rustc --explain E0191`.
+For more information about this error, try `rustc --explain E0225`.
diff --git a/tests/ui/associated-types/issue-22828.rs b/tests/ui/associated-types/issue-22828.rs
index 2f65f1c2303..5624b9c693b 100644
--- a/tests/ui/associated-types/issue-22828.rs
+++ b/tests/ui/associated-types/issue-22828.rs
@@ -3,7 +3,6 @@
 // Test transitive analysis for associated types. Collected types
 // should be normalized and new obligations generated.
 
-//@ pretty-expanded FIXME #23616
 
 trait Foo {
     type A;
diff --git a/tests/ui/associated-types/missing-associated-types.rs b/tests/ui/associated-types/missing-associated-types.rs
index 3c8410e39bd..4e532715f1e 100644
--- a/tests/ui/associated-types/missing-associated-types.rs
+++ b/tests/ui/associated-types/missing-associated-types.rs
@@ -11,16 +11,12 @@ trait Fine<Rhs>: Div<Rhs, Output = Rhs> {}
 
 type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
 //~^ ERROR only auto traits can be used as additional traits in a trait object
-//~| ERROR the value of the associated types
 type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
 //~^ ERROR only auto traits can be used as additional traits in a trait object
-//~| ERROR the value of the associated types
 type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
 //~^ ERROR only auto traits can be used as additional traits in a trait object
-//~| ERROR the value of the associated types
 type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
 //~^ ERROR only auto traits can be used as additional traits in a trait object
-//~| ERROR the value of the associated types
 type Bal<Rhs> = dyn X<Rhs>;
 //~^ ERROR the value of the associated types
 
diff --git a/tests/ui/associated-types/missing-associated-types.stderr b/tests/ui/associated-types/missing-associated-types.stderr
index 0636667ea1f..ce4b57e8af8 100644
--- a/tests/ui/associated-types/missing-associated-types.stderr
+++ b/tests/ui/associated-types/missing-associated-types.stderr
@@ -9,26 +9,8 @@ LL | type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs> {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
-error[E0191]: the value of the associated types `A` in `Y`, `Output` in `Add`, `Output` in `Mul`, `Output` in `Sub` must be specified
-  --> $DIR/missing-associated-types.rs:12:21
-   |
-LL |     type A;
-   |     ------ `A` defined here
-...
-LL | type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
-   |                     ^^^^^^^^   ^^^^^^^^   ^^^^^^   ^^^^^^ associated type `A` must be specified
-   |                     |          |          |
-   |                     |          |          associated type `Output` must be specified
-   |                     |          associated type `Output` must be specified
-   |                     associated type `Output` must be specified
-   |
-help: specify the associated types
-   |
-LL | type Foo<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + X<Rhs, Output = Type> + Y<Rhs, A = Type>;
-   |                     ~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~
-
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/missing-associated-types.rs:15:32
+  --> $DIR/missing-associated-types.rs:14:32
    |
 LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
    |                     --------   ^^^^^^^^ additional non-auto trait
@@ -38,33 +20,8 @@ LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs> {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
-error[E0191]: the value of the associated types `A` and `B` in `Z`, `Output` and `Output` in `Div`, `Output` in `Add`, `Output` in `Mul`, `Output` in `Sub` must be specified
-  --> $DIR/missing-associated-types.rs:15:21
-   |
-LL |     type A;
-   |     ------ `A` defined here
-LL |     type B;
-   |     ------ `B` defined here
-...
-LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
-   |                     ^^^^^^^^   ^^^^^^^^   ^^^^^^   ^^^^^^ associated types `A`, `B`, `Output` must be specified
-   |                     |          |          |
-   |                     |          |          associated types `Output` (from trait `Div`), `Output` (from trait `Mul`) must be specified
-   |                     |          associated type `Output` must be specified
-   |                     associated type `Output` must be specified
-   |
-help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types
-  --> $DIR/missing-associated-types.rs:15:43
-   |
-LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
-   |                                           ^^^^^^
-help: specify the associated types
-   |
-LL | type Bar<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + X<Rhs> + Z<Rhs, A = Type, B = Type, Output = Type>;
-   |                     ~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/missing-associated-types.rs:18:32
+  --> $DIR/missing-associated-types.rs:16:32
    |
 LL | type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
    |                     --------   ^^^^^^^^ additional non-auto trait
@@ -74,25 +31,8 @@ LL | type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + Y<Rhs> {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
-error[E0191]: the value of the associated types `A` in `Y`, `Output` in `Add`, `Output` in `Sub` must be specified
-  --> $DIR/missing-associated-types.rs:18:21
-   |
-LL |     type A;
-   |     ------ `A` defined here
-...
-LL | type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
-   |                     ^^^^^^^^   ^^^^^^^^   ^^^^^^ associated type `A` must be specified
-   |                     |          |
-   |                     |          associated type `Output` must be specified
-   |                     associated type `Output` must be specified
-   |
-help: specify the associated types
-   |
-LL | type Baz<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + Y<Rhs, A = Type>;
-   |                     ~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~
-
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/missing-associated-types.rs:21:32
+  --> $DIR/missing-associated-types.rs:18:32
    |
 LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
    |                     --------   ^^^^^^^^ additional non-auto trait
@@ -102,28 +42,15 @@ LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + Fine<Rhs> {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
-error[E0191]: the value of the associated types `Output` in `Add`, `Output` in `Sub` must be specified
-  --> $DIR/missing-associated-types.rs:21:21
-   |
-LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
-   |                     ^^^^^^^^   ^^^^^^^^ associated type `Output` must be specified
-   |                     |
-   |                     associated type `Output` must be specified
-   |
-help: specify the associated types
-   |
-LL | type Bat<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + Fine<Rhs>;
-   |                     ~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~
-
 error[E0191]: the value of the associated types `Output` in `Div`, `Output` in `Mul` must be specified
-  --> $DIR/missing-associated-types.rs:24:21
+  --> $DIR/missing-associated-types.rs:20:21
    |
 LL | type Bal<Rhs> = dyn X<Rhs>;
    |                     ^^^^^^ associated types `Output` (from trait `Div`), `Output` (from trait `Mul`) must be specified
    |
    = help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types
 
-error: aborting due to 9 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0191, E0225.
 For more information about an error, try `rustc --explain E0191`.
diff --git a/tests/ui/async-await/async-closures/fn-exception-target-features.stderr b/tests/ui/async-await/async-closures/fn-exception-target-features.stderr
index 396167f4070..e965c40fb5b 100644
--- a/tests/ui/async-await/async-closures/fn-exception-target-features.stderr
+++ b/tests/ui/async-await/async-closures/fn-exception-target-features.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn<()>` is not satisfied
+error[E0277]: the trait bound `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn()` is not satisfied
   --> $DIR/fn-exception-target-features.rs:16:10
    |
 LL |     test(target_feature);
-   |     ---- ^^^^^^^^^^^^^^ the trait `AsyncFn<()>` is not implemented for fn item `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}`
+   |     ---- ^^^^^^^^^^^^^^ the trait `AsyncFn()` is not implemented for fn item `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}`
    |     |
    |     required by a bound introduced by this call
    |
diff --git a/tests/ui/async-await/async-closures/fn-exception.stderr b/tests/ui/async-await/async-closures/fn-exception.stderr
index bacd079af0f..20132e42833 100644
--- a/tests/ui/async-await/async-closures/fn-exception.stderr
+++ b/tests/ui/async-await/async-closures/fn-exception.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}: AsyncFn<()>` is not satisfied
+error[E0277]: the trait bound `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}: AsyncFn()` is not satisfied
   --> $DIR/fn-exception.rs:19:10
    |
 LL |     test(unsafety);
-   |     ---- ^^^^^^^^ the trait `AsyncFn<()>` is not implemented for fn item `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}`
+   |     ---- ^^^^^^^^ the trait `AsyncFn()` is not implemented for fn item `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}`
    |     |
    |     required by a bound introduced by this call
    |
@@ -12,11 +12,11 @@ note: required by a bound in `test`
 LL | fn test(f: impl async Fn()) {}
    |                 ^^^^^^^^^^ required by this bound in `test`
 
-error[E0277]: the trait bound `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}: AsyncFn<()>` is not satisfied
+error[E0277]: the trait bound `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}: AsyncFn()` is not satisfied
   --> $DIR/fn-exception.rs:20:10
    |
 LL |     test(abi);
-   |     ---- ^^^ the trait `AsyncFn<()>` is not implemented for fn item `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}`
+   |     ---- ^^^ the trait `AsyncFn()` is not implemented for fn item `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}`
    |     |
    |     required by a bound introduced by this call
    |
diff --git a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs
new file mode 100644
index 00000000000..2e7cf1b09fd
--- /dev/null
+++ b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs
@@ -0,0 +1,14 @@
+//@ edition: 2021
+
+#![feature(async_closure)]
+
+use std::ops::AsyncFnMut;
+
+fn produce() -> impl AsyncFnMut() -> &'static str {
+    async || ""
+}
+
+fn main() {
+    let x: i32 = produce();
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr
new file mode 100644
index 00000000000..863e61eb35a
--- /dev/null
+++ b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/pretty-async-fn-opaque.rs:12:18
+   |
+LL | fn produce() -> impl AsyncFnMut() -> &'static str {
+   |                 --------------------------------- the found opaque type
+...
+LL |     let x: i32 = produce();
+   |            ---   ^^^^^^^^^ expected `i32`, found opaque type
+   |            |
+   |            expected due to this
+   |
+   = note:     expected type `i32`
+           found opaque type `impl AsyncFnMut() -> &'static str`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/async-fn/edition-2015.stderr b/tests/ui/async-await/async-fn/edition-2015.stderr
index 25101cb65df..9fbceafd75d 100644
--- a/tests/ui/async-await/async-fn/edition-2015.stderr
+++ b/tests/ui/async-await/async-fn/edition-2015.stderr
@@ -4,7 +4,7 @@ error: `async` trait bounds are only allowed in Rust 2018 or later
 LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
    |                ^^^^^
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: `async` trait bounds are only allowed in Rust 2018 or later
@@ -13,7 +13,7 @@ error: `async` trait bounds are only allowed in Rust 2018 or later
 LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
    |                                    ^^^^^
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0658]: async closures are unstable
diff --git a/tests/ui/async-await/coroutine-desc.stderr b/tests/ui/async-await/coroutine-desc.stderr
index e1d7898478e..5434ff3d958 100644
--- a/tests/ui/async-await/coroutine-desc.stderr
+++ b/tests/ui/async-await/coroutine-desc.stderr
@@ -19,7 +19,7 @@ LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
    |    ^^^ -                       -----  ----- this parameter needs to match the `async` block type of `f1`
    |        |                       |
    |        |                       `f2` needs to match the `async` block type of this parameter
-   |        `f1` and `f2` all reference this parameter F
+   |        `f1` and `f2` both reference this parameter `F`
 
 error[E0308]: mismatched types
   --> $DIR/coroutine-desc.rs:12:16
@@ -39,7 +39,7 @@ LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
    |    ^^^ -                       -----  ----- this parameter needs to match the future type of `f1`
    |        |                       |
    |        |                       `f2` needs to match the future type of this parameter
-   |        `f1` and `f2` all reference this parameter F
+   |        `f1` and `f2` both reference this parameter `F`
 
 error[E0308]: mismatched types
   --> $DIR/coroutine-desc.rs:14:26
@@ -62,7 +62,7 @@ LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
    |    ^^^ -                       -----  ----- this parameter needs to match the `async` closure body type of `f1`
    |        |                       |
    |        |                       `f2` needs to match the `async` closure body type of this parameter
-   |        `f1` and `f2` all reference this parameter F
+   |        `f1` and `f2` both reference this parameter `F`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/async-await/edition-deny-async-fns-2015.stderr b/tests/ui/async-await/edition-deny-async-fns-2015.stderr
index c40cdc5acec..f39ec033e70 100644
--- a/tests/ui/async-await/edition-deny-async-fns-2015.stderr
+++ b/tests/ui/async-await/edition-deny-async-fns-2015.stderr
@@ -4,7 +4,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL | async fn foo() {}
    | ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -13,7 +13,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL | fn baz() { async fn foo() {} }
    |            ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -22,7 +22,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL | async fn async_baz() {
    | ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -31,7 +31,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |     async fn bar() {}
    |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -40,7 +40,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |     async fn foo() {}
    |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -49,7 +49,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |     async fn foo() {}
    |     ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -58,7 +58,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |         async fn bar() {}
    |         ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -67,7 +67,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |         async fn foo() {}
    |         ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
@@ -76,7 +76,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |             async fn bar() {}
    |             ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: aborting due to 9 previous errors
diff --git a/tests/ui/async-await/for-await-passthrough.rs b/tests/ui/async-await/for-await-passthrough.rs
index b4fba6b2f76..1918e2f61aa 100644
--- a/tests/ui/async-await/for-await-passthrough.rs
+++ b/tests/ui/async-await/for-await-passthrough.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 #![feature(async_iterator, async_iter_from_iter, async_for_loop, noop_waker,
            gen_blocks)]
 
diff --git a/tests/ui/async-await/suggest-switching-edition-on-await-cargo.rs b/tests/ui/async-await/suggest-switching-edition-on-await-cargo.rs
index e1fae0f0e93..bcb5cb94b77 100644
--- a/tests/ui/async-await/suggest-switching-edition-on-await-cargo.rs
+++ b/tests/ui/async-await/suggest-switching-edition-on-await-cargo.rs
@@ -12,7 +12,7 @@ fn await_on_struct_missing() {
     //~^ ERROR no field `await` on type
     //~| NOTE unknown field
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| HELP set `edition = "2024"` in `Cargo.toml`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -26,7 +26,7 @@ fn await_on_struct_similar() {
     //~| NOTE unknown field
     //~| HELP a field with a similar name exists
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| HELP set `edition = "2024"` in `Cargo.toml`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -35,7 +35,7 @@ fn await_on_63533(x: Pin<&mut dyn Future<Output = ()>>) {
     //~^ ERROR no field `await` on type
     //~| NOTE unknown field
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| HELP set `edition = "2024"` in `Cargo.toml`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -44,6 +44,6 @@ fn await_on_apit(x: impl Future<Output = ()>) {
     //~^ ERROR no field `await` on type
     //~| NOTE unknown field
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP set `edition = "2021"` in `Cargo.toml`
+    //~| HELP set `edition = "2024"` in `Cargo.toml`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
diff --git a/tests/ui/async-await/suggest-switching-edition-on-await-cargo.stderr b/tests/ui/async-await/suggest-switching-edition-on-await-cargo.stderr
index dd863ca541c..c8bbb3a243c 100644
--- a/tests/ui/async-await/suggest-switching-edition-on-await-cargo.stderr
+++ b/tests/ui/async-await/suggest-switching-edition-on-await-cargo.stderr
@@ -5,7 +5,7 @@ LL |     x.await;
    |       ^^^^^ unknown field
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: set `edition = "2024"` in `Cargo.toml`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0609]: no field `await` on type `await_on_struct_similar::S`
@@ -15,7 +15,7 @@ LL |     x.await;
    |       ^^^^^ unknown field
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: set `edition = "2024"` in `Cargo.toml`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 help: a field with a similar name exists
    |
@@ -29,7 +29,7 @@ LL |     x.await;
    |       ^^^^^ unknown field
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: set `edition = "2024"` in `Cargo.toml`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0609]: no field `await` on type `impl Future<Output = ()>`
@@ -39,7 +39,7 @@ LL |     x.await;
    |       ^^^^^ unknown field
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: set `edition = "2021"` in `Cargo.toml`
+   = help: set `edition = "2024"` in `Cargo.toml`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/async-await/suggest-switching-edition-on-await.rs b/tests/ui/async-await/suggest-switching-edition-on-await.rs
index 10e245796ee..0907a87e02c 100644
--- a/tests/ui/async-await/suggest-switching-edition-on-await.rs
+++ b/tests/ui/async-await/suggest-switching-edition-on-await.rs
@@ -10,7 +10,7 @@ fn await_on_struct_missing() {
     //~^ ERROR no field `await` on type
     //~| NOTE unknown field
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP pass `--edition 2021` to `rustc`
+    //~| HELP pass `--edition 2024` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -24,7 +24,7 @@ fn await_on_struct_similar() {
     //~| NOTE unknown field
     //~| HELP a field with a similar name exists
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP pass `--edition 2021` to `rustc`
+    //~| HELP pass `--edition 2024` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -33,7 +33,7 @@ fn await_on_63533(x: Pin<&mut dyn Future<Output = ()>>) {
     //~^ ERROR no field `await` on type
     //~| NOTE unknown field
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP pass `--edition 2021` to `rustc`
+    //~| HELP pass `--edition 2024` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -42,6 +42,6 @@ fn await_on_apit(x: impl Future<Output = ()>) {
     //~^ ERROR no field `await` on type
     //~| NOTE unknown field
     //~| NOTE to `.await` a `Future`, switch to Rust 2018
-    //~| HELP pass `--edition 2021` to `rustc`
+    //~| HELP pass `--edition 2024` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
diff --git a/tests/ui/async-await/suggest-switching-edition-on-await.stderr b/tests/ui/async-await/suggest-switching-edition-on-await.stderr
index 0ed256b059f..ef5a5f81269 100644
--- a/tests/ui/async-await/suggest-switching-edition-on-await.stderr
+++ b/tests/ui/async-await/suggest-switching-edition-on-await.stderr
@@ -5,7 +5,7 @@ LL |     x.await;
    |       ^^^^^ unknown field
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0609]: no field `await` on type `await_on_struct_similar::S`
@@ -15,7 +15,7 @@ LL |     x.await;
    |       ^^^^^ unknown field
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 help: a field with a similar name exists
    |
@@ -29,7 +29,7 @@ LL |     x.await;
    |       ^^^^^ unknown field
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0609]: no field `await` on type `impl Future<Output = ()>`
@@ -39,7 +39,7 @@ LL |     x.await;
    |       ^^^^^ unknown field
    |
    = note: to `.await` a `Future`, switch to Rust 2018 or later
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/attr-start.rs b/tests/ui/attr-start.rs
index 27cf35601fd..232f50955b2 100644
--- a/tests/ui/attr-start.rs
+++ b/tests/ui/attr-start.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![feature(start)]
 
diff --git a/tests/ui/attributes/attr-before-view-item.rs b/tests/ui/attributes/attr-before-view-item.rs
index e0e086ea476..19874052e33 100644
--- a/tests/ui/attributes/attr-before-view-item.rs
+++ b/tests/ui/attributes/attr-before-view-item.rs
@@ -1,5 +1,4 @@
 //@ build-pass (FIXME(62277): could be check-pass?)
-//@ pretty-expanded FIXME #23616
 
 #![feature(rustc_attrs)]
 #![feature(test)]
diff --git a/tests/ui/attributes/attr-before-view-item2.rs b/tests/ui/attributes/attr-before-view-item2.rs
index 8d74d73fe2e..e58063a13ab 100644
--- a/tests/ui/attributes/attr-before-view-item2.rs
+++ b/tests/ui/attributes/attr-before-view-item2.rs
@@ -1,5 +1,4 @@
 //@ build-pass (FIXME(62277): could be check-pass?)
-//@ pretty-expanded FIXME #23616
 
 #![feature(rustc_attrs)]
 #![feature(test)]
diff --git a/tests/ui/attributes/attr-mix-new.rs b/tests/ui/attributes/attr-mix-new.rs
index bb2bab8f267..bd249a0c198 100644
--- a/tests/ui/attributes/attr-mix-new.rs
+++ b/tests/ui/attributes/attr-mix-new.rs
@@ -1,5 +1,4 @@
 //@ build-pass (FIXME(62277): could be check-pass?)
-//@ pretty-expanded FIXME #23616
 
 #![feature(rustc_attrs)]
 
diff --git a/tests/ui/attributes/method-attributes.rs b/tests/ui/attributes/method-attributes.rs
index 4a7f042c20a..ded72d2457b 100644
--- a/tests/ui/attributes/method-attributes.rs
+++ b/tests/ui/attributes/method-attributes.rs
@@ -1,6 +1,5 @@
 //@ build-pass (FIXME(62277): could be check-pass?)
 //@ pp-exact - Make sure we print all the attributes
-//@ pretty-expanded FIXME #23616
 
 #![feature(rustc_attrs)]
 
diff --git a/tests/ui/attributes/no-sanitize.rs b/tests/ui/attributes/no-sanitize.rs
index 82b7a22d570..8c79866d5aa 100644
--- a/tests/ui/attributes/no-sanitize.rs
+++ b/tests/ui/attributes/no-sanitize.rs
@@ -4,31 +4,37 @@
 #![allow(dead_code)]
 
 fn invalid() {
-    #[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
+    #[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function
     {
         1
     };
 }
 
-#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
+#[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function
 type InvalidTy = ();
 
-#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
+#[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function
 mod invalid_module {}
 
 fn main() {
-    let _ = #[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
+    let _ = #[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function
     (|| 1);
 }
 
-#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
+#[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function
 struct F;
 
-#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
+#[no_sanitize(memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function
 impl F {
     #[no_sanitize(memory)]
     fn valid(&self) {}
 }
 
+#[no_sanitize(address, memory)] //~ ERROR `#[no_sanitize(memory)]` should be applied to a function
+static INVALID : i32 = 0;
+
 #[no_sanitize(memory)]
 fn valid() {}
+
+#[no_sanitize(address)]
+static VALID : i32 = 0;
diff --git a/tests/ui/attributes/no-sanitize.stderr b/tests/ui/attributes/no-sanitize.stderr
index f742ba0beed..9b0b76e3f4e 100644
--- a/tests/ui/attributes/no-sanitize.stderr
+++ b/tests/ui/attributes/no-sanitize.stderr
@@ -1,55 +1,63 @@
-error: attribute should be applied to a function definition
-  --> $DIR/no-sanitize.rs:7:5
+error: `#[no_sanitize(memory)]` should be applied to a function
+  --> $DIR/no-sanitize.rs:7:19
    |
 LL |       #[no_sanitize(memory)]
-   |       ^^^^^^^^^^^^^^^^^^^^^^
+   |                     ^^^^^^
 LL | /     {
 LL | |         1
 LL | |     };
-   | |_____- not a function definition
+   | |_____- not a function
 
-error: attribute should be applied to a function definition
-  --> $DIR/no-sanitize.rs:13:1
+error: `#[no_sanitize(memory)]` should be applied to a function
+  --> $DIR/no-sanitize.rs:13:15
    |
 LL | #[no_sanitize(memory)]
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   |               ^^^^^^
 LL | type InvalidTy = ();
-   | -------------------- not a function definition
+   | -------------------- not a function
 
-error: attribute should be applied to a function definition
-  --> $DIR/no-sanitize.rs:16:1
+error: `#[no_sanitize(memory)]` should be applied to a function
+  --> $DIR/no-sanitize.rs:16:15
    |
 LL | #[no_sanitize(memory)]
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   |               ^^^^^^
 LL | mod invalid_module {}
-   | --------------------- not a function definition
+   | --------------------- not a function
 
-error: attribute should be applied to a function definition
-  --> $DIR/no-sanitize.rs:20:13
+error: `#[no_sanitize(memory)]` should be applied to a function
+  --> $DIR/no-sanitize.rs:20:27
    |
 LL |     let _ = #[no_sanitize(memory)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
+   |                           ^^^^^^
 LL |     (|| 1);
-   |     ------ not a function definition
+   |     ------ not a function
 
-error: attribute should be applied to a function definition
-  --> $DIR/no-sanitize.rs:24:1
+error: `#[no_sanitize(memory)]` should be applied to a function
+  --> $DIR/no-sanitize.rs:24:15
    |
 LL | #[no_sanitize(memory)]
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   |               ^^^^^^
 LL | struct F;
-   | --------- not a function definition
+   | --------- not a function
 
-error: attribute should be applied to a function definition
-  --> $DIR/no-sanitize.rs:27:1
+error: `#[no_sanitize(memory)]` should be applied to a function
+  --> $DIR/no-sanitize.rs:27:15
    |
 LL |   #[no_sanitize(memory)]
-   |   ^^^^^^^^^^^^^^^^^^^^^^
+   |                 ^^^^^^
 LL | / impl F {
 LL | |     #[no_sanitize(memory)]
 LL | |     fn valid(&self) {}
 LL | | }
-   | |_- not a function definition
+   | |_- not a function
 
-error: aborting due to 6 previous errors
+error: `#[no_sanitize(memory)]` should be applied to a function
+  --> $DIR/no-sanitize.rs:33:24
+   |
+LL | #[no_sanitize(address, memory)]
+   |                        ^^^^^^
+LL | static INVALID : i32 = 0;
+   | ------------------------- not a function
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs
index 273b127bf9c..19046c08ca8 100644
--- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs
+++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 
 #[unsafe(cfg(any()))] //~ ERROR: is not an unsafe attribute
 fn a() {}
diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr
index 445d239d867..b549a638d5e 100644
--- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr
+++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr
@@ -1,5 +1,5 @@
 error: `cfg` is not an unsafe attribute
-  --> $DIR/extraneous-unsafe-attributes.rs:4:3
+  --> $DIR/extraneous-unsafe-attributes.rs:3:3
    |
 LL | #[unsafe(cfg(any()))]
    |   ^^^^^^ this is not an unsafe attribute
@@ -7,7 +7,7 @@ LL | #[unsafe(cfg(any()))]
    = note: extraneous unsafe is not allowed in attributes
 
 error: `cfg_attr` is not an unsafe attribute
-  --> $DIR/extraneous-unsafe-attributes.rs:7:3
+  --> $DIR/extraneous-unsafe-attributes.rs:6:3
    |
 LL | #[unsafe(cfg_attr(any(), allow(dead_code)))]
    |   ^^^^^^ this is not an unsafe attribute
@@ -15,7 +15,7 @@ LL | #[unsafe(cfg_attr(any(), allow(dead_code)))]
    = note: extraneous unsafe is not allowed in attributes
 
 error: `test` is not an unsafe attribute
-  --> $DIR/extraneous-unsafe-attributes.rs:10:3
+  --> $DIR/extraneous-unsafe-attributes.rs:9:3
    |
 LL | #[unsafe(test)]
    |   ^^^^^^ this is not an unsafe attribute
@@ -23,7 +23,7 @@ LL | #[unsafe(test)]
    = note: extraneous unsafe is not allowed in attributes
 
 error: expected identifier, found keyword `unsafe`
-  --> $DIR/extraneous-unsafe-attributes.rs:31:19
+  --> $DIR/extraneous-unsafe-attributes.rs:30:19
    |
 LL |     let _a = cfg!(unsafe(foo));
    |                   ^^^^^^ expected identifier, found keyword
@@ -34,13 +34,13 @@ LL |     let _a = cfg!(r#unsafe(foo));
    |                   ++
 
 error[E0537]: invalid predicate `r#unsafe`
-  --> $DIR/extraneous-unsafe-attributes.rs:31:19
+  --> $DIR/extraneous-unsafe-attributes.rs:30:19
    |
 LL |     let _a = cfg!(unsafe(foo));
    |                   ^^^^^^^^^^^
 
 error: `ignore` is not an unsafe attribute
-  --> $DIR/extraneous-unsafe-attributes.rs:13:3
+  --> $DIR/extraneous-unsafe-attributes.rs:12:3
    |
 LL | #[unsafe(ignore = "test")]
    |   ^^^^^^ this is not an unsafe attribute
@@ -48,7 +48,7 @@ LL | #[unsafe(ignore = "test")]
    = note: extraneous unsafe is not allowed in attributes
 
 error: `should_panic` is not an unsafe attribute
-  --> $DIR/extraneous-unsafe-attributes.rs:16:3
+  --> $DIR/extraneous-unsafe-attributes.rs:15:3
    |
 LL | #[unsafe(should_panic(expected = "test"))]
    |   ^^^^^^ this is not an unsafe attribute
@@ -56,7 +56,7 @@ LL | #[unsafe(should_panic(expected = "test"))]
    = note: extraneous unsafe is not allowed in attributes
 
 error: `macro_use` is not an unsafe attribute
-  --> $DIR/extraneous-unsafe-attributes.rs:19:3
+  --> $DIR/extraneous-unsafe-attributes.rs:18:3
    |
 LL | #[unsafe(macro_use)]
    |   ^^^^^^ this is not an unsafe attribute
@@ -64,7 +64,7 @@ LL | #[unsafe(macro_use)]
    = note: extraneous unsafe is not allowed in attributes
 
 error: `macro_export` is not an unsafe attribute
-  --> $DIR/extraneous-unsafe-attributes.rs:21:7
+  --> $DIR/extraneous-unsafe-attributes.rs:20:7
    |
 LL |     #[unsafe(macro_export)]
    |       ^^^^^^ this is not an unsafe attribute
@@ -72,7 +72,7 @@ LL |     #[unsafe(macro_export)]
    = note: extraneous unsafe is not allowed in attributes
 
 error: `used` is not an unsafe attribute
-  --> $DIR/extraneous-unsafe-attributes.rs:27:3
+  --> $DIR/extraneous-unsafe-attributes.rs:26:3
    |
 LL | #[unsafe(used)]
    |   ^^^^^^ this is not an unsafe attribute
diff --git a/tests/ui/attributes/variant-attributes.rs b/tests/ui/attributes/variant-attributes.rs
index 57423ad61b2..a08856aa278 100644
--- a/tests/ui/attributes/variant-attributes.rs
+++ b/tests/ui/attributes/variant-attributes.rs
@@ -1,6 +1,5 @@
 //@ build-pass (FIXME(62277): could be check-pass?)
 //@ pp-exact - Make sure we actually print the attributes
-//@ pretty-expanded FIXME #23616
 
 #![allow(non_camel_case_types)]
 #![feature(rustc_attrs)]
diff --git a/tests/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs b/tests/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs
index b44e2a8cd37..d75a2ab8bdb 100644
--- a/tests/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs
+++ b/tests/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 struct Foo {
     x: isize,
diff --git a/tests/ui/auxiliary/unsafe-fields-crate-dep.rs b/tests/ui/auxiliary/unsafe-fields-crate-dep.rs
new file mode 100644
index 00000000000..95b928402a9
--- /dev/null
+++ b/tests/ui/auxiliary/unsafe-fields-crate-dep.rs
@@ -0,0 +1,7 @@
+#![allow(incomplete_features)]
+#![feature(unsafe_fields)]
+
+pub struct WithUnsafeField {
+    pub unsafe unsafe_field: u32,
+    pub safe_field: u32,
+}
diff --git a/tests/ui/bench/issue-32062.rs b/tests/ui/bench/issue-32062.rs
index 84de427a200..a7d1f8073d4 100644
--- a/tests/ui/bench/issue-32062.rs
+++ b/tests/ui/bench/issue-32062.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let _ = test(Some(0).into_iter());
diff --git a/tests/ui/binding/inconsistent-lifetime-mismatch.rs b/tests/ui/binding/inconsistent-lifetime-mismatch.rs
index b45c72cd9bd..539f8f58a1d 100644
--- a/tests/ui/binding/inconsistent-lifetime-mismatch.rs
+++ b/tests/ui/binding/inconsistent-lifetime-mismatch.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn foo(_: &[&str]) {}
 
diff --git a/tests/ui/binding/match-naked-record-expr.rs b/tests/ui/binding/match-naked-record-expr.rs
index c6557cc10d6..57697a73ca4 100644
--- a/tests/ui/binding/match-naked-record-expr.rs
+++ b/tests/ui/binding/match-naked-record-expr.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 struct X { x: isize }
 
diff --git a/tests/ui/binding/match-naked-record.rs b/tests/ui/binding/match-naked-record.rs
index 24d7aec00e7..ce9489a00f2 100644
--- a/tests/ui/binding/match-naked-record.rs
+++ b/tests/ui/binding/match-naked-record.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 struct X { x: isize }
 
diff --git a/tests/ui/binding/match-path.rs b/tests/ui/binding/match-path.rs
index 9bcef9914d1..1305ac7668e 100644
--- a/tests/ui/binding/match-path.rs
+++ b/tests/ui/binding/match-path.rs
@@ -3,7 +3,6 @@
 #![allow(non_camel_case_types)]
 
 
-//@ pretty-expanded FIXME #23616
 
 mod m1 {
     pub enum foo { foo1, foo2, }
diff --git a/tests/ui/binding/match-pattern-simple.rs b/tests/ui/binding/match-pattern-simple.rs
index 2e43b702fae..da22acd7f37 100644
--- a/tests/ui/binding/match-pattern-simple.rs
+++ b/tests/ui/binding/match-pattern-simple.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 
 
-//@ pretty-expanded FIXME #23616
 
 fn altsimple(f: isize) { match f { _x => () } }
 
diff --git a/tests/ui/binding/match-phi.rs b/tests/ui/binding/match-phi.rs
index cfef03adaa4..128d4d618a0 100644
--- a/tests/ui/binding/match-phi.rs
+++ b/tests/ui/binding/match-phi.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_assignments)]
-//@ pretty-expanded FIXME #23616
 #![allow(non_camel_case_types)]
 #![allow(unused_variables)]
 
diff --git a/tests/ui/binding/match-range-static.rs b/tests/ui/binding/match-range-static.rs
index 478dfb3cf41..cf4d030b66f 100644
--- a/tests/ui/binding/match-range-static.rs
+++ b/tests/ui/binding/match-range-static.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 #![allow(non_upper_case_globals)]
 
 const s: isize = 1;
diff --git a/tests/ui/binding/match-value-binding-in-guard-3291.rs b/tests/ui/binding/match-value-binding-in-guard-3291.rs
index a1f939cadca..ca8c34628b7 100644
--- a/tests/ui/binding/match-value-binding-in-guard-3291.rs
+++ b/tests/ui/binding/match-value-binding-in-guard-3291.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn foo(x: Option<Box<isize>>, b: bool) -> isize {
     match x {
diff --git a/tests/ui/binding/nil-pattern.rs b/tests/ui/binding/nil-pattern.rs
index 757d701c15a..68dbfe3b453 100644
--- a/tests/ui/binding/nil-pattern.rs
+++ b/tests/ui/binding/nil-pattern.rs
@@ -1,4 +1,3 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() { let x = (); match x { () => { } } }
diff --git a/tests/ui/binding/simple-generic-match.rs b/tests/ui/binding/simple-generic-match.rs
index 910bab03e1f..001b469d35e 100644
--- a/tests/ui/binding/simple-generic-match.rs
+++ b/tests/ui/binding/simple-generic-match.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 enum clam<T> { a(#[allow(dead_code)] T), }
 
diff --git a/tests/ui/borrowck/borrowck-assign-to-subfield.rs b/tests/ui/borrowck/borrowck-assign-to-subfield.rs
index 807941d9c85..27d9046e7b7 100644
--- a/tests/ui/borrowck/borrowck-assign-to-subfield.rs
+++ b/tests/ui/borrowck/borrowck-assign-to-subfield.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     struct A {
diff --git a/tests/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs b/tests/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs
index a815253d714..ef5baae4500 100644
--- a/tests/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs
+++ b/tests/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs
@@ -7,7 +7,6 @@
 //
 // Example from compiler/rustc_borrowck/borrowck/README.md
 
-//@ pretty-expanded FIXME #23616
 
 fn foo<'a>(mut t0: &'a mut isize,
            mut t1: &'a mut isize) {
diff --git a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
index d78d8a9d966..d200ef6d6f8 100644
--- a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
+++ b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
@@ -2,7 +2,6 @@
 #![allow(unused_mut)]
 #![allow(unused_variables)]
 #![allow(dropping_copy_types)]
-//@ pretty-expanded FIXME #23616
 
 struct A { a: isize, b: Box<isize> }
 struct B { a: Box<isize>, b: Box<isize> }
diff --git a/tests/ui/borrowck/borrowck-lend-args.rs b/tests/ui/borrowck/borrowck-lend-args.rs
index 08a7aea1627..9d45730f196 100644
--- a/tests/ui/borrowck/borrowck-lend-args.rs
+++ b/tests/ui/borrowck/borrowck-lend-args.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 
-//@ pretty-expanded FIXME #23616
 
 fn borrow(_v: &isize) {}
 
diff --git a/tests/ui/borrowck/borrowck-static-item-in-fn.rs b/tests/ui/borrowck/borrowck-static-item-in-fn.rs
index 9cdd4c89132..3c2e7b92c9e 100644
--- a/tests/ui/borrowck/borrowck-static-item-in-fn.rs
+++ b/tests/ui/borrowck/borrowck-static-item-in-fn.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 // Regression test for issue #7740
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     static A: &'static char = &'A';
diff --git a/tests/ui/borrowck/borrowck-trait-lifetime.rs b/tests/ui/borrowck/borrowck-trait-lifetime.rs
index e43201fb10b..26d4cfb8887 100644
--- a/tests/ui/borrowck/borrowck-trait-lifetime.rs
+++ b/tests/ui/borrowck/borrowck-trait-lifetime.rs
@@ -3,7 +3,6 @@
 // This test verifies that casting from the same lifetime on a value
 // to the same lifetime on a trait succeeds. See issue #10766.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/borrowck/borrowck-uniq-via-ref.rs b/tests/ui/borrowck/borrowck-uniq-via-ref.rs
index d3190d66bd3..67f908a0c07 100644
--- a/tests/ui/borrowck/borrowck-uniq-via-ref.rs
+++ b/tests/ui/borrowck/borrowck-uniq-via-ref.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 
-//@ pretty-expanded FIXME #23616
 
 struct Rec {
     f: Box<isize>,
diff --git a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
index 9649f484471..5bbac021504 100644
--- a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
+++ b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(dropping_copy_types)]
 
diff --git a/tests/ui/box/new-box-syntax.rs b/tests/ui/box/new-box-syntax.rs
index f2899ff3dde..a0d8cb75584 100644
--- a/tests/ui/box/new-box-syntax.rs
+++ b/tests/ui/box/new-box-syntax.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
diff --git a/tests/ui/box/new.rs b/tests/ui/box/new.rs
index 682a998ae19..2e7525e208f 100644
--- a/tests/ui/box/new.rs
+++ b/tests/ui/box/new.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let _a = Box::new(1);
diff --git a/tests/ui/box/unit/unique-containing-tag.rs b/tests/ui/box/unit/unique-containing-tag.rs
index cd88cfab425..a9752a64f4d 100644
--- a/tests/ui/box/unit/unique-containing-tag.rs
+++ b/tests/ui/box/unit/unique-containing-tag.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     enum t { t1(isize), t2(isize), }
diff --git a/tests/ui/box/unit/unique-create.rs b/tests/ui/box/unit/unique-create.rs
index bf3826156b1..b3b72971e53 100644
--- a/tests/ui/box/unit/unique-create.rs
+++ b/tests/ui/box/unit/unique-create.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let _: Box<_> = Box::new(100);
diff --git a/tests/ui/box/unit/unique-drop-complex.rs b/tests/ui/box/unit/unique-drop-complex.rs
index f23635e59cd..6e5fb524f41 100644
--- a/tests/ui/box/unit/unique-drop-complex.rs
+++ b/tests/ui/box/unit/unique-drop-complex.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let _x: Box<_> = Box::new(vec![0,0,0,0,0]);
diff --git a/tests/ui/box/unit/unique-generic-assign.rs b/tests/ui/box/unit/unique-generic-assign.rs
index ef9c34c41a3..2c5cb0c1112 100644
--- a/tests/ui/box/unit/unique-generic-assign.rs
+++ b/tests/ui/box/unit/unique-generic-assign.rs
@@ -3,7 +3,6 @@
 // Issue #976
 
 
-//@ pretty-expanded FIXME #23616
 
 fn f<T>(x: Box<T>) {
     let _x2 = x;
diff --git a/tests/ui/box/unit/unique-init.rs b/tests/ui/box/unit/unique-init.rs
index ad2390c2ca0..0950c794c48 100644
--- a/tests/ui/box/unit/unique-init.rs
+++ b/tests/ui/box/unit/unique-init.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let _i: Box<_> = Box::new(100);
diff --git a/tests/ui/box/unit/unique-match-discrim.rs b/tests/ui/box/unit/unique-match-discrim.rs
index 97b502004f5..c1b7b15c7c4 100644
--- a/tests/ui/box/unit/unique-match-discrim.rs
+++ b/tests/ui/box/unit/unique-match-discrim.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 // Issue #961
 
-//@ pretty-expanded FIXME #23616
 
 fn altsimple() {
     match Box::new(true) {
diff --git a/tests/ui/box/unit/unique-object-move.rs b/tests/ui/box/unit/unique-object-move.rs
index f30fc5c8e64..6ed2b1dc401 100644
--- a/tests/ui/box/unit/unique-object-move.rs
+++ b/tests/ui/box/unit/unique-object-move.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 // Issue #5192
 
-//@ pretty-expanded FIXME #23616
 
 pub trait EventLoop { fn foo(&self) {} }
 
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-phantom-typaram.rs b/tests/ui/builtin-superkinds/builtin-superkinds-phantom-typaram.rs
index 8a2fa468577..ea5d3bdcfdb 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-phantom-typaram.rs
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-phantom-typaram.rs
@@ -5,7 +5,6 @@
 // super-builtin-kind of a trait, if the type parameter is never used,
 // the type can implement the trait anyway.
 
-//@ pretty-expanded FIXME #23616
 
 use std::marker;
 
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs b/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs
index 1354b4ac188..510ef4c158e 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 // Simple test case of implementing a trait with super-builtin-kinds.
 
-//@ pretty-expanded FIXME #23616
 
 trait Foo : Send { }
 
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs b/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs
index 15b867dd5e0..de2afc4a171 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs
@@ -2,7 +2,6 @@
 // Tests correct implementation of traits with super-builtin-kinds
 // using a bounded type parameter.
 
-//@ pretty-expanded FIXME #23616
 
 trait Foo : Send { }
 
diff --git a/tests/ui/can-copy-pod.rs b/tests/ui/can-copy-pod.rs
index dd4cf54040a..ffb8a08fa98 100644
--- a/tests/ui/can-copy-pod.rs
+++ b/tests/ui/can-copy-pod.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
diff --git a/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs b/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs
index 0575c29bffd..12d143bd989 100644
--- a/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs
+++ b/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn foo(x: &mut Box<u8>) {
     *x = Box::new(5);
diff --git a/tests/ui/cfg/cfg-attr-cfg.rs b/tests/ui/cfg/cfg-attr-cfg.rs
index 67d97e760d7..08b9374cfd7 100644
--- a/tests/ui/cfg/cfg-attr-cfg.rs
+++ b/tests/ui/cfg/cfg-attr-cfg.rs
@@ -2,7 +2,6 @@
 // main is conditionally compiled, but the conditional compilation
 // is conditional too!
 
-//@ pretty-expanded FIXME #23616
 
 #[cfg_attr(FALSE, cfg(bar))]
 fn main() { }
diff --git a/tests/ui/cfg/cfg-attr-crate.rs b/tests/ui/cfg/cfg-attr-crate.rs
index 444704d132a..44242a6a57d 100644
--- a/tests/ui/cfg/cfg-attr-crate.rs
+++ b/tests/ui/cfg/cfg-attr-crate.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044
 
-//@ pretty-expanded FIXME #23616
 
 #![cfg_attr(FALSE, no_core)]
 
diff --git a/tests/ui/cfg/cfg-family.rs b/tests/ui/cfg/cfg-family.rs
index caf59327f10..a13ae7f9616 100644
--- a/tests/ui/cfg/cfg-family.rs
+++ b/tests/ui/cfg/cfg-family.rs
@@ -1,5 +1,4 @@
 //@ build-pass
-//@ pretty-expanded FIXME #23616
 //@ ignore-wasm32 no bare family
 //@ ignore-sgx
 
diff --git a/tests/ui/cfg/cfg-match-arm.rs b/tests/ui/cfg/cfg-match-arm.rs
index e646a63b8fb..f6cd52c475c 100644
--- a/tests/ui/cfg/cfg-match-arm.rs
+++ b/tests/ui/cfg/cfg-match-arm.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 enum Foo {
     Bar,
diff --git a/tests/ui/cfg/cfg-target-family.rs b/tests/ui/cfg/cfg-target-family.rs
index ab3be302e64..0b1c323307a 100644
--- a/tests/ui/cfg/cfg-target-family.rs
+++ b/tests/ui/cfg/cfg-target-family.rs
@@ -1,7 +1,6 @@
 //@ build-pass
 //@ ignore-sgx
 
-//@ pretty-expanded FIXME #23616
 
 #[cfg(target_family = "windows")]
 pub fn main() {}
diff --git a/tests/ui/cfg/cfg_inner_static.rs b/tests/ui/cfg/cfg_inner_static.rs
index f4e2dc092f8..8d188b0aed7 100644
--- a/tests/ui/cfg/cfg_inner_static.rs
+++ b/tests/ui/cfg/cfg_inner_static.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:cfg_inner_static.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate cfg_inner_static;
 
diff --git a/tests/ui/cfg/conditional-compile-arch.rs b/tests/ui/cfg/conditional-compile-arch.rs
index 678b32c6a4e..594d9344561 100644
--- a/tests/ui/cfg/conditional-compile-arch.rs
+++ b/tests/ui/cfg/conditional-compile-arch.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #[cfg(target_arch = "x86")]
 pub fn main() { }
diff --git a/tests/ui/cleanup-shortcircuit.rs b/tests/ui/cleanup-shortcircuit.rs
index 312491fee24..40a5dfa94e3 100644
--- a/tests/ui/cleanup-shortcircuit.rs
+++ b/tests/ui/cleanup-shortcircuit.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Test that cleanups for the RHS of shortcircuiting operators work.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(deref_nullptr)]
 
diff --git a/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
index 5f980c46a1f..b5ad8eb790f 100644
--- a/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
+++ b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
@@ -5,7 +5,7 @@ LL |         let 0 = v1;
    |             ^ pattern `1_u32..=u32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u32`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -23,7 +23,7 @@ LL |         let (0 | 1) = v1;
    |              ^^^^^ pattern `2_u32..=u32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u32`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -37,7 +37,7 @@ LL |         let 1.. = v1;
    |             ^^^ pattern `0_u32` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u32`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -51,7 +51,7 @@ LL |         let [0, 0, 0, 0] = v2;
    |             ^^^^^^^^^^^^ pattern `[1_u32..=u32::MAX, _, _, _]` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `[u32; 4]`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -65,7 +65,7 @@ LL |         let [0] = v4;
    |             ^^^ patterns `&[]` and `&[_, _, ..]` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `&[u32]`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
@@ -79,7 +79,7 @@ LL |         let Refutable::A = v3;
    |             ^^^^^^^^^^^^ pattern `Refutable::B` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Refutable` defined here
   --> $DIR/bad-pattern.rs:4:6
    |
@@ -104,7 +104,7 @@ LL |         let PAT = v1;
    |             ^^^ pattern `1_u32..=u32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u32`
 help: introduce a variable instead
    |
diff --git a/tests/ui/closures/issue-10682.rs b/tests/ui/closures/issue-10682.rs
index 25636b9063b..265e72aaa69 100644
--- a/tests/ui/closures/issue-10682.rs
+++ b/tests/ui/closures/issue-10682.rs
@@ -2,7 +2,6 @@
 // Regression test for issue #10682
 // Nested `proc` usage can't use outer owned data
 
-//@ pretty-expanded FIXME #23616
 
 fn work(_: Box<isize>) {}
 fn foo<F:FnOnce()>(_: F) {}
diff --git a/tests/ui/closures/issue-1460.rs b/tests/ui/closures/issue-1460.rs
index c201f026bca..ceb030b92c8 100644
--- a/tests/ui/closures/issue-1460.rs
+++ b/tests/ui/closures/issue-1460.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     {|i: u32| if 1 == i { }}; //~ WARN unused closure that must be used
diff --git a/tests/ui/closures/issue-1460.stderr b/tests/ui/closures/issue-1460.stderr
index d4a8c8955e2..15eaf7a9a11 100644
--- a/tests/ui/closures/issue-1460.stderr
+++ b/tests/ui/closures/issue-1460.stderr
@@ -1,5 +1,5 @@
 warning: unused closure that must be used
-  --> $DIR/issue-1460.rs:6:6
+  --> $DIR/issue-1460.rs:5:6
    |
 LL |     {|i: u32| if 1 == i { }};
    |      ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/closures/issue-868.rs b/tests/ui/closures/issue-868.rs
index 170597b4bd5..70debbc6c87 100644
--- a/tests/ui/closures/issue-868.rs
+++ b/tests/ui/closures/issue-868.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_parens)]
 #![allow(unit_bindings)]
-//@ pretty-expanded FIXME #23616
 
 fn f<T, F>(g: F) -> T where F: FnOnce() -> T { g() }
 
diff --git a/tests/ui/codegen/init-large-type.rs b/tests/ui/codegen/init-large-type.rs
index b9fc6612e16..08697198f24 100644
--- a/tests/ui/codegen/init-large-type.rs
+++ b/tests/ui/codegen/init-large-type.rs
@@ -6,7 +6,6 @@
 // Doing it incorrectly causes massive slowdown in LLVM during
 // optimisation.
 
-//@ pretty-expanded FIXME #23616
 //@ needs-threads
 #![feature(intrinsics)]
 
diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.rs b/tests/ui/codemap_tests/huge_multispan_highlight.rs
index 7d7b7570823..6f6834b01bd 100644
--- a/tests/ui/codemap_tests/huge_multispan_highlight.rs
+++ b/tests/ui/codemap_tests/huge_multispan_highlight.rs
@@ -1,7 +1,7 @@
 //@ revisions: ascii unicode
 //@ compile-flags: --color=always
 //@[ascii] compile-flags: --error-format=human
-//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode
 //@ ignore-windows
 fn main() {
     let _ = match true {
diff --git a/tests/ui/coercion/coerce-overloaded-autoderef.rs b/tests/ui/coercion/coerce-overloaded-autoderef.rs
index 0605f20e9a3..03d0b0df543 100644
--- a/tests/ui/coercion/coerce-overloaded-autoderef.rs
+++ b/tests/ui/coercion/coerce-overloaded-autoderef.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_braces)]
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 use std::rc::Rc;
 
diff --git a/tests/ui/coercion/coerce-reborrow-imm-ptr-arg.rs b/tests/ui/coercion/coerce-reborrow-imm-ptr-arg.rs
index 139c1d18d2b..f43b6dad71d 100644
--- a/tests/ui/coercion/coerce-reborrow-imm-ptr-arg.rs
+++ b/tests/ui/coercion/coerce-reborrow-imm-ptr-arg.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn negate(x: &isize) -> isize {
     -*x
diff --git a/tests/ui/coercion/coerce-reborrow-imm-vec-arg.rs b/tests/ui/coercion/coerce-reborrow-imm-vec-arg.rs
index d8edd8648c4..afcec17d55b 100644
--- a/tests/ui/coercion/coerce-reborrow-imm-vec-arg.rs
+++ b/tests/ui/coercion/coerce-reborrow-imm-vec-arg.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn sum(x: &[isize]) -> isize {
     let mut sum = 0;
diff --git a/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr b/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
index 46723c5a297..5dea3f70fdb 100644
--- a/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
+++ b/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
@@ -16,7 +16,7 @@ LL | fn test<T>(_a: T, _b: T) {}
    |    ^^^^ -  -----  ----- this parameter needs to match the `&mut {integer}` type of `_a`
    |         |  |
    |         |  `_b` needs to match the `&mut {integer}` type of this parameter
-   |         `_a` and `_b` all reference this parameter T
+   |         `_a` and `_b` both reference this parameter `T`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coercion/coerce-reborrow-mut-ptr-arg.rs b/tests/ui/coercion/coerce-reborrow-mut-ptr-arg.rs
index 7a08e9fdbe5..0367e384829 100644
--- a/tests/ui/coercion/coerce-reborrow-mut-ptr-arg.rs
+++ b/tests/ui/coercion/coerce-reborrow-mut-ptr-arg.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 struct SpeechMaker {
     speeches: usize
diff --git a/tests/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs b/tests/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs
index fc41beb45cc..b9479f6bdf8 100644
--- a/tests/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs
+++ b/tests/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 struct SpeechMaker {
     speeches: usize
diff --git a/tests/ui/coercion/coerce-unify-return.rs b/tests/ui/coercion/coerce-unify-return.rs
index def42d9dc14..54998a35382 100644
--- a/tests/ui/coercion/coerce-unify-return.rs
+++ b/tests/ui/coercion/coerce-unify-return.rs
@@ -2,7 +2,6 @@
 // Check that coercions unify the expected return type of a polymorphic
 // function call, instead of leaving the type variables as they were.
 
-//@ pretty-expanded FIXME #23616
 
 struct Foo;
 impl Foo {
diff --git a/tests/ui/coercion/coerce-unsize-subtype.rs b/tests/ui/coercion/coerce-unsize-subtype.rs
index 5ef9a108892..a3e762e4c5f 100644
--- a/tests/ui/coercion/coerce-unsize-subtype.rs
+++ b/tests/ui/coercion/coerce-unsize-subtype.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 use std::rc::Rc;
 
diff --git a/tests/ui/coercion/issue-14589.rs b/tests/ui/coercion/issue-14589.rs
index b25ba3758e1..1e99cc4f6a8 100644
--- a/tests/ui/coercion/issue-14589.rs
+++ b/tests/ui/coercion/issue-14589.rs
@@ -2,7 +2,6 @@
 // All 3 expressions should work in that the argument gets
 // coerced to a trait object
 
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     send::<Box<dyn Foo>>(Box::new(Output(0)));
diff --git a/tests/ui/coercion/issue-14589.stderr b/tests/ui/coercion/issue-14589.stderr
index 37b7fce7462..5d7b840a8d7 100644
--- a/tests/ui/coercion/issue-14589.stderr
+++ b/tests/ui/coercion/issue-14589.stderr
@@ -1,5 +1,5 @@
 warning: method `dummy` is never used
-  --> $DIR/issue-14589.rs:22:16
+  --> $DIR/issue-14589.rs:21:16
    |
 LL | trait Foo { fn dummy(&self) { }}
    |       ---      ^^^^^
diff --git a/tests/ui/coherence/coherence-bigint-int.rs b/tests/ui/coherence/coherence-bigint-int.rs
index 0a9ddf5e2d1..739c035cc90 100644
--- a/tests/ui/coherence/coherence-bigint-int.rs
+++ b/tests/ui/coherence/coherence-bigint-int.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:coherence_lib.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate coherence_lib as lib;
 use lib::Remote1;
diff --git a/tests/ui/coherence/coherence-bigint-vecint.rs b/tests/ui/coherence/coherence-bigint-vecint.rs
index 6822c6c44b7..c26defead3f 100644
--- a/tests/ui/coherence/coherence-bigint-vecint.rs
+++ b/tests/ui/coherence/coherence-bigint-vecint.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:coherence_lib.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate coherence_lib as lib;
 use lib::Remote1;
diff --git a/tests/ui/coherence/coherence-blanket.rs b/tests/ui/coherence/coherence-blanket.rs
index db10b8e654f..cc95e15a412 100644
--- a/tests/ui/coherence/coherence-blanket.rs
+++ b/tests/ui/coherence/coherence-blanket.rs
@@ -2,7 +2,6 @@
 #![allow(unused_imports)]
 //@ aux-build:coherence_lib.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate coherence_lib as lib;
 use lib::Remote1;
diff --git a/tests/ui/coherence/coherence-covered-type-parameter.rs b/tests/ui/coherence/coherence-covered-type-parameter.rs
index b6332a04424..3f349343382 100644
--- a/tests/ui/coherence/coherence-covered-type-parameter.rs
+++ b/tests/ui/coherence/coherence-covered-type-parameter.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 //@ aux-build:coherence_lib.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate coherence_lib as lib;
 use lib::Remote;
diff --git a/tests/ui/coherence/coherence-iterator-vec-any-elem.rs b/tests/ui/coherence/coherence-iterator-vec-any-elem.rs
index a406e4408a4..1e43595d1eb 100644
--- a/tests/ui/coherence/coherence-iterator-vec-any-elem.rs
+++ b/tests/ui/coherence/coherence-iterator-vec-any-elem.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 //@ aux-build:coherence_lib.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate coherence_lib as lib;
 use lib::Remote1;
diff --git a/tests/ui/coherence/coherence-iterator-vec.rs b/tests/ui/coherence/coherence-iterator-vec.rs
index 29553484931..02c3a9d2cee 100644
--- a/tests/ui/coherence/coherence-iterator-vec.rs
+++ b/tests/ui/coherence/coherence-iterator-vec.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 //@ aux-build:coherence_lib.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate coherence_lib as lib;
 use lib::Remote1;
diff --git a/tests/ui/coherence/coherence-multidispatch-tuple.rs b/tests/ui/coherence/coherence-multidispatch-tuple.rs
index ac7b2578d77..6a2de80c0ea 100644
--- a/tests/ui/coherence/coherence-multidispatch-tuple.rs
+++ b/tests/ui/coherence/coherence-multidispatch-tuple.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(unused_imports)]
-//@ pretty-expanded FIXME #23616
 
 use std::fmt::Debug;
 use std::default::Default;
diff --git a/tests/ui/coherence/coherence-negative-impls-safe-rpass.rs b/tests/ui/coherence/coherence-negative-impls-safe-rpass.rs
index d69872ba8cf..5935e972e49 100644
--- a/tests/ui/coherence/coherence-negative-impls-safe-rpass.rs
+++ b/tests/ui/coherence/coherence-negative-impls-safe-rpass.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 #![feature(negative_impls)]
 
diff --git a/tests/ui/coherence/fuzzing/best-obligation-ICE.rs b/tests/ui/coherence/fuzzing/best-obligation-ICE.rs
new file mode 100644
index 00000000000..49f40b579d4
--- /dev/null
+++ b/tests/ui/coherence/fuzzing/best-obligation-ICE.rs
@@ -0,0 +1,20 @@
+// A regression test for #129444. This previously ICE'd as
+// computing the best obligation for one ambiguous obligation
+// added spurious inference constraints which caused another
+// candidate to pass.
+trait Trait {
+    type Assoc;
+}
+
+struct W<T: Trait>(*mut T);
+impl<T> Trait for W<W<W<T>>> {}
+//~^ ERROR the trait bound `W<W<T>>: Trait` is not satisfied
+//~| ERROR the trait bound `W<T>: Trait` is not satisfied
+//~| ERROR the trait bound `T: Trait` is not satisfied
+//~| ERROR not all trait items implemented, missing: `Assoc`
+
+trait NoOverlap {}
+impl<T: Trait> NoOverlap for T {}
+impl<T: Trait<Assoc = u32>> NoOverlap for W<T> {}
+//~^ ERROR conflicting implementations of trait `NoOverlap` for type `W<W<W<W<_>>>>`
+fn main() {}
diff --git a/tests/ui/coherence/fuzzing/best-obligation-ICE.stderr b/tests/ui/coherence/fuzzing/best-obligation-ICE.stderr
new file mode 100644
index 00000000000..88de8023f6d
--- /dev/null
+++ b/tests/ui/coherence/fuzzing/best-obligation-ICE.stderr
@@ -0,0 +1,69 @@
+error[E0277]: the trait bound `W<W<T>>: Trait` is not satisfied
+  --> $DIR/best-obligation-ICE.rs:10:19
+   |
+LL | impl<T> Trait for W<W<W<T>>> {}
+   |                   ^^^^^^^^^^ the trait `Trait` is not implemented for `W<W<T>>`
+   |
+note: required by a bound in `W`
+  --> $DIR/best-obligation-ICE.rs:9:13
+   |
+LL | struct W<T: Trait>(*mut T);
+   |             ^^^^^ required by this bound in `W`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | impl<T> Trait for W<W<W<T>>> where W<W<T>>: Trait {}
+   |                              ++++++++++++++++++++
+
+error[E0277]: the trait bound `W<T>: Trait` is not satisfied
+  --> $DIR/best-obligation-ICE.rs:10:19
+   |
+LL | impl<T> Trait for W<W<W<T>>> {}
+   |                   ^^^^^^^^^^ the trait `Trait` is not implemented for `W<T>`
+   |
+note: required by a bound in `W`
+  --> $DIR/best-obligation-ICE.rs:9:13
+   |
+LL | struct W<T: Trait>(*mut T);
+   |             ^^^^^ required by this bound in `W`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | impl<T> Trait for W<W<W<T>>> where W<T>: Trait {}
+   |                              +++++++++++++++++
+
+error[E0277]: the trait bound `T: Trait` is not satisfied
+  --> $DIR/best-obligation-ICE.rs:10:19
+   |
+LL | impl<T> Trait for W<W<W<T>>> {}
+   |                   ^^^^^^^^^^ the trait `Trait` is not implemented for `T`
+   |
+note: required by a bound in `W`
+  --> $DIR/best-obligation-ICE.rs:9:13
+   |
+LL | struct W<T: Trait>(*mut T);
+   |             ^^^^^ required by this bound in `W`
+help: consider restricting type parameter `T`
+   |
+LL | impl<T: Trait> Trait for W<W<W<T>>> {}
+   |       +++++++
+
+error[E0046]: not all trait items implemented, missing: `Assoc`
+  --> $DIR/best-obligation-ICE.rs:10:1
+   |
+LL |     type Assoc;
+   |     ---------- `Assoc` from trait
+...
+LL | impl<T> Trait for W<W<W<T>>> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation
+
+error[E0119]: conflicting implementations of trait `NoOverlap` for type `W<W<W<W<_>>>>`
+  --> $DIR/best-obligation-ICE.rs:18:1
+   |
+LL | impl<T: Trait> NoOverlap for T {}
+   | ------------------------------ first implementation here
+LL | impl<T: Trait<Assoc = u32>> NoOverlap for W<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<_>>>>`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0046, E0119, E0277.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
index ce7fce25993..06a6a5f59d6 100644
--- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
+++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
@@ -53,7 +53,7 @@ LL |     let _: [u8; baz::<'b>(&())];
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:26:23
+  --> $DIR/const-arg-in-const-arg.rs:27:23
    |
 LL |     let _ = [0; bar::<N>()];
    |                       ^ cannot perform const operation using `N`
@@ -62,7 +62,7 @@ LL |     let _ = [0; bar::<N>()];
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:28:23
+  --> $DIR/const-arg-in-const-arg.rs:29:23
    |
 LL |     let _ = [0; faz::<'a>(&())];
    |                       ^^ cannot perform const operation using `'a`
@@ -71,7 +71,7 @@ LL |     let _ = [0; faz::<'a>(&())];
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:30:23
+  --> $DIR/const-arg-in-const-arg.rs:31:23
    |
 LL |     let _ = [0; baz::<'a>(&())];
    |                       ^^ cannot perform const operation using `'a`
@@ -80,7 +80,7 @@ LL |     let _ = [0; baz::<'a>(&())];
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:31:23
+  --> $DIR/const-arg-in-const-arg.rs:32:23
    |
 LL |     let _ = [0; faz::<'b>(&())];
    |                       ^^ cannot perform const operation using `'b`
@@ -89,7 +89,7 @@ LL |     let _ = [0; faz::<'b>(&())];
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:33:23
+  --> $DIR/const-arg-in-const-arg.rs:34:23
    |
 LL |     let _ = [0; baz::<'b>(&())];
    |                       ^^ cannot perform const operation using `'b`
@@ -98,7 +98,7 @@ LL |     let _ = [0; baz::<'b>(&())];
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:34:24
+  --> $DIR/const-arg-in-const-arg.rs:35:24
    |
 LL |     let _: Foo<{ foo::<T>() }>;
    |                        ^ cannot perform const operation using `T`
@@ -107,7 +107,7 @@ LL |     let _: Foo<{ foo::<T>() }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:35:24
+  --> $DIR/const-arg-in-const-arg.rs:36:24
    |
 LL |     let _: Foo<{ bar::<N>() }>;
    |                        ^ cannot perform const operation using `N`
@@ -116,7 +116,7 @@ LL |     let _: Foo<{ bar::<N>() }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:37:24
+  --> $DIR/const-arg-in-const-arg.rs:38:24
    |
 LL |     let _: Foo<{ faz::<'a>(&()) }>;
    |                        ^^ cannot perform const operation using `'a`
@@ -125,7 +125,7 @@ LL |     let _: Foo<{ faz::<'a>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:39:24
+  --> $DIR/const-arg-in-const-arg.rs:40:24
    |
 LL |     let _: Foo<{ baz::<'a>(&()) }>;
    |                        ^^ cannot perform const operation using `'a`
@@ -134,7 +134,7 @@ LL |     let _: Foo<{ baz::<'a>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:40:24
+  --> $DIR/const-arg-in-const-arg.rs:41:24
    |
 LL |     let _: Foo<{ faz::<'b>(&()) }>;
    |                        ^^ cannot perform const operation using `'b`
@@ -143,7 +143,7 @@ LL |     let _: Foo<{ faz::<'b>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:42:24
+  --> $DIR/const-arg-in-const-arg.rs:43:24
    |
 LL |     let _: Foo<{ baz::<'b>(&()) }>;
    |                        ^^ cannot perform const operation using `'b`
@@ -152,7 +152,7 @@ LL |     let _: Foo<{ baz::<'b>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:43:27
+  --> $DIR/const-arg-in-const-arg.rs:44:27
    |
 LL |     let _ = Foo::<{ foo::<T>() }>;
    |                           ^ cannot perform const operation using `T`
@@ -161,7 +161,7 @@ LL |     let _ = Foo::<{ foo::<T>() }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:44:27
+  --> $DIR/const-arg-in-const-arg.rs:45:27
    |
 LL |     let _ = Foo::<{ bar::<N>() }>;
    |                           ^ cannot perform const operation using `N`
@@ -170,7 +170,7 @@ LL |     let _ = Foo::<{ bar::<N>() }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:46:27
+  --> $DIR/const-arg-in-const-arg.rs:47:27
    |
 LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
    |                           ^^ cannot perform const operation using `'a`
@@ -179,7 +179,7 @@ LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:48:27
+  --> $DIR/const-arg-in-const-arg.rs:49:27
    |
 LL |     let _ = Foo::<{ baz::<'a>(&()) }>;
    |                           ^^ cannot perform const operation using `'a`
@@ -188,7 +188,7 @@ LL |     let _ = Foo::<{ baz::<'a>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:49:27
+  --> $DIR/const-arg-in-const-arg.rs:50:27
    |
 LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
    |                           ^^ cannot perform const operation using `'b`
@@ -197,7 +197,7 @@ LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:51:27
+  --> $DIR/const-arg-in-const-arg.rs:52:27
    |
 LL |     let _ = Foo::<{ baz::<'b>(&()) }>;
    |                           ^^ cannot perform const operation using `'b`
@@ -241,7 +241,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
 error[E0747]: unresolved item provided when a constant was expected
-  --> $DIR/const-arg-in-const-arg.rs:35:24
+  --> $DIR/const-arg-in-const-arg.rs:36:24
    |
 LL |     let _: Foo<{ bar::<N>() }>;
    |                        ^
@@ -252,7 +252,7 @@ LL |     let _: Foo<{ bar::<{ N }>() }>;
    |                        +   +
 
 error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-  --> $DIR/const-arg-in-const-arg.rs:37:24
+  --> $DIR/const-arg-in-const-arg.rs:38:24
    |
 LL |     let _: Foo<{ faz::<'a>(&()) }>;
    |                        ^^
@@ -264,7 +264,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
 error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-  --> $DIR/const-arg-in-const-arg.rs:40:24
+  --> $DIR/const-arg-in-const-arg.rs:41:24
    |
 LL |     let _: Foo<{ faz::<'b>(&()) }>;
    |                        ^^
@@ -283,8 +283,16 @@ LL |     let _ = [0; foo::<T>()];
    |
    = note: this may fail depending on what value the parameter takes
 
+error: constant expression depends on a generic parameter
+  --> $DIR/const-arg-in-const-arg.rs:25:13
+   |
+LL |     let _ = [0; foo::<T>()];
+   |             ^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
 error[E0747]: unresolved item provided when a constant was expected
-  --> $DIR/const-arg-in-const-arg.rs:26:23
+  --> $DIR/const-arg-in-const-arg.rs:27:23
    |
 LL |     let _ = [0; bar::<N>()];
    |                       ^
@@ -295,7 +303,7 @@ LL |     let _ = [0; bar::<{ N }>()];
    |                       +   +
 
 error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-  --> $DIR/const-arg-in-const-arg.rs:28:23
+  --> $DIR/const-arg-in-const-arg.rs:29:23
    |
 LL |     let _ = [0; faz::<'a>(&())];
    |                       ^^
@@ -307,7 +315,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
 error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-  --> $DIR/const-arg-in-const-arg.rs:31:23
+  --> $DIR/const-arg-in-const-arg.rs:32:23
    |
 LL |     let _ = [0; faz::<'b>(&())];
    |                       ^^
@@ -319,7 +327,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
 error[E0747]: unresolved item provided when a constant was expected
-  --> $DIR/const-arg-in-const-arg.rs:44:27
+  --> $DIR/const-arg-in-const-arg.rs:45:27
    |
 LL |     let _ = Foo::<{ bar::<N>() }>;
    |                           ^
@@ -330,7 +338,7 @@ LL |     let _ = Foo::<{ bar::<{ N }>() }>;
    |                           +   +
 
 error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-  --> $DIR/const-arg-in-const-arg.rs:46:27
+  --> $DIR/const-arg-in-const-arg.rs:47:27
    |
 LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
    |                           ^^
@@ -342,7 +350,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
 error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-  --> $DIR/const-arg-in-const-arg.rs:49:27
+  --> $DIR/const-arg-in-const-arg.rs:50:27
    |
 LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
    |                           ^^
@@ -353,7 +361,7 @@ note: the late bound lifetime parameter is introduced here
 LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
    |              ^^
 
-error: aborting due to 36 previous errors
+error: aborting due to 37 previous errors
 
 Some errors have detailed explanations: E0747, E0794.
 For more information about an error, try `rustc --explain E0747`.
diff --git a/tests/ui/const-generics/const-arg-in-const-arg.rs b/tests/ui/const-generics/const-arg-in-const-arg.rs
index 27b74489fe8..0e1c6552edf 100644
--- a/tests/ui/const-generics/const-arg-in-const-arg.rs
+++ b/tests/ui/const-generics/const-arg-in-const-arg.rs
@@ -23,6 +23,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized {
     let _: [u8; baz::<'b>(&())]; //[min]~ ERROR generic parameters may not
 
     let _ = [0; foo::<T>()]; //[min]~ ERROR constant expression depends on a generic parameter
+                             //[min]~^ ERROR constant expression depends on a generic parameter
     let _ = [0; bar::<N>()]; //[min]~ ERROR generic parameters may not
                              //[min]~^ ERROR unresolved item provided when a constant was expected
     let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not
diff --git a/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr b/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr
index d5eefd35753..f58821283e1 100644
--- a/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr
+++ b/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/const-argument-cross-crate-mismatch.rs:6:67
    |
 LL |     let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
-   |                                         ------------------------- ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+   |                                         ------------------------- ^^^^^^^^^^ expected an array with a size of 3, found one with a size of 2
    |                                         |
    |                                         arguments to this struct are incorrect
    |
@@ -16,7 +16,7 @@ error[E0308]: mismatched types
   --> $DIR/const-argument-cross-crate-mismatch.rs:8:65
    |
 LL |     let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
-   |                                       ------------------------- ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements
+   |                                       ------------------------- ^^^^^^^^^^^^^^^ expected an array with a size of 2, found one with a size of 3
    |                                       |
    |                                       arguments to this struct are incorrect
    |
diff --git a/tests/ui/const-generics/generic-param-mismatch.stderr b/tests/ui/const-generics/generic-param-mismatch.stderr
index be6b3b90ec7..099ce03317d 100644
--- a/tests/ui/const-generics/generic-param-mismatch.stderr
+++ b/tests/ui/const-generics/generic-param-mismatch.stderr
@@ -4,10 +4,7 @@ error[E0308]: mismatched types
 LL | fn test<const N: usize, const M: usize>() -> [u8; M] {
    |                                              ------- expected `[u8; M]` because of return type
 LL |     [0; N]
-   |     ^^^^^^ expected `M`, found `N`
-   |
-   = note: expected array `[u8; M]`
-              found array `[u8; N]`
+   |     ^^^^^^ expected an array with a size of M, found one with a size of N
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs b/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs
new file mode 100644
index 00000000000..1af6d5742b1
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs
@@ -0,0 +1,18 @@
+// regression test for #124350
+
+struct Node<const D: usize> {}
+
+impl<const D: usize> Node<D>
+where
+    SmallVec<{ D * 2 }>:,
+    //~^ ERROR generic parameters may not be used in const operations
+    //~| ERROR constant provided when a type was expected
+{
+    fn new() -> Self {
+        Node::new()
+    }
+}
+
+struct SmallVec<T1>(T1);
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr b/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr
new file mode 100644
index 00000000000..a8d6cebabe7
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr
@@ -0,0 +1,18 @@
+error: generic parameters may not be used in const operations
+  --> $DIR/bad-multiply.rs:7:16
+   |
+LL |     SmallVec<{ D * 2 }>:,
+   |                ^ cannot perform const operation using `D`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `D`
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error[E0747]: constant provided when a type was expected
+  --> $DIR/bad-multiply.rs:7:14
+   |
+LL |     SmallVec<{ D * 2 }>:,
+   |              ^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
index 632ece0ddcb..7e318f8786f 100644
--- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
@@ -1,12 +1,4 @@
 error: overly complex generic constant
-  --> $DIR/dependence_lint.rs:17:9
-   |
-LL |     [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
-   |
-   = help: consider moving this anonymous constant into a `const` function
-
-error: overly complex generic constant
   --> $DIR/dependence_lint.rs:21:17
    |
 LL |     let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
@@ -36,5 +28,13 @@ help: try adding a `where` bound
 LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
    |             ++++++++++++++++++++++++++++++++
 
+error: overly complex generic constant
+  --> $DIR/dependence_lint.rs:17:9
+   |
+LL |     [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
+   |
+   = help: consider moving this anonymous constant into a `const` function
+
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
index 14c67e2528a..8efd433fd1f 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
@@ -10,12 +10,10 @@ error[E0308]: mismatched types
   --> $DIR/issue-62504.rs:18:21
    |
 LL |         ArrayHolder([0; Self::SIZE])
-   |         ----------- ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE`
+   |         ----------- ^^^^^^^^^^^^^^^ expected an array with a size of X, found one with a size of Self::SIZE
    |         |
    |         arguments to this struct are incorrect
    |
-   = note: expected array `[u32; X]`
-              found array `[u32; Self::SIZE]`
 note: tuple struct defined here
   --> $DIR/issue-62504.rs:14:8
    |
diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs
new file mode 100644
index 00000000000..e5af632da75
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs
@@ -0,0 +1,18 @@
+// Regression test for #133271.
+#![feature(generic_const_exprs)]
+//~^ WARN the feature `generic_const_exprs` is incomplete
+
+struct Foo;
+impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
+//~^ ERROR the const parameter `NUM` is not constrained by the impl trait, self type, or predicates
+where
+    [(); 1 + 0]: Sized,
+{
+    fn unimplemented(self, _: &Foo) -> Self::Output {
+        //~^ ERROR method `unimplemented` is not a member of trait `std::ops::Add`
+        //~| ERROR type annotations needed
+        loop {}
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr
new file mode 100644
index 00000000000..ade18eb88b9
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr
@@ -0,0 +1,46 @@
+error[E0407]: method `unimplemented` is not a member of trait `std::ops::Add`
+  --> $DIR/post-analysis-user-facing-param-env.rs:11:5
+   |
+LL | /     fn unimplemented(self, _: &Foo) -> Self::Output {
+LL | |
+LL | |
+LL | |         loop {}
+LL | |     }
+   | |_____^ not a member of trait `std::ops::Add`
+
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/post-analysis-user-facing-param-env.rs:2:12
+   |
+LL | #![feature(generic_const_exprs)]
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0207]: the const parameter `NUM` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/post-analysis-user-facing-param-env.rs:6:10
+   |
+LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
+   |          ^^^^^^^^^^^^^^^^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
+error[E0284]: type annotations needed
+  --> $DIR/post-analysis-user-facing-param-env.rs:11:40
+   |
+LL |     fn unimplemented(self, _: &Foo) -> Self::Output {
+   |                                        ^^^^^^^^^^^^ cannot infer the value of const parameter `NUM`
+   |
+note: required for `Foo` to implement `Add<&'a Foo>`
+  --> $DIR/post-analysis-user-facing-param-env.rs:6:28
+   |
+LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
+   |          ----------------  ^^^^^^^^^^^^^^^^^^^^^^     ^^^
+   |          |
+   |          unsatisfied trait bound introduced here
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0207, E0284, E0407.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/const-generics/kind_mismatch.rs b/tests/ui/const-generics/kind_mismatch.rs
index bab58d5952a..ecdc01a5ef9 100644
--- a/tests/ui/const-generics/kind_mismatch.rs
+++ b/tests/ui/const-generics/kind_mismatch.rs
@@ -20,5 +20,4 @@ pub fn remove_key<K, S: SubsetExcept<K>>() -> S {
 
 fn main() {
     let map: KeyHolder<0> = remove_key::<_, _>();
-    //~^ ERROR: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied
 }
diff --git a/tests/ui/const-generics/kind_mismatch.stderr b/tests/ui/const-generics/kind_mismatch.stderr
index e13bc6ee058..1487b189619 100644
--- a/tests/ui/const-generics/kind_mismatch.stderr
+++ b/tests/ui/const-generics/kind_mismatch.stderr
@@ -14,26 +14,6 @@ LL | impl<K> ContainsKey<K> for KeyHolder<K> {}
    |      |
    |      help: consider changing this type parameter to a const parameter: `const K: u8`
 
-error[E0277]: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied
-  --> $DIR/kind_mismatch.rs:22:45
-   |
-LL |     let map: KeyHolder<0> = remove_key::<_, _>();
-   |                                             ^ the trait `ContainsKey<0>` is not implemented for `KeyHolder<0>`
-   |
-note: required for `KeyHolder<0>` to implement `SubsetExcept<_>`
-  --> $DIR/kind_mismatch.rs:15:28
-   |
-LL | impl<P, T: ContainsKey<0>> SubsetExcept<P> for T {}
-   |            --------------  ^^^^^^^^^^^^^^^     ^
-   |            |
-   |            unsatisfied trait bound introduced here
-note: required by a bound in `remove_key`
-  --> $DIR/kind_mismatch.rs:17:25
-   |
-LL | pub fn remove_key<K, S: SubsetExcept<K>>() -> S {
-   |                         ^^^^^^^^^^^^^^^ required by this bound in `remove_key`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0747.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0747`.
diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.rs b/tests/ui/const-generics/not_wf_param_in_rpitit.rs
index b454562ad49..cb1e90923e7 100644
--- a/tests/ui/const-generics/not_wf_param_in_rpitit.rs
+++ b/tests/ui/const-generics/not_wf_param_in_rpitit.rs
@@ -3,9 +3,6 @@
 trait Trait<const N: dyn Trait = bar> {
     //~^ ERROR: cannot find value `bar` in this scope
     //~| ERROR: cycle detected when computing type of `Trait::N`
-    //~| ERROR: the trait `Trait` cannot be made into an object
-    //~| ERROR: the trait `Trait` cannot be made into an object
-    //~| ERROR: the trait `Trait` cannot be made into an object
     async fn a() {}
 }
 
diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr
index 2500409e828..42ae012fa55 100644
--- a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr
+++ b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr
@@ -18,77 +18,7 @@ LL | trait Trait<const N: dyn Trait = bar> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/not_wf_param_in_rpitit.rs:3:22
-   |
-LL | trait Trait<const N: dyn Trait = bar> {
-   |                      ^^^^^^^^^ `Trait` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/not_wf_param_in_rpitit.rs:9:14
-   |
-LL | trait Trait<const N: dyn Trait = bar> {
-   |       ----- this trait cannot be made into an object...
-...
-LL |     async fn a() {}
-   |              ^ ...because associated function `a` has no `self` parameter
-help: consider turning `a` into a method by giving it a `&self` argument
-   |
-LL |     async fn a(&self) {}
-   |                +++++
-help: alternatively, consider constraining `a` so it does not apply to trait objects
-   |
-LL |     async fn a() where Self: Sized {}
-   |                  +++++++++++++++++
-
-error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/not_wf_param_in_rpitit.rs:3:13
-   |
-LL | trait Trait<const N: dyn Trait = bar> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/not_wf_param_in_rpitit.rs:9:14
-   |
-LL | trait Trait<const N: dyn Trait = bar> {
-   |       ----- this trait cannot be made into an object...
-...
-LL |     async fn a() {}
-   |              ^ ...because associated function `a` has no `self` parameter
-help: consider turning `a` into a method by giving it a `&self` argument
-   |
-LL |     async fn a(&self) {}
-   |                +++++
-help: alternatively, consider constraining `a` so it does not apply to trait objects
-   |
-LL |     async fn a() where Self: Sized {}
-   |                  +++++++++++++++++
-
-error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/not_wf_param_in_rpitit.rs:3:13
-   |
-LL | trait Trait<const N: dyn Trait = bar> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/not_wf_param_in_rpitit.rs:9:14
-   |
-LL | trait Trait<const N: dyn Trait = bar> {
-   |       ----- this trait cannot be made into an object...
-...
-LL |     async fn a() {}
-   |              ^ ...because associated function `a` has no `self` parameter
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider turning `a` into a method by giving it a `&self` argument
-   |
-LL |     async fn a(&self) {}
-   |                +++++
-help: alternatively, consider constraining `a` so it does not apply to trait objects
-   |
-LL |     async fn a() where Self: Sized {}
-   |                  +++++++++++++++++
-
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0038, E0391, E0425.
-For more information about an error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0391, E0425.
+For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/consts/array-literal-len-mismatch.stderr b/tests/ui/consts/array-literal-len-mismatch.stderr
index a11506ecb6d..39b8a647324 100644
--- a/tests/ui/consts/array-literal-len-mismatch.stderr
+++ b/tests/ui/consts/array-literal-len-mismatch.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/array-literal-len-mismatch.rs:1:26
    |
 LL | const NUMBERS: [u8; 3] = [10, 20];
-   |                     -    ^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+   |                     -    ^^^^^^^^ expected an array with a size of 3, found one with a size of 2
    |                     |
    |                     help: consider specifying the actual array length: `2`
 
diff --git a/tests/ui/consts/bad-array-size-in-type-err.rs b/tests/ui/consts/bad-array-size-in-type-err.rs
new file mode 100644
index 00000000000..cb02ad3205d
--- /dev/null
+++ b/tests/ui/consts/bad-array-size-in-type-err.rs
@@ -0,0 +1,10 @@
+struct BadArraySize<const N: u8> {
+    arr: [i32; N],
+    //~^ ERROR the constant `N` is not of type `usize`
+}
+
+fn main() {
+    let _ = BadArraySize::<2> { arr: [0, 0, 0] };
+    //~^ ERROR mismatched types
+    //~| ERROR the constant `2` is not of type `usize`
+}
diff --git a/tests/ui/consts/bad-array-size-in-type-err.stderr b/tests/ui/consts/bad-array-size-in-type-err.stderr
new file mode 100644
index 00000000000..25d14d80c3e
--- /dev/null
+++ b/tests/ui/consts/bad-array-size-in-type-err.stderr
@@ -0,0 +1,21 @@
+error: the constant `N` is not of type `usize`
+  --> $DIR/bad-array-size-in-type-err.rs:2:10
+   |
+LL |     arr: [i32; N],
+   |          ^^^^^^^^ expected `usize`, found `u8`
+
+error[E0308]: mismatched types
+  --> $DIR/bad-array-size-in-type-err.rs:7:38
+   |
+LL |     let _ = BadArraySize::<2> { arr: [0, 0, 0] };
+   |                                      ^^^^^^^^^ expected an array with a size of 2, found one with a size of 3
+
+error: the constant `2` is not of type `usize`
+  --> $DIR/bad-array-size-in-type-err.rs:7:38
+   |
+LL |     let _ = BadArraySize::<2> { arr: [0, 0, 0] };
+   |                                      ^^^^^^^^^ expected `usize`, found `u8`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/const-array-oob-arith.rs b/tests/ui/consts/const-array-oob-arith.rs
index 9332cbbd4d7..0f6e76768cd 100644
--- a/tests/ui/consts/const-array-oob-arith.rs
+++ b/tests/ui/consts/const-array-oob-arith.rs
@@ -4,10 +4,10 @@ const VAL: i32 = ARR[IDX];
 const BONG: [i32; (ARR[0] - 41) as usize] = [5];
 const BLUB: [i32; (ARR[0] - 40) as usize] = [5];
 //~^ ERROR: mismatched types
-//~| expected an array with a fixed size of 2 elements, found one with 1 element
+//~| expected an array
 const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99];
 //~^ ERROR: mismatched types
-//~| expected an array with a fixed size of 1 element, found one with 2 elements
+//~| expected an array
 
 fn main() {
     let _ = VAL;
diff --git a/tests/ui/consts/const-array-oob-arith.stderr b/tests/ui/consts/const-array-oob-arith.stderr
index 029d94273fa..d3299082aa1 100644
--- a/tests/ui/consts/const-array-oob-arith.stderr
+++ b/tests/ui/consts/const-array-oob-arith.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/const-array-oob-arith.rs:5:45
    |
 LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5];
-   |                   ----------------------    ^^^ expected an array with a fixed size of 2 elements, found one with 1 element
+   |                   ----------------------    ^^^ expected an array with a size of 2, found one with a size of 1
    |                   |
    |                   help: consider specifying the actual array length: `1`
 
@@ -10,7 +10,7 @@ error[E0308]: mismatched types
   --> $DIR/const-array-oob-arith.rs:8:44
    |
 LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99];
-   |                  ----------------------    ^^^^^^^ expected an array with a fixed size of 1 element, found one with 2 elements
+   |                  ----------------------    ^^^^^^^ expected an array with a size of 1, found one with a size of 2
    |                  |
    |                  help: consider specifying the actual array length: `2`
 
diff --git a/tests/ui/consts/const-block-const-bound.rs b/tests/ui/consts/const-block-const-bound.rs
index 933eb6cfc0a..596aac09b31 100644
--- a/tests/ui/consts/const-block-const-bound.rs
+++ b/tests/ui/consts/const-block-const-bound.rs
@@ -1,7 +1,7 @@
 //@ known-bug: #103507
 
 #![allow(unused)]
-#![feature(const_trait_impl, negative_impls)]
+#![feature(const_trait_impl, negative_impls, const_destruct)]
 
 use std::marker::Destruct;
 
diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr
index 5e24959146b..b2b2f62c58f 100644
--- a/tests/ui/consts/const-block-const-bound.stderr
+++ b/tests/ui/consts/const-block-const-bound.stderr
@@ -1,25 +1,9 @@
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-block-const-bound.rs:8:15
+error[E0277]: the trait bound `UnconstDrop: const Destruct` is not satisfied
+  --> $DIR/const-block-const-bound.rs:18:9
    |
-LL | const fn f<T: ~const Destruct>(x: T) {}
-   |               ^^^^^^
+LL |         f(UnconstDrop);
+   |         ^^^^^^^^^^^^^^
 
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-block-const-bound.rs:8:15
-   |
-LL | const fn f<T: ~const Destruct>(x: T) {}
-   |               ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/const-block-const-bound.rs:8:32
-   |
-LL | const fn f<T: ~const Destruct>(x: T) {}
-   |                                ^      - value is dropped here
-   |                                |
-   |                                the destructor for this type cannot be evaluated in constant functions
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0493`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/const-bound.rs b/tests/ui/consts/const-bound.rs
index 682a2dcbbc6..00a833ba3f7 100644
--- a/tests/ui/consts/const-bound.rs
+++ b/tests/ui/consts/const-bound.rs
@@ -3,7 +3,6 @@
 // Make sure const bounds work on things, and test that a few types
 // are const.
 
-//@ pretty-expanded FIXME #23616
 
 fn foo<T: Sync>(x: T) -> T { x }
 
diff --git a/tests/ui/consts/const-eval/float_methods.rs b/tests/ui/consts/const-eval/float_methods.rs
index 49c31f68c5f..853f75825ac 100644
--- a/tests/ui/consts/const-eval/float_methods.rs
+++ b/tests/ui/consts/const-eval/float_methods.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //! Tests the float intrinsics: min, max, abs, copysign
 
-#![feature(const_float_methods)]
 #![feature(f16, f128)]
 
 const F16_MIN: f16 = 1.0_f16.min(0.5_f16);
diff --git a/tests/ui/consts/const-expr-in-fixed-length-vec.rs b/tests/ui/consts/const-expr-in-fixed-length-vec.rs
index 60b4895f5f9..f4d651af115 100644
--- a/tests/ui/consts/const-expr-in-fixed-length-vec.rs
+++ b/tests/ui/consts/const-expr-in-fixed-length-vec.rs
@@ -2,7 +2,6 @@
 // Check that constant expressions can be used for declaring the
 // type of a fixed length vector.
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
 
diff --git a/tests/ui/consts/const-expr-in-vec-repeat.rs b/tests/ui/consts/const-expr-in-vec-repeat.rs
index 5345a1c4c42..e270d4c1eb3 100644
--- a/tests/ui/consts/const-expr-in-vec-repeat.rs
+++ b/tests/ui/consts/const-expr-in-vec-repeat.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Check that constant expressions can be used in vec repeat syntax.
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
 
diff --git a/tests/ui/consts/const-match-check.eval1.stderr b/tests/ui/consts/const-match-check.eval1.stderr
index 84890214861..b1827009d2a 100644
--- a/tests/ui/consts/const-match-check.eval1.stderr
+++ b/tests/ui/consts/const-match-check.eval1.stderr
@@ -5,7 +5,7 @@ LL |     A = { let 0 = 0; 0 },
    |               ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
diff --git a/tests/ui/consts/const-match-check.eval2.stderr b/tests/ui/consts/const-match-check.eval2.stderr
index 0aa12eb86dd..04ac58bfe40 100644
--- a/tests/ui/consts/const-match-check.eval2.stderr
+++ b/tests/ui/consts/const-match-check.eval2.stderr
@@ -5,7 +5,7 @@ LL |     let x: [i32; { let 0 = 0; 0 }] = [];
    |                        ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
diff --git a/tests/ui/consts/const-match-check.matchck.stderr b/tests/ui/consts/const-match-check.matchck.stderr
index bcca4c2a647..05ddc4c8219 100644
--- a/tests/ui/consts/const-match-check.matchck.stderr
+++ b/tests/ui/consts/const-match-check.matchck.stderr
@@ -5,7 +5,7 @@ LL | const X: i32 = { let 0 = 0; 0 };
    |                      ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
@@ -23,7 +23,7 @@ LL | static Y: i32 = { let 0 = 0; 0 };
    |                       ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
@@ -41,7 +41,7 @@ LL |     const X: i32 = { let 0 = 0; 0 };
    |                          ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
@@ -59,7 +59,7 @@ LL |     const X: i32 = { let 0 = 0; 0 };
    |                          ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
diff --git a/tests/ui/consts/const-pattern-irrefutable.stderr b/tests/ui/consts/const-pattern-irrefutable.stderr
index afb67a3a118..646426c9426 100644
--- a/tests/ui/consts/const-pattern-irrefutable.stderr
+++ b/tests/ui/consts/const-pattern-irrefutable.stderr
@@ -8,7 +8,7 @@ LL |     let a = 4;
    |         ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u8`
 help: introduce a variable instead
    |
@@ -25,7 +25,7 @@ LL |     let c = 4;
    |         ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u8`
 help: introduce a variable instead
    |
@@ -42,7 +42,7 @@ LL |     let d = (4, 4);
    |         ^ patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `(u8, u8)`
 help: introduce a variable instead
    |
@@ -59,7 +59,7 @@ LL |     let e = S {
    |         ^ pattern `S { foo: 1_u8..=u8::MAX }` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `S` defined here
   --> $DIR/const-pattern-irrefutable.rs:15:8
    |
diff --git a/tests/ui/consts/const-struct-offsets.rs b/tests/ui/consts/const-struct-offsets.rs
index ee97fe3cab9..491b7095b70 100644
--- a/tests/ui/consts/const-struct-offsets.rs
+++ b/tests/ui/consts/const-struct-offsets.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 #![allow(non_upper_case_globals)]
 
 enum Foo {
diff --git a/tests/ui/consts/const-unit-struct.rs b/tests/ui/consts/const-unit-struct.rs
index 096cd1e8384..2dadb000f4c 100644
--- a/tests/ui/consts/const-unit-struct.rs
+++ b/tests/ui/consts/const-unit-struct.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 struct Foo;
 
diff --git a/tests/ui/consts/const-vec-of-fns.rs b/tests/ui/consts/const-vec-of-fns.rs
index a14cb06db61..fa7eda789ef 100644
--- a/tests/ui/consts/const-vec-of-fns.rs
+++ b/tests/ui/consts/const-vec-of-fns.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 #![allow(non_upper_case_globals)]
 
 /*!
diff --git a/tests/ui/consts/const-vec-syntax.rs b/tests/ui/consts/const-vec-syntax.rs
index 5537a8cec90..d305d45a8cd 100644
--- a/tests/ui/consts/const-vec-syntax.rs
+++ b/tests/ui/consts/const-vec-syntax.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn f(_: &[isize]) {}
 
diff --git a/tests/ui/consts/control-flow/drop-fail.precise.stderr b/tests/ui/consts/control-flow/drop-fail.precise.stderr
index 93b5f257efb..32afc51c3ee 100644
--- a/tests/ui/consts/control-flow/drop-fail.precise.stderr
+++ b/tests/ui/consts/control-flow/drop-fail.precise.stderr
@@ -1,14 +1,20 @@
 error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time
-  --> $DIR/drop-fail.rs:8:9
+  --> $DIR/drop-fail.rs:9:9
    |
 LL |     let x = Some(Vec::new());
    |         ^ the destructor for this type cannot be evaluated in constants
+...
+LL | };
+   | - value is dropped here
 
 error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time
-  --> $DIR/drop-fail.rs:39:9
+  --> $DIR/drop-fail.rs:40:9
    |
 LL |     let mut tmp = None;
    |         ^^^^^^^ the destructor for this type cannot be evaluated in constants
+...
+LL | };
+   | - value is dropped here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/control-flow/drop-fail.rs b/tests/ui/consts/control-flow/drop-fail.rs
index 25afe5d08d9..2b73e37b23d 100644
--- a/tests/ui/consts/control-flow/drop-fail.rs
+++ b/tests/ui/consts/control-flow/drop-fail.rs
@@ -1,5 +1,6 @@
 //@ revisions: stock precise
 
+#![feature(const_destruct)]
 #![cfg_attr(precise, feature(const_precise_live_drops))]
 
 // `x` is *not* always moved into the final value and may be dropped inside the initializer.
diff --git a/tests/ui/consts/control-flow/drop-fail.stock.stderr b/tests/ui/consts/control-flow/drop-fail.stock.stderr
index 2cc8568026e..8fe60fd7367 100644
--- a/tests/ui/consts/control-flow/drop-fail.stock.stderr
+++ b/tests/ui/consts/control-flow/drop-fail.stock.stderr
@@ -1,5 +1,5 @@
 error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time
-  --> $DIR/drop-fail.rs:8:9
+  --> $DIR/drop-fail.rs:9:9
    |
 LL |     let x = Some(Vec::new());
    |         ^ the destructor for this type cannot be evaluated in constants
@@ -8,7 +8,7 @@ LL | };
    | - value is dropped here
 
 error[E0493]: destructor of `(Vec<i32>,)` cannot be evaluated at compile-time
-  --> $DIR/drop-fail.rs:21:9
+  --> $DIR/drop-fail.rs:22:9
    |
 LL |     let vec_tuple = (Vec::new(),);
    |         ^^^^^^^^^ the destructor for this type cannot be evaluated in constants
@@ -17,7 +17,7 @@ LL | };
    | - value is dropped here
 
 error[E0493]: destructor of `Result<Vec<i32>, Vec<i32>>` cannot be evaluated at compile-time
-  --> $DIR/drop-fail.rs:29:9
+  --> $DIR/drop-fail.rs:30:9
    |
 LL |     let x: Result<_, Vec<i32>> = Ok(Vec::new());
    |         ^ the destructor for this type cannot be evaluated in constants
@@ -26,7 +26,7 @@ LL | };
    | - value is dropped here
 
 error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time
-  --> $DIR/drop-fail.rs:39:9
+  --> $DIR/drop-fail.rs:40:9
    |
 LL |     let mut tmp = None;
    |         ^^^^^^^ the destructor for this type cannot be evaluated in constants
diff --git a/tests/ui/consts/drop_zst.stderr b/tests/ui/consts/drop_zst.stderr
index e3c6785290d..4d1af7ef935 100644
--- a/tests/ui/consts/drop_zst.stderr
+++ b/tests/ui/consts/drop_zst.stderr
@@ -3,6 +3,8 @@ error[E0493]: destructor of `S` cannot be evaluated at compile-time
    |
 LL |     let s = S;
    |         ^ the destructor for this type cannot be evaluated in constant functions
+LL | }
+   | - value is dropped here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/fn_trait_refs.rs b/tests/ui/consts/fn_trait_refs.rs
index 4defe4dedc7..af233efd738 100644
--- a/tests/ui/consts/fn_trait_refs.rs
+++ b/tests/ui/consts/fn_trait_refs.rs
@@ -5,6 +5,7 @@
 #![feature(unboxed_closures)]
 #![feature(const_trait_impl)]
 #![feature(const_cmp)]
+#![feature(const_destruct)]
 
 use std::marker::Destruct;
 
diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr
index a686bc23c0f..10850021713 100644
--- a/tests/ui/consts/fn_trait_refs.stderr
+++ b/tests/ui/consts/fn_trait_refs.stderr
@@ -11,19 +11,13 @@ LL | #![feature(const_cmp)]
    |            ^^^^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:13:8
+  --> $DIR/fn_trait_refs.rs:14:8
    |
 LL |     T: ~const Fn<()> + ~const Destruct,
    |        ^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:13:24
-   |
-LL |     T: ~const Fn<()> + ~const Destruct,
-   |                        ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:13:8
+  --> $DIR/fn_trait_refs.rs:14:8
    |
 LL |     T: ~const Fn<()> + ~const Destruct,
    |        ^^^^^^
@@ -31,7 +25,7 @@ LL |     T: ~const Fn<()> + ~const Destruct,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:13:8
+  --> $DIR/fn_trait_refs.rs:14:8
    |
 LL |     T: ~const Fn<()> + ~const Destruct,
    |        ^^^^^^
@@ -39,27 +33,13 @@ LL |     T: ~const Fn<()> + ~const Destruct,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:13:24
-   |
-LL |     T: ~const Fn<()> + ~const Destruct,
-   |                        ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:20:8
+  --> $DIR/fn_trait_refs.rs:21:8
    |
 LL |     T: ~const FnMut<()> + ~const Destruct,
    |        ^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:20:27
-   |
-LL |     T: ~const FnMut<()> + ~const Destruct,
-   |                           ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:20:8
+  --> $DIR/fn_trait_refs.rs:21:8
    |
 LL |     T: ~const FnMut<()> + ~const Destruct,
    |        ^^^^^^
@@ -67,7 +47,7 @@ LL |     T: ~const FnMut<()> + ~const Destruct,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:20:8
+  --> $DIR/fn_trait_refs.rs:21:8
    |
 LL |     T: ~const FnMut<()> + ~const Destruct,
    |        ^^^^^^
@@ -75,21 +55,13 @@ LL |     T: ~const FnMut<()> + ~const Destruct,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:20:27
-   |
-LL |     T: ~const FnMut<()> + ~const Destruct,
-   |                           ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:27:8
+  --> $DIR/fn_trait_refs.rs:28:8
    |
 LL |     T: ~const FnOnce<()>,
    |        ^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:27:8
+  --> $DIR/fn_trait_refs.rs:28:8
    |
 LL |     T: ~const FnOnce<()>,
    |        ^^^^^^
@@ -97,7 +69,7 @@ LL |     T: ~const FnOnce<()>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:27:8
+  --> $DIR/fn_trait_refs.rs:28:8
    |
 LL |     T: ~const FnOnce<()>,
    |        ^^^^^^
@@ -105,19 +77,13 @@ LL |     T: ~const FnOnce<()>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:34:8
+  --> $DIR/fn_trait_refs.rs:35:8
    |
 LL |     T: ~const Fn<()> + ~const Destruct,
    |        ^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:34:24
-   |
-LL |     T: ~const Fn<()> + ~const Destruct,
-   |                        ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:34:8
+  --> $DIR/fn_trait_refs.rs:35:8
    |
 LL |     T: ~const Fn<()> + ~const Destruct,
    |        ^^^^^^
@@ -125,7 +91,7 @@ LL |     T: ~const Fn<()> + ~const Destruct,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:34:8
+  --> $DIR/fn_trait_refs.rs:35:8
    |
 LL |     T: ~const Fn<()> + ~const Destruct,
    |        ^^^^^^
@@ -133,27 +99,13 @@ LL |     T: ~const Fn<()> + ~const Destruct,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:34:24
-   |
-LL |     T: ~const Fn<()> + ~const Destruct,
-   |                        ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:48:8
+  --> $DIR/fn_trait_refs.rs:49:8
    |
 LL |     T: ~const FnMut<()> + ~const Destruct,
    |        ^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:48:27
-   |
-LL |     T: ~const FnMut<()> + ~const Destruct,
-   |                           ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:48:8
+  --> $DIR/fn_trait_refs.rs:49:8
    |
 LL |     T: ~const FnMut<()> + ~const Destruct,
    |        ^^^^^^
@@ -161,39 +113,45 @@ LL |     T: ~const FnMut<()> + ~const Destruct,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:48:8
+  --> $DIR/fn_trait_refs.rs:49:8
    |
 LL |     T: ~const FnMut<()> + ~const Destruct,
    |        ^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/fn_trait_refs.rs:48:27
-   |
-LL |     T: ~const FnMut<()> + ~const Destruct,
-   |                           ^^^^^^
+error[E0277]: the trait bound `fn() -> i32 {one}: const Destruct` is not satisfied
+  --> $DIR/fn_trait_refs.rs:70:24
    |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+LL |         let test_one = test_fn(one);
+   |                        ^^^^^^^^^^^^
 
-error[E0015]: cannot call non-const operator in constants
-  --> $DIR/fn_trait_refs.rs:70:17
+error[E0277]: the trait bound `fn() -> i32 {two}: const Destruct` is not satisfied
+  --> $DIR/fn_trait_refs.rs:73:24
    |
-LL |         assert!(test_one == (1, 1, 1));
-   |                 ^^^^^^^^^^^^^^^^^^^^^
+LL |         let test_two = test_fn_mut(two);
+   |                        ^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `&T: ~const Destruct` is not satisfied
+  --> $DIR/fn_trait_refs.rs:39:9
    |
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+LL |         tester_fn(&f),
+   |         ^^^^^^^^^^^^^
 
-error[E0015]: cannot call non-const operator in constants
-  --> $DIR/fn_trait_refs.rs:73:17
+error[E0277]: the trait bound `&T: ~const Destruct` is not satisfied
+  --> $DIR/fn_trait_refs.rs:41:9
    |
-LL |         assert!(test_two == (2, 2));
-   |                 ^^^^^^^^^^^^^^^^^^
+LL |         tester_fn_mut(&f),
+   |         ^^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `&mut T: ~const Destruct` is not satisfied
+  --> $DIR/fn_trait_refs.rs:53:9
    |
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+LL |         tester_fn_mut(&mut f),
+   |         ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/fn_trait_refs.rs:15:5
+  --> $DIR/fn_trait_refs.rs:16:5
    |
 LL |     f()
    |     ^^^
@@ -204,17 +162,8 @@ help: consider further restricting this bound
 LL |     T: ~const Fn<()> + ~const Destruct + ~const Fn(),
    |                                        +++++++++++++
 
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/fn_trait_refs.rs:11:23
-   |
-LL | const fn tester_fn<T>(f: T) -> T::Output
-   |                       ^ the destructor for this type cannot be evaluated in constant functions
-...
-LL | }
-   | - value is dropped here
-
 error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/fn_trait_refs.rs:22:5
+  --> $DIR/fn_trait_refs.rs:23:5
    |
 LL |     f()
    |     ^^^
@@ -225,17 +174,8 @@ help: consider further restricting this bound
 LL |     T: ~const FnMut<()> + ~const Destruct + ~const FnMut(),
    |                                           ++++++++++++++++
 
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/fn_trait_refs.rs:18:27
-   |
-LL | const fn tester_fn_mut<T>(mut f: T) -> T::Output
-   |                           ^^^^^ the destructor for this type cannot be evaluated in constant functions
-...
-LL | }
-   | - value is dropped here
-
 error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/fn_trait_refs.rs:29:5
+  --> $DIR/fn_trait_refs.rs:30:5
    |
 LL |     f()
    |     ^^^
@@ -246,25 +186,7 @@ help: consider further restricting this bound
 LL |     T: ~const FnOnce<()> + ~const FnOnce(),
    |                          +++++++++++++++++
 
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/fn_trait_refs.rs:32:21
-   |
-LL | const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output)
-   |                     ^^^^^ the destructor for this type cannot be evaluated in constant functions
-...
-LL | }
-   | - value is dropped here
-
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/fn_trait_refs.rs:46:25
-   |
-LL | const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
-   |                         ^^^^^ the destructor for this type cannot be evaluated in constant functions
-...
-LL | }
-   | - value is dropped here
-
-error: aborting due to 34 previous errors
+error: aborting due to 25 previous errors
 
-Some errors have detailed explanations: E0015, E0493, E0635.
+Some errors have detailed explanations: E0015, E0277, E0635.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/issue-13837.rs b/tests/ui/consts/issue-13837.rs
index 305512cc41c..85e278539b2 100644
--- a/tests/ui/consts/issue-13837.rs
+++ b/tests/ui/consts/issue-13837.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 struct TestStruct {
     x: *const [isize; 2]
diff --git a/tests/ui/consts/promoted-const-drop.rs b/tests/ui/consts/promoted-const-drop.rs
index c6ea0d0c924..e09c30ea785 100644
--- a/tests/ui/consts/promoted-const-drop.rs
+++ b/tests/ui/consts/promoted-const-drop.rs
@@ -3,7 +3,6 @@
 struct A();
 
 impl const Drop for A {
-    //~^ ERROR const `impl` for trait `Drop` which is not marked with `#[const_trait]`
     fn drop(&mut self) {}
 }
 
diff --git a/tests/ui/consts/promoted-const-drop.stderr b/tests/ui/consts/promoted-const-drop.stderr
index e015f756206..3f2182e7d41 100644
--- a/tests/ui/consts/promoted-const-drop.stderr
+++ b/tests/ui/consts/promoted-const-drop.stderr
@@ -1,14 +1,5 @@
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/promoted-const-drop.rs:5:12
-   |
-LL | impl const Drop for A {
-   |            ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted-const-drop.rs:13:26
+  --> $DIR/promoted-const-drop.rs:12:26
    |
 LL |     let _: &'static A = &A();
    |            ----------    ^^^ creates a temporary value which is freed while still in use
@@ -19,7 +10,7 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted-const-drop.rs:14:28
+  --> $DIR/promoted-const-drop.rs:13:28
    |
 LL |     let _: &'static [A] = &[C];
    |            ------------    ^^^ creates a temporary value which is freed while still in use
@@ -28,6 +19,6 @@ LL |     let _: &'static [A] = &[C];
 LL | }
    | - temporary value is freed at the end of this statement
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/consts/promoted_const_call.stderr b/tests/ui/consts/promoted_const_call.stderr
index bcb9dfb704b..dd70bb601c4 100644
--- a/tests/ui/consts/promoted_const_call.stderr
+++ b/tests/ui/consts/promoted_const_call.stderr
@@ -1,31 +1,10 @@
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/promoted_const_call.rs:6:12
-   |
-LL | impl const Drop for Panic { fn drop(&mut self) { panic!(); } }
-   |            ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call.rs:10:26
-   |
-LL |     let _: &'static _ = &id(&Panic);
-   |            ----------    ^^^^^^^^^^ creates a temporary value which is freed while still in use
-   |            |
-   |            type annotation requires that borrow lasts for `'static`
-...
-LL | };
-   | - temporary value is freed at the end of this statement
-
-error[E0716]: temporary value dropped while borrowed
+error[E0493]: destructor of `Panic` cannot be evaluated at compile-time
   --> $DIR/promoted_const_call.rs:10:30
    |
 LL |     let _: &'static _ = &id(&Panic);
-   |            ----------        ^^^^^ - temporary value is freed at the end of this statement
-   |            |                 |
-   |            |                 creates a temporary value which is freed while still in use
-   |            type annotation requires that borrow lasts for `'static`
+   |                              ^^^^^ - value is dropped here
+   |                              |
+   |                              the destructor for this type cannot be evaluated in constants
 
 error[E0716]: temporary value dropped while borrowed
   --> $DIR/promoted_const_call.rs:16:26
@@ -69,6 +48,7 @@ LL |     let _: &'static _ = &&(Panic, 0).1;
 LL | }
    | - temporary value is freed at the end of this statement
 
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0716`.
+Some errors have detailed explanations: E0493, E0716.
+For more information about an error, try `rustc --explain E0493`.
diff --git a/tests/ui/consts/promoted_const_call2.stderr b/tests/ui/consts/promoted_const_call2.stderr
index 177f7aed17d..bdb43385d20 100644
--- a/tests/ui/consts/promoted_const_call2.stderr
+++ b/tests/ui/consts/promoted_const_call2.stderr
@@ -22,7 +22,9 @@ error[E0493]: destructor of `String` cannot be evaluated at compile-time
   --> $DIR/promoted_const_call2.rs:4:30
    |
 LL |     let _: &'static _ = &id(&String::new());
-   |                              ^^^^^^^^^^^^^ the destructor for this type cannot be evaluated in constants
+   |                              ^^^^^^^^^^^^^ - value is dropped here
+   |                              |
+   |                              the destructor for this type cannot be evaluated in constants
 
 error[E0716]: temporary value dropped while borrowed
   --> $DIR/promoted_const_call2.rs:11:26
diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.stderr b/tests/ui/consts/qualif-indirect-mutation-fail.stderr
index 433dfba2257..f706b7cf699 100644
--- a/tests/ui/consts/qualif-indirect-mutation-fail.stderr
+++ b/tests/ui/consts/qualif-indirect-mutation-fail.stderr
@@ -3,6 +3,9 @@ error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
    |
 LL |     let mut x = None;
    |         ^^^^^ the destructor for this type cannot be evaluated in constants
+...
+LL | };
+   | - value is dropped here
 
 error[E0080]: evaluation of constant value failed
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
@@ -26,6 +29,8 @@ error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
    |
 LL |     let _z = x;
    |         ^^ the destructor for this type cannot be evaluated in constants
+LL | };
+   | - value is dropped here
 
 error[E0080]: evaluation of constant value failed
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
@@ -49,42 +54,62 @@ error[E0493]: destructor of `(u32, Option<String>)` cannot be evaluated at compi
    |
 LL |     let mut a: (u32, Option<String>) = (0, None);
    |         ^^^^^ the destructor for this type cannot be evaluated in constant functions
+LL |     let _ = &mut a.1;
+LL | }
+   | - value is dropped here
 
 error[E0493]: destructor of `Option<T>` cannot be evaluated at compile-time
   --> $DIR/qualif-indirect-mutation-fail.rs:34:9
    |
 LL |     let x: Option<T> = None;
    |         ^ the destructor for this type cannot be evaluated in constant functions
+LL |     let _ = x.is_some();
+LL | }
+   | - value is dropped here
 
 error[E0493]: destructor of `Option<T>` cannot be evaluated at compile-time
   --> $DIR/qualif-indirect-mutation-fail.rs:42:9
    |
 LL |     let _y = x;
    |         ^^ the destructor for this type cannot be evaluated in constant functions
+LL | }
+   | - value is dropped here
 
 error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
   --> $DIR/qualif-indirect-mutation-fail.rs:50:9
    |
 LL |     let mut y: Option<String> = None;
    |         ^^^^^ the destructor for this type cannot be evaluated in constant functions
+LL |     std::ptr::addr_of_mut!(y);
+LL | }
+   | - value is dropped here
 
 error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
   --> $DIR/qualif-indirect-mutation-fail.rs:47:9
    |
 LL |     let mut x: Option<String> = None;
    |         ^^^^^ the destructor for this type cannot be evaluated in constant functions
+...
+LL | }
+   | - value is dropped here
 
 error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
   --> $DIR/qualif-indirect-mutation-fail.rs:60:9
    |
 LL |     let y: Option<String> = None;
    |         ^ the destructor for this type cannot be evaluated in constant functions
+LL |     std::ptr::addr_of!(y);
+LL | }
+   | - value is dropped here
 
 error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
   --> $DIR/qualif-indirect-mutation-fail.rs:57:9
    |
 LL |     let x: Option<String> = None;
    |         ^ the destructor for this type cannot be evaluated in constant functions
+...
+LL | }
+   | - value is dropped here
 
 error: aborting due to 11 previous errors
 
diff --git a/tests/ui/consts/too_generic_eval_ice.rs b/tests/ui/consts/too_generic_eval_ice.rs
index 8b3f4b714e1..0d46a4c8276 100644
--- a/tests/ui/consts/too_generic_eval_ice.rs
+++ b/tests/ui/consts/too_generic_eval_ice.rs
@@ -7,6 +7,7 @@ impl<A, B> Foo<A, B> {
         [5; Self::HOST_SIZE] == [6; 0]
         //~^ ERROR constant expression depends on a generic parameter
         //~| ERROR constant expression depends on a generic parameter
+        //~| ERROR constant expression depends on a generic parameter
         //~| ERROR can't compare `[{integer}; Self::HOST_SIZE]` with `[{integer}; 0]`
     }
 }
diff --git a/tests/ui/consts/too_generic_eval_ice.stderr b/tests/ui/consts/too_generic_eval_ice.stderr
index 58a61b938d6..b48be16a24c 100644
--- a/tests/ui/consts/too_generic_eval_ice.stderr
+++ b/tests/ui/consts/too_generic_eval_ice.stderr
@@ -7,6 +7,14 @@ LL |         [5; Self::HOST_SIZE] == [6; 0]
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
+  --> $DIR/too_generic_eval_ice.rs:7:9
+   |
+LL |         [5; Self::HOST_SIZE] == [6; 0]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
   --> $DIR/too_generic_eval_ice.rs:7:30
    |
 LL |         [5; Self::HOST_SIZE] == [6; 0]
@@ -32,6 +40,6 @@ LL |         [5; Self::HOST_SIZE] == [6; 0]
              `[T; N]` implements `PartialEq<[U]>`
            and 3 others
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/coroutine/async_gen_fn.none.stderr b/tests/ui/coroutine/async_gen_fn.none.stderr
index 047f4d82486..2fc7419ab1c 100644
--- a/tests/ui/coroutine/async_gen_fn.none.stderr
+++ b/tests/ui/coroutine/async_gen_fn.none.stderr
@@ -4,7 +4,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL | async gen fn foo() {}
    | ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found `gen`
diff --git a/tests/ui/coroutine/async_gen_fn.rs b/tests/ui/coroutine/async_gen_fn.rs
index e8be0434b9e..b9adeec3f40 100644
--- a/tests/ui/coroutine/async_gen_fn.rs
+++ b/tests/ui/coroutine/async_gen_fn.rs
@@ -1,5 +1,5 @@
 //@ revisions: e2024 none
-//@[e2024] compile-flags: --edition 2024 -Zunstable-options
+//@[e2024] edition: 2024
 
 async gen fn foo() {}
 //[none]~^ ERROR: `async fn` is not permitted in Rust 2015
diff --git a/tests/ui/coroutine/async_gen_fn_iter.rs b/tests/ui/coroutine/async_gen_fn_iter.rs
index 42288712c70..3f7e7aa0ac2 100644
--- a/tests/ui/coroutine/async_gen_fn_iter.rs
+++ b/tests/ui/coroutine/async_gen_fn_iter.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 //@ run-pass
 
 #![feature(gen_blocks, async_iterator)]
diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs
index 97c3d06c023..d0597fdd8e1 100644
--- a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs
+++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Z unstable-options
 
 #![feature(gen_blocks)]
 #![feature(async_closure)]
diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr
index 77dc214bcec..bdd26d39d82 100644
--- a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr
+++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr
@@ -1,5 +1,5 @@
 error[E0267]: `break` inside `async` function
-  --> $DIR/break-inside-coroutine-issue-124495.rs:8:5
+  --> $DIR/break-inside-coroutine-issue-124495.rs:7:5
    |
 LL | async fn async_fn() {
    | ------------------- enclosing `async` function
@@ -7,7 +7,7 @@ LL |     break;
    |     ^^^^^ cannot `break` inside `async` function
 
 error[E0267]: `break` inside `gen` function
-  --> $DIR/break-inside-coroutine-issue-124495.rs:12:5
+  --> $DIR/break-inside-coroutine-issue-124495.rs:11:5
    |
 LL | gen fn gen_fn() {
    | --------------- enclosing `gen` function
@@ -15,7 +15,7 @@ LL |     break;
    |     ^^^^^ cannot `break` inside `gen` function
 
 error[E0267]: `break` inside `async gen` function
-  --> $DIR/break-inside-coroutine-issue-124495.rs:16:5
+  --> $DIR/break-inside-coroutine-issue-124495.rs:15:5
    |
 LL | async gen fn async_gen_fn() {
    | --------------------------- enclosing `async gen` function
@@ -23,7 +23,7 @@ LL |     break;
    |     ^^^^^ cannot `break` inside `async gen` function
 
 error[E0267]: `break` inside `async` block
-  --> $DIR/break-inside-coroutine-issue-124495.rs:20:21
+  --> $DIR/break-inside-coroutine-issue-124495.rs:19:21
    |
 LL |     let _ = async { break; };
    |             -----   ^^^^^ cannot `break` inside `async` block
@@ -31,7 +31,7 @@ LL |     let _ = async { break; };
    |             enclosing `async` block
 
 error[E0267]: `break` inside `async` closure
-  --> $DIR/break-inside-coroutine-issue-124495.rs:22:24
+  --> $DIR/break-inside-coroutine-issue-124495.rs:21:24
    |
 LL |     let _ = async || { break; };
    |             --------   ^^^^^ cannot `break` inside `async` closure
@@ -39,7 +39,7 @@ LL |     let _ = async || { break; };
    |             enclosing `async` closure
 
 error[E0267]: `break` inside `gen` block
-  --> $DIR/break-inside-coroutine-issue-124495.rs:24:19
+  --> $DIR/break-inside-coroutine-issue-124495.rs:23:19
    |
 LL |     let _ = gen { break; };
    |             ---   ^^^^^ cannot `break` inside `gen` block
@@ -47,7 +47,7 @@ LL |     let _ = gen { break; };
    |             enclosing `gen` block
 
 error[E0267]: `break` inside `async gen` block
-  --> $DIR/break-inside-coroutine-issue-124495.rs:26:25
+  --> $DIR/break-inside-coroutine-issue-124495.rs:25:25
    |
 LL |     let _ = async gen { break; };
    |             ---------   ^^^^^ cannot `break` inside `async gen` block
diff --git a/tests/ui/coroutine/const_gen_fn.rs b/tests/ui/coroutine/const_gen_fn.rs
index 986693f33ab..2701139ffed 100644
--- a/tests/ui/coroutine/const_gen_fn.rs
+++ b/tests/ui/coroutine/const_gen_fn.rs
@@ -1,5 +1,4 @@
 //@ edition:2024
-//@ compile-flags: -Zunstable-options
 
 #![feature(gen_blocks)]
 
diff --git a/tests/ui/coroutine/const_gen_fn.stderr b/tests/ui/coroutine/const_gen_fn.stderr
index b58446ac88f..4f3c73d1678 100644
--- a/tests/ui/coroutine/const_gen_fn.stderr
+++ b/tests/ui/coroutine/const_gen_fn.stderr
@@ -1,5 +1,5 @@
 error: functions cannot be both `const` and `gen`
-  --> $DIR/const_gen_fn.rs:6:1
+  --> $DIR/const_gen_fn.rs:5:1
    |
 LL | const gen fn a() {}
    | ^^^^^-^^^----------
@@ -8,7 +8,7 @@ LL | const gen fn a() {}
    | `const` because of this
 
 error: functions cannot be both `const` and `async gen`
-  --> $DIR/const_gen_fn.rs:9:1
+  --> $DIR/const_gen_fn.rs:8:1
    |
 LL | const async gen fn b() {}
    | ^^^^^-^^^^^^^^^----------
diff --git a/tests/ui/coroutine/gen_block.rs b/tests/ui/coroutine/gen_block.rs
index 7e87a572b90..6734de3b667 100644
--- a/tests/ui/coroutine/gen_block.rs
+++ b/tests/ui/coroutine/gen_block.rs
@@ -1,5 +1,5 @@
 //@ revisions: e2024 none
-//@[e2024] compile-flags: --edition 2024 -Zunstable-options
+//@[e2024] edition: 2024
 #![cfg_attr(e2024, feature(gen_blocks))]
 #![feature(stmt_expr_attributes)]
 
diff --git a/tests/ui/coroutine/gen_block_is_coro.rs b/tests/ui/coroutine/gen_block_is_coro.rs
index c98e1e60388..bccc3e86ee4 100644
--- a/tests/ui/coroutine/gen_block_is_coro.rs
+++ b/tests/ui/coroutine/gen_block_is_coro.rs
@@ -1,4 +1,5 @@
-//@compile-flags: --edition 2024 -Zunstable-options --diagnostic-width=300
+//@ edition: 2024
+//@ compile-flags: --diagnostic-width=300
 #![feature(coroutines, coroutine_trait, gen_blocks)]
 
 use std::ops::Coroutine;
diff --git a/tests/ui/coroutine/gen_block_is_coro.stderr b/tests/ui/coroutine/gen_block_is_coro.stderr
index 083e738f3ec..444f0eca1d5 100644
--- a/tests/ui/coroutine/gen_block_is_coro.stderr
+++ b/tests/ui/coroutine/gen_block_is_coro.stderr
@@ -1,26 +1,26 @@
-error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}: Coroutine` is not satisfied
-  --> $DIR/gen_block_is_coro.rs:6:13
+error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}: Coroutine` is not satisfied
+  --> $DIR/gen_block_is_coro.rs:7:13
    |
 LL | fn foo() -> impl Coroutine<Yield = u32, Return = ()> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}`
 LL |     gen { yield 42 }
-   |     ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` here
+   |     ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}` here
 
-error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}: Coroutine` is not satisfied
-  --> $DIR/gen_block_is_coro.rs:10:13
+error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}: Coroutine` is not satisfied
+  --> $DIR/gen_block_is_coro.rs:11:13
    |
 LL | fn bar() -> impl Coroutine<Yield = i64, Return = ()> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}`
 LL |     gen { yield 42 }
-   |     ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}` here
+   |     ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}` here
 
-error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}: Coroutine` is not satisfied
-  --> $DIR/gen_block_is_coro.rs:14:13
+error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}: Coroutine` is not satisfied
+  --> $DIR/gen_block_is_coro.rs:15:13
    |
 LL | fn baz() -> impl Coroutine<Yield = i32, Return = ()> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}`
 LL |     gen { yield 42 }
-   |     ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}` here
+   |     ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}` here
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/coroutine/gen_block_is_fused_iter.rs b/tests/ui/coroutine/gen_block_is_fused_iter.rs
index f3e19a7f54f..e4eab6195ee 100644
--- a/tests/ui/coroutine/gen_block_is_fused_iter.rs
+++ b/tests/ui/coroutine/gen_block_is_fused_iter.rs
@@ -1,5 +1,5 @@
 //@ revisions: next old
-//@compile-flags: --edition 2024 -Zunstable-options
+//@ edition: 2024
 //@[next] compile-flags: -Znext-solver
 //@ check-pass
 #![feature(gen_blocks)]
diff --git a/tests/ui/coroutine/gen_block_is_iter.rs b/tests/ui/coroutine/gen_block_is_iter.rs
index 396d7737132..032360fbee0 100644
--- a/tests/ui/coroutine/gen_block_is_iter.rs
+++ b/tests/ui/coroutine/gen_block_is_iter.rs
@@ -1,5 +1,5 @@
 //@ revisions: next old
-//@compile-flags: --edition 2024 -Zunstable-options
+//@ edition: 2024
 //@[next] compile-flags: -Znext-solver
 //@ check-pass
 #![feature(gen_blocks)]
diff --git a/tests/ui/coroutine/gen_block_is_no_future.rs b/tests/ui/coroutine/gen_block_is_no_future.rs
index a5bb8533719..eca8a9b6320 100644
--- a/tests/ui/coroutine/gen_block_is_no_future.rs
+++ b/tests/ui/coroutine/gen_block_is_no_future.rs
@@ -1,4 +1,4 @@
-//@compile-flags: --edition 2024 -Zunstable-options
+//@ edition: 2024
 #![feature(gen_blocks)]
 
 fn foo() -> impl std::future::Future { //~ ERROR is not a future
diff --git a/tests/ui/coroutine/gen_block_iterate.rs b/tests/ui/coroutine/gen_block_iterate.rs
index a9cb5ef3e2c..afeb56cc2f3 100644
--- a/tests/ui/coroutine/gen_block_iterate.rs
+++ b/tests/ui/coroutine/gen_block_iterate.rs
@@ -1,5 +1,5 @@
 //@ revisions: next old
-//@compile-flags: --edition 2024 -Zunstable-options
+//@ edition: 2024
 //@[next] compile-flags: -Znext-solver
 //@ run-pass
 #![feature(gen_blocks)]
diff --git a/tests/ui/coroutine/gen_block_move.fixed b/tests/ui/coroutine/gen_block_move.fixed
index 0327ca75f9e..e58c9b3f9fe 100644
--- a/tests/ui/coroutine/gen_block_move.fixed
+++ b/tests/ui/coroutine/gen_block_move.fixed
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2024 -Zunstable-options
+//@ edition: 2024
 //@ run-rustfix
 #![feature(gen_blocks)]
 
diff --git a/tests/ui/coroutine/gen_block_move.rs b/tests/ui/coroutine/gen_block_move.rs
index 53d0149872a..e249404a0a1 100644
--- a/tests/ui/coroutine/gen_block_move.rs
+++ b/tests/ui/coroutine/gen_block_move.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2024 -Zunstable-options
+//@ edition: 2024
 //@ run-rustfix
 #![feature(gen_blocks)]
 
diff --git a/tests/ui/coroutine/gen_block_panic.rs b/tests/ui/coroutine/gen_block_panic.rs
index ada56a5bd6f..b6362d5046a 100644
--- a/tests/ui/coroutine/gen_block_panic.rs
+++ b/tests/ui/coroutine/gen_block_panic.rs
@@ -1,4 +1,4 @@
-//@compile-flags: --edition 2024 -Zunstable-options
+//@ edition: 2024
 //@ run-pass
 //@ needs-unwind
 #![feature(gen_blocks)]
diff --git a/tests/ui/coroutine/gen_fn.rs b/tests/ui/coroutine/gen_fn.rs
index d47b7e576d0..2f50d5db9ac 100644
--- a/tests/ui/coroutine/gen_fn.rs
+++ b/tests/ui/coroutine/gen_fn.rs
@@ -1,5 +1,5 @@
 //@ revisions: e2024 none
-//@[e2024] compile-flags: --edition 2024 -Zunstable-options
+//@[e2024] edition: 2024
 
 gen fn foo() {}
 //[none]~^ ERROR: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen`
diff --git a/tests/ui/coroutine/gen_fn_iter.rs b/tests/ui/coroutine/gen_fn_iter.rs
index ae09d678fe3..9cd75551ad4 100644
--- a/tests/ui/coroutine/gen_fn_iter.rs
+++ b/tests/ui/coroutine/gen_fn_iter.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 //@ run-pass
 #![feature(gen_blocks)]
 
diff --git a/tests/ui/coroutine/gen_fn_lifetime_capture.rs b/tests/ui/coroutine/gen_fn_lifetime_capture.rs
index 517096d092e..bee6c2e8803 100644
--- a/tests/ui/coroutine/gen_fn_lifetime_capture.rs
+++ b/tests/ui/coroutine/gen_fn_lifetime_capture.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 //@ check-pass
 #![feature(gen_blocks)]
 
diff --git a/tests/ui/coroutine/other-attribute-on-gen.rs b/tests/ui/coroutine/other-attribute-on-gen.rs
index 0f26dc6860d..5f4584ee022 100644
--- a/tests/ui/coroutine/other-attribute-on-gen.rs
+++ b/tests/ui/coroutine/other-attribute-on-gen.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 //@ run-pass
 #![feature(gen_blocks)]
 #![feature(optimize_attribute)]
diff --git a/tests/ui/coroutine/return-types-diverge.rs b/tests/ui/coroutine/return-types-diverge.rs
index 5b639eea09a..7aa8fc028ce 100644
--- a/tests/ui/coroutine/return-types-diverge.rs
+++ b/tests/ui/coroutine/return-types-diverge.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2024 -Zunstable-options
+//@ edition: 2024
 //@ check-pass
 
 #![feature(gen_blocks)]
diff --git a/tests/ui/coroutine/return-types.rs b/tests/ui/coroutine/return-types.rs
index ad2080fd88b..4fecc550531 100644
--- a/tests/ui/coroutine/return-types.rs
+++ b/tests/ui/coroutine/return-types.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2024 -Zunstable-options
+//@ edition: 2024
 
 #![feature(gen_blocks)]
 
diff --git a/tests/ui/coroutine/self_referential_gen_block.rs b/tests/ui/coroutine/self_referential_gen_block.rs
index dccd83768c4..322cbf4f18a 100644
--- a/tests/ui/coroutine/self_referential_gen_block.rs
+++ b/tests/ui/coroutine/self_referential_gen_block.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition 2024 -Zunstable-options
+//@ edition: 2024
 #![feature(gen_blocks)]
 //! This test checks that we don't allow self-referential generators
 
diff --git a/tests/ui/crate-leading-sep.rs b/tests/ui/crate-leading-sep.rs
index fbc940aed26..6f4dd0bcfd7 100644
--- a/tests/ui/crate-leading-sep.rs
+++ b/tests/ui/crate-leading-sep.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(dropping_copy_types)]
 
diff --git a/tests/ui/crate-method-reexport-grrrrrrr.rs b/tests/ui/crate-method-reexport-grrrrrrr.rs
index 870c6851a66..aca399f4e20 100644
--- a/tests/ui/crate-method-reexport-grrrrrrr.rs
+++ b/tests/ui/crate-method-reexport-grrrrrrr.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 // This is a regression test that the metadata for the
 // name_pool::methods impl in the other crate is reachable from this
diff --git a/tests/ui/crate-name-attr-used.rs b/tests/ui/crate-name-attr-used.rs
index 8e958aa0eaa..5d5a58c32c7 100644
--- a/tests/ui/crate-name-attr-used.rs
+++ b/tests/ui/crate-name-attr-used.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ compile-flags:--crate-name crate_name_attr_used -F unused-attributes
 
-//@ pretty-expanded FIXME #23616
 
 #![crate_name = "crate_name_attr_used"]
 
diff --git a/tests/ui/cross-crate/cci_capture_clause.rs b/tests/ui/cross-crate/cci_capture_clause.rs
index 73e1020d7cf..22fe49c2ba0 100644
--- a/tests/ui/cross-crate/cci_capture_clause.rs
+++ b/tests/ui/cross-crate/cci_capture_clause.rs
@@ -4,7 +4,6 @@
 // This test makes sure we can do cross-crate inlining on functions
 // that use capture clauses.
 
-//@ pretty-expanded FIXME #23616
 //@ needs-threads
 
 extern crate cci_capture_clause;
diff --git a/tests/ui/cross-crate/cross-crate-const-pat.rs b/tests/ui/cross-crate/cross-crate-const-pat.rs
index 4ff55adb804..31521089160 100644
--- a/tests/ui/cross-crate/cross-crate-const-pat.rs
+++ b/tests/ui/cross-crate/cross-crate-const-pat.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:cci_const.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate cci_const;
 
diff --git a/tests/ui/cross-crate/moves-based-on-type-cross-crate.rs b/tests/ui/cross-crate/moves-based-on-type-cross-crate.rs
index 640a1789cbe..3e05717326c 100644
--- a/tests/ui/cross-crate/moves-based-on-type-cross-crate.rs
+++ b/tests/ui/cross-crate/moves-based-on-type-cross-crate.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:moves_based_on_type_lib.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate moves_based_on_type_lib;
 use moves_based_on_type_lib::f;
diff --git a/tests/ui/cross-crate/static-addresses.rs b/tests/ui/cross-crate/static-addresses.rs
index 66ac467e9ac..2783b44671d 100644
--- a/tests/ui/cross-crate/static-addresses.rs
+++ b/tests/ui/cross-crate/static-addresses.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:xcrate_static_addresses.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate xcrate_static_addresses;
 
diff --git a/tests/ui/cross-crate/trait-lifetime-param.rs b/tests/ui/cross-crate/trait-lifetime-param.rs
index 28955e62d95..89983492fe4 100644
--- a/tests/ui/cross-crate/trait-lifetime-param.rs
+++ b/tests/ui/cross-crate/trait-lifetime-param.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 //@ aux-build:xcrate-trait-lifetime-param.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate xcrate_trait_lifetime_param as other;
 
diff --git a/tests/ui/cross-crate/unit-struct-2.rs b/tests/ui/cross-crate/unit-struct-2.rs
index c2e3a761129..2177a8800db 100644
--- a/tests/ui/cross-crate/unit-struct-2.rs
+++ b/tests/ui/cross-crate/unit-struct-2.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 //@ aux-build:xcrate_unit_struct.rs
-//@ pretty-expanded FIXME #23616
 #![allow(non_upper_case_globals)]
 
 extern crate xcrate_unit_struct;
diff --git a/tests/ui/default-method-parsing.rs b/tests/ui/default-method-parsing.rs
index 2580a04221f..84c3ab747c8 100644
--- a/tests/ui/default-method-parsing.rs
+++ b/tests/ui/default-method-parsing.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Foo {
     fn m(&self, _:isize) { }
diff --git a/tests/ui/deref.rs b/tests/ui/deref.rs
index b491c517d94..0a6f3cc81f6 100644
--- a/tests/ui/deref.rs
+++ b/tests/ui/deref.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let x: Box<isize> = Box::new(10);
diff --git a/tests/ui/deriving/deriving-clone-enum.rs b/tests/ui/deriving/deriving-clone-enum.rs
index 59301c1d094..96b9ba4f24c 100644
--- a/tests/ui/deriving/deriving-clone-enum.rs
+++ b/tests/ui/deriving/deriving-clone-enum.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 #[derive(Clone)]
 enum E {
diff --git a/tests/ui/deriving/deriving-clone-generic-enum.rs b/tests/ui/deriving/deriving-clone-generic-enum.rs
index 7f0dd872ffd..08c91c487ba 100644
--- a/tests/ui/deriving/deriving-clone-generic-enum.rs
+++ b/tests/ui/deriving/deriving-clone-generic-enum.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 #[derive(Clone)]
 enum E<T,U> {
diff --git a/tests/ui/deriving/deriving-clone-generic-struct.rs b/tests/ui/deriving/deriving-clone-generic-struct.rs
index cbdfa8a7c9a..f2fc6d5e4d7 100644
--- a/tests/ui/deriving/deriving-clone-generic-struct.rs
+++ b/tests/ui/deriving/deriving-clone-generic-struct.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/deriving/deriving-clone-generic-tuple-struct.rs b/tests/ui/deriving/deriving-clone-generic-tuple-struct.rs
index f0bbce707f3..178075e273d 100644
--- a/tests/ui/deriving/deriving-clone-generic-tuple-struct.rs
+++ b/tests/ui/deriving/deriving-clone-generic-tuple-struct.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #[derive(Clone)]
 #[allow(dead_code)]
diff --git a/tests/ui/deriving/deriving-clone-struct.rs b/tests/ui/deriving/deriving-clone-struct.rs
index b357aa82a2a..896ce51bf3d 100644
--- a/tests/ui/deriving/deriving-clone-struct.rs
+++ b/tests/ui/deriving/deriving-clone-struct.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/deriving/deriving-clone-tuple-struct.rs b/tests/ui/deriving/deriving-clone-tuple-struct.rs
index 727860465fc..622ffb7b1f4 100644
--- a/tests/ui/deriving/deriving-clone-tuple-struct.rs
+++ b/tests/ui/deriving/deriving-clone-tuple-struct.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/deriving/deriving-enum-single-variant.rs b/tests/ui/deriving/deriving-enum-single-variant.rs
index dfdfef01298..43d229c442c 100644
--- a/tests/ui/deriving/deriving-enum-single-variant.rs
+++ b/tests/ui/deriving/deriving-enum-single-variant.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 #![allow(non_camel_case_types)]
 
 pub type task_id = isize;
diff --git a/tests/ui/deriving/deriving-in-macro.rs b/tests/ui/deriving/deriving-in-macro.rs
index e86b40d30dc..493c1415c7f 100644
--- a/tests/ui/deriving/deriving-in-macro.rs
+++ b/tests/ui/deriving/deriving-in-macro.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 #![allow(non_camel_case_types)]
 
 macro_rules! define_vec {
diff --git a/tests/ui/deriving/deriving-meta-multiple.rs b/tests/ui/deriving/deriving-meta-multiple.rs
index 07dabd9e9c3..7c2d3566fbf 100644
--- a/tests/ui/deriving/deriving-meta-multiple.rs
+++ b/tests/ui/deriving/deriving-meta-multiple.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
 #![allow(unused_imports)]
-//@ pretty-expanded FIXME #23616
 #![allow(deprecated)]
 
 use std::hash::{Hash, SipHasher};
diff --git a/tests/ui/deriving/deriving-meta.rs b/tests/ui/deriving/deriving-meta.rs
index 34d31d9ef9e..70b5821edae 100644
--- a/tests/ui/deriving/deriving-meta.rs
+++ b/tests/ui/deriving/deriving-meta.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
 #![allow(unused_imports)]
-//@ pretty-expanded FIXME #23616
 #![allow(deprecated)]
 
 use std::hash::{Hash, SipHasher};
diff --git a/tests/ui/deriving/deriving-via-extension-hash-struct.rs b/tests/ui/deriving/deriving-via-extension-hash-struct.rs
index ad2a84b6bf9..2b1bc9e108b 100644
--- a/tests/ui/deriving/deriving-via-extension-hash-struct.rs
+++ b/tests/ui/deriving/deriving-via-extension-hash-struct.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 #[derive(Hash)]
 struct Foo {
diff --git a/tests/ui/deriving/issue-15689-2.rs b/tests/ui/deriving/issue-15689-2.rs
index 790c72f6d4d..a1f66cc0643 100644
--- a/tests/ui/deriving/issue-15689-2.rs
+++ b/tests/ui/deriving/issue-15689-2.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 #[derive(Clone)]
 enum Test<'a> {
diff --git a/tests/ui/deriving/issue-6341.rs b/tests/ui/deriving/issue-6341.rs
index 5c2d0abfa8c..83b0da9a318 100644
--- a/tests/ui/deriving/issue-6341.rs
+++ b/tests/ui/deriving/issue-6341.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 #[derive(PartialEq)]
 struct A { x: usize }
diff --git a/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr b/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr
index b9ceaa4af7b..88f7d2da47c 100644
--- a/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr
+++ b/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr
@@ -5,7 +5,7 @@ LL |     None = Some(3);
    |     ^^^^ pattern `Some(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Option<i32>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs
index ce41ad2952b..dedae4365e8 100644
--- a/tests/ui/diagnostic-width/E0271.rs
+++ b/tests/ui/diagnostic-width/E0271.rs
@@ -1,6 +1,6 @@
 //@ revisions: ascii unicode
 //@[ascii] compile-flags: --diagnostic-width=40
-//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode --diagnostic-width=40
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40
 //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
 trait Future {
     type Error;
diff --git a/tests/ui/diagnostic-width/flag-human.rs b/tests/ui/diagnostic-width/flag-human.rs
index 1af41659141..8e656293b41 100644
--- a/tests/ui/diagnostic-width/flag-human.rs
+++ b/tests/ui/diagnostic-width/flag-human.rs
@@ -1,6 +1,6 @@
 //@ revisions: ascii unicode
 //@[ascii] compile-flags: --diagnostic-width=20
-//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode --diagnostic-width=20
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=20
 
 // This test checks that `-Z output-width` effects the human error output by restricting it to an
 // arbitrarily low value so that the effect is visible.
diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs
index 73f81f5872a..695852f83ac 100644
--- a/tests/ui/diagnostic-width/long-E0308.rs
+++ b/tests/ui/diagnostic-width/long-E0308.rs
@@ -1,6 +1,6 @@
 //@ revisions: ascii unicode
 //@[ascii] compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
-//@[unicode] compile-flags: -Zunstable-options=yes --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
+//@[unicode] compile-flags: -Zunstable-options --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
 //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
 
 mod a {
diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs
index 61c4b31e03a..e630db8ba42 100644
--- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs
+++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs
@@ -1,5 +1,5 @@
 //@ revisions: ascii unicode
-//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode
 // ignore-tidy-linelength
 
 fn main() {
diff --git a/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs b/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs
index 283506bd6c9..de2f42a4a72 100644
--- a/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs
+++ b/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs
@@ -1,5 +1,5 @@
 //@ revisions: ascii unicode
-//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode
 // ignore-tidy-linelength
 
 fn main() {
diff --git a/tests/ui/double-ref.rs b/tests/ui/double-ref.rs
index 62591deb868..eecf68ff209 100644
--- a/tests/ui/double-ref.rs
+++ b/tests/ui/double-ref.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn check_expr() {
     let _:         & usize =     &1;
diff --git a/tests/ui/drop/auxiliary/edition-2024-macros.rs b/tests/ui/drop/auxiliary/edition-2024-macros.rs
index 236340bfed4..44befbc9843 100644
--- a/tests/ui/drop/auxiliary/edition-2024-macros.rs
+++ b/tests/ui/drop/auxiliary/edition-2024-macros.rs
@@ -1,5 +1,4 @@
 //@ edition:2024
-//@ compile-flags: -Zunstable-options
 
 #[macro_export]
 macro_rules! edition_2024_block {
diff --git a/tests/ui/drop/drop-on-empty-block-exit.rs b/tests/ui/drop/drop-on-empty-block-exit.rs
index 63bc403a721..107ea9022f8 100644
--- a/tests/ui/drop/drop-on-empty-block-exit.rs
+++ b/tests/ui/drop/drop-on-empty-block-exit.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 #![allow(non_camel_case_types)]
 
 enum t { foo(Box<isize>), }
diff --git a/tests/ui/drop/drop-on-ret.rs b/tests/ui/drop/drop-on-ret.rs
index f8ce899adf0..4bd50e6a72d 100644
--- a/tests/ui/drop/drop-on-ret.rs
+++ b/tests/ui/drop/drop-on-ret.rs
@@ -2,7 +2,6 @@
 
 
 
-//@ pretty-expanded FIXME #23616
 
 fn f() -> isize {
     if true {
diff --git a/tests/ui/drop/drop-uninhabited-enum.rs b/tests/ui/drop/drop-uninhabited-enum.rs
index f018ffa0977..2ac6dc8e9ea 100644
--- a/tests/ui/drop/drop-uninhabited-enum.rs
+++ b/tests/ui/drop/drop-uninhabited-enum.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 enum Foo { }
 
diff --git a/tests/ui/drop/drop_order_if_let_rescope.rs b/tests/ui/drop/drop_order_if_let_rescope.rs
index cea84bbaa2b..7445e3a6a5f 100644
--- a/tests/ui/drop/drop_order_if_let_rescope.rs
+++ b/tests/ui/drop/drop_order_if_let_rescope.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 //@ edition:2024
-//@ compile-flags: -Z validate-mir -Zunstable-options
+//@ compile-flags: -Z validate-mir
 
 #![feature(let_chains)]
 
diff --git a/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs b/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs
index e055c20d777..a3583c48c39 100644
--- a/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs
+++ b/tests/ui/drop/if-let-rescope-borrowck-suggestions.rs
@@ -1,5 +1,5 @@
 //@ edition: 2024
-//@ compile-flags: -Z validate-mir -Zunstable-options
+//@ compile-flags: -Z validate-mir
 
 #![deny(if_let_rescope)]
 
diff --git a/tests/ui/drop/issue-10028.rs b/tests/ui/drop/issue-10028.rs
index 41914254522..1ca1fbf504d 100644
--- a/tests/ui/drop/issue-10028.rs
+++ b/tests/ui/drop/issue-10028.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 //@ aux-build:issue-10028.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_10028 as issue10028;
 
diff --git a/tests/ui/drop/issue-2734.rs b/tests/ui/drop/issue-2734.rs
index 028f86ebb3a..4616ea1f013 100644
--- a/tests/ui/drop/issue-2734.rs
+++ b/tests/ui/drop/issue-2734.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 trait hax {
     fn dummy(&self) { }
diff --git a/tests/ui/drop/issue-2735.rs b/tests/ui/drop/issue-2735.rs
index 8fa3ac45d08..cd7e0b8f461 100644
--- a/tests/ui/drop/issue-2735.rs
+++ b/tests/ui/drop/issue-2735.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 trait hax {
     fn dummy(&self) { }
diff --git a/tests/ui/drop/lint-tail-expr-drop-order-gated.rs b/tests/ui/drop/lint-tail-expr-drop-order-gated.rs
index 508e7bdbf99..361862100e6 100644
--- a/tests/ui/drop/lint-tail-expr-drop-order-gated.rs
+++ b/tests/ui/drop/lint-tail-expr-drop-order-gated.rs
@@ -3,7 +3,6 @@
 // Only `cargo fix --edition 2024` shall activate this lint.
 
 //@ check-pass
-//@ compile-flags: -Z unstable-options
 //@ edition: 2024
 
 #![deny(tail_expr_drop_order)]
diff --git a/tests/ui/drop/nondrop-cycle.rs b/tests/ui/drop/nondrop-cycle.rs
index 9b32d1319c9..fbee1be179f 100644
--- a/tests/ui/drop/nondrop-cycle.rs
+++ b/tests/ui/drop/nondrop-cycle.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::cell::Cell;
 
diff --git a/tests/ui/drop/tail-expr-drop-order.rs b/tests/ui/drop/tail-expr-drop-order.rs
index 80968b823f9..f74530fce1e 100644
--- a/tests/ui/drop/tail-expr-drop-order.rs
+++ b/tests/ui/drop/tail-expr-drop-order.rs
@@ -1,6 +1,6 @@
 //@ aux-build:edition-2021-macros.rs
 //@ aux-build:edition-2024-macros.rs
-//@ compile-flags: -Z validate-mir -Zunstable-options
+//@ compile-flags: -Z validate-mir
 //@ edition: 2024
 //@ run-pass
 
diff --git a/tests/ui/drop/use_inline_dtor.rs b/tests/ui/drop/use_inline_dtor.rs
index 03f476cff2a..9d3cbd0b8b4 100644
--- a/tests/ui/drop/use_inline_dtor.rs
+++ b/tests/ui/drop/use_inline_dtor.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:inline_dtor.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate inline_dtor;
 
diff --git a/tests/ui/dropck/cleanup-arm-conditional.rs b/tests/ui/dropck/cleanup-arm-conditional.rs
index 94b38080189..31331f24d6f 100644
--- a/tests/ui/dropck/cleanup-arm-conditional.rs
+++ b/tests/ui/dropck/cleanup-arm-conditional.rs
@@ -5,7 +5,6 @@
 // Test that cleanup scope for temporaries created in a match
 // arm is confined to the match arm itself.
 
-//@ pretty-expanded FIXME #23616
 
 #![feature(os)]
 
diff --git a/tests/ui/dropck/const_drop_is_valid.rs b/tests/ui/dropck/const_drop_is_valid.rs
deleted file mode 100644
index 26ef2d61deb..00000000000
--- a/tests/ui/dropck/const_drop_is_valid.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-struct A();
-
-impl const Drop for A {}
-//~^ ERROR: const trait impls are experimental
-//~| const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-//~| not all trait items implemented, missing: `drop`
-
-fn main() {}
diff --git a/tests/ui/dropck/const_drop_is_valid.stderr b/tests/ui/dropck/const_drop_is_valid.stderr
deleted file mode 100644
index 5837e1623a1..00000000000
--- a/tests/ui/dropck/const_drop_is_valid.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0658]: const trait impls are experimental
-  --> $DIR/const_drop_is_valid.rs:3:6
-   |
-LL | impl const Drop for A {}
-   |      ^^^^^
-   |
-   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
-   = help: add `#![feature(const_trait_impl)]` 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: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const_drop_is_valid.rs:3:12
-   |
-LL | impl const Drop for A {}
-   |            ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error[E0046]: not all trait items implemented, missing: `drop`
-  --> $DIR/const_drop_is_valid.rs:3:1
-   |
-LL | impl const Drop for A {}
-   | ^^^^^^^^^^^^^^^^^^^^^ missing `drop` in implementation
-   |
-   = help: implement the missing item: `fn drop(&mut self) { todo!() }`
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0046, E0658.
-For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/dupe-first-attr.rs b/tests/ui/dupe-first-attr.rs
index ec9e354e73d..c254df050c1 100644
--- a/tests/ui/dupe-first-attr.rs
+++ b/tests/ui/dupe-first-attr.rs
@@ -3,7 +3,6 @@
 // Regression test for a problem with the first mod attribute
 // being applied to every mod
 
-//@ pretty-expanded FIXME #23616
 
 #[cfg(target_os = "linux")]
 mod hello {}
diff --git a/tests/ui/dynamically-sized-types/dst-coercions.rs b/tests/ui/dynamically-sized-types/dst-coercions.rs
index 6b3c85cf83b..4813dda439b 100644
--- a/tests/ui/dynamically-sized-types/dst-coercions.rs
+++ b/tests/ui/dynamically-sized-types/dst-coercions.rs
@@ -2,7 +2,6 @@
 #![allow(unused_variables)]
 // Test coercions involving DST and/or raw pointers
 
-//@ pretty-expanded FIXME #23616
 
 struct S;
 trait T { fn dummy(&self) { } } //~ WARN method `dummy` is never used
diff --git a/tests/ui/dynamically-sized-types/dst-coercions.stderr b/tests/ui/dynamically-sized-types/dst-coercions.stderr
index e4721ce50a0..e7c48783df0 100644
--- a/tests/ui/dynamically-sized-types/dst-coercions.stderr
+++ b/tests/ui/dynamically-sized-types/dst-coercions.stderr
@@ -1,5 +1,5 @@
 warning: method `dummy` is never used
-  --> $DIR/dst-coercions.rs:8:14
+  --> $DIR/dst-coercions.rs:7:14
    |
 LL | trait T { fn dummy(&self) { } }
    |       -      ^^^^^
diff --git a/tests/ui/early-ret-binop-add.rs b/tests/ui/early-ret-binop-add.rs
index 5daf79c214c..3fec66f35fb 100644
--- a/tests/ui/early-ret-binop-add.rs
+++ b/tests/ui/early-ret-binop-add.rs
@@ -2,7 +2,6 @@
 
 #![allow(dead_code)]
 #![allow(unreachable_code)]
-//@ pretty-expanded FIXME #23616
 
 use std::ops::Add;
 
diff --git a/tests/ui/editions/async-block-2015.rs b/tests/ui/editions/async-block-2015.rs
index 3daf4930c5b..a079b4aad91 100644
--- a/tests/ui/editions/async-block-2015.rs
+++ b/tests/ui/editions/async-block-2015.rs
@@ -1,7 +1,7 @@
 async fn foo() {
 //~^ ERROR `async fn` is not permitted in Rust 2015
 //~| NOTE to use `async fn`, switch to Rust 2018 or later
-//~| HELP pass `--edition 2021` to `rustc`
+//~| HELP pass `--edition 2024` to `rustc`
 //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 
     let x = async {};
@@ -11,7 +11,7 @@ async fn foo() {
         let x = 42;
         //~^ ERROR expected identifier, found keyword `let`
         //~| NOTE expected identifier, found keyword
-        //~| HELP pass `--edition 2021` to `rustc`
+        //~| HELP pass `--edition 2024` to `rustc`
         //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
         42
     };
@@ -19,7 +19,7 @@ async fn foo() {
         42
         //~^ ERROR expected identifier, found `42`
         //~| NOTE expected identifier
-        //~| HELP pass `--edition 2021` to `rustc`
+        //~| HELP pass `--edition 2024` to `rustc`
         //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
     };
     y.await;
diff --git a/tests/ui/editions/async-block-2015.stderr b/tests/ui/editions/async-block-2015.stderr
index b792b8c1e0d..574bcacc1cf 100644
--- a/tests/ui/editions/async-block-2015.stderr
+++ b/tests/ui/editions/async-block-2015.stderr
@@ -4,7 +4,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL | async fn foo() {
    | ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: expected identifier, found keyword `let`
@@ -15,7 +15,7 @@ LL |     let y = async {
 LL |         let x = 42;
    |         ^^^ expected identifier, found keyword
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: expected identifier, found `42`
@@ -26,7 +26,7 @@ LL |     let z = async {
 LL |         42
    |         ^^ expected identifier
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0422]: cannot find struct, variant or union type `async` in this scope
diff --git a/tests/ui/editions/edition-cstr-2015-2018.rs b/tests/ui/editions/edition-cstr-2015-2018.rs
index 4c35c48646a..4d4274251f0 100644
--- a/tests/ui/editions/edition-cstr-2015-2018.rs
+++ b/tests/ui/editions/edition-cstr-2015-2018.rs
@@ -7,7 +7,7 @@ macro_rules! contain { () => { c"str" } }
     //~| NOTE expected one of 8 possible tokens
     //~| NOTE you may be trying to write a c-string literal
     //~| NOTE c-string literals require Rust 2021 or later
-    //~| HELP pass `--edition 2021` to `rustc`
+    //~| HELP pass `--edition 2024` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 
 fn check_macro_construct() {
@@ -29,7 +29,7 @@ fn check_basic() {
     //~| NOTE expected one of 8 possible tokens
     //~| NOTE you may be trying to write a c-string literal
     //~| NOTE c-string literals require Rust 2021 or later
-    //~| HELP pass `--edition 2021` to `rustc`
+    //~| HELP pass `--edition 2024` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -39,7 +39,7 @@ fn check_craw() {
     //~| NOTE expected one of 8 possible tokens
     //~| NOTE you may be trying to write a c-string literal
     //~| NOTE c-string literals require Rust 2021 or later
-    //~| HELP pass `--edition 2021` to `rustc`
+    //~| HELP pass `--edition 2024` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
@@ -49,7 +49,7 @@ fn check_craw_hash() {
     //~| NOTE expected one of 8 possible tokens
     //~| NOTE you may be trying to write a c-string literal
     //~| NOTE c-string literals require Rust 2021 or later
-    //~| HELP pass `--edition 2021` to `rustc`
+    //~| HELP pass `--edition 2024` to `rustc`
     //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
 }
 
diff --git a/tests/ui/editions/edition-cstr-2015-2018.stderr b/tests/ui/editions/edition-cstr-2015-2018.stderr
index b864df308ef..62cb8576552 100644
--- a/tests/ui/editions/edition-cstr-2015-2018.stderr
+++ b/tests/ui/editions/edition-cstr-2015-2018.stderr
@@ -6,7 +6,7 @@ LL |     c"str";
    |
    = note: you may be trying to write a c-string literal
    = note: c-string literals require Rust 2021 or later
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
@@ -17,7 +17,7 @@ LL |     cr"str";
    |
    = note: you may be trying to write a c-string literal
    = note: c-string literals require Rust 2021 or later
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `#`
@@ -28,7 +28,7 @@ LL |     cr##"str"##;
    |
    = note: you may be trying to write a c-string literal
    = note: c-string literals require Rust 2021 or later
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
@@ -59,7 +59,7 @@ LL |     contain!();
    |
    = note: you may be trying to write a c-string literal
    = note: c-string literals require Rust 2021 or later
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
    = note: this error originates in the macro `contain` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/empty-allocation-rvalue-non-null.rs b/tests/ui/empty-allocation-rvalue-non-null.rs
index 25c36679033..0cd4fde73ed 100644
--- a/tests/ui/empty-allocation-rvalue-non-null.rs
+++ b/tests/ui/empty-allocation-rvalue-non-null.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let x: () = *Box::new(());
diff --git a/tests/ui/empty/empty-never-array.stderr b/tests/ui/empty/empty-never-array.stderr
index 0104a435538..f9f39a6371e 100644
--- a/tests/ui/empty/empty-never-array.stderr
+++ b/tests/ui/empty/empty-never-array.stderr
@@ -5,7 +5,7 @@ LL |     let Helper::U(u) = Helper::T(t, []);
    |         ^^^^^^^^^^^^ pattern `Helper::T(_, _)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Helper<T, U>` defined here
   --> $DIR/empty-never-array.rs:3:6
    |
diff --git a/tests/ui/enum/issue-1821.rs b/tests/ui/enum/issue-1821.rs
index 76d60962c38..2cfdee566a6 100644
--- a/tests/ui/enum/issue-1821.rs
+++ b/tests/ui/enum/issue-1821.rs
@@ -5,7 +5,6 @@
 // Issue #1821 - Don't recurse trying to typecheck this
 
 
-//@ pretty-expanded FIXME #23616
 
 enum t {
     foo(Vec<t>)
diff --git a/tests/ui/enum/issue-19340-1.rs b/tests/ui/enum/issue-19340-1.rs
index c1ba0d23b6f..97936923442 100644
--- a/tests/ui/enum/issue-19340-1.rs
+++ b/tests/ui/enum/issue-19340-1.rs
@@ -2,7 +2,6 @@
 #![allow(unused_variables)]
 //@ aux-build:issue-19340-1.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_19340_1 as lib;
 
diff --git a/tests/ui/enum/issue-19340-2.rs b/tests/ui/enum/issue-19340-2.rs
index dd1bda78a97..0930cd5da09 100644
--- a/tests/ui/enum/issue-19340-2.rs
+++ b/tests/ui/enum/issue-19340-2.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 enum Homura {
     Madoka {
diff --git a/tests/ui/error-codes/E0005.stderr b/tests/ui/error-codes/E0005.stderr
index 4be37e2e454..c643ee07a37 100644
--- a/tests/ui/error-codes/E0005.stderr
+++ b/tests/ui/error-codes/E0005.stderr
@@ -5,7 +5,7 @@ LL |     let Some(y) = x;
    |         ^^^^^^^ pattern `None` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Option<i32>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/error-codes/E0746.stderr b/tests/ui/error-codes/E0746.stderr
index cfc747cb1e2..ce3e9736969 100644
--- a/tests/ui/error-codes/E0746.stderr
+++ b/tests/ui/error-codes/E0746.stderr
@@ -19,8 +19,11 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn bar() -> dyn Trait {
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: if there were a single returned type, you could use `impl Trait` instead
-help: box the return type, and wrap all of the returned values in `Box::new`
+help: consider returning an `impl Trait` instead of a `dyn Trait`
+   |
+LL | fn bar() -> impl Trait {
+   |             ~~~~
+help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
    |
 LL ~ fn bar() -> Box<dyn Trait> {
 LL |     if true {
diff --git a/tests/ui/error-emitter/unicode-output.rs b/tests/ui/error-emitter/unicode-output.rs
index ba6db37b66c..5c083c4e575 100644
--- a/tests/ui/error-emitter/unicode-output.rs
+++ b/tests/ui/error-emitter/unicode-output.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -Zunstable-options=yes --error-format=human-unicode --color=always
+//@ compile-flags: -Zunstable-options --error-format=human-unicode --color=always
 //@ edition:2018
 //@ only-linux
 
diff --git a/tests/ui/explicit-i-suffix.rs b/tests/ui/explicit-i-suffix.rs
index 29c7391521e..0a6ed49ae27 100644
--- a/tests/ui/explicit-i-suffix.rs
+++ b/tests/ui/explicit-i-suffix.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(unused_must_use)]
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let x: isize = 8;
diff --git a/tests/ui/expr/if/if-ret.rs b/tests/ui/expr/if/if-ret.rs
index 3aad21d34a2..2698c5bbf6e 100644
--- a/tests/ui/expr/if/if-ret.rs
+++ b/tests/ui/expr/if/if-ret.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(unused_parens)]
-//@ pretty-expanded FIXME #23616
 
 fn foo() { if (return) { } } //~ WARNING unreachable block in `if`
 
diff --git a/tests/ui/expr/if/if-ret.stderr b/tests/ui/expr/if/if-ret.stderr
index 8ced271aabc..e5464affd2f 100644
--- a/tests/ui/expr/if/if-ret.stderr
+++ b/tests/ui/expr/if/if-ret.stderr
@@ -1,5 +1,5 @@
 warning: unreachable block in `if` or `while` expression
-  --> $DIR/if-ret.rs:6:24
+  --> $DIR/if-ret.rs:5:24
    |
 LL | fn foo() { if (return) { } }
    |               -------- ^^^ unreachable block in `if` or `while` expression
diff --git a/tests/ui/expr/scope.rs b/tests/ui/expr/scope.rs
index 57321ce2aa0..3a1c8b87da8 100644
--- a/tests/ui/expr/scope.rs
+++ b/tests/ui/expr/scope.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Regression test for issue #762
 
-//@ pretty-expanded FIXME #23616
 
 pub fn f() { }
 pub fn main() { return ::f(); }
diff --git a/tests/ui/extern/extern-1.rs b/tests/ui/extern/extern-1.rs
index c0f770ab9f2..226bc1effb1 100644
--- a/tests/ui/extern/extern-1.rs
+++ b/tests/ui/extern/extern-1.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 extern "C" fn f() {
 }
diff --git a/tests/ui/extern/extern-calling-convention-test.rs b/tests/ui/extern/extern-calling-convention-test.rs
index 7c533df1986..68315ed0934 100644
--- a/tests/ui/extern/extern-calling-convention-test.rs
+++ b/tests/ui/extern/extern-calling-convention-test.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:extern_calling_convention.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate extern_calling_convention;
 
diff --git a/tests/ui/extern/extern-foreign-crate.rs b/tests/ui/extern/extern-foreign-crate.rs
index 939090ab5fc..690a6501368 100644
--- a/tests/ui/extern/extern-foreign-crate.rs
+++ b/tests/ui/extern/extern-foreign-crate.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 extern crate std as mystd;
 
diff --git a/tests/ui/extern/extern-mod-abi.rs b/tests/ui/extern/extern-mod-abi.rs
index 8700a379d29..29892c468dd 100644
--- a/tests/ui/extern/extern-mod-abi.rs
+++ b/tests/ui/extern/extern-mod-abi.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 extern "C" {
     fn pow(x: f64, y: f64) -> f64;
diff --git a/tests/ui/extern/extern-mod-ordering-exe.rs b/tests/ui/extern/extern-mod-ordering-exe.rs
index c735f6bae7a..9f5e52e3395 100644
--- a/tests/ui/extern/extern-mod-ordering-exe.rs
+++ b/tests/ui/extern/extern-mod-ordering-exe.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:extern_mod_ordering_lib.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate extern_mod_ordering_lib;
 
diff --git a/tests/ui/extern/extern-pub.rs b/tests/ui/extern/extern-pub.rs
index 80f1e295d4d..b272bc5359f 100644
--- a/tests/ui/extern/extern-pub.rs
+++ b/tests/ui/extern/extern-pub.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 extern "C" {
     pub fn free(p: *const u8);
diff --git a/tests/ui/extern/extern-rust.rs b/tests/ui/extern/extern-rust.rs
index bacdc7aeecb..b4a4a49810e 100644
--- a/tests/ui/extern/extern-rust.rs
+++ b/tests/ui/extern/extern-rust.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #[repr(C)]
 pub struct Foo(u32);
diff --git a/tests/ui/extern/issue-10025.rs b/tests/ui/extern/issue-10025.rs
index 0bdcf7c5c58..140012f4a16 100644
--- a/tests/ui/extern/issue-10025.rs
+++ b/tests/ui/extern/issue-10025.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 #![allow(dead_code)]
 
 unsafe extern fn foo() {}
diff --git a/tests/ui/extern/issue-10763.rs b/tests/ui/extern/issue-10763.rs
index 2381f22f162..6966f5571df 100644
--- a/tests/ui/extern/issue-10763.rs
+++ b/tests/ui/extern/issue-10763.rs
@@ -1,6 +1,5 @@
 //@ build-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 extern "Rust" fn foo() {}
 
diff --git a/tests/ui/extern/issue-10764-rpass.rs b/tests/ui/extern/issue-10764-rpass.rs
index 4de387e3d66..761bf4e28b7 100644
--- a/tests/ui/extern/issue-10764-rpass.rs
+++ b/tests/ui/extern/issue-10764-rpass.rs
@@ -1,4 +1,3 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 extern "Rust" fn main() {}
diff --git a/tests/ui/extern/issue-1251.rs b/tests/ui/extern/issue-1251.rs
index 5581bddaddc..ba42fef298c 100644
--- a/tests/ui/extern/issue-1251.rs
+++ b/tests/ui/extern/issue-1251.rs
@@ -1,7 +1,6 @@
 //@ build-pass
 #![allow(unused_attributes)]
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 mod rustrt {
     extern "C" {
diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs
new file mode 100644
index 00000000000..7aec7455b2e
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs
@@ -0,0 +1,23 @@
+//@ needs-asm-support
+//@ compile-flags: --target s390x-unknown-linux-gnu
+//@ needs-llvm-components: systemz
+
+#![feature(no_core, lang_items, rustc_attrs)]
+#![crate_type = "rlib"]
+#![no_core]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+unsafe fn main() {
+    asm!("", in("v0") 0);
+    //~^ ERROR register class `vreg` can only be used as a clobber in stable
+    //~| ERROR type `i32` cannot be used with this register class
+}
diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr
new file mode 100644
index 00000000000..0791ce4543c
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr
@@ -0,0 +1,23 @@
+error[E0658]: register class `vreg` can only be used as a clobber in stable
+  --> $DIR/feature-gate-asm_experimental_reg.rs:20:14
+   |
+LL |     asm!("", in("v0") 0);
+   |              ^^^^^^^^^^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: type `i32` cannot be used with this register class in stable
+  --> $DIR/feature-gate-asm_experimental_reg.rs:20:23
+   |
+LL |     asm!("", in("v0") 0);
+   |                       ^
+   |
+   = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
+   = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs
new file mode 100644
index 00000000000..294827f78d2
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs
@@ -0,0 +1,13 @@
+//@ only-x86_64
+
+#![feature(asm_goto)]
+
+use std::arch::asm;
+
+fn main() {
+    let mut _out: u64;
+    unsafe {
+        asm!("mov {}, 1", "jmp {}", out(reg) _out, label {});
+        //~^ ERROR using both label and output operands for inline assembly is unstable
+    }
+}
diff --git a/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr
new file mode 100644
index 00000000000..ff7a7d5760a
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr
@@ -0,0 +1,13 @@
+error[E0658]: using both label and output operands for inline assembly is unstable
+  --> $DIR/feature-gate-asm_goto_with_outputs.rs:10:52
+   |
+LL |         asm!("mov {}, 1", "jmp {}", out(reg) _out, label {});
+   |                                                    ^^^^^^^^
+   |
+   = note: see issue #119364 <https://github.com/rust-lang/rust/issues/119364> for more information
+   = help: add `#![feature(asm_goto_with_outputs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-coroutines.rs b/tests/ui/feature-gates/feature-gate-coroutines.rs
index a686357d910..f20dc56f122 100644
--- a/tests/ui/feature-gates/feature-gate-coroutines.rs
+++ b/tests/ui/feature-gates/feature-gate-coroutines.rs
@@ -1,5 +1,5 @@
 //@ revisions: e2024 none
-//@[e2024] compile-flags: --edition 2024 -Zunstable-options
+//@[e2024] edition: 2024
 
 fn main() {
     yield true; //~ ERROR yield syntax is experimental
diff --git a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
index 4836ffe1723..b596da8463f 100644
--- a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
+++ b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
@@ -5,7 +5,7 @@ LL |     let Ok(_x) = &foo();
    |         ^^^^^^ pattern `&Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `&Result<u32, !>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.rs b/tests/ui/feature-gates/feature-gate-gen_blocks.rs
index d9bfeac36ed..01fd922b0e9 100644
--- a/tests/ui/feature-gates/feature-gate-gen_blocks.rs
+++ b/tests/ui/feature-gates/feature-gate-gen_blocks.rs
@@ -1,5 +1,5 @@
 //@ revisions: e2024 none
-//@[e2024] compile-flags: --edition 2024 -Zunstable-options
+//@[e2024] edition: 2024
 
 fn test_gen() {
     gen {};
diff --git a/tests/ui/feature-gates/feature-gate-simd.rs b/tests/ui/feature-gates/feature-gate-simd.rs
index e7aef5a97f2..9a27cb73f00 100644
--- a/tests/ui/feature-gates/feature-gate-simd.rs
+++ b/tests/ui/feature-gates/feature-gate-simd.rs
@@ -1,5 +1,3 @@
-//@ pretty-expanded FIXME #23616
-
 #[repr(simd)] //~ ERROR SIMD types are experimental
 struct RGBA {
     rgba: [f32; 4],
diff --git a/tests/ui/feature-gates/feature-gate-simd.stderr b/tests/ui/feature-gates/feature-gate-simd.stderr
index b020db35a51..834baa0a564 100644
--- a/tests/ui/feature-gates/feature-gate-simd.stderr
+++ b/tests/ui/feature-gates/feature-gate-simd.stderr
@@ -1,5 +1,5 @@
 error[E0658]: SIMD types are experimental and possibly buggy
-  --> $DIR/feature-gate-simd.rs:3:1
+  --> $DIR/feature-gate-simd.rs:1:1
    |
 LL | #[repr(simd)]
    | ^^^^^^^^^^^^^
diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.rs b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs
new file mode 100644
index 00000000000..8f9b411df46
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs
@@ -0,0 +1,25 @@
+//@ compile-flags: --crate-type=lib
+//@ revisions: with_gate without_gate
+//@ [with_gate] check-pass
+
+#![cfg_attr(with_gate, feature(unsafe_fields))] //[with_gate]~ WARNING
+
+#[cfg(any())]
+struct Foo {
+    unsafe field: (), //[without_gate]~ ERROR
+}
+
+// This should not parse as an unsafe field definition.
+struct FooTuple(unsafe fn());
+
+#[cfg(any())]
+enum Bar {
+    Variant { unsafe field: () }, //[without_gate]~ ERROR
+    // This should not parse as an unsafe field definition.
+    VariantTuple(unsafe fn()),
+}
+
+#[cfg(any())]
+union Baz {
+    unsafe field: (), //[without_gate]~ ERROR
+}
diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr b/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr
new file mode 100644
index 00000000000..a7deeb057d8
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr
@@ -0,0 +1,11 @@
+warning: the feature `unsafe_fields` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/feature-gate-unsafe_fields.rs:5:32
+   |
+LL | #![cfg_attr(with_gate, feature(unsafe_fields))]
+   |                                ^^^^^^^^^^^^^
+   |
+   = note: see issue #132922 <https://github.com/rust-lang/rust/issues/132922> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr b/tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr
new file mode 100644
index 00000000000..ad0f5fd59ac
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr
@@ -0,0 +1,33 @@
+error[E0658]: `unsafe` fields are experimental
+  --> $DIR/feature-gate-unsafe_fields.rs:9:5
+   |
+LL |     unsafe field: (),
+   |     ^^^^^^
+   |
+   = note: see issue #132922 <https://github.com/rust-lang/rust/issues/132922> for more information
+   = help: add `#![feature(unsafe_fields)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `unsafe` fields are experimental
+  --> $DIR/feature-gate-unsafe_fields.rs:17:15
+   |
+LL |     Variant { unsafe field: () },
+   |               ^^^^^^
+   |
+   = note: see issue #132922 <https://github.com/rust-lang/rust/issues/132922> for more information
+   = help: add `#![feature(unsafe_fields)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `unsafe` fields are experimental
+  --> $DIR/feature-gate-unsafe_fields.rs:24:5
+   |
+LL |     unsafe field: (),
+   |     ^^^^^^
+   |
+   = note: see issue #132922 <https://github.com/rust-lang/rust/issues/132922> for more information
+   = help: add `#![feature(unsafe_fields)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/filter-block-view-items.rs b/tests/ui/filter-block-view-items.rs
index f582c51a3a6..975ab19ddf2 100644
--- a/tests/ui/filter-block-view-items.rs
+++ b/tests/ui/filter-block-view-items.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     // Make sure that this view item is filtered out because otherwise it would
diff --git a/tests/ui/fn/fn-item-type.stderr b/tests/ui/fn/fn-item-type.stderr
index 76cdbcceac8..5cc529543d2 100644
--- a/tests/ui/fn/fn-item-type.stderr
+++ b/tests/ui/fn/fn-item-type.stderr
@@ -17,7 +17,7 @@ LL | fn eq<T>(x: T, y: T) {}
    |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
    |       |  |
    |       |  `y` needs to match the fn item type of this parameter
-   |       `x` and `y` all reference this parameter T
+   |       `x` and `y` both reference this parameter `T`
    = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
 
 error[E0308]: mismatched types
@@ -39,7 +39,7 @@ LL | fn eq<T>(x: T, y: T) {}
    |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
    |       |  |
    |       |  `y` needs to match the fn item type of this parameter
-   |       `x` and `y` all reference this parameter T
+   |       `x` and `y` both reference this parameter `T`
    = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
 
 error[E0308]: mismatched types
@@ -61,7 +61,7 @@ LL | fn eq<T>(x: T, y: T) {}
    |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
    |       |  |
    |       |  `y` needs to match the fn item type of this parameter
-   |       `x` and `y` all reference this parameter T
+   |       `x` and `y` both reference this parameter `T`
    = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
 
 error[E0308]: mismatched types
@@ -83,7 +83,7 @@ LL | fn eq<T>(x: T, y: T) {}
    |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
    |       |  |
    |       |  `y` needs to match the fn item type of this parameter
-   |       `x` and `y` all reference this parameter T
+   |       `x` and `y` both reference this parameter `T`
    = help: consider casting both fn items to fn pointers using `as fn()`
 
 error[E0308]: mismatched types
@@ -105,7 +105,7 @@ LL | fn eq<T>(x: T, y: T) {}
    |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
    |       |  |
    |       |  `y` needs to match the fn item type of this parameter
-   |       `x` and `y` all reference this parameter T
+   |       `x` and `y` both reference this parameter `T`
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/fn/issue-1451.rs b/tests/ui/fn/issue-1451.rs
index 735b766bd0c..40b107ca7cc 100644
--- a/tests/ui/fn/issue-1451.rs
+++ b/tests/ui/fn/issue-1451.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 #![allow(non_snake_case)]
 #![allow(unused_variables)]
 
diff --git a/tests/ui/fn/param-mismatch-no-names.rs b/tests/ui/fn/param-mismatch-no-names.rs
new file mode 100644
index 00000000000..05f3de190ea
--- /dev/null
+++ b/tests/ui/fn/param-mismatch-no-names.rs
@@ -0,0 +1,8 @@
+fn same_type<T>(_: T, _: T) {}
+
+fn f<X, Y>(x: X, y: Y) {
+    same_type([x], Some(y));
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/fn/param-mismatch-no-names.stderr b/tests/ui/fn/param-mismatch-no-names.stderr
new file mode 100644
index 00000000000..d9d360d5ae4
--- /dev/null
+++ b/tests/ui/fn/param-mismatch-no-names.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+  --> $DIR/param-mismatch-no-names.rs:4:20
+   |
+LL |     same_type([x], Some(y));
+   |     --------- ---  ^^^^^^^ expected `[X; 1]`, found `Option<Y>`
+   |     |         |
+   |     |         expected all arguments to be this `[X; 1]` type because they need to match the type of this parameter
+   |     arguments to this function are incorrect
+   |
+   = note: expected array `[X; 1]`
+               found enum `Option<Y>`
+note: function defined here
+  --> $DIR/param-mismatch-no-names.rs:1:4
+   |
+LL | fn same_type<T>(_: T, _: T) {}
+   |    ^^^^^^^^^ -  ----  ---- this parameter needs to match the `[X; 1]` type of parameter #1
+   |              |  |
+   |              |  parameter #2 needs to match the `[X; 1]` type of this parameter
+   |              parameter #1 and parameter #2 both reference this parameter `T`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/for-loop-while/break-value.rs b/tests/ui/for-loop-while/break-value.rs
index 1289231fc30..eb9ccb21203 100644
--- a/tests/ui/for-loop-while/break-value.rs
+++ b/tests/ui/for-loop-while/break-value.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unreachable_code)]
-//@ pretty-expanded FIXME #23616
 
 fn int_id(x: isize) -> isize { return x; }
 
diff --git a/tests/ui/for-loop-while/issue-1257.rs b/tests/ui/for-loop-while/issue-1257.rs
index cdd4c806358..369302f9f12 100644
--- a/tests/ui/for-loop-while/issue-1257.rs
+++ b/tests/ui/for-loop-while/issue-1257.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main () {
   let mut line = "".to_string();
diff --git a/tests/ui/for-loop-while/labeled-break.rs b/tests/ui/for-loop-while/labeled-break.rs
index 0dfbdc02f5b..9c53350f227 100644
--- a/tests/ui/for-loop-while/labeled-break.rs
+++ b/tests/ui/for-loop-while/labeled-break.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     'foo: loop {
diff --git a/tests/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs b/tests/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs
index be6dc33c8be..31f2ecf2aff 100644
--- a/tests/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs
+++ b/tests/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_assignments)]
-//@ pretty-expanded FIXME #23616
 
 #![allow(unreachable_code)]
 #![allow(unused_variables)]
diff --git a/tests/ui/for-loop-while/liveness-move-in-loop.rs b/tests/ui/for-loop-while/liveness-move-in-loop.rs
index 0ae92a78a04..0c35479cf12 100644
--- a/tests/ui/for-loop-while/liveness-move-in-loop.rs
+++ b/tests/ui/for-loop-while/liveness-move-in-loop.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 
-//@ pretty-expanded FIXME #23616
 
 fn take(x: isize) -> isize {x}
 
diff --git a/tests/ui/for-loop-while/long-while.rs b/tests/ui/for-loop-while/long-while.rs
index 6db06baa873..5b9fbb10453 100644
--- a/tests/ui/for-loop-while/long-while.rs
+++ b/tests/ui/for-loop-while/long-while.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_variables)]
 
diff --git a/tests/ui/for-loop-while/loop-diverges.rs b/tests/ui/for-loop-while/loop-diverges.rs
index fdf46387795..77d15e3c321 100644
--- a/tests/ui/for-loop-while/loop-diverges.rs
+++ b/tests/ui/for-loop-while/loop-diverges.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_parens)]
-//@ pretty-expanded FIXME #23616
 
 /* Make sure a loop{} can be the tailexpr in the body
 of a diverging function */
diff --git a/tests/ui/for-loop-while/loop-label-shadowing.rs b/tests/ui/for-loop-while/loop-label-shadowing.rs
index e3dfbe65d8c..030da69cbb7 100644
--- a/tests/ui/for-loop-while/loop-label-shadowing.rs
+++ b/tests/ui/for-loop-while/loop-label-shadowing.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Issue #12512.
 
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let mut foo = Vec::new();
diff --git a/tests/ui/for-loop-while/loop-labeled-break-value.rs b/tests/ui/for-loop-while/loop-labeled-break-value.rs
index 0ab07ffd7e2..702bda1b90a 100644
--- a/tests/ui/for-loop-while/loop-labeled-break-value.rs
+++ b/tests/ui/for-loop-while/loop-labeled-break-value.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     'outer: loop {
diff --git a/tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs b/tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs
index 531c3dc377d..cf4474d815b 100644
--- a/tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs
+++ b/tests/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 struct S;
 // Ensure S is moved, not copied, on assignment.
diff --git a/tests/ui/for-loop-while/while-flow-graph.rs b/tests/ui/for-loop-while/while-flow-graph.rs
index 9148b42a606..e964d019588 100644
--- a/tests/ui/for-loop-while/while-flow-graph.rs
+++ b/tests/ui/for-loop-while/while-flow-graph.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() { let x: isize = 10; while x == 10 && x == 11 { let _y = 0xf00_usize; } }
diff --git a/tests/ui/foreign/foreign-mod-unused-const.rs b/tests/ui/foreign/foreign-mod-unused-const.rs
index 2cc0a4f6018..4e40f92fdd4 100644
--- a/tests/ui/foreign/foreign-mod-unused-const.rs
+++ b/tests/ui/foreign/foreign-mod-unused-const.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 mod foo {
     extern "C" {
diff --git a/tests/ui/foreign/foreign2.rs b/tests/ui/foreign/foreign2.rs
index 178a04255cc..a2f8385c845 100644
--- a/tests/ui/foreign/foreign2.rs
+++ b/tests/ui/foreign/foreign2.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 #![feature(rustc_private)]
diff --git a/tests/ui/foreign/nil-decl-in-foreign.rs b/tests/ui/foreign/nil-decl-in-foreign.rs
index 355278d99da..6adf08246e7 100644
--- a/tests/ui/foreign/nil-decl-in-foreign.rs
+++ b/tests/ui/foreign/nil-decl-in-foreign.rs
@@ -3,7 +3,6 @@
 #![allow(improper_ctypes)]
 #![allow(dead_code)]
 // Issue #901
-//@ pretty-expanded FIXME #23616
 
 mod libc {
     extern "C" {
diff --git a/tests/ui/fuel/optimization-fuel-0.rs b/tests/ui/fuel/optimization-fuel-0.rs
deleted file mode 100644
index cbcb1d329a3..00000000000
--- a/tests/ui/fuel/optimization-fuel-0.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ run-pass
-
-#![crate_name="foo"]
-
-use std::mem::size_of;
-
-//@ compile-flags: -Z fuel=foo=0
-
-#[allow(dead_code)]
-struct S1(u8, u16, u8);
-#[allow(dead_code)]
-struct S2(u8, u16, u8);
-
-fn main() {
-    assert_eq!(size_of::<S1>(), 6);
-    assert_eq!(size_of::<S2>(), 6);
-}
diff --git a/tests/ui/fuel/optimization-fuel-0.stderr b/tests/ui/fuel/optimization-fuel-0.stderr
deleted file mode 100644
index f0e2ebfc37a..00000000000
--- a/tests/ui/fuel/optimization-fuel-0.stderr
+++ /dev/null
@@ -1,4 +0,0 @@
-warning: optimization-fuel-exhausted: Reorder fields of "S1"
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/fuel/optimization-fuel-1.rs b/tests/ui/fuel/optimization-fuel-1.rs
deleted file mode 100644
index 97edb0bd259..00000000000
--- a/tests/ui/fuel/optimization-fuel-1.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-//@ run-pass
-
-#![crate_name="foo"]
-
-use std::mem::size_of;
-
-//@ compile-flags: -Z fuel=foo=1
-
-#[allow(dead_code)]
-struct S1(u8, u16, u8);
-#[allow(dead_code)]
-struct S2(u8, u16, u8);
-
-fn main() {
-    let optimized = (size_of::<S1>() == 4) as usize
-        +(size_of::<S2>() == 4) as usize;
-    assert_eq!(optimized, 1);
-}
diff --git a/tests/ui/fuel/optimization-fuel-1.stderr b/tests/ui/fuel/optimization-fuel-1.stderr
deleted file mode 100644
index 53eafb05830..00000000000
--- a/tests/ui/fuel/optimization-fuel-1.stderr
+++ /dev/null
@@ -1,4 +0,0 @@
-warning: optimization-fuel-exhausted: Reorder fields of "S2"
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/fuel/print-fuel.rs b/tests/ui/fuel/print-fuel.rs
deleted file mode 100644
index fd7e568bea7..00000000000
--- a/tests/ui/fuel/print-fuel.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-#![crate_name="foo"]
-#![allow(dead_code)]
-
-// (#55495: The --error-format is to sidestep an issue in our test harness)
-//@ compile-flags: -C opt-level=0 --error-format human -Z print-fuel=foo
-//@ check-pass
-
-struct S1(u8, u16, u8);
-struct S2(u8, u16, u8);
-struct S3(u8, u16, u8);
-
-fn main() {
-}
diff --git a/tests/ui/fuel/print-fuel.stderr b/tests/ui/fuel/print-fuel.stderr
deleted file mode 100644
index cc88cc077bb..00000000000
--- a/tests/ui/fuel/print-fuel.stderr
+++ /dev/null
@@ -1 +0,0 @@
-Fuel used by foo: 3
diff --git a/tests/ui/functions-closures/closure-bounds-can-capture-chan.rs b/tests/ui/functions-closures/closure-bounds-can-capture-chan.rs
index 4f38ea02d9c..318ca54ffd6 100644
--- a/tests/ui/functions-closures/closure-bounds-can-capture-chan.rs
+++ b/tests/ui/functions-closures/closure-bounds-can-capture-chan.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::sync::mpsc::channel;
 
diff --git a/tests/ui/functions-closures/fn-abi.rs b/tests/ui/functions-closures/fn-abi.rs
index d33158e8917..350132f0f55 100644
--- a/tests/ui/functions-closures/fn-abi.rs
+++ b/tests/ui/functions-closures/fn-abi.rs
@@ -2,7 +2,6 @@
 // Ensure that declarations and types which use `extern fn` both have the same
 // ABI (#9309).
 
-//@ pretty-expanded FIXME #23616
 //@ aux-build:fn-abi.rs
 
 extern crate fn_abi;
diff --git a/tests/ui/functions-closures/fn-bare-coerce-to-block.rs b/tests/ui/functions-closures/fn-bare-coerce-to-block.rs
index 18015a41564..9c80463d59e 100644
--- a/tests/ui/functions-closures/fn-bare-coerce-to-block.rs
+++ b/tests/ui/functions-closures/fn-bare-coerce-to-block.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn bare() {}
 
diff --git a/tests/ui/functions-closures/fn-coerce-field.rs b/tests/ui/functions-closures/fn-coerce-field.rs
index dd7be374c84..7a9e1e5e82c 100644
--- a/tests/ui/functions-closures/fn-coerce-field.rs
+++ b/tests/ui/functions-closures/fn-coerce-field.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 #![allow(non_camel_case_types)]
 
 struct r<F> where F: FnOnce() {
diff --git a/tests/ui/functions-closures/fn-item-type-coerce.rs b/tests/ui/functions-closures/fn-item-type-coerce.rs
index e858f9e9e19..a5a0a4995bf 100644
--- a/tests/ui/functions-closures/fn-item-type-coerce.rs
+++ b/tests/ui/functions-closures/fn-item-type-coerce.rs
@@ -2,7 +2,6 @@
 #![allow(unused_variables)]
 // Test implicit coercions from a fn item type to a fn pointer type.
 
-//@ pretty-expanded FIXME #23616
 
 fn foo(x: isize) -> isize { x * 2 }
 fn bar(x: isize) -> isize { x * 4 }
diff --git a/tests/ui/functions-closures/fn-lval.rs b/tests/ui/functions-closures/fn-lval.rs
index aa080f6b985..7b5e4d66517 100644
--- a/tests/ui/functions-closures/fn-lval.rs
+++ b/tests/ui/functions-closures/fn-lval.rs
@@ -2,7 +2,6 @@
 
 
 
-//@ pretty-expanded FIXME #23616
 
 fn foo(_f: fn(isize) -> isize) { }
 
diff --git a/tests/ui/functions-closures/fn-type-infer.rs b/tests/ui/functions-closures/fn-type-infer.rs
index b1624e476ef..eb9e5b10467 100644
--- a/tests/ui/functions-closures/fn-type-infer.rs
+++ b/tests/ui/functions-closures/fn-type-infer.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_variables)]
 
diff --git a/tests/ui/generic-associated-types/issue-71176.rs b/tests/ui/generic-associated-types/issue-71176.rs
index b33fda8e154..7fffe312f4b 100644
--- a/tests/ui/generic-associated-types/issue-71176.rs
+++ b/tests/ui/generic-associated-types/issue-71176.rs
@@ -16,6 +16,8 @@ struct Holder<B> {
 
 fn main() {
     Holder {
-        inner: Box::new(()), //~ ERROR: the trait `Provider` cannot be made into an object
+        inner: Box::new(()),
+        //~^ ERROR: the trait `Provider` cannot be made into an object
+        //~| ERROR: the trait `Provider` cannot be made into an object
     };
 }
diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr
index 15d5a3df6f2..1cd2ed0d313 100644
--- a/tests/ui/generic-associated-types/issue-71176.stderr
+++ b/tests/ui/generic-associated-types/issue-71176.stderr
@@ -80,7 +80,24 @@ LL |     type A<'a>;
    = help: consider moving `A` to another trait
    = help: only type `()` implements the trait, consider using it directly instead
 
-error: aborting due to 5 previous errors
+error[E0038]: the trait `Provider` cannot be made into an object
+  --> $DIR/issue-71176.rs:19:16
+   |
+LL |         inner: Box::new(()),
+   |                ^^^^^^^^^^^^ `Provider` cannot be made into an object
+   |
+note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-71176.rs:2:10
+   |
+LL | trait Provider {
+   |       -------- this trait cannot be made into an object...
+LL |     type A<'a>;
+   |          ^ ...because it contains the generic associated type `A`
+   = help: consider moving `A` to another trait
+   = help: only type `()` implements the trait, consider using it directly instead
+   = note: required for the cast from `Box<()>` to `Box<(dyn Provider<A<'_> = _> + 'static), {type error}>`
+
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0038, E0107.
 For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/generics/generic-default-type-params-cross-crate.rs b/tests/ui/generics/generic-default-type-params-cross-crate.rs
index 7da61572501..1b21e4cd191 100644
--- a/tests/ui/generics/generic-default-type-params-cross-crate.rs
+++ b/tests/ui/generics/generic-default-type-params-cross-crate.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:default_type_params_xc.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate default_type_params_xc;
 
diff --git a/tests/ui/generics/generic-fn-twice.rs b/tests/ui/generics/generic-fn-twice.rs
index f9e08401c6d..26d6f750c80 100644
--- a/tests/ui/generics/generic-fn-twice.rs
+++ b/tests/ui/generics/generic-fn-twice.rs
@@ -2,7 +2,6 @@
 
 
 
-//@ pretty-expanded FIXME #23616
 
 mod foomod {
     pub fn foo<T>() { }
diff --git a/tests/ui/generics/generic-newtype-struct.rs b/tests/ui/generics/generic-newtype-struct.rs
index a1d539c8c22..4cb481044f2 100644
--- a/tests/ui/generics/generic-newtype-struct.rs
+++ b/tests/ui/generics/generic-newtype-struct.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 struct S<T>(#[allow(dead_code)] T);
 
diff --git a/tests/ui/generics/generic-tag-corruption.rs b/tests/ui/generics/generic-tag-corruption.rs
index 78fdfe4ac7f..b7fd66a0523 100644
--- a/tests/ui/generics/generic-tag-corruption.rs
+++ b/tests/ui/generics/generic-tag-corruption.rs
@@ -3,7 +3,6 @@
 
 
 // This used to cause memory corruption in stage 0.
-//@ pretty-expanded FIXME #23616
 
 enum thing<K> { some(#[allow(dead_code)] K), }
 
diff --git a/tests/ui/generics/generic-tag-local.rs b/tests/ui/generics/generic-tag-local.rs
index e7c394efa09..025827783c3 100644
--- a/tests/ui/generics/generic-tag-local.rs
+++ b/tests/ui/generics/generic-tag-local.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 enum clam<T> { a(#[allow(dead_code)] T), }
 
diff --git a/tests/ui/generics/generic-tag.rs b/tests/ui/generics/generic-tag.rs
index cb46c3155a3..98350e93ece 100644
--- a/tests/ui/generics/generic-tag.rs
+++ b/tests/ui/generics/generic-tag.rs
@@ -2,7 +2,6 @@
 #![allow(unused_assignments)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_variables)]
 
diff --git a/tests/ui/generics/generic-type-synonym.rs b/tests/ui/generics/generic-type-synonym.rs
index 879bd91cab5..a8a946d5ed2 100644
--- a/tests/ui/generics/generic-type-synonym.rs
+++ b/tests/ui/generics/generic-type-synonym.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 
 
-//@ pretty-expanded FIXME #23616
 
 struct Foo<T> {
     a: T
diff --git a/tests/ui/generics/mid-path-type-params.rs b/tests/ui/generics/mid-path-type-params.rs
index f7dbd789079..5100e8e7353 100644
--- a/tests/ui/generics/mid-path-type-params.rs
+++ b/tests/ui/generics/mid-path-type-params.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 struct S<T> {
     contents: T,
diff --git a/tests/ui/generics/type-params-in-for-each.rs b/tests/ui/generics/type-params-in-for-each.rs
index e98f7bbb66b..004b7754887 100644
--- a/tests/ui/generics/type-params-in-for-each.rs
+++ b/tests/ui/generics/type-params-in-for-each.rs
@@ -2,7 +2,6 @@
 
 #![allow(dead_code)]
 
-//@ pretty-expanded FIXME #23616
 
 struct S<T> {
     a: T,
diff --git a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
index af11bc82d0c..65903dbe12e 100644
--- a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
+++ b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
@@ -15,7 +15,7 @@ LL |     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `[i32::MIN..=2_i32, ..]` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `[i32; 8]`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
index 0f60cd397b9..aa3d2cd2d90 100644
--- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
@@ -67,7 +67,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
index 204ee373bc5..63258f35383 100644
--- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
@@ -94,7 +94,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -108,7 +108,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
index e2916725fbd..62be2ef7a4d 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
@@ -4,7 +4,7 @@ error: expected a pattern range bound, found an expression
 LL |             0..5+1 => errors_only.push(x),
    |                ^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +         const VAL: /* Type */ = 5+1;
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
index f54e07c3a63..dbe7f4482ee 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
@@ -16,7 +16,7 @@ error: expected a pattern range bound, found an expression
 LL |             0..=(5+1) => errors_only.push(x),
    |                  ^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +         const VAL: /* Type */ = 5+1;
diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
index 49515919904..17b65c1dae5 100644
--- a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
+++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
@@ -15,7 +15,7 @@ LL |     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `[i32::MIN..=2_i32, ..]` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `[i32; 8]`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/higher-ranked/builtin-closure-like-bounds.rs b/tests/ui/higher-ranked/builtin-closure-like-bounds.rs
index dee290cc439..c177ee6fb3a 100644
--- a/tests/ui/higher-ranked/builtin-closure-like-bounds.rs
+++ b/tests/ui/higher-ranked/builtin-closure-like-bounds.rs
@@ -1,5 +1,4 @@
 //@ edition:2024
-//@ compile-flags: -Zunstable-options
 //@ revisions: current next
 //@[next] compile-flags: -Znext-solver
 //@ check-pass
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs
index 5dec55d5612..09f3f7845d9 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs
@@ -6,7 +6,6 @@
 // `&Typer<'tcx>` was getting an incorrect binder level, yielding
 // weird compilation ICEs and so forth.
 
-//@ pretty-expanded FIXME #23616
 
 trait Typer<'tcx> {
     fn method(&self, data: &'tcx isize) -> &'tcx isize { data }
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs
index f28b0776fda..745a2fcc4f0 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait Typer<'tcx> {
     fn method(&self, data: &'tcx isize) -> &'tcx isize { data }
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs
index 0edddf9423e..7ecba7301ef 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs
@@ -2,7 +2,6 @@
 // Test that we can parse all the various places that a `for` keyword
 // can appear representing universal quantification.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs
index b49c69d90cf..8c63dff8782 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 // Test that `F : Fn(isize) -> isize + Send` is interpreted as two
 // distinct bounds on `F`.
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs
index d50fd8cb8f3..2c8d3ac0d41 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 // Test that `Fn(isize) -> isize + 'static` parses as `(Fn(isize) -> isize) +
 // 'static` and not `Fn(isize) -> (isize + 'static)`. The latter would
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs
index 4a0b8362d4b..271eedae89a 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 // A basic test of using a higher-ranked trait bound.
 
-//@ pretty-expanded FIXME #23616
 
 trait FnLike<A,R> {
     fn call(&self, arg: A) -> R;
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs
index 255e5d68e50..7a75218da3a 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs
@@ -4,7 +4,6 @@
 // PrinterSupport<'b>`, gets properly expanded when it appears in a
 // closure type. This used to result in messed up De Bruijn indices.
 
-//@ pretty-expanded FIXME #23616
 
 trait PrinterSupport<'ast> {
     fn ast_map(&self) -> Option<&'ast usize> { None }
diff --git a/tests/ui/hygiene/issue-15221.rs b/tests/ui/hygiene/issue-15221.rs
index ebb1a234051..7703cb2de4e 100644
--- a/tests/ui/hygiene/issue-15221.rs
+++ b/tests/ui/hygiene/issue-15221.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(path_statements)]
-//@ pretty-expanded FIXME #23616
 
 macro_rules! inner {
     ($e:pat ) => ($e)
diff --git a/tests/ui/impl-privacy-xc-1.rs b/tests/ui/impl-privacy-xc-1.rs
index 1a2af8098f5..6a10986739c 100644
--- a/tests/ui/impl-privacy-xc-1.rs
+++ b/tests/ui/impl-privacy-xc-1.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:impl_privacy_xc_1.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate impl_privacy_xc_1;
 
diff --git a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
index 8716088ccbd..9ed3d21c13c 100644
--- a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
+++ b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
@@ -261,8 +261,11 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn bat() -> dyn Trait {
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: if there were a single returned type, you could use `impl Trait` instead
-help: box the return type, and wrap all of the returned values in `Box::new`
+help: consider returning an `impl Trait` instead of a `dyn Trait`
+   |
+LL | fn bat() -> impl Trait {
+   |             ~~~~
+help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
    |
 LL ~ fn bat() -> Box<dyn Trait> {
 LL |     if true {
@@ -277,8 +280,11 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn bay() -> dyn Trait {
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: if there were a single returned type, you could use `impl Trait` instead
-help: box the return type, and wrap all of the returned values in `Box::new`
+help: consider returning an `impl Trait` instead of a `dyn Trait`
+   |
+LL | fn bay() -> impl Trait {
+   |             ~~~~
+help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
    |
 LL ~ fn bay() -> Box<dyn Trait> {
 LL |     if true {
diff --git a/tests/ui/impl-trait/example-calendar.rs b/tests/ui/impl-trait/example-calendar.rs
index 1dadc5dfcb3..c3c01f01036 100644
--- a/tests/ui/impl-trait/example-calendar.rs
+++ b/tests/ui/impl-trait/example-calendar.rs
@@ -156,7 +156,7 @@ impl<'a, 'b> std::ops::Add<&'b NaiveDate> for &'a NaiveDate {
 }
 
 impl std::iter::Step for NaiveDate {
-    fn steps_between(_: &Self, _: &Self) -> Option<usize> {
+    fn steps_between(_: &Self, _: &Self) -> (usize, Option<usize>) {
         unimplemented!()
     }
 
diff --git a/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs
index 83466535e13..42b33c6e31d 100644
--- a/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs
+++ b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs
@@ -1,5 +1,5 @@
 // Test for issue #132429
-//@compile-flags: -Zunstable-options --edition=2024
+//@ edition: 2024
 //@check-pass
 
 use std::future::Future;
diff --git a/tests/ui/impl-trait/issues/issue-79099.stderr b/tests/ui/impl-trait/issues/issue-79099.stderr
index 6c26d5bd1b7..96825eabec7 100644
--- a/tests/ui/impl-trait/issues/issue-79099.stderr
+++ b/tests/ui/impl-trait/issues/issue-79099.stderr
@@ -6,7 +6,7 @@ LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
    |                                                         |
    |                                                         `async` blocks are only allowed in Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0562]: `impl Trait` is not allowed in the type of variable bindings
diff --git a/tests/ui/impl-trait/normalize-tait-in-const.rs b/tests/ui/impl-trait/normalize-tait-in-const.rs
index 134b202d655..1fd543b72e7 100644
--- a/tests/ui/impl-trait/normalize-tait-in-const.rs
+++ b/tests/ui/impl-trait/normalize-tait-in-const.rs
@@ -1,7 +1,7 @@
 //@ known-bug: #103507
 
 #![feature(type_alias_impl_trait)]
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, const_destruct)]
 
 use std::marker::Destruct;
 
diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr
index f9142664f1b..bb874cbe41b 100644
--- a/tests/ui/impl-trait/normalize-tait-in-const.stderr
+++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr
@@ -5,12 +5,6 @@ LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruc
    |                                   ^^^^^^
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/normalize-tait-in-const.rs:26:62
-   |
-LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
-   |                                                              ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/normalize-tait-in-const.rs:26:35
    |
 LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
@@ -18,13 +12,11 @@ LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruc
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/normalize-tait-in-const.rs:26:62
-   |
-LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
-   |                                                              ^^^^^^
+error[E0277]: the trait bound `for<'a, 'b> fn(&'a foo::Alias<'b>) {foo}: const Destruct` is not satisfied
+  --> $DIR/normalize-tait-in-const.rs:33:5
    |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+LL |     with_positive(foo);
+   |     ^^^^^^^^^^^^^^^^^^
 
 error[E0015]: cannot call non-const closure in constant functions
   --> $DIR/normalize-tait-in-const.rs:27:5
@@ -38,16 +30,7 @@ help: consider further restricting this bound
 LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct + ~const Fn(&foo::Alias<'_>)>(fun: F) {
    |                                                                              ++++++++++++++++++++++++++++
 
-error[E0493]: destructor of `F` cannot be evaluated at compile-time
-  --> $DIR/normalize-tait-in-const.rs:26:79
-   |
-LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
-   |                                                                               ^^^ the destructor for this type cannot be evaluated in constant functions
-LL |     fun(filter_positive());
-LL | }
-   | - value is dropped here
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0015, E0493.
+Some errors have detailed explanations: E0015, E0277.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
index caaac5434c5..6f0f287fe12 100644
--- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
+++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
@@ -74,7 +74,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/opaque-used-in-extraneous-argument.rs:20:5
    |
 LL |     open_parent(&old_path)
-   |     ^^^^^^^^^^^ --------- unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static`
+   |     ^^^^^^^^^^^ --------- unexpected argument of type `&impl Fn<{type error}> + FnOnce<{type error}, Output = {type error}> + 'static`
    |
 note: function defined here
   --> $DIR/opaque-used-in-extraneous-argument.rs:12:4
diff --git a/tests/ui/impl-trait/precise-capturing/auxiliary/foreign.rs b/tests/ui/impl-trait/precise-capturing/auxiliary/foreign.rs
index 49015bc48ba..09b7ef14e6b 100644
--- a/tests/ui/impl-trait/precise-capturing/auxiliary/foreign.rs
+++ b/tests/ui/impl-trait/precise-capturing/auxiliary/foreign.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 
 use std::fmt::Display;
 
diff --git a/tests/ui/impl-trait/precise-capturing/capturing-implicit.rs b/tests/ui/impl-trait/precise-capturing/capturing-implicit.rs
index 5ef8542d862..7b53b20ceff 100644
--- a/tests/ui/impl-trait/precise-capturing/capturing-implicit.rs
+++ b/tests/ui/impl-trait/precise-capturing/capturing-implicit.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 
 #![feature(rustc_attrs)]
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/impl-trait/precise-capturing/capturing-implicit.stderr b/tests/ui/impl-trait/precise-capturing/capturing-implicit.stderr
index b14ed20bd36..4d8c5cb40b4 100644
--- a/tests/ui/impl-trait/precise-capturing/capturing-implicit.stderr
+++ b/tests/ui/impl-trait/precise-capturing/capturing-implicit.stderr
@@ -1,5 +1,5 @@
 error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
-  --> $DIR/capturing-implicit.rs:8:11
+  --> $DIR/capturing-implicit.rs:7:11
    |
 LL | fn foo(x: &()) -> impl IntoIterator<Item = impl Sized> + use<> {
    |           ^       -------------------------------------------- lifetime captured due to being mentioned in the bounds of the `impl Trait`
@@ -7,13 +7,13 @@ LL | fn foo(x: &()) -> impl IntoIterator<Item = impl Sized> + use<> {
    |           this lifetime parameter is captured
 
 error: ['_: o]
-  --> $DIR/capturing-implicit.rs:8:19
+  --> $DIR/capturing-implicit.rs:7:19
    |
 LL | fn foo(x: &()) -> impl IntoIterator<Item = impl Sized> + use<> {
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: ['_: o]
-  --> $DIR/capturing-implicit.rs:8:44
+  --> $DIR/capturing-implicit.rs:7:44
    |
 LL | fn foo(x: &()) -> impl IntoIterator<Item = impl Sized> + use<> {
    |                                            ^^^^^^^^^^
diff --git a/tests/ui/impl-trait/precise-capturing/external-macro.rs b/tests/ui/impl-trait/precise-capturing/external-macro.rs
index 492e8036461..87bad7455eb 100644
--- a/tests/ui/impl-trait/precise-capturing/external-macro.rs
+++ b/tests/ui/impl-trait/precise-capturing/external-macro.rs
@@ -5,7 +5,6 @@
 //@ aux-crate: no_use_pm=no-use-pm.rs
 //@ aux-crate: no_use_macro=no-use-macro.rs
 //@ edition: 2024
-//@ compile-flags:-Z unstable-options
 //@ check-pass
 
 no_use_pm::pm_rpit!{}
diff --git a/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr b/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr
index 2a17ef72912..cd9ed0fb885 100644
--- a/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr
+++ b/tests/ui/impl-trait/precise-capturing/foreign-2021.stderr
@@ -16,7 +16,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
 LL |     let h = foreign::hello(&x);
    |             ^^^^^^^^^^^^^^^^^^
 help: if you can modify this crate, add a precise capturing bound to avoid overcapturing: `+ use<>`
-  --> $DIR/auxiliary/foreign.rs:6:31
+  --> $DIR/auxiliary/foreign.rs:5:31
    |
 LL | pub fn hello(x: &Vec<i32>) -> impl Display { 0 }
    |                               ^^^^^^^^^^^^
diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.rs b/tests/ui/impl-trait/precise-capturing/migration-note.rs
index 1d98750f6dd..36db07e5764 100644
--- a/tests/ui/impl-trait/precise-capturing/migration-note.rs
+++ b/tests/ui/impl-trait/precise-capturing/migration-note.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 
 use std::fmt::Display;
 
diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.stderr b/tests/ui/impl-trait/precise-capturing/migration-note.stderr
index a859a114dbc..c9403532dfa 100644
--- a/tests/ui/impl-trait/precise-capturing/migration-note.stderr
+++ b/tests/ui/impl-trait/precise-capturing/migration-note.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `x` does not live long enough
-  --> $DIR/migration-note.rs:183:17
+  --> $DIR/migration-note.rs:182:17
    |
 LL |     let x = vec![0];
    |         - binding `x` declared here
@@ -14,7 +14,7 @@ LL | }
    | - `x` dropped here while still borrowed
 
 error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
-  --> $DIR/migration-note.rs:20:5
+  --> $DIR/migration-note.rs:19:5
    |
 LL |     let a = display_len(&x);
    |                         -- immutable borrow occurs here
@@ -26,7 +26,7 @@ LL |     println!("{a}");
    |               --- immutable borrow later used here
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:17:13
+  --> $DIR/migration-note.rs:16:13
    |
 LL |     let a = display_len(&x);
    |             ^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
 
 error[E0597]: `x` does not live long enough
-  --> $DIR/migration-note.rs:30:25
+  --> $DIR/migration-note.rs:29:25
    |
 LL |     let x = vec![1];
    |         - binding `x` declared here
@@ -51,7 +51,7 @@ LL | }
    | - `x` dropped here while still borrowed
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:30:13
+  --> $DIR/migration-note.rs:29:13
    |
 LL |     let a = display_len(&x);
    |             ^^^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
 
 error[E0505]: cannot move out of `x` because it is borrowed
-  --> $DIR/migration-note.rs:49:8
+  --> $DIR/migration-note.rs:48:8
    |
 LL |     let x = vec![1];
    |         - binding `x` declared here
@@ -76,7 +76,7 @@ LL | }
    | - borrow might be used here, when `a` is dropped and runs the destructor for type `impl std::fmt::Display`
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:44:13
+  --> $DIR/migration-note.rs:43:13
    |
 LL |     let a = display_len(&x);
    |             ^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL |     let a = display_len(&x.clone());
    |                           ++++++++
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time
-  --> $DIR/migration-note.rs:67:5
+  --> $DIR/migration-note.rs:66:5
    |
 LL |     let a = display_len_mut(&mut x);
    |                             ------ first mutable borrow occurs here
@@ -102,7 +102,7 @@ LL |     println!("{a}");
    |               --- first borrow later used here
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:64:13
+  --> $DIR/migration-note.rs:63:13
    |
 LL |     let a = display_len_mut(&mut x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -112,7 +112,7 @@ LL | fn display_len_mut<T>(x: &mut Vec<T>) -> impl Display + use<T> {
    |                                                       ++++++++
 
 error[E0597]: `x` does not live long enough
-  --> $DIR/migration-note.rs:77:29
+  --> $DIR/migration-note.rs:76:29
    |
 LL |     let mut x = vec![1];
    |         ----- binding `x` declared here
@@ -127,7 +127,7 @@ LL | }
    | - `x` dropped here while still borrowed
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:77:13
+  --> $DIR/migration-note.rs:76:13
    |
 LL |     let a = display_len_mut(&mut x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -137,7 +137,7 @@ LL | fn display_len_mut<T>(x: &mut Vec<T>) -> impl Display + use<T> {
    |                                                       ++++++++
 
 error[E0505]: cannot move out of `x` because it is borrowed
-  --> $DIR/migration-note.rs:96:8
+  --> $DIR/migration-note.rs:95:8
    |
 LL |     let mut x = vec![1];
    |         ----- binding `x` declared here
@@ -152,7 +152,7 @@ LL | }
    | - borrow might be used here, when `a` is dropped and runs the destructor for type `impl std::fmt::Display`
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:91:13
+  --> $DIR/migration-note.rs:90:13
    |
 LL |     let a = display_len_mut(&mut x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -166,7 +166,7 @@ LL |     let a = display_len_mut(&mut x.clone());
    |                                   ++++++++
 
 error[E0506]: cannot assign to `s.f` because it is borrowed
-  --> $DIR/migration-note.rs:116:5
+  --> $DIR/migration-note.rs:115:5
    |
 LL |     let a = display_field(&s.f);
    |                           ---- `s.f` is borrowed here
@@ -178,7 +178,7 @@ LL |     println!("{a}");
    |               --- borrow later used here
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:113:13
+  --> $DIR/migration-note.rs:112:13
    |
 LL |     let a = display_field(&s.f);
    |             ^^^^^^^^^^^^^^^^^^^
@@ -188,7 +188,7 @@ LL | fn display_field<T: Copy + Display>(t: &T) -> impl Display + use<T> {
    |                                                            ++++++++
 
 error[E0506]: cannot assign to `s.f` because it is borrowed
-  --> $DIR/migration-note.rs:132:5
+  --> $DIR/migration-note.rs:131:5
    |
 LL |     let a = display_field(&mut s.f);
    |                           -------- `s.f` is borrowed here
@@ -200,7 +200,7 @@ LL |     println!("{a}");
    |               --- borrow later used here
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:129:13
+  --> $DIR/migration-note.rs:128:13
    |
 LL |     let a = display_field(&mut s.f);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -210,7 +210,7 @@ LL | fn display_field<T: Copy + Display>(t: &T) -> impl Display + use<T> {
    |                                                            ++++++++
 
 error[E0503]: cannot use `s.f` because it was mutably borrowed
-  --> $DIR/migration-note.rs:144:5
+  --> $DIR/migration-note.rs:143:5
    |
 LL |     let a = display_field(&mut s.f);
    |                           -------- `s.f` is borrowed here
@@ -222,7 +222,7 @@ LL |     println!("{a}");
    |               --- borrow later used here
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:141:13
+  --> $DIR/migration-note.rs:140:13
    |
 LL |     let a = display_field(&mut s.f);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -232,7 +232,7 @@ LL | fn display_field<T: Copy + Display>(t: &T) -> impl Display + use<T> {
    |                                                            ++++++++
 
 error[E0597]: `z.f` does not live long enough
-  --> $DIR/migration-note.rs:160:25
+  --> $DIR/migration-note.rs:159:25
    |
 LL |         let z = Z { f: vec![1] };
    |             - binding `z` declared here
@@ -248,7 +248,7 @@ LL | }
    |
    = note: values in a scope are dropped in the opposite order they are defined
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:160:13
+  --> $DIR/migration-note.rs:159:13
    |
 LL |         x = display_len(&z.f);
    |             ^^^^^^^^^^^^^^^^^
@@ -258,7 +258,7 @@ LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/migration-note.rs:171:40
+  --> $DIR/migration-note.rs:170:40
    |
 LL |     let x = { let x = display_len(&mut vec![0]); x };
    |                                        ^^^^^^^ - - borrow later used here
@@ -268,7 +268,7 @@ LL |     let x = { let x = display_len(&mut vec![0]); x };
    |
    = note: consider using a `let` binding to create a longer lived value
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:171:23
+  --> $DIR/migration-note.rs:170:23
    |
 LL |     let x = { let x = display_len(&mut vec![0]); x };
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +279,7 @@ LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
 
 error[E0505]: cannot move out of `x` because it is borrowed
-  --> $DIR/migration-note.rs:199:10
+  --> $DIR/migration-note.rs:198:10
    |
 LL |     let x = String::new();
    |         - binding `x` declared here
@@ -294,12 +294,12 @@ LL | }
    | - borrow might be used here, when `y` is dropped and runs the destructor for type `impl Sized`
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:196:13
+  --> $DIR/migration-note.rs:195:13
    |
 LL |     let y = capture_apit(&x);
    |             ^^^^^^^^^^^^^^^^
 note: you could use a `use<...>` bound to explicitly specify captures, but argument-position `impl Trait`s are not nameable
-  --> $DIR/migration-note.rs:190:21
+  --> $DIR/migration-note.rs:189:21
    |
 LL | fn capture_apit(x: &impl Sized) -> impl Sized {}
    |                     ^^^^^^^^^^
diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rs b/tests/ui/impl-trait/precise-capturing/redundant.rs
index e19d935f5b0..075d7c70ac6 100644
--- a/tests/ui/impl-trait/precise-capturing/redundant.rs
+++ b/tests/ui/impl-trait/precise-capturing/redundant.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -Zunstable-options --edition=2024
+//@ edition: 2024
 //@ check-pass
 
 #![feature(precise_capturing_in_traits)]
diff --git a/tests/ui/impl-trait/transmute/in-defining-scope.rs b/tests/ui/impl-trait/transmute/in-defining-scope.rs
index b9a9dbc10a5..4c8e1852a91 100644
--- a/tests/ui/impl-trait/transmute/in-defining-scope.rs
+++ b/tests/ui/impl-trait/transmute/in-defining-scope.rs
@@ -1,5 +1,5 @@
-// This causes a query cycle due to using `Reveal::All`,
-// in #119821 const eval was changed to always use `Reveal::All`
+// This causes a query cycle due to using `TypingEnv::PostAnalysis`,
+// in #119821 const eval was changed to always use this mode.
 //
 // See that PR for more details.
 use std::mem::transmute;
diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr
index 4cebd26a5be..bea5ddb0aef 100644
--- a/tests/ui/impl-trait/unsized_coercion.next.stderr
+++ b/tests/ui/impl-trait/unsized_coercion.next.stderr
@@ -1,35 +1,11 @@
 error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
-  --> $DIR/unsized_coercion.rs:15:17
+  --> $DIR/unsized_coercion.rs:14:17
    |
 LL |         let x = hello();
    |                 ^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `dyn Trait`
 
-error[E0308]: mismatched types
-  --> $DIR/unsized_coercion.rs:19:5
-   |
-LL | fn hello() -> Box<impl Trait> {
-   |               ---------------
-   |               |   |
-   |               |   the expected opaque type
-   |               expected `Box<impl Trait>` because of return type
-...
-LL |     Box::new(1u32)
-   |     ^^^^^^^^^^^^^^ types differ
-   |
-   = note: expected struct `Box<impl Trait>`
-              found struct `Box<u32>`
-
-error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
-  --> $DIR/unsized_coercion.rs:12:1
-   |
-LL | fn hello() -> Box<impl Trait> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `dyn Trait`
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0308.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/unsized_coercion.rs b/tests/ui/impl-trait/unsized_coercion.rs
index b3791b38abc..2cbf0d25d7e 100644
--- a/tests/ui/impl-trait/unsized_coercion.rs
+++ b/tests/ui/impl-trait/unsized_coercion.rs
@@ -10,13 +10,12 @@ trait Trait {}
 impl Trait for u32 {}
 
 fn hello() -> Box<impl Trait> {
-    //[next]~^ ERROR the size for values of type `dyn Trait` cannot be known at compilation time
     if true {
         let x = hello();
         //[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time
         let y: Box<dyn Trait> = x;
     }
-    Box::new(1u32) //[next]~ ERROR: mismatched types
+    Box::new(1u32)
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr
index d1e1809cf16..28771e01813 100644
--- a/tests/ui/impl-trait/unsized_coercion3.next.stderr
+++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr
@@ -1,35 +1,11 @@
 error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
-  --> $DIR/unsized_coercion3.rs:14:17
+  --> $DIR/unsized_coercion3.rs:13:17
    |
 LL |         let x = hello();
    |                 ^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
    |
    = help: the trait `Trait` is implemented for `u32`
 
-error[E0308]: mismatched types
-  --> $DIR/unsized_coercion3.rs:19:5
-   |
-LL | fn hello() -> Box<impl Trait + ?Sized> {
-   |               ------------------------
-   |               |   |
-   |               |   the expected opaque type
-   |               expected `Box<impl Trait + ?Sized>` because of return type
-...
-LL |     Box::new(1u32)
-   |     ^^^^^^^^^^^^^^ types differ
-   |
-   = note: expected struct `Box<impl Trait + ?Sized>`
-              found struct `Box<u32>`
-
-error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
-  --> $DIR/unsized_coercion3.rs:11:1
-   |
-LL | fn hello() -> Box<impl Trait + ?Sized> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
-   |
-   = help: the trait `Trait` is implemented for `u32`
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0308.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/unsized_coercion3.old.stderr b/tests/ui/impl-trait/unsized_coercion3.old.stderr
index 3bb9f9c2095..52a72b84a8d 100644
--- a/tests/ui/impl-trait/unsized_coercion3.old.stderr
+++ b/tests/ui/impl-trait/unsized_coercion3.old.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
-  --> $DIR/unsized_coercion3.rs:16:32
+  --> $DIR/unsized_coercion3.rs:15:32
    |
 LL |         let y: Box<dyn Send> = x;
    |                                ^ doesn't have a size known at compile-time
diff --git a/tests/ui/impl-trait/unsized_coercion3.rs b/tests/ui/impl-trait/unsized_coercion3.rs
index c1dd5350e22..ebfbb2955de 100644
--- a/tests/ui/impl-trait/unsized_coercion3.rs
+++ b/tests/ui/impl-trait/unsized_coercion3.rs
@@ -9,7 +9,6 @@ trait Trait {}
 impl Trait for u32 {}
 
 fn hello() -> Box<impl Trait + ?Sized> {
-    //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
     if true {
         let x = hello();
         //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
@@ -17,7 +16,6 @@ fn hello() -> Box<impl Trait + ?Sized> {
         //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
     }
     Box::new(1u32)
-    //[next]~^ ERROR: mismatched types
 }
 
 fn main() {}
diff --git a/tests/ui/imports/export-glob-imports-target.rs b/tests/ui/imports/export-glob-imports-target.rs
index 0133e8a94b5..6fde9fef0b6 100644
--- a/tests/ui/imports/export-glob-imports-target.rs
+++ b/tests/ui/imports/export-glob-imports-target.rs
@@ -7,7 +7,6 @@
 
 // Modified to not use export since it's going away. --pcw
 
-//@ pretty-expanded FIXME #23616
 
 mod foo {
     use foo::bar::*;
diff --git a/tests/ui/imports/export-multi.rs b/tests/ui/imports/export-multi.rs
index b52e952f33c..4f7f7d3a6c0 100644
--- a/tests/ui/imports/export-multi.rs
+++ b/tests/ui/imports/export-multi.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use m::f;
 use m::g;
diff --git a/tests/ui/imports/import-crate-with-invalid-spans/main.rs b/tests/ui/imports/import-crate-with-invalid-spans/main.rs
index 3234cf304f7..ed042f74f3f 100644
--- a/tests/ui/imports/import-crate-with-invalid-spans/main.rs
+++ b/tests/ui/imports/import-crate-with-invalid-spans/main.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:crate_with_invalid_spans.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate crate_with_invalid_spans;
 
diff --git a/tests/ui/imports/import-from.rs b/tests/ui/imports/import-from.rs
index c5ff4b3abc6..128002e0e2a 100644
--- a/tests/ui/imports/import-from.rs
+++ b/tests/ui/imports/import-from.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use spam::{ham, eggs};
 
diff --git a/tests/ui/imports/import-in-block.rs b/tests/ui/imports/import-in-block.rs
index c17e2cffa51..2588ea77023 100644
--- a/tests/ui/imports/import-in-block.rs
+++ b/tests/ui/imports/import-in-block.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     use std::mem::replace;
diff --git a/tests/ui/imports/import-trailing-comma.rs b/tests/ui/imports/import-trailing-comma.rs
index 3803b56487f..4147357a22b 100644
--- a/tests/ui/imports/import-trailing-comma.rs
+++ b/tests/ui/imports/import-trailing-comma.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use foo::bar::{baz, quux,};
 
diff --git a/tests/ui/imports/reexport-star.rs b/tests/ui/imports/reexport-star.rs
index 3e41f12fa2d..461dc23b4dc 100644
--- a/tests/ui/imports/reexport-star.rs
+++ b/tests/ui/imports/reexport-star.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 mod a {
     pub fn f() {}
diff --git a/tests/ui/imports/use-mod.rs b/tests/ui/imports/use-mod.rs
index 065079b21e5..cabea16e725 100644
--- a/tests/ui/imports/use-mod.rs
+++ b/tests/ui/imports/use-mod.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(unused_imports)]
-//@ pretty-expanded FIXME #23616
 
 pub use foo::bar::{self, First};
 use self::bar::Second;
diff --git a/tests/ui/inference/array-len-mismatch.stderr b/tests/ui/inference/array-len-mismatch.stderr
index 7358e478397..7146e3803d5 100644
--- a/tests/ui/inference/array-len-mismatch.stderr
+++ b/tests/ui/inference/array-len-mismatch.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/array-len-mismatch.rs:6:26
    |
 LL |     let wrong: [u8; 3] = [10, 20];
-   |                -------   ^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+   |                -------   ^^^^^^^^ expected an array with a size of 3, found one with a size of 2
    |                |    |
    |                |    help: consider specifying the actual array length: `2`
    |                expected due to this
@@ -11,7 +11,7 @@ error[E0308]: mismatched types
   --> $DIR/array-len-mismatch.rs:9:26
    |
 LL |     let wrong: [u8; 3] = returns_arr();
-   |                -------   ^^^^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+   |                -------   ^^^^^^^^^^^^^ expected an array with a size of 3, found one with a size of 2
    |                |    |
    |                |    help: consider specifying the actual array length: `2`
    |                expected due to this
diff --git a/tests/ui/inference/infer-fn-tail-expr.rs b/tests/ui/inference/infer-fn-tail-expr.rs
index 31b71e49bd6..e97522ed526 100644
--- a/tests/ui/inference/infer-fn-tail-expr.rs
+++ b/tests/ui/inference/infer-fn-tail-expr.rs
@@ -4,7 +4,6 @@
 // issue #680
 
 
-//@ pretty-expanded FIXME #23616
 
 fn f() -> Vec<isize> { Vec::new() }
 
diff --git a/tests/ui/inference/newlambdas-ret-infer.rs b/tests/ui/inference/newlambdas-ret-infer.rs
index 893b62e967d..980a2fdd905 100644
--- a/tests/ui/inference/newlambdas-ret-infer.rs
+++ b/tests/ui/inference/newlambdas-ret-infer.rs
@@ -4,7 +4,6 @@
 // Test that the lambda kind is inferred correctly as a return
 // expression
 
-//@ pretty-expanded FIXME #23616
 
 fn unique() -> Box<dyn FnMut()+'static> { return Box::new(|| ()); }
 
diff --git a/tests/ui/inference/newlambdas-ret-infer2.rs b/tests/ui/inference/newlambdas-ret-infer2.rs
index cad8b02910b..40d45d3569c 100644
--- a/tests/ui/inference/newlambdas-ret-infer2.rs
+++ b/tests/ui/inference/newlambdas-ret-infer2.rs
@@ -4,7 +4,6 @@
 // Test that the lambda kind is inferred correctly as a return
 // expression
 
-//@ pretty-expanded FIXME #23616
 
 fn unique() -> Box<dyn FnMut()+'static> { Box::new(|| ()) }
 
diff --git a/tests/ui/invalid-compile-flags/fuel.rs b/tests/ui/invalid-compile-flags/fuel.rs
deleted file mode 100644
index 855aa858122..00000000000
--- a/tests/ui/invalid-compile-flags/fuel.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ revisions: incremental threads
-//@ dont-check-compiler-stderr
-//
-//@ [threads] compile-flags: -Zfuel=a=1 -Zthreads=2
-//@ [threads] error-pattern:optimization fuel is incompatible with multiple threads
-//
-//@ [incremental] incremental
-//@ [incremental] compile-flags: -Zprint-fuel=a
-//@ [incremental] error-pattern:optimization fuel is incompatible with incremental compilation
-
-fn main() {}
diff --git a/tests/ui/issue-15924.rs b/tests/ui/issue-15924.rs
index 77e1ae697c5..eb2aef9cee1 100644
--- a/tests/ui/issue-15924.rs
+++ b/tests/ui/issue-15924.rs
@@ -2,7 +2,6 @@
 
 #![allow(unused_imports)]
 #![allow(unused_must_use)]
-//@ pretty-expanded FIXME #23616
 
 use std::fmt;
 use std::marker::PhantomData;
diff --git a/tests/ui/issues/issue-10228.rs b/tests/ui/issues/issue-10228.rs
index 7934afc7b9b..a59ccf926f9 100644
--- a/tests/ui/issues/issue-10228.rs
+++ b/tests/ui/issues/issue-10228.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 enum StdioContainer {
     CreatePipe(bool)
diff --git a/tests/ui/issues/issue-10456.rs b/tests/ui/issues/issue-10456.rs
index a43cc5d36f1..51c740fd729 100644
--- a/tests/ui/issues/issue-10456.rs
+++ b/tests/ui/issues/issue-10456.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 pub struct Foo;
 
diff --git a/tests/ui/issues/issue-10638.rs b/tests/ui/issues/issue-10638.rs
index f82023f2da5..c6c6939bda5 100644
--- a/tests/ui/issues/issue-10638.rs
+++ b/tests/ui/issues/issue-10638.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     //// I am not a doc comment!
diff --git a/tests/ui/issues/issue-10683.rs b/tests/ui/issues/issue-10683.rs
index 675a8323fc4..5657ec1864b 100644
--- a/tests/ui/issues/issue-10683.rs
+++ b/tests/ui/issues/issue-10683.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 static NAME: &'static str = "hello world";
 
diff --git a/tests/ui/issues/issue-10718.rs b/tests/ui/issues/issue-10718.rs
index 5d3cf2621ac..68ac0bbe49f 100644
--- a/tests/ui/issues/issue-10718.rs
+++ b/tests/ui/issues/issue-10718.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn f<F:FnOnce()>(p: F) {
     p();
diff --git a/tests/ui/issues/issue-10767.rs b/tests/ui/issues/issue-10767.rs
index 7d74f1e9017..2060d15b4c7 100644
--- a/tests/ui/issues/issue-10767.rs
+++ b/tests/ui/issues/issue-10767.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     fn f() {
diff --git a/tests/ui/issues/issue-10806.rs b/tests/ui/issues/issue-10806.rs
index 731edc8335d..72d99ae3a79 100644
--- a/tests/ui/issues/issue-10806.rs
+++ b/tests/ui/issues/issue-10806.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_imports)]
 
-//@ pretty-expanded FIXME #23616
 
 pub fn foo() -> isize {
     3
diff --git a/tests/ui/issues/issue-10853.rs b/tests/ui/issues/issue-10853.rs
index 0b0bcb710ad..4c22393d9c0 100644
--- a/tests/ui/issues/issue-10853.rs
+++ b/tests/ui/issues/issue-10853.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 #![deny(missing_docs)]
 #![doc="module"]
diff --git a/tests/ui/issues/issue-10902.rs b/tests/ui/issues/issue-10902.rs
index 72f08ec3f94..7cdf8808aa0 100644
--- a/tests/ui/issues/issue-10902.rs
+++ b/tests/ui/issues/issue-10902.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub mod two_tuple {
     pub trait T { fn dummy(&self) { } }
diff --git a/tests/ui/issues/issue-11085.rs b/tests/ui/issues/issue-11085.rs
index f646ba35cbf..d0703b06395 100644
--- a/tests/ui/issues/issue-11085.rs
+++ b/tests/ui/issues/issue-11085.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/issues/issue-11205.rs b/tests/ui/issues/issue-11205.rs
index f21a52050ff..8530514f0ed 100644
--- a/tests/ui/issues/issue-11205.rs
+++ b/tests/ui/issues/issue-11205.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/issues/issue-11224.rs b/tests/ui/issues/issue-11224.rs
index 3a504604b6a..a7255e6299f 100644
--- a/tests/ui/issues/issue-11224.rs
+++ b/tests/ui/issues/issue-11224.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-11224.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_11224 as unused;
 
diff --git a/tests/ui/issues/issue-11384.rs b/tests/ui/issues/issue-11384.rs
index 0d1cce71958..ad0affa4b0d 100644
--- a/tests/ui/issues/issue-11384.rs
+++ b/tests/ui/issues/issue-11384.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Common { fn dummy(&self) { } }
 
diff --git a/tests/ui/issues/issue-11529.rs b/tests/ui/issues/issue-11529.rs
index db7ff85d46b..73940c22be4 100644
--- a/tests/ui/issues/issue-11529.rs
+++ b/tests/ui/issues/issue-11529.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-11529.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_11529 as a;
 
diff --git a/tests/ui/issues/issue-11820.rs b/tests/ui/issues/issue-11820.rs
index 372ce2c2a16..ada844f8ee1 100644
--- a/tests/ui/issues/issue-11820.rs
+++ b/tests/ui/issues/issue-11820.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(noop_method_call)]
 
diff --git a/tests/ui/issues/issue-11869.rs b/tests/ui/issues/issue-11869.rs
index 606a0c7b9d9..dd752227bbe 100644
--- a/tests/ui/issues/issue-11869.rs
+++ b/tests/ui/issues/issue-11869.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 struct A {
     a: String
diff --git a/tests/ui/issues/issue-12612.rs b/tests/ui/issues/issue-12612.rs
index 0ffe7422fb3..ec0f3926aa5 100644
--- a/tests/ui/issues/issue-12612.rs
+++ b/tests/ui/issues/issue-12612.rs
@@ -3,7 +3,6 @@
 //@ aux-build:issue-12612-1.rs
 //@ aux-build:issue-12612-2.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_12612_1 as foo;
 extern crate issue_12612_2 as bar;
diff --git a/tests/ui/issues/issue-12660.rs b/tests/ui/issues/issue-12660.rs
index 997c10ae5cf..3aa3426519a 100644
--- a/tests/ui/issues/issue-12660.rs
+++ b/tests/ui/issues/issue-12660.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-12660-aux.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue12660aux;
 
diff --git a/tests/ui/issues/issue-12729.rs b/tests/ui/issues/issue-12729.rs
index 43e692b895a..74014981df5 100644
--- a/tests/ui/issues/issue-12729.rs
+++ b/tests/ui/issues/issue-12729.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub struct Foo;
 
diff --git a/tests/ui/issues/issue-12909.rs b/tests/ui/issues/issue-12909.rs
index 3af8c07d7a7..f2c33806aae 100644
--- a/tests/ui/issues/issue-12909.rs
+++ b/tests/ui/issues/issue-12909.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 use std::collections::HashMap;
 
diff --git a/tests/ui/issues/issue-13105.rs b/tests/ui/issues/issue-13105.rs
index 1ef9a6b7e33..0dd78372a26 100644
--- a/tests/ui/issues/issue-13105.rs
+++ b/tests/ui/issues/issue-13105.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Foo {
     #[allow(anonymous_parameters)]
diff --git a/tests/ui/issues/issue-13167.rs b/tests/ui/issues/issue-13167.rs
index 15ee02b9cd4..5f733e85948 100644
--- a/tests/ui/issues/issue-13167.rs
+++ b/tests/ui/issues/issue-13167.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 //@ revisions: current next
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
diff --git a/tests/ui/issues/issue-13214.rs b/tests/ui/issues/issue-13214.rs
index 7144094d8c2..8140ec943a0 100644
--- a/tests/ui/issues/issue-13214.rs
+++ b/tests/ui/issues/issue-13214.rs
@@ -3,7 +3,6 @@
 // defining static with struct that contains enum
 // with &'static str variant used to cause ICE
 
-//@ pretty-expanded FIXME #23616
 
 pub enum Foo {
     Bar,
diff --git a/tests/ui/issues/issue-13405.rs b/tests/ui/issues/issue-13405.rs
index b2b26ab39c5..80b298d2f37 100644
--- a/tests/ui/issues/issue-13405.rs
+++ b/tests/ui/issues/issue-13405.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 struct Foo<'a> {
     i: &'a bool,
diff --git a/tests/ui/issues/issue-13620.rs b/tests/ui/issues/issue-13620.rs
index 0225114e6c3..4d9db3aa7ce 100644
--- a/tests/ui/issues/issue-13620.rs
+++ b/tests/ui/issues/issue-13620.rs
@@ -2,7 +2,6 @@
 //@ aux-build:issue-13620-1.rs
 //@ aux-build:issue-13620-2.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_13620_2 as crate2;
 
diff --git a/tests/ui/issues/issue-13665.rs b/tests/ui/issues/issue-13665.rs
index 3d5cffa9855..e1d8be16f45 100644
--- a/tests/ui/issues/issue-13665.rs
+++ b/tests/ui/issues/issue-13665.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn foo<'r>() {
   let maybe_value_ref: Option<&'r u8> = None;
diff --git a/tests/ui/issues/issue-13703.rs b/tests/ui/issues/issue-13703.rs
index 9748ab3719e..b385e6b9d2e 100644
--- a/tests/ui/issues/issue-13703.rs
+++ b/tests/ui/issues/issue-13703.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 pub struct Foo<'a, 'b: 'a> { foo: &'a &'b isize }
 pub fn foo<'a, 'b>(x: Foo<'a, 'b>, _o: Option<&   &   ()>) { let _y = x.foo; }
diff --git a/tests/ui/issues/issue-13763.rs b/tests/ui/issues/issue-13763.rs
index 3044c671169..67b9bdc5f03 100644
--- a/tests/ui/issues/issue-13763.rs
+++ b/tests/ui/issues/issue-13763.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 mod u8 {
     pub const BITS: usize = 8;
diff --git a/tests/ui/issues/issue-13775.rs b/tests/ui/issues/issue-13775.rs
index 1d7a40b72d3..500ec6782a8 100644
--- a/tests/ui/issues/issue-13775.rs
+++ b/tests/ui/issues/issue-13775.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Foo {
     #[allow(anonymous_parameters)]
diff --git a/tests/ui/issues/issue-13808.rs b/tests/ui/issues/issue-13808.rs
index 91b771c6a68..d2961b35f2e 100644
--- a/tests/ui/issues/issue-13808.rs
+++ b/tests/ui/issues/issue-13808.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 struct Foo<'a> {
     listener: Box<dyn FnMut() + 'a>,
diff --git a/tests/ui/issues/issue-14082.rs b/tests/ui/issues/issue-14082.rs
index 116002415df..16556e1d260 100644
--- a/tests/ui/issues/issue-14082.rs
+++ b/tests/ui/issues/issue-14082.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_imports, dead_code)]
 
diff --git a/tests/ui/issues/issue-14254.rs b/tests/ui/issues/issue-14254.rs
index 9175ac8f92e..90ad375c262 100644
--- a/tests/ui/issues/issue-14254.rs
+++ b/tests/ui/issues/issue-14254.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Foo: Sized {
     fn bar(&self);
diff --git a/tests/ui/issues/issue-14330.rs b/tests/ui/issues/issue-14330.rs
index f6461c834a5..11199db5901 100644
--- a/tests/ui/issues/issue-14330.rs
+++ b/tests/ui/issues/issue-14330.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(unused_imports)]
-//@ pretty-expanded FIXME #23616
 
 #[macro_use] extern crate std as std2;
 
diff --git a/tests/ui/issues/issue-14393.rs b/tests/ui/issues/issue-14393.rs
index b7e64d6dca6..69c3fc15d31 100644
--- a/tests/ui/issues/issue-14393.rs
+++ b/tests/ui/issues/issue-14393.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     match ("", 1_usize) {
diff --git a/tests/ui/issues/issue-14399.rs b/tests/ui/issues/issue-14399.rs
index cb768f63baa..a539e270fb0 100644
--- a/tests/ui/issues/issue-14399.rs
+++ b/tests/ui/issues/issue-14399.rs
@@ -4,7 +4,6 @@
 // value was coerced to a trait object. (v.clone() returns Box<B1>
 // which is coerced to Box<A>).
 
-//@ pretty-expanded FIXME #23616
 
 #[derive(Clone)]
 struct B1;
diff --git a/tests/ui/issues/issue-14399.stderr b/tests/ui/issues/issue-14399.stderr
index d226ece6fb0..5821c3cc389 100644
--- a/tests/ui/issues/issue-14399.stderr
+++ b/tests/ui/issues/issue-14399.stderr
@@ -1,5 +1,5 @@
 warning: method `foo` is never used
-  --> $DIR/issue-14399.rs:12:14
+  --> $DIR/issue-14399.rs:11:14
    |
 LL | trait A { fn foo(&self) {} }
    |       -      ^^^
diff --git a/tests/ui/issues/issue-14421.rs b/tests/ui/issues/issue-14421.rs
index 4acbce66b6f..b7038584fce 100644
--- a/tests/ui/issues/issue-14421.rs
+++ b/tests/ui/issues/issue-14421.rs
@@ -3,7 +3,6 @@
 
 //@ aux-build:issue-14421.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_14421 as bug_lib;
 
diff --git a/tests/ui/issues/issue-14422.rs b/tests/ui/issues/issue-14422.rs
index ed9e72390c5..b7bb2caa7f0 100644
--- a/tests/ui/issues/issue-14422.rs
+++ b/tests/ui/issues/issue-14422.rs
@@ -3,7 +3,6 @@
 
 //@ aux-build:issue-14422.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_14422 as bug_lib;
 
diff --git a/tests/ui/issues/issue-14919.rs b/tests/ui/issues/issue-14919.rs
index 8a8324e57ea..3a834b13d07 100644
--- a/tests/ui/issues/issue-14919.rs
+++ b/tests/ui/issues/issue-14919.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait Matcher {
     fn next_match(&mut self) -> Option<(usize, usize)>;
diff --git a/tests/ui/issues/issue-14959.rs b/tests/ui/issues/issue-14959.rs
index 401bd82ded3..57af1207ff9 100644
--- a/tests/ui/issues/issue-14959.rs
+++ b/tests/ui/issues/issue-14959.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 #![feature(fn_traits, unboxed_closures)]
 
diff --git a/tests/ui/issues/issue-15043.rs b/tests/ui/issues/issue-15043.rs
index b00c878086d..a9bb46b649b 100644
--- a/tests/ui/issues/issue-15043.rs
+++ b/tests/ui/issues/issue-15043.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(warnings)]
 
diff --git a/tests/ui/issues/issue-15444.rs b/tests/ui/issues/issue-15444.rs
index a9a33bd5de4..14708c7733c 100644
--- a/tests/ui/issues/issue-15444.rs
+++ b/tests/ui/issues/issue-15444.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 trait MyTrait {
     fn foo(&self);
diff --git a/tests/ui/issues/issue-15562.rs b/tests/ui/issues/issue-15562.rs
index faa46cd5ece..d3a8f24c51b 100644
--- a/tests/ui/issues/issue-15562.rs
+++ b/tests/ui/issues/issue-15562.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-15562.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_15562 as i;
 
diff --git a/tests/ui/issues/issue-15774.rs b/tests/ui/issues/issue-15774.rs
index 383003b2dd7..8eb327a0d5e 100644
--- a/tests/ui/issues/issue-15774.rs
+++ b/tests/ui/issues/issue-15774.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![deny(warnings)]
 #![allow(unused_imports)]
diff --git a/tests/ui/issues/issue-16256.rs b/tests/ui/issues/issue-16256.rs
index f5873331c2d..1024e4511d6 100644
--- a/tests/ui/issues/issue-16256.rs
+++ b/tests/ui/issues/issue-16256.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let mut buf = Vec::new();
diff --git a/tests/ui/issues/issue-16256.stderr b/tests/ui/issues/issue-16256.stderr
index d920530b57c..75c3ec1bd1c 100644
--- a/tests/ui/issues/issue-16256.stderr
+++ b/tests/ui/issues/issue-16256.stderr
@@ -1,5 +1,5 @@
 warning: unused closure that must be used
-  --> $DIR/issue-16256.rs:6:5
+  --> $DIR/issue-16256.rs:5:5
    |
 LL |     |c: u8| buf.push(c);
    |     ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/issues/issue-16441.rs b/tests/ui/issues/issue-16441.rs
index 21608cf04c3..58cfb389297 100644
--- a/tests/ui/issues/issue-16441.rs
+++ b/tests/ui/issues/issue-16441.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 struct Empty;
 
diff --git a/tests/ui/issues/issue-16452.rs b/tests/ui/issues/issue-16452.rs
index 07dbf4729e6..4ab74f09059 100644
--- a/tests/ui/issues/issue-16452.rs
+++ b/tests/ui/issues/issue-16452.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     if true { return }
diff --git a/tests/ui/issues/issue-16643.rs b/tests/ui/issues/issue-16643.rs
index e00978ce66a..6cef11ffa87 100644
--- a/tests/ui/issues/issue-16643.rs
+++ b/tests/ui/issues/issue-16643.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-16643.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_16643 as i;
 
diff --git a/tests/ui/issues/issue-16783.rs b/tests/ui/issues/issue-16783.rs
index a69ecb353bb..2ecc42b579d 100644
--- a/tests/ui/issues/issue-16783.rs
+++ b/tests/ui/issues/issue-16783.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let x = [1, 2, 3];
diff --git a/tests/ui/issues/issue-16922-rpass.rs b/tests/ui/issues/issue-16922-rpass.rs
index 6cce4179b7c..f7ffcfb1d94 100644
--- a/tests/ui/issues/issue-16922-rpass.rs
+++ b/tests/ui/issues/issue-16922-rpass.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::any::Any;
 
diff --git a/tests/ui/issues/issue-17121.rs b/tests/ui/issues/issue-17121.rs
index 0a788b317cd..6bb89a4aa7b 100644
--- a/tests/ui/issues/issue-17121.rs
+++ b/tests/ui/issues/issue-17121.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 use std::fs::File;
 use std::io::{self, BufReader, Read};
diff --git a/tests/ui/issues/issue-17322.rs b/tests/ui/issues/issue-17322.rs
index 71ff38a0145..014e6b718f1 100644
--- a/tests/ui/issues/issue-17322.rs
+++ b/tests/ui/issues/issue-17322.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::io::{self, Write};
 
diff --git a/tests/ui/issues/issue-17351.rs b/tests/ui/issues/issue-17351.rs
index 15bff07f6e5..86049377198 100644
--- a/tests/ui/issues/issue-17351.rs
+++ b/tests/ui/issues/issue-17351.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 trait Str { fn foo(&self) {} } //~ WARN method `foo` is never used
 impl Str for str {}
diff --git a/tests/ui/issues/issue-17351.stderr b/tests/ui/issues/issue-17351.stderr
index 3242d578dab..e4c84ab9315 100644
--- a/tests/ui/issues/issue-17351.stderr
+++ b/tests/ui/issues/issue-17351.stderr
@@ -1,5 +1,5 @@
 warning: method `foo` is never used
-  --> $DIR/issue-17351.rs:4:16
+  --> $DIR/issue-17351.rs:3:16
    |
 LL | trait Str { fn foo(&self) {} }
    |       ---      ^^^
diff --git a/tests/ui/issues/issue-17361.rs b/tests/ui/issues/issue-17361.rs
index 1b1eeb5a252..6f6fc42db38 100644
--- a/tests/ui/issues/issue-17361.rs
+++ b/tests/ui/issues/issue-17361.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Test that HIR ty lowering doesn't forget about mutability of `&mut str`.
 
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     fn foo<T: ?Sized>(_: &mut T) {}
diff --git a/tests/ui/issues/issue-17732.rs b/tests/ui/issues/issue-17732.rs
index 4bf7ee286e1..e093ed7f41f 100644
--- a/tests/ui/issues/issue-17732.rs
+++ b/tests/ui/issues/issue-17732.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
-//@ pretty-expanded FIXME #23616
 
 trait Person {
     type string;
diff --git a/tests/ui/issues/issue-17771.rs b/tests/ui/issues/issue-17771.rs
index d7c0ea3eb2a..2e27cfceb8c 100644
--- a/tests/ui/issues/issue-17771.rs
+++ b/tests/ui/issues/issue-17771.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait Aaa { fn dummy(&self) { } }
 
diff --git a/tests/ui/issues/issue-17904.rs b/tests/ui/issues/issue-17904.rs
index 5eaa306e80e..fba71f70dd9 100644
--- a/tests/ui/issues/issue-17904.rs
+++ b/tests/ui/issues/issue-17904.rs
@@ -3,7 +3,6 @@
 // Test that we can parse where clauses on various forms of tuple
 // structs.
 
-//@ pretty-expanded FIXME #23616
 
 struct Bar<T>(T) where T: Copy;
 struct Bleh<T, U>(T, U) where T: Copy, U: Sized;
diff --git a/tests/ui/issues/issue-18110.rs b/tests/ui/issues/issue-18110.rs
index 8ab9be19531..6d563a5bae1 100644
--- a/tests/ui/issues/issue-18110.rs
+++ b/tests/ui/issues/issue-18110.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unreachable_code)]
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     ({return},);
diff --git a/tests/ui/issues/issue-18188.rs b/tests/ui/issues/issue-18188.rs
index b99e6aea6bd..b3b008229a5 100644
--- a/tests/ui/issues/issue-18188.rs
+++ b/tests/ui/issues/issue-18188.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 pub trait Promisable: Send + Sync {}
 impl<T: Send + Sync> Promisable for T {}
diff --git a/tests/ui/issues/issue-18232.rs b/tests/ui/issues/issue-18232.rs
index 5ace2231192..d526a67950c 100644
--- a/tests/ui/issues/issue-18232.rs
+++ b/tests/ui/issues/issue-18232.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 struct Cursor<'a>(::std::marker::PhantomData<&'a ()>);
 
diff --git a/tests/ui/issues/issue-18353.rs b/tests/ui/issues/issue-18353.rs
index a9c0b3bcdbd..378caa9f369 100644
--- a/tests/ui/issues/issue-18353.rs
+++ b/tests/ui/issues/issue-18353.rs
@@ -3,7 +3,6 @@
 // Test that wrapping an unsized struct in an enum which gets optimised does
 // not ICE.
 
-//@ pretty-expanded FIXME #23616
 
 struct Str {
     f: [u8]
diff --git a/tests/ui/issues/issue-18501.rs b/tests/ui/issues/issue-18501.rs
index 559428d4d08..54e53e434c4 100644
--- a/tests/ui/issues/issue-18501.rs
+++ b/tests/ui/issues/issue-18501.rs
@@ -4,7 +4,6 @@
 // translating the def ID of the trait during AST decoding.
 
 //@ aux-build:issue-18501.rs
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_18501 as issue;
 
diff --git a/tests/ui/issues/issue-18539.rs b/tests/ui/issues/issue-18539.rs
index eaf8294aa47..66f0dabb73a 100644
--- a/tests/ui/issues/issue-18539.rs
+++ b/tests/ui/issues/issue-18539.rs
@@ -2,7 +2,6 @@
 // Test that coercing bare fn's that return a zero sized type to
 // a closure doesn't cause an LLVM ERROR
 
-//@ pretty-expanded FIXME #23616
 
 struct Foo;
 
diff --git a/tests/ui/issues/issue-18685.rs b/tests/ui/issues/issue-18685.rs
index cea60e6f4f2..3dab341f615 100644
--- a/tests/ui/issues/issue-18685.rs
+++ b/tests/ui/issues/issue-18685.rs
@@ -2,7 +2,6 @@
 // Test that the self param space is not used in a conflicting
 // manner by unboxed closures within a default method on a trait
 
-//@ pretty-expanded FIXME #23616
 
 trait Tr {
     fn foo(&self);
diff --git a/tests/ui/issues/issue-18711.rs b/tests/ui/issues/issue-18711.rs
index c62f83004ae..1d5e3349a6d 100644
--- a/tests/ui/issues/issue-18711.rs
+++ b/tests/ui/issues/issue-18711.rs
@@ -2,7 +2,6 @@
 // Test that we don't panic on a RefCell borrow conflict in certain
 // code paths involving unboxed closures.
 
-//@ pretty-expanded FIXME #23616
 
 //@ aux-build:issue-18711.rs
 extern crate issue_18711 as issue;
diff --git a/tests/ui/issues/issue-18906.rs b/tests/ui/issues/issue-18906.rs
index 95ad8073955..84b0f5a1788 100644
--- a/tests/ui/issues/issue-18906.rs
+++ b/tests/ui/issues/issue-18906.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub trait Borrow<Borrowed: ?Sized> {
         fn borrow(&self) -> &Borrowed;
diff --git a/tests/ui/issues/issue-19037.rs b/tests/ui/issues/issue-19037.rs
index 961ef69a3b9..7f88a89a657 100644
--- a/tests/ui/issues/issue-19037.rs
+++ b/tests/ui/issues/issue-19037.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 struct Str([u8]);
 
diff --git a/tests/ui/issues/issue-19127.rs b/tests/ui/issues/issue-19127.rs
index dd0526592e4..2172c631b84 100644
--- a/tests/ui/issues/issue-19127.rs
+++ b/tests/ui/issues/issue-19127.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 fn foo<T, F: FnOnce(T) -> T>(f: F) {}
 fn id<'a>(input: &'a u8) -> &'a u8 { input }
diff --git a/tests/ui/issues/issue-19293.rs b/tests/ui/issues/issue-19293.rs
index 7a971a59c3d..42effe303d0 100644
--- a/tests/ui/issues/issue-19293.rs
+++ b/tests/ui/issues/issue-19293.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 //@ aux-build:issue-19293.rs
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_19293;
 use issue_19293::{Foo, MyEnum};
diff --git a/tests/ui/issues/issue-19398.rs b/tests/ui/issues/issue-19398.rs
index 751fffb1744..473e43650c2 100644
--- a/tests/ui/issues/issue-19398.rs
+++ b/tests/ui/issues/issue-19398.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait T {
     unsafe extern "Rust" fn foo(&self);
diff --git a/tests/ui/issues/issue-19479.rs b/tests/ui/issues/issue-19479.rs
index 2818be310be..ed586b76550 100644
--- a/tests/ui/issues/issue-19479.rs
+++ b/tests/ui/issues/issue-19479.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Base {
     fn dummy(&self) { }
diff --git a/tests/ui/issues/issue-19499.rs b/tests/ui/issues/issue-19499.rs
index 0bd70865211..d2a6862e05c 100644
--- a/tests/ui/issues/issue-19499.rs
+++ b/tests/ui/issues/issue-19499.rs
@@ -7,7 +7,6 @@
 // reasonable examples) let to ambiguity errors about not being able
 // to infer sufficient type information.
 
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let n = 0;
diff --git a/tests/ui/issues/issue-19631.rs b/tests/ui/issues/issue-19631.rs
index a20df9c9d4c..d13ac216e36 100644
--- a/tests/ui/issues/issue-19631.rs
+++ b/tests/ui/issues/issue-19631.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait PoolManager {
     type C;
diff --git a/tests/ui/issues/issue-19632.rs b/tests/ui/issues/issue-19632.rs
index 53e25112ecc..a99ab5f5ebe 100644
--- a/tests/ui/issues/issue-19632.rs
+++ b/tests/ui/issues/issue-19632.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait PoolManager {
     type C;
diff --git a/tests/ui/issues/issue-19850.rs b/tests/ui/issues/issue-19850.rs
index 5e8ba2d4881..485b1a76390 100644
--- a/tests/ui/issues/issue-19850.rs
+++ b/tests/ui/issues/issue-19850.rs
@@ -3,7 +3,6 @@
 // Test that `<Type as Trait>::Output` and `Self::Output` are accepted as type annotations in let
 // bindings
 
-//@ pretty-expanded FIXME #23616
 
 trait Int {
     fn one() -> Self;
diff --git a/tests/ui/issues/issue-20009.rs b/tests/ui/issues/issue-20009.rs
index ed884d12834..4d091f3a962 100644
--- a/tests/ui/issues/issue-20009.rs
+++ b/tests/ui/issues/issue-20009.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 // Check that associated types are `Sized`
 
-//@ pretty-expanded FIXME #23616
 
 trait Trait {
     type Output;
diff --git a/tests/ui/issues/issue-20313-rpass.rs b/tests/ui/issues/issue-20313-rpass.rs
index 66ba97b1074..a9cd0cbd88e 100644
--- a/tests/ui/issues/issue-20313-rpass.rs
+++ b/tests/ui/issues/issue-20313-rpass.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 #![feature(link_llvm_intrinsics)]
 
 extern "C" {
diff --git a/tests/ui/issues/issue-20389.rs b/tests/ui/issues/issue-20389.rs
index 7d3b49ee25f..e201663afc5 100644
--- a/tests/ui/issues/issue-20389.rs
+++ b/tests/ui/issues/issue-20389.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 //@ aux-build:issue-20389.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_20389;
 
diff --git a/tests/ui/issues/issue-20396.rs b/tests/ui/issues/issue-20396.rs
index 46a06bb8e3c..4a7b57903b5 100644
--- a/tests/ui/issues/issue-20396.rs
+++ b/tests/ui/issues/issue-20396.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/issues/issue-20414.rs b/tests/ui/issues/issue-20414.rs
index ea086c2fbeb..070e0f451a5 100644
--- a/tests/ui/issues/issue-20414.rs
+++ b/tests/ui/issues/issue-20414.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait Trait {
         fn method(self) -> isize;
diff --git a/tests/ui/issues/issue-20575.rs b/tests/ui/issues/issue-20575.rs
index f8ff8b7d23d..b213b79d37c 100644
--- a/tests/ui/issues/issue-20575.rs
+++ b/tests/ui/issues/issue-20575.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Test that overloaded calls work with zero arity closures
 
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let functions: [Box<dyn Fn() -> Option<()>>; 1] = [Box::new(|| None)];
diff --git a/tests/ui/issues/issue-20644.rs b/tests/ui/issues/issue-20644.rs
index f71e1a5ba8f..5f7e4054f77 100644
--- a/tests/ui/issues/issue-20644.rs
+++ b/tests/ui/issues/issue-20644.rs
@@ -6,7 +6,6 @@
 // A reduced version of the rustbook ice. The problem this encountered
 // had to do with codegen ignoring binders.
 
-//@ pretty-expanded FIXME #23616
 
 #![feature(os)]
 
diff --git a/tests/ui/issues/issue-2074.rs b/tests/ui/issues/issue-2074.rs
index ebf0de4348c..b6e3fb1fa23 100644
--- a/tests/ui/issues/issue-2074.rs
+++ b/tests/ui/issues/issue-2074.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(non_camel_case_types)]
 
diff --git a/tests/ui/issues/issue-21033.rs b/tests/ui/issues/issue-21033.rs
index 4ddc7a1db58..e6b13eb3f4b 100644
--- a/tests/ui/issues/issue-21033.rs
+++ b/tests/ui/issues/issue-21033.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_mut)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 #![feature(box_patterns)]
 
diff --git a/tests/ui/issues/issue-21245.rs b/tests/ui/issues/issue-21245.rs
index f25ebf718b1..b7c694763c6 100644
--- a/tests/ui/issues/issue-21245.rs
+++ b/tests/ui/issues/issue-21245.rs
@@ -5,7 +5,6 @@
 // insufficient type propagation caused the type of the iterator to be
 // incorrectly unified with the `*const` type to which it is coerced.
 
-//@ pretty-expanded FIXME #23616
 
 use std::ptr;
 
diff --git a/tests/ui/issues/issue-21402.rs b/tests/ui/issues/issue-21402.rs
index 28d1e1a0d77..fa0ece3ec3b 100644
--- a/tests/ui/issues/issue-21402.rs
+++ b/tests/ui/issues/issue-21402.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 #[derive(Hash)]
 struct Foo {
diff --git a/tests/ui/issues/issue-2170-exe.rs b/tests/ui/issues/issue-2170-exe.rs
index 9e3586afbbc..b66843d48ca 100644
--- a/tests/ui/issues/issue-2170-exe.rs
+++ b/tests/ui/issues/issue-2170-exe.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 //@ aux-build:issue-2170-lib.rs
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_2170_lib;
 
diff --git a/tests/ui/issues/issue-21891.rs b/tests/ui/issues/issue-21891.rs
index 1feb0daa2d1..0da6071cdac 100644
--- a/tests/ui/issues/issue-21891.rs
+++ b/tests/ui/issues/issue-21891.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
-//@ pretty-expanded FIXME #23616
 
 static foo: [usize; 3] = [1, 2, 3];
 
diff --git a/tests/ui/issues/issue-2190-1.rs b/tests/ui/issues/issue-2190-1.rs
index 5b2890c89fb..8db4a84aac8 100644
--- a/tests/ui/issues/issue-2190-1.rs
+++ b/tests/ui/issues/issue-2190-1.rs
@@ -2,7 +2,6 @@
 #![allow(unused_must_use)]
 #![allow(non_upper_case_globals)]
 
-//@ pretty-expanded FIXME #23616
 //@ ignore-emscripten no threads
 
 use std::thread::Builder;
diff --git a/tests/ui/issues/issue-21909.rs b/tests/ui/issues/issue-21909.rs
index bbf654cb208..ffc75f1f08c 100644
--- a/tests/ui/issues/issue-21909.rs
+++ b/tests/ui/issues/issue-21909.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait A<X> {
     fn dummy(&self, arg: X);
diff --git a/tests/ui/issues/issue-22346.rs b/tests/ui/issues/issue-22346.rs
index 42280a7ddb6..710dc0acda7 100644
--- a/tests/ui/issues/issue-22346.rs
+++ b/tests/ui/issues/issue-22346.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 // This used to cause an ICE because the retslot for the "return" had the wrong type
 fn testcase<'a>() -> Box<dyn Iterator<Item=usize> + 'a> {
diff --git a/tests/ui/issues/issue-22356.rs b/tests/ui/issues/issue-22356.rs
index 6b0024ee0ee..b7c5c2a5932 100644
--- a/tests/ui/issues/issue-22356.rs
+++ b/tests/ui/issues/issue-22356.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 #![allow(type_alias_bounds)]
 
-//@ pretty-expanded FIXME #23616
 
 use std::marker::PhantomData;
 
diff --git a/tests/ui/issues/issue-22426.rs b/tests/ui/issues/issue-22426.rs
index d5254528a12..0857ac9dfb4 100644
--- a/tests/ui/issues/issue-22426.rs
+++ b/tests/ui/issues/issue-22426.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn main() {
   match 42 {
diff --git a/tests/ui/issues/issue-22577.rs b/tests/ui/issues/issue-22577.rs
index 09857c95e1b..0fa284cc7c0 100644
--- a/tests/ui/issues/issue-22577.rs
+++ b/tests/ui/issues/issue-22577.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 use std::{fs, net};
 
diff --git a/tests/ui/issues/issue-22629.rs b/tests/ui/issues/issue-22629.rs
index 0a75d3dd152..22da414650f 100644
--- a/tests/ui/issues/issue-22629.rs
+++ b/tests/ui/issues/issue-22629.rs
@@ -3,7 +3,6 @@
 // Test transitive analysis for associated types. Collected types
 // should be normalized and new obligations generated.
 
-//@ pretty-expanded FIXME #23616
 
 use std::borrow::{ToOwned, Cow};
 
diff --git a/tests/ui/issues/issue-22777.rs b/tests/ui/issues/issue-22777.rs
index 56b385a1691..c95bb9cc3bb 100644
--- a/tests/ui/issues/issue-22777.rs
+++ b/tests/ui/issues/issue-22777.rs
@@ -3,7 +3,6 @@
 // can successfully deal with a "deep" structure, which the drop-check
 // was hitting a recursion limit on at one point.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(non_camel_case_types)]
 
diff --git a/tests/ui/issues/issue-2284.rs b/tests/ui/issues/issue-2284.rs
index 281dce913ad..358331ecd9a 100644
--- a/tests/ui/issues/issue-2284.rs
+++ b/tests/ui/issues/issue-2284.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait Send {
     fn f(&self);
diff --git a/tests/ui/issues/issue-23024.rs b/tests/ui/issues/issue-23024.rs
index 25220dc3e61..1b072dd7b69 100644
--- a/tests/ui/issues/issue-23024.rs
+++ b/tests/ui/issues/issue-23024.rs
@@ -8,5 +8,4 @@ fn main()
     println!("{:?}",(vfnfer[0] as dyn Fn)(3));
     //~^ ERROR the precise format of `Fn`-family traits'
     //~| ERROR missing generics for trait `Fn`
-    //~| ERROR the value of the associated type `Output` in `FnOnce`
 }
diff --git a/tests/ui/issues/issue-23024.stderr b/tests/ui/issues/issue-23024.stderr
index 62278a51be6..51db0414f3a 100644
--- a/tests/ui/issues/issue-23024.stderr
+++ b/tests/ui/issues/issue-23024.stderr
@@ -19,13 +19,7 @@ help: add missing generic argument
 LL |     println!("{:?}",(vfnfer[0] as dyn Fn<Args>)(3));
    |                                         ++++++
 
-error[E0191]: the value of the associated type `Output` in `FnOnce` must be specified
-  --> $DIR/issue-23024.rs:8:39
-   |
-LL |     println!("{:?}",(vfnfer[0] as dyn Fn)(3));
-   |                                       ^^ help: specify the associated type: `Fn::<Output = Type>`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0107, E0191, E0658.
+Some errors have detailed explanations: E0107, E0658.
 For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/issues/issue-2311.rs b/tests/ui/issues/issue-2311.rs
index dc2fb394f83..5388e634c09 100644
--- a/tests/ui/issues/issue-2311.rs
+++ b/tests/ui/issues/issue-2311.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 trait clam<A> { fn get(self) -> A; }
 trait foo<A> {
diff --git a/tests/ui/issues/issue-2316-c.rs b/tests/ui/issues/issue-2316-c.rs
index 52e2995ec58..f800d4723ff 100644
--- a/tests/ui/issues/issue-2316-c.rs
+++ b/tests/ui/issues/issue-2316-c.rs
@@ -2,7 +2,6 @@
 //@ aux-build:issue-2316-a.rs
 //@ aux-build:issue-2316-b.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_2316_b;
 use issue_2316_b::cloth;
diff --git a/tests/ui/issues/issue-2380-b.rs b/tests/ui/issues/issue-2380-b.rs
index 722b463de09..503698f88c6 100644
--- a/tests/ui/issues/issue-2380-b.rs
+++ b/tests/ui/issues/issue-2380-b.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-2380.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate a;
 
diff --git a/tests/ui/issues/issue-2383.rs b/tests/ui/issues/issue-2383.rs
index eecbaa2562e..5d60018ae67 100644
--- a/tests/ui/issues/issue-2383.rs
+++ b/tests/ui/issues/issue-2383.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::collections::VecDeque;
 
diff --git a/tests/ui/issues/issue-2414-c.rs b/tests/ui/issues/issue-2414-c.rs
index 1437a4199dc..ac75c5c5105 100644
--- a/tests/ui/issues/issue-2414-c.rs
+++ b/tests/ui/issues/issue-2414-c.rs
@@ -2,7 +2,6 @@
 //@ aux-build:issue-2414-a.rs
 //@ aux-build:issue-2414-b.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate b;
 
diff --git a/tests/ui/issues/issue-2445-b.rs b/tests/ui/issues/issue-2445-b.rs
index 8f52c0f47a5..3a54c62a771 100644
--- a/tests/ui/issues/issue-2445-b.rs
+++ b/tests/ui/issues/issue-2445-b.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 struct c1<T> {
     x: T,
diff --git a/tests/ui/issues/issue-2445.rs b/tests/ui/issues/issue-2445.rs
index da82a489c1e..e6c33a8fd01 100644
--- a/tests/ui/issues/issue-2445.rs
+++ b/tests/ui/issues/issue-2445.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 struct c1<T> {
     x: T,
diff --git a/tests/ui/issues/issue-2463.rs b/tests/ui/issues/issue-2463.rs
index 7650da845e3..8fff9763bd9 100644
--- a/tests/ui/issues/issue-2463.rs
+++ b/tests/ui/issues/issue-2463.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 struct Pair { f: isize, g: isize }
 
diff --git a/tests/ui/issues/issue-2472.rs b/tests/ui/issues/issue-2472.rs
index afebc7b16e5..f8f539ed1d1 100644
--- a/tests/ui/issues/issue-2472.rs
+++ b/tests/ui/issues/issue-2472.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-2472-b.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_2472_b;
 
diff --git a/tests/ui/issues/issue-2487-a.rs b/tests/ui/issues/issue-2487-a.rs
index 6cdb9f2afe2..d38616929fa 100644
--- a/tests/ui/issues/issue-2487-a.rs
+++ b/tests/ui/issues/issue-2487-a.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 struct socket {
     sock: isize,
diff --git a/tests/ui/issues/issue-2502.rs b/tests/ui/issues/issue-2502.rs
index d857099e7b9..dfc0995104e 100644
--- a/tests/ui/issues/issue-2502.rs
+++ b/tests/ui/issues/issue-2502.rs
@@ -3,7 +3,6 @@
 #![allow(non_camel_case_types)]
 
 
-//@ pretty-expanded FIXME #23616
 
 struct font<'a> {
     fontbuf: &'a Vec<u8> ,
diff --git a/tests/ui/issues/issue-2526-a.rs b/tests/ui/issues/issue-2526-a.rs
index 62e687f7f3f..379146d02b3 100644
--- a/tests/ui/issues/issue-2526-a.rs
+++ b/tests/ui/issues/issue-2526-a.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-2526.rs
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_imports)]
 
diff --git a/tests/ui/issues/issue-2550.rs b/tests/ui/issues/issue-2550.rs
index 4fc5ba1f7b2..450db9be627 100644
--- a/tests/ui/issues/issue-2550.rs
+++ b/tests/ui/issues/issue-2550.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_snake_case)]
 
-//@ pretty-expanded FIXME #23616
 
 struct C {
     x: usize,
diff --git a/tests/ui/issues/issue-25901.rs b/tests/ui/issues/issue-25901.rs
index 85e12463a90..eae038c71a0 100644
--- a/tests/ui/issues/issue-25901.rs
+++ b/tests/ui/issues/issue-25901.rs
@@ -2,7 +2,7 @@ struct A;
 struct B;
 
 static S: &'static B = &A;
-//~^ ERROR cannot perform deref coercion
+//~^ ERROR cannot call conditionally-const method
 
 use std::ops::Deref;
 
diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr
index bcbc805908f..655a8b78c6a 100644
--- a/tests/ui/issues/issue-25901.stderr
+++ b/tests/ui/issues/issue-25901.stderr
@@ -1,23 +1,13 @@
-error[E0015]: cannot perform deref coercion on `A` in statics
+error[E0658]: cannot call conditionally-const method `<A as Deref>::deref` in statics
   --> $DIR/issue-25901.rs:4:24
    |
 LL | static S: &'static B = &A;
    |                        ^^
    |
-   = note: attempting to deref into `B`
-note: deref defined here
-  --> $DIR/issue-25901.rs:10:5
-   |
-LL |     type Target = B;
-   |     ^^^^^^^^^^^
-note: impl defined here, but it is not `const`
-  --> $DIR/issue-25901.rs:9:1
-   |
-LL | impl Deref for A {
-   | ^^^^^^^^^^^^^^^^
-   = note: calls in statics are limited to constant functions, tuple structs and tuple variants
-   = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` 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 E0015`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/issues/issue-2642.rs b/tests/ui/issues/issue-2642.rs
index d7d97b84799..ad572149509 100644
--- a/tests/ui/issues/issue-2642.rs
+++ b/tests/ui/issues/issue-2642.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn f() {
    let _x: usize = loop { loop { break; } };
diff --git a/tests/ui/issues/issue-2708.rs b/tests/ui/issues/issue-2708.rs
index 68ac4bc343c..09d19f87aa6 100644
--- a/tests/ui/issues/issue-2708.rs
+++ b/tests/ui/issues/issue-2708.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_snake_case)]
 
-//@ pretty-expanded FIXME #23616
 
 
 
diff --git a/tests/ui/issues/issue-3012-2.rs b/tests/ui/issues/issue-3012-2.rs
index 913f92fa8e2..fd090d5e7b5 100644
--- a/tests/ui/issues/issue-3012-2.rs
+++ b/tests/ui/issues/issue-3012-2.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-3012-1.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate socketlib;
 
diff --git a/tests/ui/issues/issue-3026.rs b/tests/ui/issues/issue-3026.rs
index 9d1c0f5a341..05dc46c3cc0 100644
--- a/tests/ui/issues/issue-3026.rs
+++ b/tests/ui/issues/issue-3026.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::collections::HashMap;
 
diff --git a/tests/ui/issues/issue-3037.rs b/tests/ui/issues/issue-3037.rs
index 166f4b91cbc..933b450ac8e 100644
--- a/tests/ui/issues/issue-3037.rs
+++ b/tests/ui/issues/issue-3037.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 #![allow(non_camel_case_types)]
 
 enum what { }
diff --git a/tests/ui/issues/issue-3052.rs b/tests/ui/issues/issue-3052.rs
index 4aa785e797f..ab3519fe714 100644
--- a/tests/ui/issues/issue-3052.rs
+++ b/tests/ui/issues/issue-3052.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 type Connection = Box<dyn FnMut(Vec<u8>) + 'static>;
 
diff --git a/tests/ui/issues/issue-3136-b.rs b/tests/ui/issues/issue-3136-b.rs
index 2995c96ebb9..bd6ea732643 100644
--- a/tests/ui/issues/issue-3136-b.rs
+++ b/tests/ui/issues/issue-3136-b.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-3136-a.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_3136_a;
 
diff --git a/tests/ui/issues/issue-3149.rs b/tests/ui/issues/issue-3149.rs
index b0abd5996b1..76744213d51 100644
--- a/tests/ui/issues/issue-3149.rs
+++ b/tests/ui/issues/issue-3149.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 #![allow(dead_code)]
 #![allow(non_snake_case)]
-//@ pretty-expanded FIXME #23616
 
 fn Matrix4<T>(m11: T, m12: T, m13: T, m14: T,
               m21: T, m22: T, m23: T, m24: T,
diff --git a/tests/ui/issues/issue-3220.rs b/tests/ui/issues/issue-3220.rs
index 62a979b47c7..2f5ca82b2fa 100644
--- a/tests/ui/issues/issue-3220.rs
+++ b/tests/ui/issues/issue-3220.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
-//@ pretty-expanded FIXME #23616
 
 struct thing { x: isize, }
 
diff --git a/tests/ui/issues/issue-3429.rs b/tests/ui/issues/issue-3429.rs
index 38ea7df1aa0..39d657573db 100644
--- a/tests/ui/issues/issue-3429.rs
+++ b/tests/ui/issues/issue-3429.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
   let x = 1_usize;
diff --git a/tests/ui/issues/issue-34373.rs b/tests/ui/issues/issue-34373.rs
index dc20c5589b3..707aa8cf338 100644
--- a/tests/ui/issues/issue-34373.rs
+++ b/tests/ui/issues/issue-34373.rs
@@ -6,7 +6,6 @@ trait Trait<T> {
 
 pub struct Foo<T = Box<Trait<DefaultFoo>>>;  //~ ERROR cycle detected
 //~^ ERROR `T` is never used
-//~| ERROR `Trait` cannot be made into an object
 type DefaultFoo = Foo;
 
 fn main() {
diff --git a/tests/ui/issues/issue-34373.stderr b/tests/ui/issues/issue-34373.stderr
index 4e8e7c61fee..06365558217 100644
--- a/tests/ui/issues/issue-34373.stderr
+++ b/tests/ui/issues/issue-34373.stderr
@@ -5,7 +5,7 @@ LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
    |                              ^^^^^^^^^^
    |
 note: ...which requires expanding type alias `DefaultFoo`...
-  --> $DIR/issue-34373.rs:10:19
+  --> $DIR/issue-34373.rs:9:19
    |
 LL | type DefaultFoo = Foo;
    |                   ^^^
@@ -17,28 +17,6 @@ LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/issue-34373.rs:7:24
-   |
-LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
-   |                        ^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/issue-34373.rs:4:8
-   |
-LL | trait Trait<T> {
-   |       ----- this trait cannot be made into an object...
-LL |     fn foo(_: T) {}
-   |        ^^^ ...because associated function `foo` has no `self` parameter
-help: consider turning `foo` into a method by giving it a `&self` argument
-   |
-LL |     fn foo(&self, _: T) {}
-   |            ++++++
-help: alternatively, consider constraining `foo` so it does not apply to trait objects
-   |
-LL |     fn foo(_: T) where Self: Sized {}
-   |                  +++++++++++++++++
-
 error[E0392]: type parameter `T` is never used
   --> $DIR/issue-34373.rs:7:16
    |
@@ -48,7 +26,7 @@ LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0038, E0391, E0392.
-For more information about an error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0391, E0392.
+For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/issues/issue-3500.rs b/tests/ui/issues/issue-3500.rs
index 038707ef1ec..0860d0f5926 100644
--- a/tests/ui/issues/issue-3500.rs
+++ b/tests/ui/issues/issue-3500.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let x = &Some(1);
diff --git a/tests/ui/issues/issue-3656.rs b/tests/ui/issues/issue-3656.rs
index 975695e497f..15ad3232555 100644
--- a/tests/ui/issues/issue-3656.rs
+++ b/tests/ui/issues/issue-3656.rs
@@ -5,7 +5,6 @@
 // Incorrect struct size computation in the FFI, because of not taking
 // the alignment of elements into account.
 
-//@ pretty-expanded FIXME #23616
 
 use std::ffi::{c_uint, c_void};
 
diff --git a/tests/ui/issues/issue-3874.rs b/tests/ui/issues/issue-3874.rs
index 737f2c69e1e..251e8e1da6d 100644
--- a/tests/ui/issues/issue-3874.rs
+++ b/tests/ui/issues/issue-3874.rs
@@ -1,6 +1,5 @@
 //@ build-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 enum PureCounter { PureCounterVariant(usize) }
 
diff --git a/tests/ui/issues/issue-3888-2.rs b/tests/ui/issues/issue-3888-2.rs
index c06d20961c2..39b7126f069 100644
--- a/tests/ui/issues/issue-3888-2.rs
+++ b/tests/ui/issues/issue-3888-2.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn vec_peek<'r, T>(v: &'r [T]) -> &'r [T] {
     &v[1..5]
diff --git a/tests/ui/issues/issue-39211.rs b/tests/ui/issues/issue-39211.rs
index 6f3834d51a1..ab86afc3410 100644
--- a/tests/ui/issues/issue-39211.rs
+++ b/tests/ui/issues/issue-39211.rs
@@ -8,6 +8,7 @@ trait Mat {
 fn m<M: Mat>() {
     let a = [3; M::Row::DIM];
     //~^ ERROR constant expression depends on a generic parameter
+    //~| ERROR constant expression depends on a generic parameter
 }
 fn main() {
 }
diff --git a/tests/ui/issues/issue-39211.stderr b/tests/ui/issues/issue-39211.stderr
index 15c9a80bb35..2124bc667ff 100644
--- a/tests/ui/issues/issue-39211.stderr
+++ b/tests/ui/issues/issue-39211.stderr
@@ -6,5 +6,13 @@ LL |     let a = [3; M::Row::DIM];
    |
    = note: this may fail depending on what value the parameter takes
 
-error: aborting due to 1 previous error
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-39211.rs:9:13
+   |
+LL |     let a = [3; M::Row::DIM];
+   |             ^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/issues/issue-3979-2.rs b/tests/ui/issues/issue-3979-2.rs
index 620090bc3ec..98b6e85225d 100644
--- a/tests/ui/issues/issue-3979-2.rs
+++ b/tests/ui/issues/issue-3979-2.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait A {
     fn a_method(&self);
diff --git a/tests/ui/issues/issue-3991.rs b/tests/ui/issues/issue-3991.rs
index 97bddb9250a..e69c693ed49 100644
--- a/tests/ui/issues/issue-3991.rs
+++ b/tests/ui/issues/issue-3991.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 #![allow(dead_code)]
 
-//@ pretty-expanded FIXME #23616
 
 struct HasNested {
     nest: Vec<Vec<isize> > ,
diff --git a/tests/ui/issues/issue-4208.rs b/tests/ui/issues/issue-4208.rs
index 1691bec980b..84938bea022 100644
--- a/tests/ui/issues/issue-4208.rs
+++ b/tests/ui/issues/issue-4208.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 //@ aux-build:issue-4208-cc.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate numeric;
 use numeric::{sin, Angle};
diff --git a/tests/ui/issues/issue-4228.rs b/tests/ui/issues/issue-4228.rs
index 8ae8a84dac9..362d5925c70 100644
--- a/tests/ui/issues/issue-4228.rs
+++ b/tests/ui/issues/issue-4228.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 struct Foo;
 
diff --git a/tests/ui/issues/issue-4333.rs b/tests/ui/issues/issue-4333.rs
index 9b45e1665be..dccaa6f68bd 100644
--- a/tests/ui/issues/issue-4333.rs
+++ b/tests/ui/issues/issue-4333.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ pretty-expanded FIXME #23616
 
 use std::io;
 
diff --git a/tests/ui/issues/issue-4387.rs b/tests/ui/issues/issue-4387.rs
index 1299c4fcc3a..10f607aacbd 100644
--- a/tests/ui/issues/issue-4387.rs
+++ b/tests/ui/issues/issue-4387.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let _foo = [0; 2*4];
diff --git a/tests/ui/issues/issue-4464.rs b/tests/ui/issues/issue-4464.rs
index a2d6ed718c2..7b3df9af223 100644
--- a/tests/ui/issues/issue-4464.rs
+++ b/tests/ui/issues/issue-4464.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn broken(v: &[u8], i: usize, j: usize) -> &[u8] { &v[i..j] }
 
diff --git a/tests/ui/issues/issue-4542.rs b/tests/ui/issues/issue-4542.rs
index bd63246fa33..15fd31d92d2 100644
--- a/tests/ui/issues/issue-4542.rs
+++ b/tests/ui/issues/issue-4542.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::env;
 
diff --git a/tests/ui/issues/issue-4545.rs b/tests/ui/issues/issue-4545.rs
index 6a2f04e4511..dfb89136cbd 100644
--- a/tests/ui/issues/issue-4545.rs
+++ b/tests/ui/issues/issue-4545.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-4545.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_4545 as somelib;
 pub fn main() { somelib::mk::<isize>(); }
diff --git a/tests/ui/issues/issue-4735.rs b/tests/ui/issues/issue-4735.rs
index 1223e15b2d9..1ca145bae42 100644
--- a/tests/ui/issues/issue-4735.rs
+++ b/tests/ui/issues/issue-4735.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::mem::transmute;
 
diff --git a/tests/ui/issues/issue-4759.rs b/tests/ui/issues/issue-4759.rs
index 49fe5f92759..4b49442b401 100644
--- a/tests/ui/issues/issue-4759.rs
+++ b/tests/ui/issues/issue-4759.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 #![allow(non_shorthand_field_patterns)]
 
 struct T { a: Box<isize> }
diff --git a/tests/ui/issues/issue-48006.rs b/tests/ui/issues/issue-48006.rs
index e48146d07bc..1adc76f2a26 100644
--- a/tests/ui/issues/issue-48006.rs
+++ b/tests/ui/issues/issue-48006.rs
@@ -6,10 +6,10 @@ use std::iter::Step;
 
 #[cfg(target_pointer_width = "16")]
 fn main() {
-    assert!(Step::steps_between(&0u32, &u32::MAX).is_none());
+    assert!(Step::steps_between(&0u32, &u32::MAX).1.is_none());
 }
 
 #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
 fn main() {
-    assert!(Step::steps_between(&0u32, &u32::MAX).is_some());
+    assert!(Step::steps_between(&0u32, &u32::MAX).1.is_some());
 }
diff --git a/tests/ui/issues/issue-4830.rs b/tests/ui/issues/issue-4830.rs
index 364def61da8..d48c13fd10b 100644
--- a/tests/ui/issues/issue-4830.rs
+++ b/tests/ui/issues/issue-4830.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 #![allow(dead_code)]
 
-//@ pretty-expanded FIXME #23616
 
 pub struct Scheduler {
     /// The event loop used to drive the scheduler and perform I/O
diff --git a/tests/ui/issues/issue-4875.rs b/tests/ui/issues/issue-4875.rs
index 3b09331873c..5068399ff0d 100644
--- a/tests/ui/issues/issue-4875.rs
+++ b/tests/ui/issues/issue-4875.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 // regression test for issue 4875
 
-//@ pretty-expanded FIXME #23616
 
 pub struct Foo<T> {
     data: T,
diff --git a/tests/ui/issues/issue-5192.rs b/tests/ui/issues/issue-5192.rs
index 8911e7a733b..be5d70f09b3 100644
--- a/tests/ui/issues/issue-5192.rs
+++ b/tests/ui/issues/issue-5192.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub trait EventLoop {
     fn dummy(&self) { }
diff --git a/tests/ui/issues/issue-5315.rs b/tests/ui/issues/issue-5315.rs
index 64a48b9e842..29a6f8f2934 100644
--- a/tests/ui/issues/issue-5315.rs
+++ b/tests/ui/issues/issue-5315.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 struct A(#[allow(dead_code)] bool);
 
diff --git a/tests/ui/issues/issue-5518.rs b/tests/ui/issues/issue-5518.rs
index 4e1049f02fb..333185c482f 100644
--- a/tests/ui/issues/issue-5518.rs
+++ b/tests/ui/issues/issue-5518.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-5518.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_5518 as other;
 
diff --git a/tests/ui/issues/issue-5550.rs b/tests/ui/issues/issue-5550.rs
index e967590c650..41de8ee5d32 100644
--- a/tests/ui/issues/issue-5550.rs
+++ b/tests/ui/issues/issue-5550.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_assignments)]
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let s: String = "foobar".to_string();
diff --git a/tests/ui/issues/issue-5554.rs b/tests/ui/issues/issue-5554.rs
index 532d1b4092e..7d219a0df70 100644
--- a/tests/ui/issues/issue-5554.rs
+++ b/tests/ui/issues/issue-5554.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 
 pub struct X<T> {
diff --git a/tests/ui/issues/issue-55587.stderr b/tests/ui/issues/issue-55587.stderr
index eec6426a299..7a5d0e28100 100644
--- a/tests/ui/issues/issue-55587.stderr
+++ b/tests/ui/issues/issue-55587.stderr
@@ -4,7 +4,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function
 LL |     let Path::new();
    |         ^^^^^^^^^^^ `fn` calls are not allowed in patterns
    |
-   = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
+   = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-5572.rs b/tests/ui/issues/issue-5572.rs
index 8a4c867f585..f27744ef0ac 100644
--- a/tests/ui/issues/issue-5572.rs
+++ b/tests/ui/issues/issue-5572.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn foo<T: ::std::cmp::PartialEq>(_t: T) { }
 
diff --git a/tests/ui/issues/issue-5718.rs b/tests/ui/issues/issue-5718.rs
index c30061298d1..234fb2e2222 100644
--- a/tests/ui/issues/issue-5718.rs
+++ b/tests/ui/issues/issue-5718.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 struct Element;
 
diff --git a/tests/ui/issues/issue-5741.rs b/tests/ui/issues/issue-5741.rs
index dad16dd39e2..af4702ec22c 100644
--- a/tests/ui/issues/issue-5741.rs
+++ b/tests/ui/issues/issue-5741.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 #![allow(while_true)]
 #![allow(unreachable_code)]
 
diff --git a/tests/ui/issues/issue-5754.rs b/tests/ui/issues/issue-5754.rs
index 2b61da02c30..0aa09882959 100644
--- a/tests/ui/issues/issue-5754.rs
+++ b/tests/ui/issues/issue-5754.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(improper_ctypes)]
 
-//@ pretty-expanded FIXME #23616
 
 struct TwoDoubles {
     r: f64,
diff --git a/tests/ui/issues/issue-5884.rs b/tests/ui/issues/issue-5884.rs
index 17cb4133632..559b897395d 100644
--- a/tests/ui/issues/issue-5884.rs
+++ b/tests/ui/issues/issue-5884.rs
@@ -1,6 +1,5 @@
 //@ build-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub struct Foo {
     a: isize,
diff --git a/tests/ui/issues/issue-5900.rs b/tests/ui/issues/issue-5900.rs
index 986a8233ef2..14b7b8f815a 100644
--- a/tests/ui/issues/issue-5900.rs
+++ b/tests/ui/issues/issue-5900.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub mod foo {
     use super::Bar;
diff --git a/tests/ui/issues/issue-5950.rs b/tests/ui/issues/issue-5950.rs
index a0822459ad1..6015560fcf8 100644
--- a/tests/ui/issues/issue-5950.rs
+++ b/tests/ui/issues/issue-5950.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 
-//@ pretty-expanded FIXME #23616
 
 pub use local as local_alias;
 
diff --git a/tests/ui/issues/issue-5988.rs b/tests/ui/issues/issue-5988.rs
index 801a5edca08..b7527d9bea8 100644
--- a/tests/ui/issues/issue-5988.rs
+++ b/tests/ui/issues/issue-5988.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 trait B {
     fn f(&self);
diff --git a/tests/ui/issues/issue-6117.rs b/tests/ui/issues/issue-6117.rs
index 4fa99d955c9..3ccf67b0319 100644
--- a/tests/ui/issues/issue-6117.rs
+++ b/tests/ui/issues/issue-6117.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 enum Either<T, U> { Left(T), Right(U) }
 
diff --git a/tests/ui/issues/issue-6318.rs b/tests/ui/issues/issue-6318.rs
index 3b17754ffdc..d3f08285a93 100644
--- a/tests/ui/issues/issue-6318.rs
+++ b/tests/ui/issues/issue-6318.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub enum Thing {
     A(Box<dyn Foo+'static>)
diff --git a/tests/ui/issues/issue-6557.rs b/tests/ui/issues/issue-6557.rs
index 89ebb0610dd..64a025a294f 100644
--- a/tests/ui/issues/issue-6557.rs
+++ b/tests/ui/issues/issue-6557.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 #![feature(box_patterns)]
 
diff --git a/tests/ui/issues/issue-6898.rs b/tests/ui/issues/issue-6898.rs
index cc0fe35fc88..c810acaf61b 100644
--- a/tests/ui/issues/issue-6898.rs
+++ b/tests/ui/issues/issue-6898.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 use std::mem;
 
diff --git a/tests/ui/issues/issue-6919.rs b/tests/ui/issues/issue-6919.rs
index 3aa66882c19..7fb8a2f33bc 100644
--- a/tests/ui/issues/issue-6919.rs
+++ b/tests/ui/issues/issue-6919.rs
@@ -2,7 +2,6 @@
 #![allow(unused_attributes)]
 //@ aux-build:iss.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue6919_3;
 
diff --git a/tests/ui/issues/issue-7178.rs b/tests/ui/issues/issue-7178.rs
index 153ce2cf057..408ce0b03eb 100644
--- a/tests/ui/issues/issue-7178.rs
+++ b/tests/ui/issues/issue-7178.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-7178.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_7178 as cross_crate_self;
 
diff --git a/tests/ui/issues/issue-7268.rs b/tests/ui/issues/issue-7268.rs
index 99b780bcf5c..a3bc1bc3446 100644
--- a/tests/ui/issues/issue-7268.rs
+++ b/tests/ui/issues/issue-7268.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn foo<T: 'static>(_: T) {}
 
diff --git a/tests/ui/issues/issue-7344.rs b/tests/ui/issues/issue-7344.rs
index 9503037723e..406b24634f5 100644
--- a/tests/ui/issues/issue-7344.rs
+++ b/tests/ui/issues/issue-7344.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ pretty-expanded FIXME #23616
 
 #![allow(unreachable_code)]
 
diff --git a/tests/ui/issues/issue-7519-match-unit-in-arg.rs b/tests/ui/issues/issue-7519-match-unit-in-arg.rs
index 2b5f1b7f169..a7cea577b22 100644
--- a/tests/ui/issues/issue-7519-match-unit-in-arg.rs
+++ b/tests/ui/issues/issue-7519-match-unit-in-arg.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 /*
 #7519 ICE pattern matching unit in function argument
diff --git a/tests/ui/issues/issue-7660.rs b/tests/ui/issues/issue-7660.rs
index 4b0f7d84b75..104cdad8f7b 100644
--- a/tests/ui/issues/issue-7660.rs
+++ b/tests/ui/issues/issue-7660.rs
@@ -3,7 +3,6 @@
 // Regression test for issue 7660
 // rvalue lifetime too short when equivalent `match` works
 
-//@ pretty-expanded FIXME #23616
 
 use std::collections::HashMap;
 
diff --git a/tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs b/tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs
index 742152b6c81..edba3284e31 100644
--- a/tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs
+++ b/tests/ui/issues/issue-7673-cast-generically-implemented-trait.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 /*
 
diff --git a/tests/ui/issues/issue-7899.rs b/tests/ui/issues/issue-7899.rs
index a2aee240da7..4b69f3e3d89 100644
--- a/tests/ui/issues/issue-7899.rs
+++ b/tests/ui/issues/issue-7899.rs
@@ -2,7 +2,6 @@
 #![allow(unused_variables)]
 //@ aux-build:issue-7899.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_7899 as testcrate;
 
diff --git a/tests/ui/issues/issue-8044.rs b/tests/ui/issues/issue-8044.rs
index b965e0bbb10..3c10bbca634 100644
--- a/tests/ui/issues/issue-8044.rs
+++ b/tests/ui/issues/issue-8044.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-8044.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_8044 as minimal;
 use minimal::{BTree, leaf};
diff --git a/tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs b/tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
index 88d56185f6b..6a03404cdca 100644
--- a/tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
+++ b/tests/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 /*
 
diff --git a/tests/ui/issues/issue-8248.rs b/tests/ui/issues/issue-8248.rs
index c34575df368..95f626658cc 100644
--- a/tests/ui/issues/issue-8248.rs
+++ b/tests/ui/issues/issue-8248.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 trait A {
     fn dummy(&self) { } //~ WARN method `dummy` is never used
diff --git a/tests/ui/issues/issue-8248.stderr b/tests/ui/issues/issue-8248.stderr
index a0098bcb771..8570bfaefad 100644
--- a/tests/ui/issues/issue-8248.stderr
+++ b/tests/ui/issues/issue-8248.stderr
@@ -1,5 +1,5 @@
 warning: method `dummy` is never used
-  --> $DIR/issue-8248.rs:5:8
+  --> $DIR/issue-8248.rs:4:8
    |
 LL | trait A {
    |       - method in this trait
diff --git a/tests/ui/issues/issue-8249.rs b/tests/ui/issues/issue-8249.rs
index 67a42619316..2364fc14d31 100644
--- a/tests/ui/issues/issue-8249.rs
+++ b/tests/ui/issues/issue-8249.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait A {
     fn dummy(&self) { }
diff --git a/tests/ui/issues/issue-8259.rs b/tests/ui/issues/issue-8259.rs
index f790e1a2155..e843f7f9c50 100644
--- a/tests/ui/issues/issue-8259.rs
+++ b/tests/ui/issues/issue-8259.rs
@@ -4,7 +4,6 @@
 
 //@ aux-build:issue-8259.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_8259 as other;
 static a: other::Foo<'static> = other::Foo::A;
diff --git a/tests/ui/issues/issue-8398.rs b/tests/ui/issues/issue-8398.rs
index 6f91b1dbb28..7d100b855fd 100644
--- a/tests/ui/issues/issue-8398.rs
+++ b/tests/ui/issues/issue-8398.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub trait Writer {
     fn write(&mut self, b: &[u8]) -> Result<(), ()>;
diff --git a/tests/ui/issues/issue-8401.rs b/tests/ui/issues/issue-8401.rs
index b72616bb28f..1df63516fb0 100644
--- a/tests/ui/issues/issue-8401.rs
+++ b/tests/ui/issues/issue-8401.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-8401.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_8401;
 
diff --git a/tests/ui/issues/issue-8506.rs b/tests/ui/issues/issue-8506.rs
index 48abd7efc7b..30a789a3e27 100644
--- a/tests/ui/issues/issue-8506.rs
+++ b/tests/ui/issues/issue-8506.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 #![allow(non_upper_case_globals)]
 
 #![allow(dead_code)]
diff --git a/tests/ui/issues/issue-8578.rs b/tests/ui/issues/issue-8578.rs
index e081d7a5415..9baa2f70a02 100644
--- a/tests/ui/issues/issue-8578.rs
+++ b/tests/ui/issues/issue-8578.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 #![allow(non_upper_case_globals)]
-//@ pretty-expanded FIXME #23616
 
 pub struct UninterpretedOption_NamePart {
     name_part: Option<String>,
diff --git a/tests/ui/issues/issue-8783.rs b/tests/ui/issues/issue-8783.rs
index a7c96b69b18..d0ff79f8ac8 100644
--- a/tests/ui/issues/issue-8783.rs
+++ b/tests/ui/issues/issue-8783.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 struct X { pub x: usize }
 impl Default for X {
diff --git a/tests/ui/issues/issue-9110.rs b/tests/ui/issues/issue-9110.rs
index 9aeda7d5b1b..47533dc43b5 100644
--- a/tests/ui/issues/issue-9110.rs
+++ b/tests/ui/issues/issue-9110.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 #![allow(non_snake_case)]
 
 macro_rules! silly_macro {
diff --git a/tests/ui/issues/issue-9123.rs b/tests/ui/issues/issue-9123.rs
index e554a8c8ff2..bbf6c13341c 100644
--- a/tests/ui/issues/issue-9123.rs
+++ b/tests/ui/issues/issue-9123.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-9123.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_9123;
 
diff --git a/tests/ui/issues/issue-9155.rs b/tests/ui/issues/issue-9155.rs
index e177c597800..dfd9dea2009 100644
--- a/tests/ui/issues/issue-9155.rs
+++ b/tests/ui/issues/issue-9155.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-9155.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_9155;
 
diff --git a/tests/ui/issues/issue-9249.rs b/tests/ui/issues/issue-9249.rs
index 893d01637de..b98ba050521 100644
--- a/tests/ui/issues/issue-9249.rs
+++ b/tests/ui/issues/issue-9249.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 static DATA:&'static [&'static str] = &["my string"];
 fn main() { }
diff --git a/tests/ui/issues/issue-9382.rs b/tests/ui/issues/issue-9382.rs
index 4b37e5b381f..27f9ab57743 100644
--- a/tests/ui/issues/issue-9382.rs
+++ b/tests/ui/issues/issue-9382.rs
@@ -1,6 +1,3 @@
-//@ pretty-expanded FIXME #23616
-
-
 //@ run-pass
 #![allow(dead_code)]
 
diff --git a/tests/ui/issues/issue-9719.rs b/tests/ui/issues/issue-9719.rs
index e48c020328a..904768c9341 100644
--- a/tests/ui/issues/issue-9719.rs
+++ b/tests/ui/issues/issue-9719.rs
@@ -1,6 +1,5 @@
 //@ build-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 mod a {
     pub enum Enum<T> {
diff --git a/tests/ui/issues/issue-9906.rs b/tests/ui/issues/issue-9906.rs
index b425df4975f..50417d3e456 100644
--- a/tests/ui/issues/issue-9906.rs
+++ b/tests/ui/issues/issue-9906.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-9906.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_9906 as testmod;
 
diff --git a/tests/ui/issues/issue-9942.rs b/tests/ui/issues/issue-9942.rs
index 76c90903306..6332d9b3e08 100644
--- a/tests/ui/issues/issue-9942.rs
+++ b/tests/ui/issues/issue-9942.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     const S: usize = 23 as usize; [0; S]; ()
diff --git a/tests/ui/issues/issue-9951.rs b/tests/ui/issues/issue-9951.rs
index 42a65c701f7..2cd7cd4f430 100644
--- a/tests/ui/issues/issue-9951.rs
+++ b/tests/ui/issues/issue-9951.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_variables)]
 
diff --git a/tests/ui/issues/issue-9951.stderr b/tests/ui/issues/issue-9951.stderr
index 475f2817914..62ed9f3e0cc 100644
--- a/tests/ui/issues/issue-9951.stderr
+++ b/tests/ui/issues/issue-9951.stderr
@@ -1,5 +1,5 @@
 warning: method `noop` is never used
-  --> $DIR/issue-9951.rs:7:6
+  --> $DIR/issue-9951.rs:6:6
    |
 LL | trait Bar {
    |       --- method in this trait
diff --git a/tests/ui/issues/issue-9968.rs b/tests/ui/issues/issue-9968.rs
index 5ceea056634..89e60ba5ac7 100644
--- a/tests/ui/issues/issue-9968.rs
+++ b/tests/ui/issues/issue-9968.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-9968.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_9968 as lib;
 
diff --git a/tests/ui/item-name-overload.rs b/tests/ui/item-name-overload.rs
index 54aa470e59e..dd2925aa53f 100644
--- a/tests/ui/item-name-overload.rs
+++ b/tests/ui/item-name-overload.rs
@@ -4,7 +4,6 @@
 
 
 
-//@ pretty-expanded FIXME #23616
 
 mod foo {
     pub fn baz() { }
diff --git a/tests/ui/iterators/into-iter-on-boxed-slices-2024.rs b/tests/ui/iterators/into-iter-on-boxed-slices-2024.rs
index ffd6f022bc6..6e9b38be080 100644
--- a/tests/ui/iterators/into-iter-on-boxed-slices-2024.rs
+++ b/tests/ui/iterators/into-iter-on-boxed-slices-2024.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 //@ edition:2024
-//@ compile-flags: -Zunstable-options
 
 use std::ops::Deref;
 use std::rc::Rc;
diff --git a/tests/ui/iterators/into-iterator-type-inference-shift.rs b/tests/ui/iterators/into-iterator-type-inference-shift.rs
index b550dc27f5c..6b07a6bcb0a 100644
--- a/tests/ui/iterators/into-iterator-type-inference-shift.rs
+++ b/tests/ui/iterators/into-iterator-type-inference-shift.rs
@@ -8,7 +8,6 @@
 // propagation yet, and so we just saw a type variable, yielding an
 // error.
 
-//@ pretty-expanded FIXME #23616
 
 trait IntoIterator {
     type Iter: Iterator;
diff --git a/tests/ui/kinds-in-metadata.rs b/tests/ui/kinds-in-metadata.rs
index d557f949c76..58dffba861d 100644
--- a/tests/ui/kinds-in-metadata.rs
+++ b/tests/ui/kinds-in-metadata.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:kinds_in_metadata.rs
 
-//@ pretty-expanded FIXME #23616
 
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
diff --git a/tests/ui/layout/aggregate-lang/struct-align.rs b/tests/ui/layout/aggregate-lang/struct-align.rs
new file mode 100644
index 00000000000..f3b88a6d85d
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/struct-align.rs
@@ -0,0 +1,29 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-size-align
+//@ edition: 2018
+
+#[repr(align(64))]
+#[derive(Copy, Clone)]
+#[allow(dead_code)]
+pub struct Overaligned(u8);
+
+#[allow(dead_code)]
+struct ReprRustStruct {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+    b: Overaligned,
+}
+
+fn test_alignment_contains_all_fields() {
+    assert!(core::mem::align_of::<ReprRustStruct>() >= core::mem::align_of::<i32>());
+    assert!(core::mem::align_of::<ReprRustStruct>() >= core::mem::align_of::<[u32; 4]>());
+    assert!(core::mem::align_of::<ReprRustStruct>() >= core::mem::align_of::<f32>());
+    assert!(core::mem::align_of::<ReprRustStruct>() >= core::mem::align_of::<u128>());
+    assert!(core::mem::align_of::<ReprRustStruct>() >= core::mem::align_of::<Overaligned>());
+}
+
+fn main() {
+    test_alignment_contains_all_fields();
+}
diff --git a/tests/ui/layout/aggregate-lang/struct-offsets.rs b/tests/ui/layout/aggregate-lang/struct-offsets.rs
new file mode 100644
index 00000000000..ca199bdfeb1
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/struct-offsets.rs
@@ -0,0 +1,78 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-offsets
+//@ edition: 2018
+
+#[repr(align(64))]
+#[derive(Copy, Clone)]
+#[allow(dead_code)]
+pub struct Overaligned(u8);
+
+#[allow(dead_code)]
+struct ReprRustStruct {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+    b: Overaligned,
+}
+
+macro_rules! span_of {
+    ($ty:ty , $field:tt) => {{
+        let __field = unsafe { ::core::mem::zeroed::<$ty>() };
+
+        (
+            core::mem::offset_of!($ty, $field),
+            core::mem::offset_of!($ty, $field) + core::mem::size_of_val(&__field.$field),
+        )
+    }};
+}
+
+fn test_fields_make_sense(a: &(usize, usize)) {
+    assert!(a.0 <= a.1);
+}
+
+// order is `begin, end`
+fn test_non_overlapping(a: &(usize, usize), b: &(usize, usize)) {
+    assert!((a.1 <= b.0) || (b.1 <= a.0));
+}
+
+fn test_fields_non_overlapping() {
+    let fields = [
+        span_of!(ReprRustStruct, x),
+        span_of!(ReprRustStruct, y),
+        span_of!(ReprRustStruct, z),
+        span_of!(ReprRustStruct, a),
+        span_of!(ReprRustStruct, b),
+    ];
+
+    test_fields_make_sense(&fields[0]);
+    test_fields_make_sense(&fields[1]);
+    test_fields_make_sense(&fields[2]);
+    test_fields_make_sense(&fields[3]);
+    test_fields_make_sense(&fields[4]);
+
+    test_non_overlapping(&fields[0], &fields[1]);
+    test_non_overlapping(&fields[0], &fields[2]);
+    test_non_overlapping(&fields[0], &fields[3]);
+    test_non_overlapping(&fields[0], &fields[4]);
+    test_non_overlapping(&fields[1], &fields[2]);
+    test_non_overlapping(&fields[2], &fields[3]);
+    test_non_overlapping(&fields[2], &fields[4]);
+    test_non_overlapping(&fields[3], &fields[4]);
+}
+
+fn test_fields_aligned() {
+    assert_eq!((core::mem::offset_of!(ReprRustStruct, x) % (core::mem::align_of::<i32>())), 0);
+    assert_eq!((core::mem::offset_of!(ReprRustStruct, y) % (core::mem::align_of::<[u32; 4]>())), 0);
+    assert_eq!((core::mem::offset_of!(ReprRustStruct, z) % (core::mem::align_of::<f32>())), 0);
+    assert_eq!((core::mem::offset_of!(ReprRustStruct, a) % (core::mem::align_of::<u128>())), 0);
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustStruct, b) % (core::mem::align_of::<Overaligned>())),
+        0
+    );
+}
+
+fn main() {
+    test_fields_non_overlapping();
+    test_fields_aligned();
+}
diff --git a/tests/ui/layout/aggregate-lang/struct-size.rs b/tests/ui/layout/aggregate-lang/struct-size.rs
new file mode 100644
index 00000000000..f9fb605c324
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/struct-size.rs
@@ -0,0 +1,50 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-size-align
+//@ edition: 2018
+
+#[allow(dead_code)]
+struct ReprRustStruct {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+}
+
+fn test_size_contains_all_types() {
+    assert!(
+        core::mem::size_of::<ReprRustStruct>()
+            >= (core::mem::size_of::<i32>()
+                + core::mem::size_of::<[u32; 4]>()
+                + core::mem::size_of::<f32>()
+                + core::mem::size_of::<u128>())
+    );
+}
+
+fn test_size_contains_all_fields() {
+    assert!(
+        (core::mem::offset_of!(ReprRustStruct, x) + core::mem::size_of::<i32>())
+            <= core::mem::size_of::<ReprRustStruct>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustStruct, y) + core::mem::size_of::<[u32; 4]>())
+            <= core::mem::size_of::<ReprRustStruct>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustStruct, z) + core::mem::size_of::<f32>())
+            <= core::mem::size_of::<ReprRustStruct>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustStruct, a) + core::mem::size_of::<u128>())
+            <= core::mem::size_of::<ReprRustStruct>()
+    );
+}
+
+fn test_size_modulo_align() {
+    assert_eq!(core::mem::size_of::<ReprRustStruct>() % core::mem::align_of::<ReprRustStruct>(), 0);
+}
+
+fn main() {
+    test_size_contains_all_fields();
+    test_size_contains_all_types();
+    test_size_modulo_align();
+}
diff --git a/tests/ui/layout/aggregate-lang/union-align.rs b/tests/ui/layout/aggregate-lang/union-align.rs
new file mode 100644
index 00000000000..03825f1df21
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/union-align.rs
@@ -0,0 +1,29 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-size-align
+//@ edition: 2018
+
+#[repr(align(64))]
+#[derive(Copy, Clone)]
+#[allow(dead_code)]
+pub struct Overaligned(u8);
+
+#[allow(dead_code)]
+union ReprRustUnion {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+    b: Overaligned,
+}
+
+fn test_alignment_contains_all_fields() {
+    assert!(core::mem::align_of::<ReprRustUnion>() >= core::mem::align_of::<i32>());
+    assert!(core::mem::align_of::<ReprRustUnion>() >= core::mem::align_of::<[u32; 4]>());
+    assert!(core::mem::align_of::<ReprRustUnion>() >= core::mem::align_of::<f32>());
+    assert!(core::mem::align_of::<ReprRustUnion>() >= core::mem::align_of::<u128>());
+    assert!(core::mem::align_of::<ReprRustUnion>() >= core::mem::align_of::<Overaligned>());
+}
+
+fn main() {
+    test_alignment_contains_all_fields();
+}
diff --git a/tests/ui/layout/aggregate-lang/union-offsets.rs b/tests/ui/layout/aggregate-lang/union-offsets.rs
new file mode 100644
index 00000000000..29ab0a9ce54
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/union-offsets.rs
@@ -0,0 +1,32 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-offsets
+//@ edition: 2018
+
+#[repr(align(64))]
+#[derive(Copy, Clone)]
+#[allow(dead_code)]
+pub struct Overaligned(u8);
+
+#[allow(dead_code)]
+union ReprRustUnion {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+    b: Overaligned,
+}
+
+fn test_fields_aligned() {
+    assert_eq!((core::mem::offset_of!(ReprRustUnion, x) % (core::mem::align_of::<i32>())), 0);
+    assert_eq!((core::mem::offset_of!(ReprRustUnion, y) % (core::mem::align_of::<[u32; 4]>())), 0);
+    assert_eq!((core::mem::offset_of!(ReprRustUnion, z) % (core::mem::align_of::<f32>())), 0);
+    assert_eq!((core::mem::offset_of!(ReprRustUnion, a) % (core::mem::align_of::<u128>())), 0);
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustUnion, b) % (core::mem::align_of::<Overaligned>())),
+        0
+    );
+}
+
+fn main() {
+    test_fields_aligned();
+}
diff --git a/tests/ui/layout/aggregate-lang/union-size.rs b/tests/ui/layout/aggregate-lang/union-size.rs
new file mode 100644
index 00000000000..6d1b51b172d
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/union-size.rs
@@ -0,0 +1,47 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-size-align
+//@ edition: 2018
+
+#[allow(dead_code)]
+union ReprRustUnion {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+}
+
+fn test_size_contains_each_type() {
+    assert!(core::mem::size_of::<i32>() <= core::mem::size_of::<ReprRustUnion>());
+    assert!(core::mem::size_of::<[u32; 4]>() <= core::mem::size_of::<ReprRustUnion>());
+    assert!(core::mem::size_of::<f32>() <= core::mem::size_of::<ReprRustUnion>());
+    assert!(core::mem::size_of::<u128>() <= core::mem::size_of::<ReprRustUnion>());
+}
+
+fn test_size_contains_all_fields() {
+    assert!(
+        (core::mem::offset_of!(ReprRustUnion, x) + core::mem::size_of::<i32>())
+            <= core::mem::size_of::<ReprRustUnion>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustUnion, y) + core::mem::size_of::<[u32; 4]>())
+            <= core::mem::size_of::<ReprRustUnion>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustUnion, z) + core::mem::size_of::<f32>())
+            <= core::mem::size_of::<ReprRustUnion>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustUnion, a) + core::mem::size_of::<u128>())
+            <= core::mem::size_of::<ReprRustUnion>()
+    );
+}
+
+fn test_size_modulo_align() {
+    assert_eq!(core::mem::size_of::<ReprRustUnion>() % core::mem::align_of::<ReprRustUnion>(), 0);
+}
+
+fn main() {
+    test_size_contains_each_type();
+    test_size_contains_all_fields();
+    test_size_modulo_align();
+}
diff --git a/tests/ui/layout/ice-type-error-in-tail-124031.rs b/tests/ui/layout/ice-type-error-in-tail-124031.rs
index 0a2be117403..ecd6f3d56f3 100644
--- a/tests/ui/layout/ice-type-error-in-tail-124031.rs
+++ b/tests/ui/layout/ice-type-error-in-tail-124031.rs
@@ -1,3 +1,5 @@
+//@ normalize-stderr-test: "\d+ bits" -> "$$BITS bits"
+
 // Regression test for issue #124031
 // Checks that we don't ICE when the tail
 // of an ADT has a type error
@@ -16,5 +18,6 @@ struct Other {
 fn main() {
     unsafe {
         std::mem::transmute::<Option<()>, Option<&Other>>(None);
+        //~^ ERROR cannot transmute between types of different sizes
     }
 }
diff --git a/tests/ui/layout/ice-type-error-in-tail-124031.stderr b/tests/ui/layout/ice-type-error-in-tail-124031.stderr
index 57dc83f92df..a066e8574dc 100644
--- a/tests/ui/layout/ice-type-error-in-tail-124031.stderr
+++ b/tests/ui/layout/ice-type-error-in-tail-124031.stderr
@@ -1,5 +1,5 @@
 error[E0046]: not all trait items implemented, missing: `RefTarget`
-  --> $DIR/ice-type-error-in-tail-124031.rs:9:1
+  --> $DIR/ice-type-error-in-tail-124031.rs:11:1
    |
 LL |     type RefTarget;
    |     -------------- `RefTarget` from trait
@@ -7,6 +7,16 @@ LL |     type RefTarget;
 LL | impl Trait for () {}
    | ^^^^^^^^^^^^^^^^^ missing `RefTarget` in implementation
 
-error: aborting due to 1 previous error
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+  --> $DIR/ice-type-error-in-tail-124031.rs:20:9
+   |
+LL |         std::mem::transmute::<Option<()>, Option<&Other>>(None);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: `Option<()>` ($BITS bits)
+   = note: target type: `Option<&Other>` ($BITS bits)
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0046`.
+Some errors have detailed explanations: E0046, E0512.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs
new file mode 100644
index 00000000000..6ded9118700
--- /dev/null
+++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs
@@ -0,0 +1,18 @@
+// regression test for #127351
+
+#![feature(lazy_type_alias)]
+//~^ WARN the feature `lazy_type_alias` is incomplete
+
+type ExplicitTypeOutlives<T> = T;
+
+pub struct Warns {
+    _significant_drop: ExplicitTypeOutlives,
+    //~^ ERROR missing generics for type alias `ExplicitTypeOutlives`
+    field: String,
+}
+
+pub fn test(w: Warns) {
+    let _ = || drop(w.field);
+}
+
+fn main() {}
diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr
new file mode 100644
index 00000000000..3a5ded60241
--- /dev/null
+++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr
@@ -0,0 +1,28 @@
+warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/bad-lazy-type-alias.rs:3:12
+   |
+LL | #![feature(lazy_type_alias)]
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0107]: missing generics for type alias `ExplicitTypeOutlives`
+  --> $DIR/bad-lazy-type-alias.rs:9:24
+   |
+LL |     _significant_drop: ExplicitTypeOutlives,
+   |                        ^^^^^^^^^^^^^^^^^^^^ expected 1 generic argument
+   |
+note: type alias defined here, with 1 generic parameter: `T`
+  --> $DIR/bad-lazy-type-alias.rs:6:6
+   |
+LL | type ExplicitTypeOutlives<T> = T;
+   |      ^^^^^^^^^^^^^^^^^^^^ -
+help: add missing generic argument
+   |
+LL |     _significant_drop: ExplicitTypeOutlives<T>,
+   |                                            +++
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr b/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr
index 13312306c07..58f9e267db3 100644
--- a/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr
+++ b/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr
@@ -5,7 +5,7 @@ LL |     let Some(x);
    |         ^^^^^^^ pattern `None` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Option<i32>`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/lifetimes/tail-expr-in-nested-expr.rs b/tests/ui/lifetimes/tail-expr-in-nested-expr.rs
index 2ac97aff2b0..741cdacdb1d 100644
--- a/tests/ui/lifetimes/tail-expr-in-nested-expr.rs
+++ b/tests/ui/lifetimes/tail-expr-in-nested-expr.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 
 fn main() {
     let _ = { String::new().as_str() }.len();
diff --git a/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr b/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr
index 96e88eaca92..6770da091ce 100644
--- a/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr
+++ b/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr
@@ -1,5 +1,5 @@
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/tail-expr-in-nested-expr.rs:5:15
+  --> $DIR/tail-expr-in-nested-expr.rs:4:15
    |
 LL |     let _ = { String::new().as_str() }.len();
    |               ^^^^^^^^^^^^^---------
diff --git a/tests/ui/linkage-attr/issue-12133-1.rs b/tests/ui/linkage-attr/issue-12133-1.rs
index dc3f7f33da1..f545db67e92 100644
--- a/tests/ui/linkage-attr/issue-12133-1.rs
+++ b/tests/ui/linkage-attr/issue-12133-1.rs
@@ -2,7 +2,6 @@
 //@ aux-build:issue-12133-rlib.rs
 //@ aux-build:issue-12133-dylib.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_12133_rlib as a;
 extern crate issue_12133_dylib as b;
diff --git a/tests/ui/linkage-attr/issue-12133-2.rs b/tests/ui/linkage-attr/issue-12133-2.rs
index 55742a1b383..bc2dd84e0f7 100644
--- a/tests/ui/linkage-attr/issue-12133-2.rs
+++ b/tests/ui/linkage-attr/issue-12133-2.rs
@@ -3,7 +3,6 @@
 //@ aux-build:issue-12133-dylib.rs
 //@ no-prefer-dynamic
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_12133_rlib as a;
 extern crate issue_12133_dylib as b;
diff --git a/tests/ui/linkage-attr/issue-12133-3.rs b/tests/ui/linkage-attr/issue-12133-3.rs
index a34c075d64d..473d5774c16 100644
--- a/tests/ui/linkage-attr/issue-12133-3.rs
+++ b/tests/ui/linkage-attr/issue-12133-3.rs
@@ -6,7 +6,6 @@
 //@ ignore-musl
 //@ needs-dynamic-linking
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_12133_dylib2 as other;
 
diff --git a/tests/ui/lint/dead-code/leading-underscore.rs b/tests/ui/lint/dead-code/leading-underscore.rs
index 0ef123efc24..0c5fecb27a8 100644
--- a/tests/ui/lint/dead-code/leading-underscore.rs
+++ b/tests/ui/lint/dead-code/leading-underscore.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![deny(dead_code)]
 
diff --git a/tests/ui/lint/issue-14837.rs b/tests/ui/lint/issue-14837.rs
index 73c63cde2ba..829df15ae51 100644
--- a/tests/ui/lint/issue-14837.rs
+++ b/tests/ui/lint/issue-14837.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 #[deny(dead_code)]
 pub enum Foo {
diff --git a/tests/ui/lint/issue-1866.rs b/tests/ui/lint/issue-1866.rs
index 386aeeb6ad0..4a571fbeb02 100644
--- a/tests/ui/lint/issue-1866.rs
+++ b/tests/ui/lint/issue-1866.rs
@@ -3,7 +3,6 @@
 #![allow(non_camel_case_types)]
 #![warn(clashing_extern_declarations)]
 
-//@ pretty-expanded FIXME #23616
 
 mod a {
     pub type rust_task = usize;
diff --git a/tests/ui/lint/issue-1866.stderr b/tests/ui/lint/issue-1866.stderr
index d19a1349668..3ea9d209658 100644
--- a/tests/ui/lint/issue-1866.stderr
+++ b/tests/ui/lint/issue-1866.stderr
@@ -1,5 +1,5 @@
 warning: `rust_task_is_unwinding` redeclared with a different signature
-  --> $DIR/issue-1866.rs:23:13
+  --> $DIR/issue-1866.rs:22:13
    |
 LL |             pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool;
    |             ------------------------------------------------------------ `rust_task_is_unwinding` previously declared here
diff --git a/tests/ui/lint/issue-20343.rs b/tests/ui/lint/issue-20343.rs
index 24e8062b1f3..da353c985c9 100644
--- a/tests/ui/lint/issue-20343.rs
+++ b/tests/ui/lint/issue-20343.rs
@@ -2,7 +2,6 @@
 #![allow(unused_variables)]
 // Regression test for Issue #20343.
 
-//@ pretty-expanded FIXME #23616
 
 #![deny(dead_code)]
 
diff --git a/tests/ui/lint/issue-79546-fuel-ice.rs b/tests/ui/lint/issue-79546-fuel-ice.rs
deleted file mode 100644
index dbee924d26e..00000000000
--- a/tests/ui/lint/issue-79546-fuel-ice.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// Regression test for the ICE described in #79546.
-
-//@ compile-flags: --cap-lints=allow -Zfuel=issue79546=0
-//@ check-pass
-#![crate_name="issue79546"]
-
-struct S;
-fn main() {}
diff --git a/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs b/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs
index 30091253f4d..178ee0e6663 100644
--- a/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs
+++ b/tests/ui/lint/lint-non-camel-case-with-trailing-underscores.rs
@@ -3,7 +3,6 @@
 #![allow(dead_code)]
 // This is ok because we often use the trailing underscore to mean 'prime'
 
-//@ pretty-expanded FIXME #23616
 
 #[forbid(non_camel_case_types)]
 type Foo_ = isize;
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-no-lowercase-equivalent.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-no-lowercase-equivalent.rs
index a43d2974ff3..7622f8b0454 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-no-lowercase-equivalent.rs
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-no-lowercase-equivalent.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 #![deny(non_snake_case)]
 
diff --git a/tests/ui/lint/warn-ctypes-inhibit.rs b/tests/ui/lint/warn-ctypes-inhibit.rs
index e3952dd0049..0f401150adf 100644
--- a/tests/ui/lint/warn-ctypes-inhibit.rs
+++ b/tests/ui/lint/warn-ctypes-inhibit.rs
@@ -3,7 +3,6 @@
 #![allow(dead_code)]
 //@ compile-flags:-D improper-ctypes
 
-//@ pretty-expanded FIXME #23616
 #![allow(improper_ctypes)]
 
 mod libc {
diff --git a/tests/ui/list.rs b/tests/ui/list.rs
index 7e5c2d8548b..443c4c9f28f 100644
--- a/tests/ui/list.rs
+++ b/tests/ui/list.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(non_camel_case_types)]
-//@ pretty-expanded FIXME #23616
 
 enum list { #[allow(dead_code)] cons(isize, Box<list>), nil, }
 
diff --git a/tests/ui/liveness/liveness-assign-imm-local-after-ret.rs b/tests/ui/liveness/liveness-assign-imm-local-after-ret.rs
index 298181e5529..ebdb5658537 100644
--- a/tests/ui/liveness/liveness-assign-imm-local-after-ret.rs
+++ b/tests/ui/liveness/liveness-assign-imm-local-after-ret.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(unreachable_code)]
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/loops/issue-1974.rs b/tests/ui/loops/issue-1974.rs
index ea67b2541de..9416f09c6e3 100644
--- a/tests/ui/loops/issue-1974.rs
+++ b/tests/ui/loops/issue-1974.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Issue 1974
 // Don't double free the condition allocation
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let s = "hej".to_string();
diff --git a/tests/ui/loops/loop-else-break-with-value.stderr b/tests/ui/loops/loop-else-break-with-value.stderr
index ca18f0fdd7f..da3276c8cd3 100644
--- a/tests/ui/loops/loop-else-break-with-value.stderr
+++ b/tests/ui/loops/loop-else-break-with-value.stderr
@@ -21,7 +21,7 @@ LL |     let Some(1) = loop {
    |         ^^^^^^^ pattern `None` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Option<i32>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/tests/ui/macros/defined-later-issue-121061-2.stderr b/tests/ui/macros/defined-later-issue-121061-2.stderr
index aa6ef338531..2ec590d46ed 100644
--- a/tests/ui/macros/defined-later-issue-121061-2.stderr
+++ b/tests/ui/macros/defined-later-issue-121061-2.stderr
@@ -4,7 +4,7 @@ error: cannot find macro `something_later` in this scope
 LL |         something_later!();
    |         ^^^^^^^^^^^^^^^ consider moving the definition of `something_later` before this call
    |
-note: a macro with the same name exists, but it appears later at here
+note: a macro with the same name exists, but it appears later
   --> $DIR/defined-later-issue-121061-2.rs:6:18
    |
 LL |     macro_rules! something_later {
diff --git a/tests/ui/macros/defined-later-issue-121061.stderr b/tests/ui/macros/defined-later-issue-121061.stderr
index 65cb53432a9..7b3496991af 100644
--- a/tests/ui/macros/defined-later-issue-121061.stderr
+++ b/tests/ui/macros/defined-later-issue-121061.stderr
@@ -4,7 +4,7 @@ error: cannot find macro `something_later` in this scope
 LL |     something_later!();
    |     ^^^^^^^^^^^^^^^ consider moving the definition of `something_later` before this call
    |
-note: a macro with the same name exists, but it appears later at here
+note: a macro with the same name exists, but it appears later
   --> $DIR/defined-later-issue-121061.rs:5:14
    |
 LL | macro_rules! something_later {
diff --git a/tests/ui/macros/expr_2021_implicit_in_2024.rs b/tests/ui/macros/expr_2021_implicit_in_2024.rs
index b3f7a31a802..f2eee1aa272 100644
--- a/tests/ui/macros/expr_2021_implicit_in_2024.rs
+++ b/tests/ui/macros/expr_2021_implicit_in_2024.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition=2024 -Zunstable-options
+//@ edition: 2024
 //@ aux-build:expr_2021_implicit.rs
 
 //@ check-pass
diff --git a/tests/ui/macros/expr_2021_inline_const.rs b/tests/ui/macros/expr_2021_inline_const.rs
index 312256f1879..257f5b2f8cf 100644
--- a/tests/ui/macros/expr_2021_inline_const.rs
+++ b/tests/ui/macros/expr_2021_inline_const.rs
@@ -1,6 +1,6 @@
 //@ revisions: edi2021 edi2024
-//@[edi2024]compile-flags: --edition=2024 -Z unstable-options
-//@[edi2021]compile-flags: --edition=2021
+//@[edi2024] edition: 2024
+//@[edi2021] edition: 2021
 
 // This test ensures that the inline const match only on edition 2024
 macro_rules! m2021 {
diff --git a/tests/ui/macros/expr_2024_underscore_expr.rs b/tests/ui/macros/expr_2024_underscore_expr.rs
index 6f8ec139109..1d45d60c136 100644
--- a/tests/ui/macros/expr_2024_underscore_expr.rs
+++ b/tests/ui/macros/expr_2024_underscore_expr.rs
@@ -1,6 +1,6 @@
 //@ revisions: edi2021 edi2024
-//@[edi2024]compile-flags: --edition=2024 -Z unstable-options
-//@[edi2021]compile-flags: --edition=2021
+//@[edi2024] edition: 2024
+//@[edi2021] edition: 2021
 // This test ensures that the `_` tok is considered an
 // expression on edition 2024.
 macro_rules! m2021 {
diff --git a/tests/ui/macros/issue-8851.rs b/tests/ui/macros/issue-8851.rs
index 4a398d15997..0198f3f358e 100644
--- a/tests/ui/macros/issue-8851.rs
+++ b/tests/ui/macros/issue-8851.rs
@@ -5,7 +5,6 @@
 // doesn't cause capture. Making this macro hygienic (as I've done)
 // could very well make this test case completely pointless....
 
-//@ pretty-expanded FIXME #23616
 
 enum T {
     A(isize),
diff --git a/tests/ui/macros/log_syntax-trace_macros-macro-locations.rs b/tests/ui/macros/log_syntax-trace_macros-macro-locations.rs
index 85a65300eaf..adf5448ffc0 100644
--- a/tests/ui/macros/log_syntax-trace_macros-macro-locations.rs
+++ b/tests/ui/macros/log_syntax-trace_macros-macro-locations.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![feature(trace_macros, log_syntax)]
 
diff --git a/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs b/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs
index 08fe2c92830..e80c712b03d 100644
--- a/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs
+++ b/tests/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 macro_rules! four {
     () => (4)
diff --git a/tests/ui/macros/macro-nt-list.rs b/tests/ui/macros/macro-nt-list.rs
index 7a6bc6a8d73..b7b260c5398 100644
--- a/tests/ui/macros/macro-nt-list.rs
+++ b/tests/ui/macros/macro-nt-list.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 macro_rules! list {
     ( ($($id:ident),*) ) => (());
diff --git a/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs
new file mode 100644
index 00000000000..a2e1398c61e
--- /dev/null
+++ b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs
@@ -0,0 +1,9 @@
+#![crate_type = "lib"]
+
+macro_rules! sample { () => {} }
+
+#[sample]           //~ ERROR cannot find attribute `sample` in this scope
+#[derive(sample)]   //~ ERROR cannot find derive macro `sample` in this scope
+                    //~| ERROR cannot find derive macro `sample` in this scope
+                    //~| ERROR cannot find derive macro `sample` in this scope
+pub struct S {}
diff --git a/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr
new file mode 100644
index 00000000000..e5b913b208d
--- /dev/null
+++ b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr
@@ -0,0 +1,42 @@
+error: cannot find derive macro `sample` in this scope
+  --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:6:10
+   |
+LL | macro_rules! sample { () => {} }
+   |              ------ `sample` exists, but a declarative macro cannot be used as a derive macro
+...
+LL | #[derive(sample)]
+   |          ^^^^^^
+
+error: cannot find attribute `sample` in this scope
+  --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:5:3
+   |
+LL | macro_rules! sample { () => {} }
+   |              ------ `sample` exists, but a declarative macro cannot be used as an attribute macro
+LL |
+LL | #[sample]
+   |   ^^^^^^
+
+error: cannot find derive macro `sample` in this scope
+  --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:6:10
+   |
+LL | macro_rules! sample { () => {} }
+   |              ------ `sample` exists, but a declarative macro cannot be used as a derive macro
+...
+LL | #[derive(sample)]
+   |          ^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: cannot find derive macro `sample` in this scope
+  --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:6:10
+   |
+LL | macro_rules! sample { () => {} }
+   |              ------ `sample` exists, but a declarative macro cannot be used as a derive macro
+...
+LL | #[derive(sample)]
+   |          ^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/macros/macro_with_super_2.rs b/tests/ui/macros/macro_with_super_2.rs
index 5353405ca57..5e7ec251549 100644
--- a/tests/ui/macros/macro_with_super_2.rs
+++ b/tests/ui/macros/macro_with_super_2.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:macro_with_super_1.rs
 
-//@ pretty-expanded FIXME #23616
 
 #[macro_use]
 extern crate macro_with_super_1;
diff --git a/tests/ui/macros/metavar_cross_edition_recursive_macros.rs b/tests/ui/macros/metavar_cross_edition_recursive_macros.rs
index 9a5b92f5032..ae1bc00236f 100644
--- a/tests/ui/macros/metavar_cross_edition_recursive_macros.rs
+++ b/tests/ui/macros/metavar_cross_edition_recursive_macros.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: --edition=2024 -Z unstable-options
+//@ edition: 2024
 //@ aux-build: metavar_2018.rs
 //@ known-bug: #130484
 //@ run-pass
diff --git a/tests/ui/macros/parse-complex-macro-invoc-op.rs b/tests/ui/macros/parse-complex-macro-invoc-op.rs
index bbb9b0270f2..27ead36f69d 100644
--- a/tests/ui/macros/parse-complex-macro-invoc-op.rs
+++ b/tests/ui/macros/parse-complex-macro-invoc-op.rs
@@ -8,7 +8,6 @@
 
 // Test parsing binary operators after macro invocations.
 
-//@ pretty-expanded FIXME #23616
 
 #![feature(macro_rules)]
 
diff --git a/tests/ui/macros/pub-item-inside-macro.rs b/tests/ui/macros/pub-item-inside-macro.rs
index b05d8539d58..c37945a2d67 100644
--- a/tests/ui/macros/pub-item-inside-macro.rs
+++ b/tests/ui/macros/pub-item-inside-macro.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Issue #14660
 
-//@ pretty-expanded FIXME #23616
 
 mod bleh {
     macro_rules! foo {
diff --git a/tests/ui/macros/pub-method-inside-macro.rs b/tests/ui/macros/pub-method-inside-macro.rs
index c4f9acc637d..dd4e6fda8be 100644
--- a/tests/ui/macros/pub-method-inside-macro.rs
+++ b/tests/ui/macros/pub-method-inside-macro.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Issue #17436
 
-//@ pretty-expanded FIXME #23616
 
 mod bleh {
     macro_rules! foo {
diff --git a/tests/ui/match/match-fn-call.stderr b/tests/ui/match/match-fn-call.stderr
index 297aa4cd95d..a3d61947080 100644
--- a/tests/ui/match/match-fn-call.stderr
+++ b/tests/ui/match/match-fn-call.stderr
@@ -4,7 +4,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function
 LL |         Path::new("foo") => println!("foo"),
    |         ^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
    |
-   = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
+   = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html
 
 error[E0164]: expected tuple struct or tuple variant, found associated function `Path::new`
   --> $DIR/match-fn-call.rs:8:9
@@ -12,7 +12,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function
 LL |         Path::new("bar") => println!("bar"),
    |         ^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
    |
-   = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
+   = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs
index 7cbe8e0943a..bc12d69b105 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 // gate-test-ref_pat_eat_one_layer_2024_structural
 
 pub fn main() {
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr
index b3ea60252ac..132fe421a18 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:6:22
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:5:22
    |
 LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
    |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -14,7 +14,7 @@ LL |     if let Some(Some(x)) = &Some(&Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:11:23
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:10:23
    |
 LL |         let _: &u32 = x;
    |                ----   ^ expected `&u32`, found integer
@@ -27,7 +27,7 @@ LL |         let _: &u32 = &x;
    |                       +
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:14:23
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:13:23
    |
 LL |     if let Some(Some(&&x)) = &Some(Some(&0)) {
    |                       ^^     --------------- this expression has type `&Option<Option<&{integer}>>`
@@ -43,7 +43,7 @@ LL +     if let Some(Some(&x)) = &Some(Some(&0)) {
    |
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:18:17
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:17:17
    |
 LL |     if let Some(&Some(x)) = &Some(Some(0)) {
    |                 ^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
@@ -54,7 +54,7 @@ LL |     if let Some(&Some(x)) = &Some(Some(0)) {
            found reference `&_`
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:22:22
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22
    |
 LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    |                      ^^^^^^     ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
@@ -64,7 +64,7 @@ LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    = note:           expected type `{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:22:22
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22
    |
 LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    |                      ^^^^^^
@@ -74,7 +74,7 @@ LL |     if let Some(Some(x)) = &mut Some(&mut Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:26:22
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:25:22
    |
 LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
    |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -89,7 +89,7 @@ LL |     if let Some(Some(x)) = &Some(&Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:30:27
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:29:27
    |
 LL |     if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
    |                           ^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
@@ -104,7 +104,7 @@ LL |     if let Some(&mut Some(x)) = &Some(&mut Some(0)) {
    |                           ~
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:34:23
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23
    |
 LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
@@ -114,7 +114,7 @@ LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    = note:           expected type `{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:34:23
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23
    |
 LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    |                       ^^^^^^
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
index c6a699d2ff8..b145446de0a 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 //@ revisions: classic structural both
 #![allow(incomplete_features)]
 #![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr
index 0215df98ea1..f8672d755b9 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17
    |
 LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
    |                 ^^^^^^^^^^^^^    --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -10,7 +10,7 @@ LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23
    |
 LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
    |                       ^^^^^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
@@ -21,7 +21,7 @@ LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27
    |
 LL |         let _: &mut u32 = x;
    |                --------   ^ types differ in mutability
@@ -32,7 +32,7 @@ LL |         let _: &mut u32 = x;
                       found reference `&{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23
    |
 LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
    |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
@@ -43,7 +43,7 @@ LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29
    |
 LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
    |                             ^^^^^^       ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
@@ -54,7 +54,7 @@ LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17
    |
 LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
    |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
@@ -65,7 +65,7 @@ LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17
    |
 LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
    |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
@@ -76,7 +76,7 @@ LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9
    |
 LL |     let &mut _ = &&0;
    |         ^^^^^^   --- this expression has type `&&{integer}`
@@ -87,7 +87,7 @@ LL |     let &mut _ = &&0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9
    |
 LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
    |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
@@ -98,7 +98,7 @@ LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9
    |
 LL |     let &mut _ = &&mut 0;
    |         ^^^^^^   ------- this expression has type `&&mut {integer}`
@@ -109,7 +109,7 @@ LL |     let &mut _ = &&mut 0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9
    |
 LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
    |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
@@ -120,7 +120,7 @@ LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14
    |
 LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
    |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
@@ -131,7 +131,7 @@ LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
            found mutable reference `&mut _`
 
 error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13
    |
 LL |     let Foo(mut a) = &Foo(0);
    |             ^^^^
@@ -141,7 +141,7 @@ LL |     let Foo(mut a) = &Foo(0);
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13
    |
 LL |     let Foo(mut a) = &mut Foo(0);
    |             ^^^^
@@ -151,14 +151,14 @@ LL |     let Foo(mut a) = &mut Foo(0);
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0277]: the trait bound `&_: main::Ref` is not satisfied
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14
    |
 LL |     let &_ = generic();
    |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
    |
    = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
 note: required by a bound in `generic`
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19
    |
 LL |     fn generic<R: Ref>() -> R {
    |                   ^^^ required by this bound in `generic`
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr
index 9428b32c4af..a37316b3097 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17
    |
 LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
    |                 ^^^^^
@@ -11,7 +11,7 @@ LL |     if let Some(&Some(&_)) = &Some(&Some(0)) {
    |                 ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23
    |
 LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
    |                       ^^^^^
@@ -23,7 +23,7 @@ LL |     if let Some(&Some(&_)) = &Some(&mut Some(0)) {
    |                       ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27
    |
 LL |         let _: &mut u32 = x;
    |                --------   ^ types differ in mutability
@@ -34,7 +34,7 @@ LL |         let _: &mut u32 = x;
                       found reference `&{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23
    |
 LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
    |                       ^^^^^
@@ -46,7 +46,7 @@ LL |     if let Some(&Some(&_)) = &mut Some(&Some(0)) {
    |                       ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29
    |
 LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
    |                             ^^^^^
@@ -58,7 +58,7 @@ LL |     if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) {
    |                             ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17
    |
 LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
    |                 ^^^^^
@@ -70,7 +70,7 @@ LL |     if let Some(&Some(x)) = &Some(Some(0)) {
    |                 ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17
    |
 LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
    |                 ^^^^^
@@ -82,7 +82,7 @@ LL |     if let Some(&Some(x)) = &Some(Some(0)) {
    |                 ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9
    |
 LL |     let &mut _ = &&0;
    |         ^^^^^^   --- this expression has type `&&{integer}`
@@ -93,7 +93,7 @@ LL |     let &mut _ = &&0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9
    |
 LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
    |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
@@ -104,7 +104,7 @@ LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:38:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:37:17
    |
 LL |     if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
    |                 ^^^^^
@@ -116,7 +116,7 @@ LL |     if let Some(&Some(&_)) = &Some(&mut Some(0)) {
    |                 ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:42:22
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:41:22
    |
 LL |     if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
    |                      ^^^^^
@@ -128,7 +128,7 @@ LL |     if let Some(Some(&x)) = &Some(Some(&mut 0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9
    |
 LL |     let &mut _ = &&mut 0;
    |         ^^^^^^   ------- this expression has type `&&mut {integer}`
@@ -139,7 +139,7 @@ LL |     let &mut _ = &&mut 0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9
    |
 LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
    |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
@@ -150,7 +150,7 @@ LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14
    |
 LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
    |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
@@ -161,7 +161,7 @@ LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
            found mutable reference `&mut _`
 
 error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13
    |
 LL |     let Foo(mut a) = &Foo(0);
    |             ^^^^
@@ -171,7 +171,7 @@ LL |     let Foo(mut a) = &Foo(0);
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13
    |
 LL |     let Foo(mut a) = &mut Foo(0);
    |             ^^^^
@@ -181,14 +181,14 @@ LL |     let Foo(mut a) = &mut Foo(0);
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0277]: the trait bound `&_: main::Ref` is not satisfied
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14
    |
 LL |     let &_ = generic();
    |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
    |
    = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
 note: required by a bound in `generic`
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19
    |
 LL |     fn generic<R: Ref>() -> R {
    |                   ^^^ required by this bound in `generic`
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
index d23e9c8083d..fd616807b28 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 //@ revisions: classic structural both
 #![allow(incomplete_features)]
 #![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr
index 56dad605030..2f62e9974fa 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:8:17
    |
 LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
    |                 ^^^^^^^^^^^^^    --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -10,7 +10,7 @@ LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:11:23
    |
 LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
    |                       ^^^^^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
@@ -21,7 +21,7 @@ LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:15:27
    |
 LL |         let _: &mut u32 = x;
    |                --------   ^ types differ in mutability
@@ -32,7 +32,7 @@ LL |         let _: &mut u32 = x;
                       found reference `&{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:18:23
    |
 LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
    |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
@@ -43,7 +43,7 @@ LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:29
    |
 LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
    |                             ^^^^^^       ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
@@ -54,7 +54,7 @@ LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:24:17
    |
 LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
    |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
@@ -65,7 +65,7 @@ LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:27:17
    |
 LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
    |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
@@ -76,7 +76,7 @@ LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9
    |
 LL |     let &mut _ = &&0;
    |         ^^^^^^   --- this expression has type `&&{integer}`
@@ -87,7 +87,7 @@ LL |     let &mut _ = &&0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:34:9
    |
 LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
    |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
@@ -98,7 +98,7 @@ LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:45:9
    |
 LL |     let &mut _ = &&mut 0;
    |         ^^^^^^   ------- this expression has type `&&mut {integer}`
@@ -109,7 +109,7 @@ LL |     let &mut _ = &&mut 0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:48:9
    |
 LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
    |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
@@ -120,7 +120,7 @@ LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:51:14
    |
 LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
    |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
@@ -131,7 +131,7 @@ LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:17
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:54:17
    |
 LL |     if let Some(&mut _) = &mut Some(&0) {
    |                 ^^^^^^    ------------- this expression has type `&mut Option<&{integer}>`
@@ -142,7 +142,7 @@ LL |     if let Some(&mut _) = &mut Some(&0) {
            found mutable reference `&mut _`
 
 error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:60:13
    |
 LL |     let Foo(mut a) = &Foo(0);
    |             ^^^^
@@ -152,7 +152,7 @@ LL |     let Foo(mut a) = &Foo(0);
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:64:13
    |
 LL |     let Foo(mut a) = &mut Foo(0);
    |             ^^^^
@@ -162,14 +162,14 @@ LL |     let Foo(mut a) = &mut Foo(0);
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0277]: the trait bound `&_: main::Ref` is not satisfied
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:82:14
    |
 LL |     let &_ = generic();
    |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
    |
    = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
 note: required by a bound in `generic`
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:68:19
    |
 LL |     fn generic<R: Ref>() -> R {
    |                   ^^^ required by this bound in `generic`
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs
index 3cdf47c1dbf..79403b19365 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 #![allow(incomplete_features)]
 #![feature(ref_pat_eat_one_layer_2024)]
 
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr
index 8b86fa65c4d..52f4c09e5c0 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr
@@ -1,5 +1,5 @@
 error[E0507]: cannot move out of a shared reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:7:29
+  --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:6:29
    |
 LL |     if let Some(&Some(x)) = Some(&Some(&mut 0)) {
    |                       -     ^^^^^^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL |     if let Some(&Some(ref x)) = Some(&Some(&mut 0)) {
    |                       +++
 
 error[E0596]: cannot borrow data in a `&` reference as mutable
-  --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:12:10
+  --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:11:10
    |
 LL |     let &ref mut x = &0;
    |          ^^^^^^^^^ cannot borrow as mutable
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed
index bc7a58a382d..e69d169966b 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 //@ run-rustfix
 #![allow(incomplete_features)]
 #![feature(ref_pat_eat_one_layer_2024)]
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs
index c6d72b0a9d7..a300cbcd4df 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 //@ run-rustfix
 #![allow(incomplete_features)]
 #![feature(ref_pat_eat_one_layer_2024)]
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr
index 964e9f36596..8e135b65253 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr
@@ -1,5 +1,5 @@
 error[E0596]: cannot borrow as mutable inside an `&` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:8:31
+  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:7:31
    |
 LL |     if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
    |                 -             ^
@@ -7,7 +7,7 @@ LL |     if let Some(&Some(ref mut x)) = &mut Some(Some(0)) {
    |                 help: replace this `&` with `&mut`: `&mut`
 
 error[E0596]: cannot borrow as mutable inside an `&` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:13:31
+  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:12:31
    |
 LL |     if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
    |            -                  ^
@@ -15,7 +15,7 @@ LL |     if let &Some(Some(ref mut x)) = &mut Some(Some(0)) {
    |            help: replace this `&` with `&mut`: `&mut`
 
 error[E0596]: cannot borrow as mutable inside an `&` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:21:15
+  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:20:15
    |
 LL |     let &pat!(x) = &mut 0;
    |         -     ^
@@ -23,7 +23,7 @@ LL |     let &pat!(x) = &mut 0;
    |         help: replace this `&` with `&mut`: `&mut`
 
 error[E0596]: cannot borrow as mutable inside an `&` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:19
+  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:24:19
    |
 LL |     let &(ref mut a, ref mut b) = &mut (true, false);
    |         -         ^
@@ -31,7 +31,7 @@ LL |     let &(ref mut a, ref mut b) = &mut (true, false);
    |         help: replace this `&` with `&mut`: `&mut`
 
 error[E0596]: cannot borrow as mutable inside an `&` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:30
+  --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:24:30
    |
 LL |     let &(ref mut a, ref mut b) = &mut (true, false);
    |         -                    ^
diff --git a/tests/ui/methods/method-early-bound-lifetimes-on-self.rs b/tests/ui/methods/method-early-bound-lifetimes-on-self.rs
index 8721dd85ac7..ec7abe1280d 100644
--- a/tests/ui/methods/method-early-bound-lifetimes-on-self.rs
+++ b/tests/ui/methods/method-early-bound-lifetimes-on-self.rs
@@ -2,7 +2,6 @@
 // Check that we successfully handle methods where the `self` type has
 // an early-bound lifetime. Issue #18208.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/methods/method-normalize-bounds-issue-20604.rs b/tests/ui/methods/method-normalize-bounds-issue-20604.rs
index b3979e75b61..ea18fe14d15 100644
--- a/tests/ui/methods/method-normalize-bounds-issue-20604.rs
+++ b/tests/ui/methods/method-normalize-bounds-issue-20604.rs
@@ -9,7 +9,6 @@
 // winnowing stage of method resolution failed to handle an associated
 // type projection.
 
-//@ pretty-expanded FIXME #23616
 
 #![feature(associated_types)]
 
diff --git a/tests/ui/methods/method-recursive-blanket-impl.rs b/tests/ui/methods/method-recursive-blanket-impl.rs
index 09bbfffcd55..547e57885e0 100644
--- a/tests/ui/methods/method-recursive-blanket-impl.rs
+++ b/tests/ui/methods/method-recursive-blanket-impl.rs
@@ -6,7 +6,6 @@
 // know not to stop at the blanket, we have to recursively evaluate
 // the `T:Foo` bound.
 
-//@ pretty-expanded FIXME #23616
 
 use std::marker::Sized;
 
diff --git a/tests/ui/methods/method-recursive-blanket-impl.stderr b/tests/ui/methods/method-recursive-blanket-impl.stderr
index 9797a8f6c83..e358f80d3ff 100644
--- a/tests/ui/methods/method-recursive-blanket-impl.stderr
+++ b/tests/ui/methods/method-recursive-blanket-impl.stderr
@@ -1,5 +1,5 @@
 warning: trait `Foo` is never used
-  --> $DIR/method-recursive-blanket-impl.rs:14:7
+  --> $DIR/method-recursive-blanket-impl.rs:13:7
    |
 LL | trait Foo<A> {
    |       ^^^
diff --git a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs
index 373439d2559..2ef2848c216 100644
--- a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs
+++ b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs
@@ -2,7 +2,6 @@
 // Test that we select between traits A and B. To do that, we must
 // consider the `Sized` bound.
 
-//@ pretty-expanded FIXME #23616
 
 trait A { //~ WARN trait `A` is never used
     fn foo(self);
diff --git a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr
index 0a60c6242bb..fa87ce5cc49 100644
--- a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr
+++ b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr
@@ -1,5 +1,5 @@
 warning: trait `A` is never used
-  --> $DIR/method-two-traits-distinguished-via-where-clause.rs:7:7
+  --> $DIR/method-two-traits-distinguished-via-where-clause.rs:6:7
    |
 LL | trait A {
    |       ^
diff --git a/tests/ui/mir-dataflow/def-inits-1.rs b/tests/ui/mir-dataflow/def-inits-1.rs
deleted file mode 100644
index 30460824a16..00000000000
--- a/tests/ui/mir-dataflow/def-inits-1.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-// General test of maybe_uninits state computed by MIR dataflow.
-
-#![feature(core_intrinsics, rustc_attrs)]
-
-use std::intrinsics::rustc_peek;
-use std::mem::{drop, replace};
-
-struct S(i32);
-
-#[rustc_mir(rustc_peek_definite_init,stop_after_dataflow)]
-fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
-    let ret;
-    // `ret` starts off uninitialized
-    rustc_peek(&ret);  //~ ERROR rustc_peek: bit not set
-
-    // All function formal parameters start off initialized.
-
-    rustc_peek(&x);
-    rustc_peek(&y);
-    rustc_peek(&z);
-
-    ret = if test {
-        ::std::mem::replace(x, y)
-    } else {
-        z = y;
-        z
-    };
-
-    // `z` may be uninitialized here.
-    rustc_peek(&z); //~ ERROR rustc_peek: bit not set
-
-    // `y` is definitely uninitialized here.
-    rustc_peek(&y); //~ ERROR rustc_peek: bit not set
-
-    // `x` is still (definitely) initialized (replace above is a reborrow).
-    rustc_peek(&x);
-
-    ::std::mem::drop(x);
-
-    // `x` is *definitely* uninitialized here
-    rustc_peek(&x); //~ ERROR rustc_peek: bit not set
-
-    // `ret` is now definitely initialized (via `if` above).
-    rustc_peek(&ret);
-
-    ret
-}
-fn main() {
-    foo(true, &mut S(13), S(14), S(15));
-    foo(false, &mut S(13), S(14), S(15));
-}
diff --git a/tests/ui/mir-dataflow/def-inits-1.stderr b/tests/ui/mir-dataflow/def-inits-1.stderr
deleted file mode 100644
index e2bddb54d9b..00000000000
--- a/tests/ui/mir-dataflow/def-inits-1.stderr
+++ /dev/null
@@ -1,28 +0,0 @@
-error: rustc_peek: bit not set
-  --> $DIR/def-inits-1.rs:14:5
-   |
-LL |     rustc_peek(&ret);
-   |     ^^^^^^^^^^^^^^^^
-
-error: rustc_peek: bit not set
-  --> $DIR/def-inits-1.rs:30:5
-   |
-LL |     rustc_peek(&z);
-   |     ^^^^^^^^^^^^^^
-
-error: rustc_peek: bit not set
-  --> $DIR/def-inits-1.rs:33:5
-   |
-LL |     rustc_peek(&y);
-   |     ^^^^^^^^^^^^^^
-
-error: rustc_peek: bit not set
-  --> $DIR/def-inits-1.rs:41:5
-   |
-LL |     rustc_peek(&x);
-   |     ^^^^^^^^^^^^^^
-
-error: stop_after_dataflow ended compilation
-
-error: aborting due to 5 previous errors
-
diff --git a/tests/ui/mir/issue-112269.stderr b/tests/ui/mir/issue-112269.stderr
index adb662c98a7..80f329e2ce0 100644
--- a/tests/ui/mir/issue-112269.stderr
+++ b/tests/ui/mir/issue-112269.stderr
@@ -7,7 +7,7 @@ LL |     let x: i32 = 3;
    |         ^ patterns `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: introduce a variable instead
    |
@@ -23,7 +23,7 @@ LL |     let y = 4;
    |         ^ patterns `i32::MIN..=2_i32` and `4_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: introduce a variable instead
    |
diff --git a/tests/ui/mir/validate/needs-reveal-all.rs b/tests/ui/mir/validate/needs-reveal-all.rs
index be2f5dd322f..7d793ebbba6 100644
--- a/tests/ui/mir/validate/needs-reveal-all.rs
+++ b/tests/ui/mir/validate/needs-reveal-all.rs
@@ -1,8 +1,8 @@
-// Regression test for #105009. the issue here was that even after the `RevealAll` pass,
+// Regression test for #105009. the issue here was that even after the `PostAnalysisNormalize` pass,
 // `validate` still used `Reveal::UserFacing`. This meant that it now ends up comparing
 // opaque types with their revealed version, resulting in an ICE.
 //
-// We're using these flags to run the `RevealAll` pass while making it less likely to
+// We're using these flags to run the `PostAnalysisNormalize` pass while making it less likely to
 // accidentally removing the assignment from `Foo<fn_ptr>` to `Foo<fn_def>`.
 
 //@ compile-flags: -Zinline_mir=yes -Zmir-opt-level=0 -Zvalidate-mir
diff --git a/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr
index a845dfabe93..0a86f884e70 100644
--- a/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr
+++ b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr
@@ -14,7 +14,7 @@ LL | fn foo<T>(a: T, b: T) {}
    |    ^^^ -  ----  ---- this parameter needs to match the integer type of `a`
    |        |  |
    |        |  `b` needs to match the integer type of this parameter
-   |        `a` and `b` all reference this parameter T
+   |        `a` and `b` both reference this parameter `T`
 
 error[E0308]: arguments to this function are incorrect
   --> $DIR/generic-mismatch-reporting-issue-116615.rs:8:5
@@ -38,7 +38,7 @@ LL | fn foo_multi_same<T>(a: T, b: T, c: T, d: T, e: T, f: i32) {}
    |                   |  |     |     this parameter needs to match the `&str` type of `a` and `b`
    |                   |  |     `c`, `d` and `e` need to match the `&str` type of this parameter
    |                   |  `c`, `d` and `e` need to match the `&str` type of this parameter
-   |                   `a`, `b`, `c`, `d` and `e` all reference this parameter T
+   |                   `a`, `b`, `c`, `d` and `e` all reference this parameter `T`
 
 error[E0308]: arguments to this function are incorrect
   --> $DIR/generic-mismatch-reporting-issue-116615.rs:10:5
@@ -65,8 +65,8 @@ LL | fn foo_multi_generics<S, T>(a: T, b: T, c: T, d: T, e: T, f: S, g: S) {}
    |                       |  |  |     |     `d` and `e` need to match the `&str` type of this parameter
    |                       |  |  |     `d` and `e` need to match the `&str` type of this parameter
    |                       |  |  `d` and `e` need to match the `&str` type of this parameter
-   |                       |  `a`, `b`, `c`, `d` and `e` all reference this parameter T
-   |                       `f` and `g` all reference this parameter S
+   |                       |  `a`, `b`, `c`, `d` and `e` all reference this parameter `T`
+   |                       `f` and `g` both reference this parameter `S`
 
 error[E0308]: arguments to this function are incorrect
   --> $DIR/generic-mismatch-reporting-issue-116615.rs:12:5
@@ -90,7 +90,7 @@ LL | fn foo_multi_same<T>(a: T, b: T, c: T, d: T, e: T, f: i32) {}
    |                   |  |     |     this parameter needs to match the `&str` type of `a`, `d` and `e`
    |                   |  |     this parameter needs to match the `&str` type of `a`, `d` and `e`
    |                   |  `b` and `c` need to match the `&str` type of this parameter
-   |                   `a`, `b`, `c`, `d` and `e` all reference this parameter T
+   |                   `a`, `b`, `c`, `d` and `e` all reference this parameter `T`
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/modules/issue-13872.rs b/tests/ui/modules/issue-13872.rs
index 5589d2d4f68..a29f378c844 100644
--- a/tests/ui/modules/issue-13872.rs
+++ b/tests/ui/modules/issue-13872.rs
@@ -3,7 +3,6 @@
 //@ aux-build:issue-13872-2.rs
 //@ aux-build:issue-13872-3.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_13872_3 as other;
 
diff --git a/tests/ui/modules/mod-view-items.rs b/tests/ui/modules/mod-view-items.rs
index 462071b7b12..2d25c83f362 100644
--- a/tests/ui/modules/mod-view-items.rs
+++ b/tests/ui/modules/mod-view-items.rs
@@ -5,7 +5,6 @@
 // pretty-print such view items. If that happens again, this should
 // begin failing.
 
-//@ pretty-expanded FIXME #23616
 
 mod m {
     pub fn f() -> Vec<isize> { Vec::new() }
diff --git a/tests/ui/moves/move-nullary-fn.rs b/tests/ui/moves/move-nullary-fn.rs
index 8c7bcf395e7..0480d2b1045 100644
--- a/tests/ui/moves/move-nullary-fn.rs
+++ b/tests/ui/moves/move-nullary-fn.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 // Issue #922
-//@ pretty-expanded FIXME #23616
 
 fn f2<F>(_thing: F) where F: FnOnce() { }
 
diff --git a/tests/ui/multiline-comment.rs b/tests/ui/multiline-comment.rs
index bf86250c1f8..98174882032 100644
--- a/tests/ui/multiline-comment.rs
+++ b/tests/ui/multiline-comment.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 /*
  * This is a multi-line oldcomment.
diff --git a/tests/ui/mutual-recursion-group.rs b/tests/ui/mutual-recursion-group.rs
index dc6d216f8d9..f83150af7dc 100644
--- a/tests/ui/mutual-recursion-group.rs
+++ b/tests/ui/mutual-recursion-group.rs
@@ -3,7 +3,6 @@
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
 
-//@ pretty-expanded FIXME #23616
 
 enum colour { red, green, blue, }
 
diff --git a/tests/ui/nested-block-comment.rs b/tests/ui/nested-block-comment.rs
index 07414345c38..008df27e0e2 100644
--- a/tests/ui/nested-block-comment.rs
+++ b/tests/ui/nested-block-comment.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 /* This test checks that nested comments are supported
 
diff --git a/tests/ui/never_type/exhaustive_patterns.stderr b/tests/ui/never_type/exhaustive_patterns.stderr
index 1314cbc52f8..1f22b9e6198 100644
--- a/tests/ui/never_type/exhaustive_patterns.stderr
+++ b/tests/ui/never_type/exhaustive_patterns.stderr
@@ -5,7 +5,7 @@ LL |     let Either::A(()) = foo();
    |         ^^^^^^^^^^^^^ pattern `Either::B(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Either<(), !>` defined here
   --> $DIR/exhaustive_patterns.rs:9:6
    |
diff --git a/tests/ui/never_type/expr-empty-ret.rs b/tests/ui/never_type/expr-empty-ret.rs
index 5d315934e00..e6af5bd3153 100644
--- a/tests/ui/never_type/expr-empty-ret.rs
+++ b/tests/ui/never_type/expr-empty-ret.rs
@@ -3,7 +3,6 @@
 #![allow(dead_code)]
 // Issue #521
 
-//@ pretty-expanded FIXME #23616
 
 fn f() {
     let _x = match true {
diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.rs b/tests/ui/nll/user-annotations/region-error-ice-109072.rs
index bcdc6651cf5..3f2ad3ccbf5 100644
--- a/tests/ui/nll/user-annotations/region-error-ice-109072.rs
+++ b/tests/ui/nll/user-annotations/region-error-ice-109072.rs
@@ -11,5 +11,4 @@ impl Lt<'missing> for () { //~ ERROR undeclared lifetime
 
 fn main() {
     let _: <() as Lt<'_>>::T = &();
-    //~^ ERROR the trait bound `(): Lt<'_>` is not satisfied
 }
diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr
index c187c17d98c..d90971bed25 100644
--- a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr
+++ b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr
@@ -21,13 +21,6 @@ help: consider introducing lifetime `'missing` here
 LL | impl<'missing> Lt<'missing> for () {
    |     ++++++++++
 
-error[E0277]: the trait bound `(): Lt<'_>` is not satisfied
-  --> $DIR/region-error-ice-109072.rs:13:13
-   |
-LL |     let _: <() as Lt<'_>>::T = &();
-   |             ^^ the trait `Lt<'_>` is not implemented for `()`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0261, E0277.
-For more information about an error, try `rustc --explain E0261`.
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/numbers-arithmetic/int.rs b/tests/ui/numbers-arithmetic/int.rs
index edc7f729444..42f8e50d6ef 100644
--- a/tests/ui/numbers-arithmetic/int.rs
+++ b/tests/ui/numbers-arithmetic/int.rs
@@ -2,6 +2,5 @@
 
 
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() { let _x: isize = 10; }
diff --git a/tests/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs b/tests/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs
index 406ed470458..2cbbdfc6479 100644
--- a/tests/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs
+++ b/tests/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn foo(_: *const ()) {}
 
diff --git a/tests/ui/numbers-arithmetic/integer-literal-suffix-inference.rs b/tests/ui/numbers-arithmetic/integer-literal-suffix-inference.rs
index 97c10bc3c56..ed59bba1196 100644
--- a/tests/ui/numbers-arithmetic/integer-literal-suffix-inference.rs
+++ b/tests/ui/numbers-arithmetic/integer-literal-suffix-inference.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     fn id_i8(n: i8) -> i8 { n }
diff --git a/tests/ui/numbers-arithmetic/uint.rs b/tests/ui/numbers-arithmetic/uint.rs
index c64361c2726..c2087b5a06c 100644
--- a/tests/ui/numbers-arithmetic/uint.rs
+++ b/tests/ui/numbers-arithmetic/uint.rs
@@ -2,6 +2,5 @@
 
 
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() { let _x: usize = 10 as usize; }
diff --git a/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs b/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs
index edbd9f35d4d..23e58523356 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs
+++ b/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs
@@ -2,7 +2,6 @@
 // Test that `Box<Test>` is equivalent to `Box<Test+'static>`, both in
 // fields and fn arguments.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs b/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs
index 986fc836799..040ac1f8913 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs
+++ b/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs
@@ -2,7 +2,6 @@
 // Test that the lifetime of the enclosing `&` is used for the object
 // lifetime bound.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs
index 3c88f2b9f37..c3f3101155c 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs
+++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs
@@ -2,7 +2,6 @@
 // Test that the lifetime from the enclosing `&` is "inherited"
 // through the `Box` struct.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs
index 412695f7086..db4f9a40235 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs
+++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs
@@ -2,7 +2,6 @@
 // Test that the lifetime of the enclosing `&` is used for the object
 // lifetime bound.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs
index 591f843a284..5163ff1c245 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs
+++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs
@@ -2,7 +2,6 @@
 // Test that the lifetime from the enclosing `&` is "inherited"
 // through the `MyBox` struct.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs
index bc47b8d46a1..556bde78415 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs
+++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs
@@ -2,7 +2,6 @@
 // Test that the lifetime of the enclosing `&` is used for the object
 // lifetime bound.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/object-lifetime/object-lifetime-default-inferred.rs b/tests/ui/object-lifetime/object-lifetime-default-inferred.rs
index 53b9c488645..5abe09e2729 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-inferred.rs
+++ b/tests/ui/object-lifetime/object-lifetime-default-inferred.rs
@@ -2,7 +2,6 @@
 // Test that even with prior inferred parameters, object lifetimes of objects after are still
 // valid.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 #![feature(generic_arg_infer)]
diff --git a/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr b/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
index fdb1a9bb4b7..7044b8e035a 100644
--- a/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
+++ b/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
@@ -5,7 +5,7 @@ LL |     let (0 | (1 | 2)) = 0;
    |          ^^^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
diff --git a/tests/ui/output-slot-variants.rs b/tests/ui/output-slot-variants.rs
index c545b2504cb..97757e74fc4 100644
--- a/tests/ui/output-slot-variants.rs
+++ b/tests/ui/output-slot-variants.rs
@@ -3,7 +3,6 @@
 #![allow(dead_code)]
 #![allow(unused_assignments)]
 #![allow(unknown_lints)]
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_assignment)]
 #![allow(unused_variables)]
diff --git a/tests/ui/overloaded/fixup-deref-mut.rs b/tests/ui/overloaded/fixup-deref-mut.rs
index 2879554bb94..f8d3e678f0c 100644
--- a/tests/ui/overloaded/fixup-deref-mut.rs
+++ b/tests/ui/overloaded/fixup-deref-mut.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 use std::ops::{Deref, DerefMut};
 
diff --git a/tests/ui/overloaded/issue-14958.rs b/tests/ui/overloaded/issue-14958.rs
index 3df4732d9ad..a4e5c8e3562 100644
--- a/tests/ui/overloaded/issue-14958.rs
+++ b/tests/ui/overloaded/issue-14958.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![feature(fn_traits, unboxed_closures)]
 
diff --git a/tests/ui/overloaded/issue-14958.stderr b/tests/ui/overloaded/issue-14958.stderr
index cc97730239c..e4f527319e7 100644
--- a/tests/ui/overloaded/issue-14958.stderr
+++ b/tests/ui/overloaded/issue-14958.stderr
@@ -1,5 +1,5 @@
 warning: method `dummy` is never used
-  --> $DIR/issue-14958.rs:6:16
+  --> $DIR/issue-14958.rs:5:16
    |
 LL | trait Foo { fn dummy(&self) { }}
    |       ---      ^^^^^
diff --git a/tests/ui/overloaded/overloaded-calls-param-vtables.rs b/tests/ui/overloaded/overloaded-calls-param-vtables.rs
index 7b89b45eb9b..b82e2ab05be 100644
--- a/tests/ui/overloaded/overloaded-calls-param-vtables.rs
+++ b/tests/ui/overloaded/overloaded-calls-param-vtables.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Tests that nested vtables work with overloaded calls.
 
-//@ pretty-expanded FIXME #23616
 
 #![feature(unboxed_closures, fn_traits)]
 
diff --git a/tests/ui/panic-handler/weak-lang-item-2.rs b/tests/ui/panic-handler/weak-lang-item-2.rs
index 2acaff3ab71..5291f3c4403 100644
--- a/tests/ui/panic-handler/weak-lang-item-2.rs
+++ b/tests/ui/panic-handler/weak-lang-item-2.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:weak-lang-items.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate weak_lang_items as other;
 
diff --git a/tests/ui/parser/bad-name.stderr b/tests/ui/parser/bad-name.stderr
index 5ca248380ee..a336923f4fd 100644
--- a/tests/ui/parser/bad-name.stderr
+++ b/tests/ui/parser/bad-name.stderr
@@ -10,7 +10,7 @@ error: expected a pattern, found an expression
 LL |   let x.y::<isize>.z foo;
    |       ^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator, found `foo`
   --> $DIR/bad-name.rs:2:22
diff --git a/tests/ui/parser/help-set-edition-ice-122130.stderr b/tests/ui/parser/help-set-edition-ice-122130.stderr
index fe4d212f2db..700b1ec911b 100644
--- a/tests/ui/parser/help-set-edition-ice-122130.stderr
+++ b/tests/ui/parser/help-set-edition-ice-122130.stderr
@@ -6,7 +6,7 @@ LL |     s#[c"owned_box"]
    |
    = note: you may be trying to write a c-string literal
    = note: c-string literals require Rust 2021 or later
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error: expected item, found `"owned_box"`
diff --git a/tests/ui/parser/issues/issue-21475.rs b/tests/ui/parser/issues/issue-21475.rs
index 27248179ef4..43dc7c53a70 100644
--- a/tests/ui/parser/issues/issue-21475.rs
+++ b/tests/ui/parser/issues/issue-21475.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_imports, overlapping_range_endpoints)]
-//@ pretty-expanded FIXME #23616
 
 use m::{START, END};
 
diff --git a/tests/ui/parser/issues/issue-24197.stderr b/tests/ui/parser/issues/issue-24197.stderr
index c92e165b23b..4eadc897d88 100644
--- a/tests/ui/parser/issues/issue-24197.stderr
+++ b/tests/ui/parser/issues/issue-24197.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |     let buf[0] = 0;
    |         ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/issue-24375.stderr b/tests/ui/parser/issues/issue-24375.stderr
index fef3fcde7b7..03cd33f1875 100644
--- a/tests/ui/parser/issues/issue-24375.stderr
+++ b/tests/ui/parser/issues/issue-24375.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |         tmp[0] => {}
    |         ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == tmp[0] => {}
diff --git a/tests/ui/parser/issues/issue-7222.rs b/tests/ui/parser/issues/issue-7222.rs
index 6f6b34f4f48..d601731dc77 100644
--- a/tests/ui/parser/issues/issue-7222.rs
+++ b/tests/ui/parser/issues/issue-7222.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     const FOO: f64 = 10.0;
diff --git a/tests/ui/parser/parse-assoc-type-lt.rs b/tests/ui/parser/parse-assoc-type-lt.rs
index f1823ce96b9..48e1423023e 100644
--- a/tests/ui/parser/parse-assoc-type-lt.rs
+++ b/tests/ui/parser/parse-assoc-type-lt.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Foo {
     type T;
diff --git a/tests/ui/parser/pat-lt-bracket-5.stderr b/tests/ui/parser/pat-lt-bracket-5.stderr
index a2a972652d1..c68aefa0546 100644
--- a/tests/ui/parser/pat-lt-bracket-5.stderr
+++ b/tests/ui/parser/pat-lt-bracket-5.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |     let v[0] = v[1];
    |         ^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error[E0425]: cannot find value `v` in this scope
   --> $DIR/pat-lt-bracket-5.rs:2:16
diff --git a/tests/ui/parser/pat-lt-bracket-6.stderr b/tests/ui/parser/pat-lt-bracket-6.stderr
index 14ae602fedf..0274809f800 100644
--- a/tests/ui/parser/pat-lt-bracket-6.stderr
+++ b/tests/ui/parser/pat-lt-bracket-6.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |     let Test(&desc[..]) = x;
    |              ^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error[E0308]: mismatched types
   --> $DIR/pat-lt-bracket-6.rs:10:30
diff --git a/tests/ui/parser/pat-ranges-3.stderr b/tests/ui/parser/pat-ranges-3.stderr
index ef080368e19..fcda924d98c 100644
--- a/tests/ui/parser/pat-ranges-3.stderr
+++ b/tests/ui/parser/pat-ranges-3.stderr
@@ -4,7 +4,7 @@ error: expected a pattern range bound, found an expression
 LL |     let 10 ..= 10 + 3 = 12;
    |                ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern range bound, found an expression
   --> $DIR/pat-ranges-3.rs:7:9
@@ -12,7 +12,7 @@ error: expected a pattern range bound, found an expression
 LL |     let 10 - 3 ..= 10 = 8;
    |         ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/parser/recover/recover-pat-exprs.stderr b/tests/ui/parser/recover/recover-pat-exprs.stderr
index 6cb3753de8d..041dfd647ad 100644
--- a/tests/ui/parser/recover/recover-pat-exprs.stderr
+++ b/tests/ui/parser/recover/recover-pat-exprs.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |         x.y => (),
    |         ^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.y => (),
@@ -27,7 +27,7 @@ error: expected a pattern, found an expression
 LL |         x.0 => (),
    |         ^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.0 => (),
@@ -51,7 +51,7 @@ error: expected a pattern, found an expression
 LL |         x._0 => (),
    |         ^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x._0 => (),
@@ -76,7 +76,7 @@ error: expected a pattern, found an expression
 LL |         x.0.1 => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.0.1 => (),
@@ -101,7 +101,7 @@ error: expected a pattern, found an expression
 LL |         x.4.y.17.__z => (),
    |         ^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.4.y.17.__z => (),
@@ -156,7 +156,7 @@ error: expected a pattern, found an expression
 LL |         x[0] => (),
    |         ^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x[0] => (),
@@ -178,7 +178,7 @@ error: expected a pattern, found an expression
 LL |         x[..] => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x[..] => (),
@@ -228,7 +228,7 @@ error: expected a pattern, found an expression
 LL |         x.f() => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.f() => (),
@@ -250,7 +250,7 @@ error: expected a pattern, found an expression
 LL |         x._f() => (),
    |         ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x._f() => (),
@@ -273,7 +273,7 @@ error: expected a pattern, found an expression
 LL |         x? => (),
    |         ^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x? => (),
@@ -297,7 +297,7 @@ error: expected a pattern, found an expression
 LL |         ().f() => (),
    |         ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == ().f() => (),
@@ -322,7 +322,7 @@ error: expected a pattern, found an expression
 LL |         (0, x)?.f() => (),
    |         ^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == (0, x)?.f() => (),
@@ -347,7 +347,7 @@ error: expected a pattern, found an expression
 LL |         x.f().g() => (),
    |         ^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.f().g() => (),
@@ -372,7 +372,7 @@ error: expected a pattern, found an expression
 LL |         0.f()?.g()?? => (),
    |         ^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == 0.f()?.g()?? => (),
@@ -397,7 +397,7 @@ error: expected a pattern, found an expression
 LL |         x as usize => (),
    |         ^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x as usize => (),
@@ -419,7 +419,7 @@ error: expected a pattern, found an expression
 LL |         0 as usize => (),
    |         ^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == 0 as usize => (),
@@ -442,7 +442,7 @@ error: expected a pattern, found an expression
 LL |         x.f().0.4 as f32 => (),
    |         ^^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.f().0.4 as f32 => (),
@@ -466,7 +466,7 @@ error: expected a pattern, found an expression
 LL |         1 + 1 => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == 1 + 1 => (),
@@ -488,7 +488,7 @@ error: expected a pattern, found an expression
 LL |         (1 + 2) * 3 => (),
    |         ^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == (1 + 2) * 3 => (),
@@ -511,7 +511,7 @@ error: expected a pattern, found an expression
 LL |         x.0 > 2 => (),
    |         ^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == (x.0 > 2) => (),
@@ -536,7 +536,7 @@ error: expected a pattern, found an expression
 LL |         x.0 == 2 => (),
    |         ^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == (x.0 == 2) => (),
@@ -561,7 +561,7 @@ error: expected a pattern, found an expression
 LL |         (x, y.0 > 2) if x != 0 => (),
    |             ^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to the match arm guard
    |
 LL |         (x, val) if x != 0 && val == (y.0 > 2) => (),
@@ -583,7 +583,7 @@ error: expected a pattern, found an expression
 LL |         (x, y.0 > 2) if x != 0 || x != 1 => (),
    |             ^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to the match arm guard
    |
 LL |         (x, val) if (x != 0 || x != 1) && val == (y.0 > 2) => (),
@@ -623,7 +623,7 @@ error: expected a pattern, found an expression
 LL |         u8::MAX.abs() => (),
    |         ^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == u8::MAX.abs() => (),
@@ -645,7 +645,7 @@ error: expected a pattern, found an expression
 LL |         z @ w @ v.u() => (),
    |                 ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         z @ w @ val if val == v.u() => (),
@@ -670,7 +670,7 @@ error: expected a pattern, found an expression
 LL |         y.ilog(3) => (),
    |         ^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == y.ilog(3) => (),
@@ -695,7 +695,7 @@ error: expected a pattern, found an expression
 LL |         n + 1 => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == n + 1 => (),
@@ -720,7 +720,7 @@ error: expected a pattern, found an expression
 LL |         ("".f() + 14 * 8) => (),
    |          ^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         (val) if val == "".f() + 14 * 8 => (),
@@ -745,7 +745,7 @@ error: expected a pattern, found an expression
 LL |         f?() => (),
    |         ^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == f?() => (),
@@ -770,7 +770,7 @@ error: expected a pattern, found an expression
 LL |     let 1 + 1 = 2;
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected one of `)`, `,`, `@`, or `|`, found `*`
   --> $DIR/recover-pat-exprs.rs:104:28
@@ -787,7 +787,7 @@ error: expected a pattern, found an expression
 LL |         (1 + 2) * 3 => (),
    |          ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:75:5
@@ -795,7 +795,7 @@ error: expected a pattern, found an expression
 LL |     1 + 2 * PI.cos() => 2,
    |     ^^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:83:9
@@ -803,7 +803,7 @@ error: expected a pattern, found an expression
 LL |         x.sqrt() @ .. => (),
    |         ^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: aborting due to 45 previous errors
 
diff --git a/tests/ui/parser/recover/recover-pat-issues.stderr b/tests/ui/parser/recover/recover-pat-issues.stderr
index 17cb7b4aead..bdd0b2b260e 100644
--- a/tests/ui/parser/recover/recover-pat-issues.stderr
+++ b/tests/ui/parser/recover/recover-pat-issues.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |         Foo("hi".to_owned()) => true,
    |             ^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         Foo(val) if val == "hi".to_owned() => true,
@@ -26,7 +26,7 @@ error: expected a pattern, found an expression
 LL |         Bar { baz: "hi".to_owned() } => true,
    |                    ^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         Bar { baz } if baz == "hi".to_owned() => true,
@@ -48,7 +48,7 @@ error: expected a pattern, found an expression
 LL |         &["foo".to_string()] => {}
    |           ^^^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         &[val] if val == "foo".to_string() => {}
@@ -70,7 +70,7 @@ error: expected a pattern, found an expression
 LL |     if let Some(MAGIC.0 as usize) = None::<usize> {}
    |                 ^^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = MAGIC.0 as usize;
@@ -87,7 +87,7 @@ error: expected a pattern, found an expression
 LL |     if let (-1.some(4)) = (0, Some(4)) {}
    |             ^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = -1.some(4);
@@ -104,7 +104,7 @@ error: expected a pattern, found an expression
 LL |     if let (-1.Some(4)) = (0, Some(4)) {}
    |             ^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = -1.Some(4);
diff --git a/tests/ui/parser/recover/recover-pat-lets.stderr b/tests/ui/parser/recover/recover-pat-lets.stderr
index b481813b246..55252729d7b 100644
--- a/tests/ui/parser/recover/recover-pat-lets.stderr
+++ b/tests/ui/parser/recover/recover-pat-lets.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |     let x.expect("foo");
    |         ^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-lets.rs:7:9
@@ -12,7 +12,7 @@ error: expected a pattern, found an expression
 LL |     let x.unwrap(): u32;
    |         ^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-lets.rs:10:9
@@ -20,7 +20,7 @@ error: expected a pattern, found an expression
 LL |     let x[0] = 1;
    |         ^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-lets.rs:13:14
@@ -28,7 +28,7 @@ error: expected a pattern, found an expression
 LL |     let Some(1 + 1) = x else {
    |              ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 1 + 1;
@@ -45,7 +45,7 @@ error: expected a pattern, found an expression
 LL |     if let Some(1 + 1) = x {
    |                 ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 1 + 1;
diff --git a/tests/ui/parser/recover/recover-pat-ranges.stderr b/tests/ui/parser/recover/recover-pat-ranges.stderr
index 0a9b5447468..e8f323596d0 100644
--- a/tests/ui/parser/recover/recover-pat-ranges.stderr
+++ b/tests/ui/parser/recover/recover-pat-ranges.stderr
@@ -88,7 +88,7 @@ error: expected a pattern range bound, found an expression
 LL |         ..=1 + 2 => (),
    |            ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 1 + 2;
@@ -109,7 +109,7 @@ error: expected a pattern range bound, found an expression
 LL |         (-4 + 0).. => (),
    |          ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = -4 + 0;
@@ -130,7 +130,7 @@ error: expected a pattern range bound, found an expression
 LL |         (1 + 4)...1 * 2 => (),
    |          ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 1 + 4;
@@ -151,7 +151,7 @@ error: expected a pattern range bound, found an expression
 LL |         (1 + 4)...1 * 2 => (),
    |                   ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 1 * 2;
@@ -172,7 +172,7 @@ error: expected a pattern range bound, found an expression
 LL |         0.x()..="y".z() => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 0.x();
@@ -193,7 +193,7 @@ error: expected a pattern range bound, found an expression
 LL |         0.x()..="y".z() => (),
    |                 ^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = "y".z();
diff --git a/tests/ui/parser/recover/recover-pat-wildcards.stderr b/tests/ui/parser/recover/recover-pat-wildcards.stderr
index 8d4212ed389..81a9920f6a2 100644
--- a/tests/ui/parser/recover/recover-pat-wildcards.stderr
+++ b/tests/ui/parser/recover/recover-pat-wildcards.stderr
@@ -77,7 +77,7 @@ error: expected a pattern range bound, found an expression
 LL |         4..=(2 + _) => ()
    |              ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 2 + _;
diff --git a/tests/ui/parser/recover/recover-range-pats.stderr b/tests/ui/parser/recover/recover-range-pats.stderr
index b8e91c2344a..5c134bd4a82 100644
--- a/tests/ui/parser/recover/recover-range-pats.stderr
+++ b/tests/ui/parser/recover/recover-range-pats.stderr
@@ -613,7 +613,7 @@ LL |     mac2!(0, 1);
    |     ----------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -627,7 +627,7 @@ LL |     mac2!(0, 1);
    |     ----------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -641,7 +641,7 @@ LL |     mac2!(0, 1);
    |     ----------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -655,7 +655,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -669,7 +669,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -683,7 +683,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -697,7 +697,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -711,7 +711,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -725,7 +725,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/path.rs b/tests/ui/path.rs
index cd6962ac3e0..bd7b99ac01a 100644
--- a/tests/ui/path.rs
+++ b/tests/ui/path.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 mod foo {
     pub fn bar(_offset: usize) { }
diff --git a/tests/ui/pattern/fn-in-pat.stderr b/tests/ui/pattern/fn-in-pat.stderr
index 41ea4df72a2..90b1dff32ce 100644
--- a/tests/ui/pattern/fn-in-pat.stderr
+++ b/tests/ui/pattern/fn-in-pat.stderr
@@ -4,7 +4,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function
 LL |         A::new() => (),
    |         ^^^^^^^^ `fn` calls are not allowed in patterns
    |
-   = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
+   = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/pattern/issue-106552.stderr b/tests/ui/pattern/issue-106552.stderr
index 96f3d68458f..6d9a989f182 100644
--- a/tests/ui/pattern/issue-106552.stderr
+++ b/tests/ui/pattern/issue-106552.stderr
@@ -5,7 +5,7 @@ LL |     let 5 = 6;
    |         ^ patterns `i32::MIN..=4_i32` and `6_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
@@ -23,7 +23,7 @@ LL |     let x @ 5 = 6;
    |         ^ patterns `i32::MIN..=4_i32` and `6_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `let else` to handle the variants that aren't matched
    |
diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs
index 19aa73573b4..a4afcb2e511 100644
--- a/tests/ui/pattern/mut_preserve_binding_mode_2024.rs
+++ b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 #![feature(mut_ref, ref_pat_eat_one_layer_2024)]
 #![allow(incomplete_features, unused)]
 
diff --git a/tests/ui/pattern/pattern-binding-disambiguation.stderr b/tests/ui/pattern/pattern-binding-disambiguation.stderr
index 61c32b6a17b..3ba63b4d253 100644
--- a/tests/ui/pattern/pattern-binding-disambiguation.stderr
+++ b/tests/ui/pattern/pattern-binding-disambiguation.stderr
@@ -87,7 +87,7 @@ LL |     let UnitVariant = UnitVariant;
    |         ^^^^^^^^^^^ patterns `E::TupleVariant` and `E::BracedVariant {  }` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `E` defined here
   --> $DIR/pattern-binding-disambiguation.rs:5:6
    |
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs
index 0b70e4404ab..daa9b7368fd 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Z unstable-options
 
 // This contains a binding in edition 2024, so if matched with a reference binding mode it will end
 // up with a `mut ref mut` binding mode. We use this to test the migration lint on patterns with
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
index a822c90ab6e..50b716a1111 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
@@ -1,6 +1,5 @@
 //@ check-fail
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 #![deny(rust_2024_incompatible_pat)]
 
 fn main() {}
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
index 33e4f0021b7..92058095f84 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:24:20
+  --> $DIR/min_match_ergonomics_fail.rs:23:20
    |
 LL | test_pat_on_type![(&x,): &(T,)];
    |                    ^^    ----- expected due to this
@@ -15,7 +15,7 @@ LL + test_pat_on_type![(x,): &(T,)];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:26:20
+  --> $DIR/min_match_ergonomics_fail.rs:25:20
    |
 LL | test_pat_on_type![(&x,): &(&mut T,)];
    |                    ^^    ---------- expected due to this
@@ -31,7 +31,7 @@ LL + test_pat_on_type![(x,): &(&mut T,)];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:27:20
+  --> $DIR/min_match_ergonomics_fail.rs:26:20
    |
 LL | test_pat_on_type![(&mut x,): &(&T,)];
    |                    ^^^^^^    ------ expected due to this
@@ -41,7 +41,7 @@ LL | test_pat_on_type![(&mut x,): &(&T,)];
    = note:      expected reference `&T`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/min_match_ergonomics_fail.rs:27:20
+  --> $DIR/min_match_ergonomics_fail.rs:26:20
    |
 LL | test_pat_on_type![(&mut x,): &(&T,)];
    |                    ^^^^^^
@@ -52,7 +52,7 @@ LL + test_pat_on_type![(x,): &(&T,)];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:29:20
+  --> $DIR/min_match_ergonomics_fail.rs:28:20
    |
 LL | test_pat_on_type![(&x,): &&mut &(T,)];
    |                    ^^    ----------- expected due to this
@@ -68,7 +68,7 @@ LL + test_pat_on_type![(x,): &&mut &(T,)];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:30:29
+  --> $DIR/min_match_ergonomics_fail.rs:29:29
    |
 LL | test_pat_on_type![Foo { f: (&x,) }: Foo];
    |                             ^^      --- expected due to this
@@ -84,7 +84,7 @@ LL + test_pat_on_type![Foo { f: (x,) }: Foo];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:31:29
+  --> $DIR/min_match_ergonomics_fail.rs:30:29
    |
 LL | test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
    |                             ^^      -------- expected due to this
@@ -100,7 +100,7 @@ LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo];
    |
 
 error: patterns are not allowed to reset the default binding mode in edition 2024
-  --> $DIR/min_match_ergonomics_fail.rs:25:19
+  --> $DIR/min_match_ergonomics_fail.rs:24:19
    |
 LL | test_pat_on_type![(&x,): &(&T,)];
    |                   -^^^^
@@ -108,7 +108,7 @@ LL | test_pat_on_type![(&x,): &(&T,)];
    |                   help: desugar the match ergonomics: `&`
 
 error: patterns are not allowed to reset the default binding mode in edition 2024
-  --> $DIR/min_match_ergonomics_fail.rs:28:19
+  --> $DIR/min_match_ergonomics_fail.rs:27:19
    |
 LL | test_pat_on_type![(&mut x,): &(&mut T,)];
    |                   -^^^^^^^^
@@ -116,7 +116,7 @@ LL | test_pat_on_type![(&mut x,): &(&mut T,)];
    |                   help: desugar the match ergonomics: `&`
 
 error: patterns are not allowed to reset the default binding mode in edition 2024
-  --> $DIR/min_match_ergonomics_fail.rs:32:19
+  --> $DIR/min_match_ergonomics_fail.rs:31:19
    |
 LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
    |                   -^^^^^^^^^^^^^^^
@@ -124,7 +124,7 @@ LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
    |                   help: desugar the match ergonomics: `&`
 
 error: patterns are not allowed to reset the default binding mode in edition 2024
-  --> $DIR/min_match_ergonomics_fail.rs:33:19
+  --> $DIR/min_match_ergonomics_fail.rs:32:19
    |
 LL | test_pat_on_type![(mut x,): &(T,)];
    |                   -^^^^^^^
@@ -132,7 +132,7 @@ LL | test_pat_on_type![(mut x,): &(T,)];
    |                   help: desugar the match ergonomics: `&`
 
 error: patterns are not allowed to reset the default binding mode in edition 2024
-  --> $DIR/min_match_ergonomics_fail.rs:34:19
+  --> $DIR/min_match_ergonomics_fail.rs:33:19
    |
 LL | test_pat_on_type![(ref x,): &(T,)];
    |                   -^^^^^^^
@@ -140,7 +140,7 @@ LL | test_pat_on_type![(ref x,): &(T,)];
    |                   help: desugar the match ergonomics: `&`
 
 error: patterns are not allowed to reset the default binding mode in edition 2024
-  --> $DIR/min_match_ergonomics_fail.rs:35:19
+  --> $DIR/min_match_ergonomics_fail.rs:34:19
    |
 LL | test_pat_on_type![(ref mut x,): &mut (T,)];
    |                   -^^^^^^^^^^^
@@ -148,7 +148,7 @@ LL | test_pat_on_type![(ref mut x,): &mut (T,)];
    |                   help: desugar the match ergonomics: `&mut`
 
 error: patterns are not allowed to reset the default binding mode in edition 2024
-  --> $DIR/min_match_ergonomics_fail.rs:44:9
+  --> $DIR/min_match_ergonomics_fail.rs:43:9
    |
 LL |         (&x,) => x,
    |         -^^^^
diff --git a/tests/ui/pattern/self-ctor-133272.rs b/tests/ui/pattern/self-ctor-133272.rs
new file mode 100644
index 00000000000..ad64d6b88cd
--- /dev/null
+++ b/tests/ui/pattern/self-ctor-133272.rs
@@ -0,0 +1,21 @@
+//! Regression test for <https://github.com/rust-lang/rust/issues/133272>, where a `ref Self` ctor
+//! makes it possible to hit a `delayed_bug` that was converted into a `span_bug` in
+//! <https://github.com/rust-lang/rust/pull/121208>, and hitting this reveals that we did not have
+//! test coverage for this specific code pattern (heh) previously.
+//!
+//! # References
+//!
+//! - ICE bug report: <https://github.com/rust-lang/rust/issues/133272>.
+//! - Previous PR to change `delayed_bug` -> `span_bug`:
+//!   <https://github.com/rust-lang/rust/pull/121208>
+#![crate_type = "lib"]
+
+struct Foo;
+
+impl Foo {
+    fn fun() {
+        let S { ref Self } = todo!();
+        //~^ ERROR expected identifier, found keyword `Self`
+        //~| ERROR cannot find struct, variant or union type `S` in this scope
+    }
+}
diff --git a/tests/ui/pattern/self-ctor-133272.stderr b/tests/ui/pattern/self-ctor-133272.stderr
new file mode 100644
index 00000000000..bca55a43d9c
--- /dev/null
+++ b/tests/ui/pattern/self-ctor-133272.stderr
@@ -0,0 +1,15 @@
+error: expected identifier, found keyword `Self`
+  --> $DIR/self-ctor-133272.rs:17:21
+   |
+LL |         let S { ref Self } = todo!();
+   |                     ^^^^ expected identifier, found keyword
+
+error[E0422]: cannot find struct, variant or union type `S` in this scope
+  --> $DIR/self-ctor-133272.rs:17:13
+   |
+LL |         let S { ref Self } = todo!();
+   |             ^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0422`.
diff --git a/tests/ui/pattern/skipped-ref-pats-issue-125058.rs b/tests/ui/pattern/skipped-ref-pats-issue-125058.rs
index b733e5fda0a..2b587ecb91f 100644
--- a/tests/ui/pattern/skipped-ref-pats-issue-125058.rs
+++ b/tests/ui/pattern/skipped-ref-pats-issue-125058.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 
 #![allow(incomplete_features)]
 #![feature(ref_pat_eat_one_layer_2024)]
diff --git a/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr b/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr
index cee1cc673c7..f7fd4a4cc29 100644
--- a/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr
+++ b/tests/ui/pattern/skipped-ref-pats-issue-125058.stderr
@@ -1,5 +1,5 @@
 warning: struct `Foo` is never constructed
-  --> $DIR/skipped-ref-pats-issue-125058.rs:8:8
+  --> $DIR/skipped-ref-pats-issue-125058.rs:7:8
    |
 LL | struct Foo;
    |        ^^^
@@ -7,7 +7,7 @@ LL | struct Foo;
    = note: `#[warn(dead_code)]` on by default
 
 warning: unused closure that must be used
-  --> $DIR/skipped-ref-pats-issue-125058.rs:12:5
+  --> $DIR/skipped-ref-pats-issue-125058.rs:11:5
    |
 LL | /     || {
 LL | |
diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
index ec08e22e2ca..4a435bcc8ba 100644
--- a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
@@ -54,7 +54,7 @@ LL |     let None = *x;
    |         ^^^^ pattern `Some(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: pattern `Some(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
    = note: the matched value is of type `Option<SecretlyUninhabitedForeignStruct>`
 help: you might want to use `if let` to ignore the variant that isn't matched
diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
index ec08e22e2ca..4a435bcc8ba 100644
--- a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
@@ -54,7 +54,7 @@ LL |     let None = *x;
    |         ^^^^ pattern `Some(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: pattern `Some(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
    = note: the matched value is of type `Option<SecretlyUninhabitedForeignStruct>`
 help: you might want to use `if let` to ignore the variant that isn't matched
diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
index c6e41c1875f..23821decd6e 100644
--- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
@@ -150,7 +150,7 @@ LL |     let Ok(_x) = res_u32_never.as_ref();
    |         ^^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<&u32, &!>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
index 2e5511527d5..cf37bf67e86 100644
--- a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
@@ -126,7 +126,7 @@ LL |     let Ok(_x) = res_u32_never.as_ref();
    |         ^^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<&u32, &!>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
@@ -140,7 +140,7 @@ LL |     let Ok(_x) = &res_u32_never;
    |         ^^^^^^ pattern `&Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `&Result<u32, !>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
index 3f312d46c7e..84aefe7d963 100644
--- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
@@ -104,7 +104,7 @@ LL |     let Ok(_x) = res_u32_never.as_ref();
    |         ^^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<&u32, &!>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
@@ -118,7 +118,7 @@ LL |     let Ok(_x) = &res_u32_never;
    |         ^^^^^^ pattern `&Err(!)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `&Result<u32, !>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
@@ -239,7 +239,7 @@ LL |         let Ok(_) = *ptr_result_never_err;
    |             ^^^^^ pattern `Err(!)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<u8, !>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr
index bba50dab27b..f3af74c16c3 100644
--- a/tests/ui/pattern/usefulness/empty-types.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr
@@ -95,7 +95,7 @@ LL |     let Ok(_x) = res_u32_never.as_ref();
    |         ^^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<&u32, &!>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
@@ -109,7 +109,7 @@ LL |     let Ok(_x) = &res_u32_never;
    |         ^^^^^^ pattern `&Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `&Result<u32, !>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
@@ -230,7 +230,7 @@ LL |         let Ok(_) = *ptr_result_never_err;
    |             ^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<u8, !>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/tests/ui/pattern/usefulness/irrefutable-unit.rs b/tests/ui/pattern/usefulness/irrefutable-unit.rs
index b4e72c0aa2a..9a48b1a8679 100644
--- a/tests/ui/pattern/usefulness/irrefutable-unit.rs
+++ b/tests/ui/pattern/usefulness/irrefutable-unit.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let ((),()) = ((),());
diff --git a/tests/ui/pattern/usefulness/issue-31561.stderr b/tests/ui/pattern/usefulness/issue-31561.stderr
index cc720565828..ba7ae3fa9a0 100644
--- a/tests/ui/pattern/usefulness/issue-31561.stderr
+++ b/tests/ui/pattern/usefulness/issue-31561.stderr
@@ -5,7 +5,7 @@ LL |     let Thing::Foo(y) = Thing::Foo(1);
    |         ^^^^^^^^^^^^^ patterns `Thing::Bar` and `Thing::Baz` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Thing` defined here
   --> $DIR/issue-31561.rs:1:6
    |
diff --git a/tests/ui/pattern/usefulness/nested-exhaustive-match.rs b/tests/ui/pattern/usefulness/nested-exhaustive-match.rs
index 51b05c9a111..23782a49b5b 100644
--- a/tests/ui/pattern/usefulness/nested-exhaustive-match.rs
+++ b/tests/ui/pattern/usefulness/nested-exhaustive-match.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 struct Foo { foo: bool, bar: Option<isize>, baz: isize }
 
diff --git a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs
index 1d1ea8e4964..d0a8a10f2f3 100644
--- a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs
+++ b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs
@@ -44,7 +44,7 @@ fn by_val(e: E) {
     //~^ ERROR refutable pattern in local binding
     //~| patterns `E::B` and `E::C` not covered
     //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
-    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
     //~| NOTE the matched value is of type `E`
 }
 
@@ -60,7 +60,7 @@ fn by_ref_once(e: &E) {
     //~^ ERROR refutable pattern in local binding
     //~| patterns `&E::B` and `&E::C` not covered
     //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
-    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
     //~| NOTE the matched value is of type `&E`
 }
 
@@ -76,7 +76,7 @@ fn by_ref_thrice(e: & &mut &E) {
     //~^ ERROR refutable pattern in local binding
     //~| patterns `&&mut &E::B` and `&&mut &E::C` not covered
     //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
-    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
     //~| NOTE the matched value is of type `&&mut &E`
 }
 
@@ -103,7 +103,7 @@ fn ref_pat(e: Opt) {
     //~| NOTE the matched value is of type `Opt`
     //~| NOTE pattern `Opt::None` not covered
     //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
-    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 }
 
 fn main() {}
diff --git a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
index a9e55fa53a6..48d7a636055 100644
--- a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
+++ b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
@@ -29,7 +29,7 @@ LL |     let E::A = e;
    |         ^^^^ patterns `E::B` and `E::C` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `E` defined here
   --> $DIR/non-exhaustive-defined-here.rs:8:6
    |
@@ -78,7 +78,7 @@ LL |     let E::A = e;
    |         ^^^^ patterns `&E::B` and `&E::C` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `E` defined here
   --> $DIR/non-exhaustive-defined-here.rs:8:6
    |
@@ -127,7 +127,7 @@ LL |     let E::A = e;
    |         ^^^^ patterns `&&mut &E::B` and `&&mut &E::C` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `E` defined here
   --> $DIR/non-exhaustive-defined-here.rs:8:6
    |
@@ -173,7 +173,7 @@ LL |     let Opt::Some(ref _x) = e;
    |         ^^^^^^^^^^^^^^^^^ pattern `Opt::None` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Opt` defined here
   --> $DIR/non-exhaustive-defined-here.rs:83:6
    |
diff --git a/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr b/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr
index e66cd113023..23a5d895d6c 100644
--- a/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr
+++ b/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr
@@ -13,7 +13,7 @@ LL |     let (1, (Some(1), 2..=3)) = (1, (None, 2));
    |         ^^^^^^^^^^^^^^^^^^^^^ patterns `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `(i32, (Option<i32>, i32))`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
diff --git a/tests/ui/privacy/priv-impl-prim-ty.rs b/tests/ui/privacy/priv-impl-prim-ty.rs
index f4c4973f61b..ea1145f3c34 100644
--- a/tests/ui/privacy/priv-impl-prim-ty.rs
+++ b/tests/ui/privacy/priv-impl-prim-ty.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:priv-impl-prim-ty.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate priv_impl_prim_ty as bar;
 
diff --git a/tests/ui/privacy/privacy-ns.rs b/tests/ui/privacy/privacy-ns.rs
index 10d5e722217..ab3d79e40f9 100644
--- a/tests/ui/privacy/privacy-ns.rs
+++ b/tests/ui/privacy/privacy-ns.rs
@@ -5,7 +5,6 @@
 // Check we do the correct privacy checks when we import a name and there is an
 // item with that name in both the value and type namespaces.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 #![allow(unused_imports)]
diff --git a/tests/ui/privacy/privacy-reexport.rs b/tests/ui/privacy/privacy-reexport.rs
index df642a57372..74ac7cdce94 100644
--- a/tests/ui/privacy/privacy-reexport.rs
+++ b/tests/ui/privacy/privacy-reexport.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:privacy_reexport.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate privacy_reexport;
 
diff --git a/tests/ui/privacy/privacy1-rpass.rs b/tests/ui/privacy/privacy1-rpass.rs
index 10bc2492bc8..546492c8709 100644
--- a/tests/ui/privacy/privacy1-rpass.rs
+++ b/tests/ui/privacy/privacy1-rpass.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub mod test2 {
     // This used to generate an ICE (make sure that default functions are
diff --git a/tests/ui/privacy/private-method-rpass.rs b/tests/ui/privacy/private-method-rpass.rs
index 2ec29327d46..f62dd682d2b 100644
--- a/tests/ui/privacy/private-method-rpass.rs
+++ b/tests/ui/privacy/private-method-rpass.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 struct cat {
     meows : usize,
diff --git a/tests/ui/privacy/pub-extern-privacy.rs b/tests/ui/privacy/pub-extern-privacy.rs
index dc5e8951bfc..0f9131685b0 100644
--- a/tests/ui/privacy/pub-extern-privacy.rs
+++ b/tests/ui/privacy/pub-extern-privacy.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 
-//@ pretty-expanded FIXME #23616
 
 use std::mem::transmute;
 
diff --git a/tests/ui/privacy/pub-use-xcrate.rs b/tests/ui/privacy/pub-use-xcrate.rs
index 96c650d0c68..76891161aed 100644
--- a/tests/ui/privacy/pub-use-xcrate.rs
+++ b/tests/ui/privacy/pub-use-xcrate.rs
@@ -2,7 +2,6 @@
 //@ aux-build:pub_use_xcrate1.rs
 //@ aux-build:pub_use_xcrate2.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate pub_use_xcrate2;
 
diff --git a/tests/ui/privacy/pub_use_mods_xcrate_exe.rs b/tests/ui/privacy/pub_use_mods_xcrate_exe.rs
index 12b16c8cec8..f986bfb76e1 100644
--- a/tests/ui/privacy/pub_use_mods_xcrate_exe.rs
+++ b/tests/ui/privacy/pub_use_mods_xcrate_exe.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:pub_use_mods_xcrate.rs
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_imports)]
 
diff --git a/tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs b/tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs
new file mode 100644
index 00000000000..a4fd76b9c9d
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs
@@ -0,0 +1,42 @@
+//@ force-host
+//@ no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn make_edition_macro(_input: TokenStream) -> TokenStream {
+    "macro_rules! edition {
+        ($_:expr) => {
+            2024
+        };
+        (const {}) => {
+            2021
+        };
+    }
+    "
+    .parse()
+    .unwrap()
+}
+
+#[proc_macro]
+pub fn make_nested_edition_macro(_input: TokenStream) -> TokenStream {
+    "macro_rules! make_inner {
+        () => {
+            macro_rules! edition_inner {
+                ($_:expr) => {
+                    2024
+                };
+                (const {}) => {
+                    2021
+                };
+            }
+        };
+    }
+    "
+    .parse()
+    .unwrap()
+}
diff --git a/tests/ui/proc-macro/macro_rules_edition_from_pm.rs b/tests/ui/proc-macro/macro_rules_edition_from_pm.rs
new file mode 100644
index 00000000000..3ba80f5177a
--- /dev/null
+++ b/tests/ui/proc-macro/macro_rules_edition_from_pm.rs
@@ -0,0 +1,27 @@
+// Tests how edition hygiene works for macro_rules macros generated from a
+// proc-macro.
+// See https://github.com/rust-lang/rust/issues/132906
+
+//@ aux-crate: macro_rules_edition_pm=macro_rules_edition_pm.rs
+//@ revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+//@ check-pass
+
+// This checks how the expr fragment specifier works.
+macro_rules_edition_pm::make_edition_macro!{}
+
+const _: () = {
+    assert!(edition!(const {}) == 2021);
+};
+
+// This checks how the expr fragment specifier from a nested macro.
+macro_rules_edition_pm::make_nested_edition_macro!{}
+make_inner!{}
+
+const _: () = {
+    assert!(edition_inner!(const {}) == 2021);
+};
+
+fn main() {}
diff --git a/tests/ui/ptr-coercion-rpass.rs b/tests/ui/ptr-coercion-rpass.rs
index 5d9b907f0e4..8cc4120328e 100644
--- a/tests/ui/ptr-coercion-rpass.rs
+++ b/tests/ui/ptr-coercion-rpass.rs
@@ -3,7 +3,6 @@
 #![allow(unused_variables)]
 // Test coercions between pointers which don't do anything fancy like unsizing.
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     // &mut -> &
diff --git a/tests/ui/reachable/issue-11225-1.rs b/tests/ui/reachable/issue-11225-1.rs
index 6af270555c3..c87dd0d819b 100644
--- a/tests/ui/reachable/issue-11225-1.rs
+++ b/tests/ui/reachable/issue-11225-1.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-11225-1.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_11225_1 as foo;
 
diff --git a/tests/ui/reachable/issue-11225-2.rs b/tests/ui/reachable/issue-11225-2.rs
index d9449564e7f..2f2ca47aa04 100644
--- a/tests/ui/reachable/issue-11225-2.rs
+++ b/tests/ui/reachable/issue-11225-2.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-11225-2.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_11225_2 as foo;
 
diff --git a/tests/ui/reachable/issue-11225-3.rs b/tests/ui/reachable/issue-11225-3.rs
index 6f2d7dafdf6..0d2911bde8b 100644
--- a/tests/ui/reachable/issue-11225-3.rs
+++ b/tests/ui/reachable/issue-11225-3.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:issue-11225-3.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate issue_11225_3;
 
diff --git a/tests/ui/recursion/instantiable.rs b/tests/ui/recursion/instantiable.rs
index 9bbae7dfca0..3fe50e8d011 100644
--- a/tests/ui/recursion/instantiable.rs
+++ b/tests/ui/recursion/instantiable.rs
@@ -2,7 +2,6 @@
 
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 use std::ptr;
 
diff --git a/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr b/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr
index 5abec88eeff..35d436a1413 100644
--- a/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr
+++ b/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr
@@ -5,7 +5,7 @@ LL |     let Ok(x) = res;
    |         ^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<u32, &R<'_>>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/regions/issue-11612.rs b/tests/ui/regions/issue-11612.rs
index b95229ffa4a..af0071e1088 100644
--- a/tests/ui/regions/issue-11612.rs
+++ b/tests/ui/regions/issue-11612.rs
@@ -4,7 +4,6 @@
 // We weren't updating the auto adjustments with all the resolved
 // type information after type check.
 
-//@ pretty-expanded FIXME #23616
 
 trait A { fn dummy(&self) { } }
 
diff --git a/tests/ui/regions/issue-21520.rs b/tests/ui/regions/issue-21520.rs
index 4f92109ab90..825d6f2ee56 100644
--- a/tests/ui/regions/issue-21520.rs
+++ b/tests/ui/regions/issue-21520.rs
@@ -3,7 +3,6 @@
 // Test that the requirement (in `Bar`) that `T::Bar : 'static` does
 // not wind up propagating to `T`.
 
-//@ pretty-expanded FIXME #23616
 
 pub trait Foo {
     type Bar;
diff --git a/tests/ui/regions/issue-5243.rs b/tests/ui/regions/issue-5243.rs
index a346903d652..d3c77403a37 100644
--- a/tests/ui/regions/issue-5243.rs
+++ b/tests/ui/regions/issue-5243.rs
@@ -4,7 +4,6 @@
 // enough for codegen to consider this as non-monomorphic,
 // which led to various assertions and failures in turn.
 
-//@ pretty-expanded FIXME #23616
 
 struct S<'a> {
     v: &'a isize
diff --git a/tests/ui/regions/issue-6157.rs b/tests/ui/regions/issue-6157.rs
index 03a8c14e1a6..8d3002e52c8 100644
--- a/tests/ui/regions/issue-6157.rs
+++ b/tests/ui/regions/issue-6157.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub trait OpInt { fn call(&mut self, _: isize, _: isize) -> isize; }
 
diff --git a/tests/ui/regions/owned-implies-static.rs b/tests/ui/regions/owned-implies-static.rs
index d97e2f2d239..ffbee5a4bb7 100644
--- a/tests/ui/regions/owned-implies-static.rs
+++ b/tests/ui/regions/owned-implies-static.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn f<T: 'static>(_x: T) {}
 
diff --git a/tests/ui/regions/regions-addr-of-interior-of-unique-box.rs b/tests/ui/regions/regions-addr-of-interior-of-unique-box.rs
index bd3d4a1acdc..9dd49d35d44 100644
--- a/tests/ui/regions/regions-addr-of-interior-of-unique-box.rs
+++ b/tests/ui/regions/regions-addr-of-interior-of-unique-box.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 
-//@ pretty-expanded FIXME #23616
 
 struct Point {
     x: isize,
diff --git a/tests/ui/regions/regions-assoc-type-region-bound.rs b/tests/ui/regions/regions-assoc-type-region-bound.rs
index 1b7fdf11251..86c8359b61a 100644
--- a/tests/ui/regions/regions-assoc-type-region-bound.rs
+++ b/tests/ui/regions/regions-assoc-type-region-bound.rs
@@ -3,7 +3,6 @@
 // Test that the compiler considers the 'a bound declared in the
 // trait. Issue #20890.
 
-//@ pretty-expanded FIXME #23616
 
 trait Foo<'a> {
     type Value: 'a;
diff --git a/tests/ui/regions/regions-assoc-type-static-bound.rs b/tests/ui/regions/regions-assoc-type-static-bound.rs
index 9ffc66d284d..111cffcaf27 100644
--- a/tests/ui/regions/regions-assoc-type-static-bound.rs
+++ b/tests/ui/regions/regions-assoc-type-static-bound.rs
@@ -3,7 +3,6 @@
 // Test that the compiler considers the 'static bound declared in the
 // trait. Issue #20890.
 
-//@ pretty-expanded FIXME #23616
 
 trait Foo {
     type Value: 'static;
diff --git a/tests/ui/regions/regions-creating-enums2.rs b/tests/ui/regions/regions-creating-enums2.rs
index b81344cceec..de6e51b1fbd 100644
--- a/tests/ui/regions/regions-creating-enums2.rs
+++ b/tests/ui/regions/regions-creating-enums2.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 enum ast<'a> {
     num(usize),
diff --git a/tests/ui/regions/regions-creating-enums5.rs b/tests/ui/regions/regions-creating-enums5.rs
index 55793fb6202..14221a9d75f 100644
--- a/tests/ui/regions/regions-creating-enums5.rs
+++ b/tests/ui/regions/regions-creating-enums5.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 enum ast<'a> {
     num(usize),
diff --git a/tests/ui/regions/regions-debruijn-of-object.rs b/tests/ui/regions/regions-debruijn-of-object.rs
index 04bedf18ef0..a2de66aef37 100644
--- a/tests/ui/regions/regions-debruijn-of-object.rs
+++ b/tests/ui/regions/regions-debruijn-of-object.rs
@@ -3,7 +3,6 @@
 #![allow(unused_variables)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 struct ctxt<'tcx> {
     x: &'tcx i32
diff --git a/tests/ui/regions/regions-dependent-autofn.rs b/tests/ui/regions/regions-dependent-autofn.rs
index ccbb1219ce2..c58ae5e24ee 100644
--- a/tests/ui/regions/regions-dependent-autofn.rs
+++ b/tests/ui/regions/regions-dependent-autofn.rs
@@ -2,7 +2,6 @@
 // Test lifetimes are linked properly when we autoslice a vector.
 // Issue #3148.
 
-//@ pretty-expanded FIXME #23616
 
 fn subslice<F>(v: F) -> F where F: FnOnce() { v }
 
diff --git a/tests/ui/regions/regions-dependent-let-ref.rs b/tests/ui/regions/regions-dependent-let-ref.rs
index f3127abafb7..23b46abc91d 100644
--- a/tests/ui/regions/regions-dependent-let-ref.rs
+++ b/tests/ui/regions/regions-dependent-let-ref.rs
@@ -2,7 +2,6 @@
 // Test lifetimes are linked properly when we take reference
 // to interior.
 
-//@ pretty-expanded FIXME #23616
 
 struct Foo(isize);
 pub fn main() {
diff --git a/tests/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs b/tests/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs
index 1b6c3c93377..c08142154ed 100644
--- a/tests/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs
+++ b/tests/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs
@@ -6,7 +6,6 @@
 // lifetime parameters must be early bound in the type of the
 // associated item.
 
-//@ pretty-expanded FIXME #23616
 
 use std::marker;
 
diff --git a/tests/ui/regions/regions-expl-self.rs b/tests/ui/regions/regions-expl-self.rs
index 812201d7e52..552204867f6 100644
--- a/tests/ui/regions/regions-expl-self.rs
+++ b/tests/ui/regions/regions-expl-self.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 // Test that you can insert an explicit lifetime in explicit self.
 
-//@ pretty-expanded FIXME #23616
 
 struct Foo {
     f: usize
diff --git a/tests/ui/regions/regions-fn-subtyping-2.rs b/tests/ui/regions/regions-fn-subtyping-2.rs
index f5332ac1280..98be8de8671 100644
--- a/tests/ui/regions/regions-fn-subtyping-2.rs
+++ b/tests/ui/regions/regions-fn-subtyping-2.rs
@@ -5,7 +5,6 @@
 // Here, `f` is a function that takes a pointer `x` and a function
 // `g`, where `g` requires its argument `y` to be in the same region
 // that `x` is in.
-//@ pretty-expanded FIXME #23616
 
 fn has_same_region(f: Box<dyn for<'a> FnMut(&'a isize, Box<dyn FnMut(&'a isize)>)>) {
     // `f` should be the type that `wants_same_region` wants, but
diff --git a/tests/ui/regions/regions-fn-subtyping.rs b/tests/ui/regions/regions-fn-subtyping.rs
index 7e264eb03d8..dacd2f007c1 100644
--- a/tests/ui/regions/regions-fn-subtyping.rs
+++ b/tests/ui/regions/regions-fn-subtyping.rs
@@ -3,7 +3,6 @@
 #![allow(unused_assignments)]
 // Issue #2263.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_variables)]
 
diff --git a/tests/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs b/tests/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs
index f5d28a28154..f4e5c3a93a6 100644
--- a/tests/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs
+++ b/tests/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs
@@ -3,7 +3,6 @@
 // Test an edge case in region inference: the lifetime of the borrow
 // of `*x` must be extended to at least 'a.
 
-//@ pretty-expanded FIXME #23616
 
 fn foo<'a,'b>(x: &'a &'b mut isize) -> &'a isize {
     let y = &*x; // should be inferred to have type &'a &'b mut isize...
diff --git a/tests/ui/regions/regions-infer-region-in-fn-but-not-type.rs b/tests/ui/regions/regions-infer-region-in-fn-but-not-type.rs
index 165a246935f..402cee201be 100644
--- a/tests/ui/regions/regions-infer-region-in-fn-but-not-type.rs
+++ b/tests/ui/regions/regions-infer-region-in-fn-but-not-type.rs
@@ -6,7 +6,6 @@
 
 // check that the &isize here does not cause us to think that `foo`
 // contains region pointers
-//@ pretty-expanded FIXME #23616
 
 struct foo(Box<dyn FnMut(&isize)+'static>);
 
diff --git a/tests/ui/regions/regions-infer-static-from-proc.rs b/tests/ui/regions/regions-infer-static-from-proc.rs
index 9a130808ae8..09e1c8f635b 100644
--- a/tests/ui/regions/regions-infer-static-from-proc.rs
+++ b/tests/ui/regions/regions-infer-static-from-proc.rs
@@ -5,7 +5,6 @@
 // region variables contained within (otherwise, region inference will
 // give `x` a very short lifetime).
 
-//@ pretty-expanded FIXME #23616
 
 static i: usize = 3;
 fn foo<F:FnOnce()+'static>(_: F) {}
diff --git a/tests/ui/regions/regions-issue-21422.rs b/tests/ui/regions/regions-issue-21422.rs
index 54beed9b3ac..25f5d0f5013 100644
--- a/tests/ui/regions/regions-issue-21422.rs
+++ b/tests/ui/regions/regions-issue-21422.rs
@@ -3,7 +3,6 @@
 // add inference constraints that the operands of a binary operator
 // should outlive the binary operation itself.
 
-//@ pretty-expanded FIXME #23616
 
 pub struct P<'a> {
     _ptr: *const &'a u8,
diff --git a/tests/ui/regions/regions-issue-22246.rs b/tests/ui/regions/regions-issue-22246.rs
index e3bf7b31205..c943f33150e 100644
--- a/tests/ui/regions/regions-issue-22246.rs
+++ b/tests/ui/regions/regions-issue-22246.rs
@@ -3,7 +3,6 @@
 // Regression test for issue #22246 -- we should be able to deduce
 // that `&'a B::Owned` implies that `B::Owned : 'a`.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/regions/regions-lifetime-nonfree-late-bound.rs b/tests/ui/regions/regions-lifetime-nonfree-late-bound.rs
index ee29f44ecc9..57ad6cbbaf7 100644
--- a/tests/ui/regions/regions-lifetime-nonfree-late-bound.rs
+++ b/tests/ui/regions/regions-lifetime-nonfree-late-bound.rs
@@ -13,7 +13,6 @@
 // doing region-folding, when really all clients of the region-folding
 // case only want to see FREE lifetime variables, not bound ones.
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     fn explicit() {
diff --git a/tests/ui/regions/regions-link-fn-args.rs b/tests/ui/regions/regions-link-fn-args.rs
index 5fed86d5048..9172ebf9664 100644
--- a/tests/ui/regions/regions-link-fn-args.rs
+++ b/tests/ui/regions/regions-link-fn-args.rs
@@ -2,7 +2,6 @@
 // Test that region inference correctly links up the regions when a
 // `ref` borrow occurs inside a fn argument.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/regions/regions-mock-codegen.rs b/tests/ui/regions/regions-mock-codegen.rs
index 4cdbc680e6f..99c86364066 100644
--- a/tests/ui/regions/regions-mock-codegen.rs
+++ b/tests/ui/regions/regions-mock-codegen.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
-//@ pretty-expanded FIXME #23616
 #![feature(allocator_api)]
 
 use std::alloc::{handle_alloc_error, Allocator, Global, Layout};
diff --git a/tests/ui/regions/regions-no-bound-in-argument-cleanup.rs b/tests/ui/regions/regions-no-bound-in-argument-cleanup.rs
index 2c02ce670b9..3836c661df8 100644
--- a/tests/ui/regions/regions-no-bound-in-argument-cleanup.rs
+++ b/tests/ui/regions/regions-no-bound-in-argument-cleanup.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::marker;
 
diff --git a/tests/ui/regions/regions-nullary-variant.rs b/tests/ui/regions/regions-nullary-variant.rs
index 8fe0a97c61c..8624f9961f6 100644
--- a/tests/ui/regions/regions-nullary-variant.rs
+++ b/tests/ui/regions/regions-nullary-variant.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 enum roption<'a> {
     a, b(&'a usize)
diff --git a/tests/ui/regions/regions-reassign-let-bound-pointer.rs b/tests/ui/regions/regions-reassign-let-bound-pointer.rs
index d2f35973511..7ecfd958512 100644
--- a/tests/ui/regions/regions-reassign-let-bound-pointer.rs
+++ b/tests/ui/regions/regions-reassign-let-bound-pointer.rs
@@ -5,7 +5,6 @@
 // started out with a longer lifetime and was reassigned to a shorter
 // one (it should infer to be the intersection).
 
-//@ pretty-expanded FIXME #23616
 
 fn foo(x: &isize) {
     let a = 1;
diff --git a/tests/ui/regions/regions-reassign-match-bound-pointer.rs b/tests/ui/regions/regions-reassign-match-bound-pointer.rs
index 5e69396aa37..e549804db43 100644
--- a/tests/ui/regions/regions-reassign-match-bound-pointer.rs
+++ b/tests/ui/regions/regions-reassign-match-bound-pointer.rs
@@ -5,7 +5,6 @@
 // started out with a longer lifetime and was reassigned to a shorter
 // one (it should infer to be the intersection).
 
-//@ pretty-expanded FIXME #23616
 
 fn foo(x: &isize) {
     let a = 1;
diff --git a/tests/ui/regions/regions-scope-chain-example.rs b/tests/ui/regions/regions-scope-chain-example.rs
index 01ce04b63d0..184ce015892 100644
--- a/tests/ui/regions/regions-scope-chain-example.rs
+++ b/tests/ui/regions/regions-scope-chain-example.rs
@@ -9,7 +9,6 @@
 // wrong path. The new algorithm avoids this problem and hence this
 // example typechecks correctly.
 
-//@ pretty-expanded FIXME #23616
 
 enum ScopeChain<'a> {
     Link(Scope<'a>),
diff --git a/tests/ui/regions/regions-variance-contravariant-use-contravariant.rs b/tests/ui/regions/regions-variance-contravariant-use-contravariant.rs
index b177f3a0110..db7cf869450 100644
--- a/tests/ui/regions/regions-variance-contravariant-use-contravariant.rs
+++ b/tests/ui/regions/regions-variance-contravariant-use-contravariant.rs
@@ -7,7 +7,6 @@
 // Note: see ui/variance/variance-regions-*.rs for the tests that check that the
 // variance inference works in the first place.
 
-//@ pretty-expanded FIXME #23616
 
 struct Contravariant<'a> {
     f: &'a isize
diff --git a/tests/ui/regions/regions-variance-covariant-use-covariant.rs b/tests/ui/regions/regions-variance-covariant-use-covariant.rs
index bd5959df2e1..4258268c3e0 100644
--- a/tests/ui/regions/regions-variance-covariant-use-covariant.rs
+++ b/tests/ui/regions/regions-variance-covariant-use-covariant.rs
@@ -9,7 +9,6 @@
 // This is covariant with respect to 'a, meaning that
 // Covariant<'foo> <: Covariant<'static> because
 // 'foo <= 'static
-//@ pretty-expanded FIXME #23616
 
 struct Covariant<'a> {
     f: extern "Rust" fn(&'a isize)
diff --git a/tests/ui/regions/wf-bound-region-in-object-type.rs b/tests/ui/regions/wf-bound-region-in-object-type.rs
index caa265b4ea2..c77845ab306 100644
--- a/tests/ui/regions/wf-bound-region-in-object-type.rs
+++ b/tests/ui/regions/wf-bound-region-in-object-type.rs
@@ -5,7 +5,6 @@
 // Test that the `wf` checker properly handles bound regions in object
 // types. Compiling this code used to trigger an ICE.
 
-//@ pretty-expanded FIXME #23616
 
 pub struct Context<'tcx> {
     vec: &'tcx Vec<isize>
diff --git a/tests/ui/resolve/blind-item-mixed-crate-use-item.rs b/tests/ui/resolve/blind-item-mixed-crate-use-item.rs
index 9869881db9a..6c1ae737cc2 100644
--- a/tests/ui/resolve/blind-item-mixed-crate-use-item.rs
+++ b/tests/ui/resolve/blind-item-mixed-crate-use-item.rs
@@ -2,7 +2,6 @@
 //@ aux-build:blind-item-mixed-crate-use-item-foo.rs
 //@ aux-build:blind-item-mixed-crate-use-item-foo2.rs
 
-//@ pretty-expanded FIXME #23616
 
 mod m {
     pub fn f<T>(_: T, _: (), _: ()) { }
diff --git a/tests/ui/resolve/blind-item-mixed-use-item.rs b/tests/ui/resolve/blind-item-mixed-use-item.rs
index 416496f3219..7796233c419 100644
--- a/tests/ui/resolve/blind-item-mixed-use-item.rs
+++ b/tests/ui/resolve/blind-item-mixed-use-item.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 mod m {
     pub fn f<T>(_: T, _: ()) { }
diff --git a/tests/ui/resolve/const-with-typo-in-pattern-binding.rs b/tests/ui/resolve/const-with-typo-in-pattern-binding.rs
new file mode 100644
index 00000000000..fe45cee91db
--- /dev/null
+++ b/tests/ui/resolve/const-with-typo-in-pattern-binding.rs
@@ -0,0 +1,45 @@
+#![deny(unreachable_patterns)] //~ NOTE the lint level is defined here
+#![allow(non_snake_case, non_upper_case_globals)]
+mod x {
+    pub use std::env::consts::ARCH;
+    const X: i32 = 0; //~ NOTE there is a constant of the same name
+}
+fn main() {
+    let input: i32 = 42;
+
+    const god: i32 = 1;
+    const GOOD: i32 = 1;
+    const BAD: i32 = 2;
+
+    let name: i32 = 42; //~ NOTE there is a binding of the same name
+
+    match input {
+        X => {} //~ NOTE matches any value
+        _ => {} //~ ERROR unreachable pattern
+        //~^ NOTE no value can reach this
+    }
+    match input {
+        GOD => {} //~ HELP you might have meant to pattern match against the value of similarly named constant `god`
+        //~^ NOTE matches any value
+        _ => {} //~ ERROR unreachable pattern
+        //~^ NOTE no value can reach this
+    }
+    match input {
+        GOOOD => {} //~ HELP you might have meant to pattern match against the value of similarly named constant `GOOD`
+        //~^ NOTE matches any value
+        _ => {} //~ ERROR unreachable pattern
+        //~^ NOTE no value can reach this
+    }
+    match input {
+        name => {}
+        //~^ NOTE matches any value
+        _ => {} //~ ERROR unreachable pattern
+        //~^ NOTE no value can reach this
+    }
+    match "" {
+        ARCH => {} //~ HELP you might have meant to pattern match against the value of constant `ARCH`
+        //~^ NOTE matches any value
+        _ => {} //~ ERROR unreachable pattern
+        //~^ NOTE no value can reach this
+    }
+}
diff --git a/tests/ui/resolve/const-with-typo-in-pattern-binding.stderr b/tests/ui/resolve/const-with-typo-in-pattern-binding.stderr
new file mode 100644
index 00000000000..a0cdac3fa25
--- /dev/null
+++ b/tests/ui/resolve/const-with-typo-in-pattern-binding.stderr
@@ -0,0 +1,78 @@
+error: unreachable pattern
+  --> $DIR/const-with-typo-in-pattern-binding.rs:18:9
+   |
+LL |         X => {}
+   |         - matches any value
+LL |         _ => {}
+   |         ^ no value can reach this
+   |
+note: there is a constant of the same name, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it is not accessible from this scope
+  --> $DIR/const-with-typo-in-pattern-binding.rs:5:5
+   |
+LL |     const X: i32 = 0;
+   |     ^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/const-with-typo-in-pattern-binding.rs:1:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/const-with-typo-in-pattern-binding.rs:24:9
+   |
+LL |         GOD => {}
+   |         --- matches any value
+LL |
+LL |         _ => {}
+   |         ^ no value can reach this
+   |
+help: you might have meant to pattern match against the value of similarly named constant `god` instead of introducing a new catch-all binding
+   |
+LL |         god => {}
+   |         ~~~
+
+error: unreachable pattern
+  --> $DIR/const-with-typo-in-pattern-binding.rs:30:9
+   |
+LL |         GOOOD => {}
+   |         ----- matches any value
+LL |
+LL |         _ => {}
+   |         ^ no value can reach this
+   |
+help: you might have meant to pattern match against the value of similarly named constant `GOOD` instead of introducing a new catch-all binding
+   |
+LL |         GOOD => {}
+   |         ~~~~
+
+error: unreachable pattern
+  --> $DIR/const-with-typo-in-pattern-binding.rs:36:9
+   |
+LL |         name => {}
+   |         ---- matches any value
+LL |
+LL |         _ => {}
+   |         ^ no value can reach this
+   |
+note: there is a binding of the same name; if you meant to pattern match against the value of that binding, that is a feature of constants that is not available for `let` bindings
+  --> $DIR/const-with-typo-in-pattern-binding.rs:14:9
+   |
+LL |     let name: i32 = 42;
+   |         ^^^^
+
+error: unreachable pattern
+  --> $DIR/const-with-typo-in-pattern-binding.rs:42:9
+   |
+LL |         ARCH => {}
+   |         ---- matches any value
+LL |
+LL |         _ => {}
+   |         ^ no value can reach this
+   |
+help: you might have meant to pattern match against the value of constant `ARCH` instead of introducing a new catch-all binding
+   |
+LL |         std::env::consts::ARCH => {}
+   |         ~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/resolve/issue-10200.stderr b/tests/ui/resolve/issue-10200.stderr
index 172d016c6e6..4b6d9b6f1df 100644
--- a/tests/ui/resolve/issue-10200.stderr
+++ b/tests/ui/resolve/issue-10200.stderr
@@ -7,7 +7,7 @@ LL | struct Foo(bool);
 LL |         foo(x)
    |         ^^^ help: a tuple struct with a similar name exists (notice the capitalization): `Foo`
    |
-   = note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/return/return-nil.rs b/tests/ui/return/return-nil.rs
index 403eae260dc..c2591a77b30 100644
--- a/tests/ui/return/return-nil.rs
+++ b/tests/ui/return/return-nil.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn f() { let x = (); return x; }
 
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr
index 1037033c4b7..f89ae241f44 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr
@@ -136,7 +136,7 @@ LL |     let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit
    |         ^^^^^^^^^^^^^^^ pattern `_` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `NonExhaustiveEnum`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs
index 389c76337f0..2c7fe2eea33 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs
@@ -1,5 +1,5 @@
 // issue-103476
-//@ compile-flags: -Zlint-mir -Zunstable-options
+//@ compile-flags: -Zlint-mir
 //@ edition: 2024
 //@ check-pass
 
diff --git a/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2024.rs b/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2024.rs
index 2c3dc30f0ae..aa655942150 100644
--- a/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2024.rs
+++ b/tests/ui/rust-2024/auxiliary/reserved-guarded-strings-macro-2024.rs
@@ -1,5 +1,4 @@
 //@ force-host
-//@ compile-flags: -Zunstable-options
 //@ edition:2024
 //@ no-prefer-dynamic
 
diff --git a/tests/ui/rust-2024/prelude2024.rs b/tests/ui/rust-2024/prelude2024.rs
index e58ebe74188..b7573948d9a 100644
--- a/tests/ui/rust-2024/prelude2024.rs
+++ b/tests/ui/rust-2024/prelude2024.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ compile-flags: -Zunstable-options
 //@ edition:2024
 
 fn main() {
diff --git a/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs b/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs
index f9e3c1e3c51..882f52c48a6 100644
--- a/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs
+++ b/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ compile-flags: -Zunstable-options
 //@ edition:2024
 //@ aux-build:reserved-guarded-strings-macro-2021.rs
 
diff --git a/tests/ui/rust-2024/reserved-guarded-strings.rs b/tests/ui/rust-2024/reserved-guarded-strings.rs
index dab97039be0..878881c1d24 100644
--- a/tests/ui/rust-2024/reserved-guarded-strings.rs
+++ b/tests/ui/rust-2024/reserved-guarded-strings.rs
@@ -1,4 +1,3 @@
-//@ compile-flags: -Zunstable-options
 //@ edition:2024
 // ignore-tidy-linelength
 
diff --git a/tests/ui/rust-2024/reserved-guarded-strings.stderr b/tests/ui/rust-2024/reserved-guarded-strings.stderr
index f465ba7944a..c8f8557b0f4 100644
--- a/tests/ui/rust-2024/reserved-guarded-strings.stderr
+++ b/tests/ui/rust-2024/reserved-guarded-strings.stderr
@@ -1,5 +1,5 @@
 error: prefix `blah` is unknown
-  --> $DIR/reserved-guarded-strings.rs:45:12
+  --> $DIR/reserved-guarded-strings.rs:44:12
    |
 LL |     demo2!(blah"xx");
    |            ^^^^ unknown prefix
@@ -11,7 +11,7 @@ LL |     demo2!(blah "xx");
    |                +
 
 error: prefix `blah` is unknown
-  --> $DIR/reserved-guarded-strings.rs:46:12
+  --> $DIR/reserved-guarded-strings.rs:45:12
    |
 LL |     demo2!(blah#"xx"#);
    |            ^^^^ unknown prefix
@@ -23,7 +23,7 @@ LL |     demo2!(blah #"xx"#);
    |                +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:46:16
+  --> $DIR/reserved-guarded-strings.rs:45:16
    |
 LL |     demo2!(blah#"xx"#);
    |                ^^^^^^
@@ -35,7 +35,7 @@ LL |     demo2!(blah# "xx"#);
    |                 +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:50:12
+  --> $DIR/reserved-guarded-strings.rs:49:12
    |
 LL |     demo2!(## "foo");
    |            ^^
@@ -47,7 +47,7 @@ LL |     demo2!(# # "foo");
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:51:17
+  --> $DIR/reserved-guarded-strings.rs:50:17
    |
 LL |     demo3!("foo"###);
    |                 ^^
@@ -59,7 +59,7 @@ LL |     demo3!("foo"# ##);
    |                  +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:52:12
+  --> $DIR/reserved-guarded-strings.rs:51:12
    |
 LL |     demo3!(### "foo");
    |            ^^
@@ -71,7 +71,7 @@ LL |     demo3!(# ## "foo");
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:53:12
+  --> $DIR/reserved-guarded-strings.rs:52:12
    |
 LL |     demo3!(## "foo"#);
    |            ^^
@@ -83,7 +83,7 @@ LL |     demo3!(# # "foo"#);
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:54:12
+  --> $DIR/reserved-guarded-strings.rs:53:12
    |
 LL |     demo5!(### "foo"###);
    |            ^^
@@ -95,7 +95,7 @@ LL |     demo5!(# ## "foo"###);
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:54:21
+  --> $DIR/reserved-guarded-strings.rs:53:21
    |
 LL |     demo5!(### "foo"###);
    |                     ^^
@@ -107,7 +107,7 @@ LL |     demo5!(### "foo"# ##);
    |                      +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:58:12
+  --> $DIR/reserved-guarded-strings.rs:57:12
    |
 LL |     demo1!(#"");
    |            ^^^
@@ -119,7 +119,7 @@ LL |     demo1!(# "");
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:59:12
+  --> $DIR/reserved-guarded-strings.rs:58:12
    |
 LL |     demo1!(#""#);
    |            ^^^^
@@ -131,7 +131,7 @@ LL |     demo1!(# ""#);
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:60:12
+  --> $DIR/reserved-guarded-strings.rs:59:12
    |
 LL |     demo1!(####"");
    |            ^^^^^^
@@ -143,7 +143,7 @@ LL |     demo1!(# ###"");
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:61:12
+  --> $DIR/reserved-guarded-strings.rs:60:12
    |
 LL |     demo1!(#"foo");
    |            ^^^^^^
@@ -155,7 +155,7 @@ LL |     demo1!(# "foo");
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:62:12
+  --> $DIR/reserved-guarded-strings.rs:61:12
    |
 LL |     demo1!(###"foo");
    |            ^^^^^^^^
@@ -167,7 +167,7 @@ LL |     demo1!(# ##"foo");
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:63:12
+  --> $DIR/reserved-guarded-strings.rs:62:12
    |
 LL |     demo1!(#"foo"#);
    |            ^^^^^^^
@@ -179,7 +179,7 @@ LL |     demo1!(# "foo"#);
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:64:12
+  --> $DIR/reserved-guarded-strings.rs:63:12
    |
 LL |     demo1!(###"foo"#);
    |            ^^^^^^^^^
@@ -191,7 +191,7 @@ LL |     demo1!(# ##"foo"#);
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:65:12
+  --> $DIR/reserved-guarded-strings.rs:64:12
    |
 LL |     demo1!(###"foo"##);
    |            ^^^^^^^^^^
@@ -203,7 +203,7 @@ LL |     demo1!(# ##"foo"##);
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:66:12
+  --> $DIR/reserved-guarded-strings.rs:65:12
    |
 LL |     demo1!(###"foo"###);
    |            ^^^^^^^^^^^
@@ -215,7 +215,7 @@ LL |     demo1!(# ##"foo"###);
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:67:12
+  --> $DIR/reserved-guarded-strings.rs:66:12
    |
 LL |     demo2!(#"foo"###);
    |            ^^^^^^^
@@ -227,7 +227,7 @@ LL |     demo2!(# "foo"###);
    |             +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:67:19
+  --> $DIR/reserved-guarded-strings.rs:66:19
    |
 LL |     demo2!(#"foo"###);
    |                   ^^
@@ -239,7 +239,7 @@ LL |     demo2!(#"foo"## #);
    |                    +
 
 error: invalid string literal
-  --> $DIR/reserved-guarded-strings.rs:72:12
+  --> $DIR/reserved-guarded-strings.rs:71:12
    |
 LL | ...n!(####################################################################################################################################################################################################################################################################"foo...
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs b/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs
new file mode 100644
index 00000000000..557731d82d3
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs
@@ -0,0 +1,22 @@
+//@ force-host
+//@ no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn missing_unsafe(_input: TokenStream) -> TokenStream {
+    "#[no_mangle] pub fn abc() {}".parse().unwrap()
+}
+
+#[proc_macro]
+pub fn macro_rules_missing_unsafe(_input: TokenStream) -> TokenStream {
+    "macro_rules! make_fn {
+        () => { #[no_mangle] pub fn foo() { } };
+    }"
+    .parse()
+    .unwrap()
+}
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs
new file mode 100644
index 00000000000..782a3942236
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs
@@ -0,0 +1,17 @@
+// Test for unsafe attributes generated by a proc-macro.
+// See https://github.com/rust-lang/rust/issues/132906
+
+//@ revisions: edition2021 edition2024
+//@ check-pass
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+//@ aux-crate: unsafe_attributes_pm=unsafe-attributes-pm.rs
+
+unsafe_attributes_pm::missing_unsafe!();
+
+unsafe_attributes_pm::macro_rules_missing_unsafe!();
+
+make_fn!();
+
+fn main() {}
diff --git a/tests/ui/sanitizer/cfi/can-reveal-opaques.rs b/tests/ui/sanitizer/cfi/can-reveal-opaques.rs
index 55988a62a8c..99c12d72eb5 100644
--- a/tests/ui/sanitizer/cfi/can-reveal-opaques.rs
+++ b/tests/ui/sanitizer/cfi/can-reveal-opaques.rs
@@ -39,6 +39,6 @@ fn main() {
     // So why is the second generic of `test` "`()`", and not the
     // `impl Sized` since we inferred it from the return type of `rpit_fn`
     // during typeck? Well, that's because we're using the generics from the
-    // terminator of the MIR, which has had the RevealAll pass performed on it.
+    // terminator of the MIR, which has had the PostAnalysisNormalize pass performed on it.
     let _ = test(rpit_fn);
 }
diff --git a/tests/ui/sanitizer/cfi/coroutine.rs b/tests/ui/sanitizer/cfi/coroutine.rs
index ad994fcf737..ec7c5888968 100644
--- a/tests/ui/sanitizer/cfi/coroutine.rs
+++ b/tests/ui/sanitizer/cfi/coroutine.rs
@@ -11,7 +11,7 @@
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
 //@ [kcfi] compile-flags: -C panic=abort -Z panic-abort-tests -C prefer-dynamic=off
-//@ compile-flags: --test -Z unstable-options
+//@ compile-flags: --test
 //@ run-pass
 
 #![feature(coroutines, stmt_expr_attributes)]
diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
index d121a194be6..2c0f25fc6ff 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
+++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
@@ -11,7 +11,7 @@ impl Foo {
         //~^ ERROR invalid generic `self` parameter type
         //~| ERROR destructor of `R` cannot be evaluated at compile-time
         self.0
-        //~^ ERROR cannot call non-const fn `<R as Deref>::deref` in constant function
+        //~^ ERROR cannot call conditionally-const method `<R as Deref>::deref` in constant function
     }
 }
 
diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
index 7252b5890fd..cf4c219215e 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
+++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
@@ -1,10 +1,12 @@
-error[E0015]: cannot call non-const fn `<R as Deref>::deref` in constant functions
+error[E0658]: cannot call conditionally-const method `<R as Deref>::deref` in constant functions
   --> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
    |
 LL |         self.0
    |         ^^^^^^
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` 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[E0493]: destructor of `R` cannot be evaluated at compile-time
   --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43
@@ -26,5 +28,5 @@ LL |     const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0015, E0493, E0801.
-For more information about an error, try `rustc --explain E0015`.
+Some errors have detailed explanations: E0493, E0658, E0801.
+For more information about an error, try `rustc --explain E0493`.
diff --git a/tests/ui/self/explicit-self-closures.rs b/tests/ui/self/explicit-self-closures.rs
index ea85caa22ce..cb8b89e90ce 100644
--- a/tests/ui/self/explicit-self-closures.rs
+++ b/tests/ui/self/explicit-self-closures.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 // Test to make sure that explicit self params work inside closures
 
-//@ pretty-expanded FIXME #23616
 
 struct Box {
     x: usize
diff --git a/tests/ui/self/explicit_self_xcrate_exe.rs b/tests/ui/self/explicit_self_xcrate_exe.rs
index f9daf91bdfa..3bd64d6a4ab 100644
--- a/tests/ui/self/explicit_self_xcrate_exe.rs
+++ b/tests/ui/self/explicit_self_xcrate_exe.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:explicit_self_xcrate.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate explicit_self_xcrate;
 use explicit_self_xcrate::{Foo, Bar};
diff --git a/tests/ui/self/self-impl-2.rs b/tests/ui/self/self-impl-2.rs
index 8c09f1ef756..7316adfde1a 100644
--- a/tests/ui/self/self-impl-2.rs
+++ b/tests/ui/self/self-impl-2.rs
@@ -3,7 +3,6 @@
 #![allow(unused_variables)]
 // Test that we can use `Self` types in impls in the expected way.
 
-//@ pretty-expanded FIXME #23616
 
 struct Foo;
 
diff --git a/tests/ui/self/self-type-param.rs b/tests/ui/self/self-type-param.rs
index 0b123de2531..3b107f465ea 100644
--- a/tests/ui/self/self-type-param.rs
+++ b/tests/ui/self/self-type-param.rs
@@ -1,6 +1,5 @@
 //@ build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait MyTrait {
     fn f(&self) -> Self;
diff --git a/tests/ui/simd-abi-checks-empty-list.stderr b/tests/ui/simd-abi-checks-empty-list.stderr
index d7ce52eab80..c49fe1a01de 100644
--- a/tests/ui/simd-abi-checks-empty-list.stderr
+++ b/tests/ui/simd-abi-checks-empty-list.stderr
@@ -10,3 +10,14 @@ LL | pub extern "C" fn pass_by_vec(_: SimdVec) {}
 
 warning: 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: this function definition uses a SIMD vector type that is not currently supported with the chosen ABI
+  --> $DIR/simd-abi-checks-empty-list.rs:17:1
+   |
+LL | pub extern "C" fn pass_by_vec(_: SimdVec) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+
diff --git a/tests/ui/simd-abi-checks-s390x.z10.stderr b/tests/ui/simd-abi-checks-s390x.z10.stderr
index a91322ec058..cf135afb428 100644
--- a/tests/ui/simd-abi-checks-s390x.z10.stderr
+++ b/tests/ui/simd-abi-checks-s390x.z10.stderr
@@ -109,3 +109,167 @@ LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>)
 
 error: aborting due to 10 previous errors
 
+Future incompatibility report: Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:46:1
+   |
+LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:52:1
+   |
+LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:99:1
+   |
+LL | / extern "C" fn vector_transparent_wrapper_ret_small(
+LL | |     x: &TransparentWrapper<i8x8>,
+LL | | ) -> TransparentWrapper<i8x8> {
+   | |_____________________________^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:107:1
+   |
+LL | / extern "C" fn vector_transparent_wrapper_ret(
+LL | |     x: &TransparentWrapper<i8x16>,
+LL | | ) -> TransparentWrapper<i8x16> {
+   | |______________________________^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:123:1
+   |
+LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:129:1
+   |
+LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:141:1
+   |
+LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:147:1
+   |
+LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:159:1
+   |
+LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:165:1
+   |
+LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr b/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr
index a91322ec058..cf135afb428 100644
--- a/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr
+++ b/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr
@@ -109,3 +109,167 @@ LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>)
 
 error: aborting due to 10 previous errors
 
+Future incompatibility report: Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:46:1
+   |
+LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:52:1
+   |
+LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:99:1
+   |
+LL | / extern "C" fn vector_transparent_wrapper_ret_small(
+LL | |     x: &TransparentWrapper<i8x8>,
+LL | | ) -> TransparentWrapper<i8x8> {
+   | |_____________________________^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:107:1
+   |
+LL | / extern "C" fn vector_transparent_wrapper_ret(
+LL | |     x: &TransparentWrapper<i8x16>,
+LL | | ) -> TransparentWrapper<i8x16> {
+   | |______________________________^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:123:1
+   |
+LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:129:1
+   |
+LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:141:1
+   |
+LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:147:1
+   |
+LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:159:1
+   |
+LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:165:1
+   |
+LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr
index a91322ec058..cf135afb428 100644
--- a/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr
+++ b/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr
@@ -109,3 +109,167 @@ LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>)
 
 error: aborting due to 10 previous errors
 
+Future incompatibility report: Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:46:1
+   |
+LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:52:1
+   |
+LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:99:1
+   |
+LL | / extern "C" fn vector_transparent_wrapper_ret_small(
+LL | |     x: &TransparentWrapper<i8x8>,
+LL | | ) -> TransparentWrapper<i8x8> {
+   | |_____________________________^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:107:1
+   |
+LL | / extern "C" fn vector_transparent_wrapper_ret(
+LL | |     x: &TransparentWrapper<i8x16>,
+LL | | ) -> TransparentWrapper<i8x16> {
+   | |______________________________^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:123:1
+   |
+LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:129:1
+   |
+LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:141:1
+   |
+LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:147:1
+   |
+LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:159:1
+   |
+LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
+  --> $DIR/simd-abi-checks-s390x.rs:165:1
+   |
+LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
+note: the lint level is defined here
+  --> $DIR/simd-abi-checks-s390x.rs:15:9
+   |
+LL | #![deny(abi_unsupported_vector_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/simd-abi-checks.rs b/tests/ui/simd-abi-checks.rs
index 9e3af26e9c4..c97767b2794 100644
--- a/tests/ui/simd-abi-checks.rs
+++ b/tests/ui/simd-abi-checks.rs
@@ -4,6 +4,7 @@
 
 #![feature(avx512_target_feature)]
 #![feature(portable_simd)]
+#![feature(target_feature_11, simd_ffi)]
 #![allow(improper_ctypes_definitions)]
 
 use std::arch::x86_64::*;
@@ -50,6 +51,14 @@ unsafe fn test() {
     as_f64x8(arg);
 }
 
+#[target_feature(enable = "avx")]
+unsafe fn in_closure() -> impl FnOnce() -> __m256 {
+    #[inline(always)] // this disables target-feature inheritance
+    || g()
+    //~^ WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+    //~| WARNING this was previously accepted by the compiler
+}
+
 fn main() {
     unsafe {
         f(g());
@@ -78,4 +87,24 @@ fn main() {
         //~| WARNING this was previously accepted by the compiler
         //~| WARNING this was previously accepted by the compiler
     }
+
+    unsafe {
+        in_closure()();
+    }
+
+    unsafe {
+        #[expect(improper_ctypes)]
+        extern "C" {
+            fn some_extern() -> __m256;
+        }
+        some_extern();
+        //~^ WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+        //~| WARNING this was previously accepted by the compiler
+    }
+}
+
+#[no_mangle]
+#[target_feature(enable = "avx")]
+fn some_extern() -> __m256 {
+    todo!()
 }
diff --git a/tests/ui/simd-abi-checks.stderr b/tests/ui/simd-abi-checks.stderr
index 7d2915f7dea..eb7d9e81029 100644
--- a/tests/ui/simd-abi-checks.stderr
+++ b/tests/ui/simd-abi-checks.stderr
@@ -1,5 +1,5 @@
 warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
-  --> $DIR/simd-abi-checks.rs:55:11
+  --> $DIR/simd-abi-checks.rs:64:11
    |
 LL |         f(g());
    |           ^^^ function called here
@@ -10,7 +10,7 @@ LL |         f(g());
    = note: `#[warn(abi_unsupported_vector_types)]` on by default
 
 warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
-  --> $DIR/simd-abi-checks.rs:55:9
+  --> $DIR/simd-abi-checks.rs:64:9
    |
 LL |         f(g());
    |         ^^^^^^ function called here
@@ -20,7 +20,7 @@ LL |         f(g());
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
 warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
-  --> $DIR/simd-abi-checks.rs:63:14
+  --> $DIR/simd-abi-checks.rs:72:14
    |
 LL |         gavx(favx());
    |              ^^^^^^ function called here
@@ -30,7 +30,7 @@ LL |         gavx(favx());
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
 warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
-  --> $DIR/simd-abi-checks.rs:63:9
+  --> $DIR/simd-abi-checks.rs:72:9
    |
 LL |         gavx(favx());
    |         ^^^^^^^^^^^^ function called here
@@ -40,7 +40,7 @@ LL |         gavx(favx());
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
 warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
-  --> $DIR/simd-abi-checks.rs:75:19
+  --> $DIR/simd-abi-checks.rs:84:19
    |
 LL |         w(Wrapper(g()));
    |                   ^^^ function called here
@@ -50,7 +50,7 @@ LL |         w(Wrapper(g()));
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
 warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
-  --> $DIR/simd-abi-checks.rs:75:9
+  --> $DIR/simd-abi-checks.rs:84:9
    |
 LL |         w(Wrapper(g()));
    |         ^^^^^^^^^^^^^^^ function called here
@@ -59,8 +59,145 @@ LL |         w(Wrapper(g()));
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+  --> $DIR/simd-abi-checks.rs:100:9
+   |
+LL |         some_extern();
+   |         ^^^^^^^^^^^^^ function called here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+
+warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
+  --> $DIR/simd-abi-checks.rs:27:1
+   |
+LL | unsafe extern "C" fn g() -> __m256 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+
+warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
+  --> $DIR/simd-abi-checks.rs:21:1
+   |
+LL | unsafe extern "C" fn f(_: __m256) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+
+warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
+  --> $DIR/simd-abi-checks.rs:15:1
+   |
+LL | unsafe extern "C" fn w(_: Wrapper) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+  --> $DIR/simd-abi-checks.rs:57:8
+   |
+LL |     || g()
+   |        ^^^ function called here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+
+warning: 11 warnings emitted
+
+Future incompatibility report: Future breakage diagnostic:
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+  --> $DIR/simd-abi-checks.rs:64:11
+   |
+LL |         f(g());
+   |           ^^^ function called here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+
+Future breakage diagnostic:
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+  --> $DIR/simd-abi-checks.rs:64:9
+   |
+LL |         f(g());
+   |         ^^^^^^ function called here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+
+Future breakage diagnostic:
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+  --> $DIR/simd-abi-checks.rs:72:14
+   |
+LL |         gavx(favx());
+   |              ^^^^^^ function called here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+
+Future breakage diagnostic:
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+  --> $DIR/simd-abi-checks.rs:72:9
+   |
+LL |         gavx(favx());
+   |         ^^^^^^^^^^^^ function called here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+
+Future breakage diagnostic:
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+  --> $DIR/simd-abi-checks.rs:84:19
+   |
+LL |         w(Wrapper(g()));
+   |                   ^^^ function called here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+
+Future breakage diagnostic:
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+  --> $DIR/simd-abi-checks.rs:84:9
+   |
+LL |         w(Wrapper(g()));
+   |         ^^^^^^^^^^^^^^^ function called here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+
+Future breakage diagnostic:
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+  --> $DIR/simd-abi-checks.rs:100:9
+   |
+LL |         some_extern();
+   |         ^^^^^^^^^^^^^ function called here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+
+Future breakage diagnostic:
 warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
-  --> $DIR/simd-abi-checks.rs:26:1
+  --> $DIR/simd-abi-checks.rs:27:1
    |
 LL | unsafe extern "C" fn g() -> __m256 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -68,9 +205,11 @@ LL | unsafe extern "C" fn g() -> __m256 {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
 
+Future breakage diagnostic:
 warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
-  --> $DIR/simd-abi-checks.rs:20:1
+  --> $DIR/simd-abi-checks.rs:21:1
    |
 LL | unsafe extern "C" fn f(_: __m256) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -78,9 +217,11 @@ LL | unsafe extern "C" fn f(_: __m256) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
 
+Future breakage diagnostic:
 warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
-  --> $DIR/simd-abi-checks.rs:14:1
+  --> $DIR/simd-abi-checks.rs:15:1
    |
 LL | unsafe extern "C" fn w(_: Wrapper) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -88,6 +229,17 @@ LL | unsafe extern "C" fn w(_: Wrapper) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
 
-warning: 9 warnings emitted
+Future breakage diagnostic:
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+  --> $DIR/simd-abi-checks.rs:57:8
+   |
+LL |     || g()
+   |        ^^^ function called here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
 
diff --git a/tests/ui/simd/array-trait.rs b/tests/ui/simd/array-trait.rs
index d2f246a2146..67583bf8208 100644
--- a/tests/ui/simd/array-trait.rs
+++ b/tests/ui/simd/array-trait.rs
@@ -2,7 +2,6 @@
 
 #![allow(dead_code)]
 
-//@ pretty-expanded FIXME #23616
 
 #![feature(repr_simd, intrinsics, generic_const_exprs)]
 #![allow(non_camel_case_types, incomplete_features)]
diff --git a/tests/ui/simd/array-trait.stderr b/tests/ui/simd/array-trait.stderr
index a63dbf37959..2d2a11f25ad 100644
--- a/tests/ui/simd/array-trait.stderr
+++ b/tests/ui/simd/array-trait.stderr
@@ -1,5 +1,5 @@
 error: unconstrained generic constant
-  --> $DIR/array-trait.rs:23:23
+  --> $DIR/array-trait.rs:22:23
    |
 LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
    |                       ^^^^^^^^^^^^^^^^^^
@@ -10,13 +10,13 @@ LL | pub struct T<S: Simd>([S::Lane; S::SIZE]) where [(); S::SIZE]:;
    |                                           ++++++++++++++++++++
 
 error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
-  --> $DIR/array-trait.rs:23:1
+  --> $DIR/array-trait.rs:22:1
    |
 LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
    | ^^^^^^^^^^^^^^^^^^^^^
 
 error: unconstrained generic constant
-  --> $DIR/array-trait.rs:23:23
+  --> $DIR/array-trait.rs:22:23
    |
 LL | #[derive(Copy, Clone)]
    |                ----- in this derive macro expansion
diff --git a/tests/ui/simd/array-type.rs b/tests/ui/simd/array-type.rs
index 4063dcd703c..8ca53b1a453 100644
--- a/tests/ui/simd/array-type.rs
+++ b/tests/ui/simd/array-type.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 
-//@ pretty-expanded FIXME #23616
 
 #![feature(repr_simd, intrinsics)]
 
diff --git a/tests/ui/sized-borrowed-pointer.rs b/tests/ui/sized-borrowed-pointer.rs
index f1635531e4e..bd213c067db 100644
--- a/tests/ui/sized-borrowed-pointer.rs
+++ b/tests/ui/sized-borrowed-pointer.rs
@@ -3,7 +3,6 @@
 #![allow(dead_code)]
 // Possibly-dynamic size of typaram should be cleared at pointer boundary.
 
-//@ pretty-expanded FIXME #23616
 
 fn bar<T: Sized>() { }
 fn foo<T>() { bar::<&T>() }
diff --git a/tests/ui/sized-owned-pointer.rs b/tests/ui/sized-owned-pointer.rs
index 48f870de9ae..b35c0f91abd 100644
--- a/tests/ui/sized-owned-pointer.rs
+++ b/tests/ui/sized-owned-pointer.rs
@@ -4,7 +4,6 @@
 // Possibly-dynamic size of typaram should be cleared at pointer boundary.
 
 
-//@ pretty-expanded FIXME #23616
 
 fn bar<T: Sized>() { }
 fn foo<T>() { bar::<Box<T>>() }
diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr
index d40e9822435..eec2f5b42fd 100644
--- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr
+++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |     let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes;
    |                               ^^^^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error[E0412]: cannot find type `T` in this scope
   --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:55
diff --git a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr
index 60433e1c284..5ecbedf1867 100644
--- a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr
+++ b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr
@@ -4,7 +4,7 @@ error[E0670]: `async fn` is not permitted in Rust 2015
 LL |     pub(crate) async fn new(
    |                ^^^^^ to use `async fn`, switch to Rust 2018 or later
    |
-   = help: pass `--edition 2021` to `rustc`
+   = help: pass `--edition 2024` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0412]: cannot find type `Duration` in this scope
diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs
index a7487b8aecb..d11ec798332 100644
--- a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs
+++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs
@@ -17,7 +17,6 @@ impl<T, D> MyTrait<T> for D {
 }
 
 impl<T> MyTrait<T> for BadStruct {
-//~^ ERROR: conflicting implementations of trait `MyTrait<_>` for type `BadStruct`
     fn foo() {}
 }
 
diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr
index 13f6ae0805d..0ecec03a023 100644
--- a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr
+++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr
@@ -4,16 +4,6 @@ error[E0412]: cannot find type `MissingType` in this scope
 LL |     err: MissingType
    |          ^^^^^^^^^^^ not found in this scope
 
-error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `BadStruct`
-  --> $DIR/issue-68830-spurious-diagnostics.rs:19:1
-   |
-LL | impl<T, D> MyTrait<T> for D {
-   | --------------------------- first implementation here
-...
-LL | impl<T> MyTrait<T> for BadStruct {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `BadStruct`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0119, E0412.
-For more information about an error, try `rustc --explain E0119`.
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr
index 2af75876d5b..04a41f0d9dd 100644
--- a/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr
+++ b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr
@@ -4,11 +4,7 @@ error[E0477]: the type `&'a i32` does not fulfill the required lifetime
 LL | impl<'a> Tr for &'a i32 {
    | ^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: type must satisfy the static lifetime as required by this binding
-  --> $DIR/specialize_with_generalize_lifetimes.rs:12:15
-   |
-LL | impl<T: Any + 'static> Tr for T {
-   |               ^^^^^^^
+   = note: type must satisfy the static lifetime
 
 error[E0477]: the type `Wrapper<'a>` does not fulfill the required lifetime
   --> $DIR/specialize_with_generalize_lifetimes.rs:31:1
@@ -16,11 +12,7 @@ error[E0477]: the type `Wrapper<'a>` does not fulfill the required lifetime
 LL | impl<'a> Tr for Wrapper<'a> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: type must satisfy the static lifetime as required by this binding
-  --> $DIR/specialize_with_generalize_lifetimes.rs:12:15
-   |
-LL | impl<T: Any + 'static> Tr for T {
-   |               ^^^^^^^
+   = note: type must satisfy the static lifetime
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/sse-abi-checks.stderr b/tests/ui/sse-abi-checks.stderr
index 7dd13af5091..e08b2d4e191 100644
--- a/tests/ui/sse-abi-checks.stderr
+++ b/tests/ui/sse-abi-checks.stderr
@@ -11,3 +11,15 @@ LL | pub unsafe extern "C" fn f(_: SseVector) {
 
 warning: 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `sse` target feature, which is not enabled
+  --> $DIR/sse-abi-checks.rs:21:1
+   |
+LL | pub unsafe extern "C" fn f(_: SseVector) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = help: consider enabling it globally (`-C target-feature=+sse`) or locally (`#[target_feature(enable="sse")]`)
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+
diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs
index 10c31d79438..19820730736 100644
--- a/tests/ui/stability-attribute/missing-const-stability.rs
+++ b/tests/ui/stability-attribute/missing-const-stability.rs
@@ -27,7 +27,7 @@ pub trait Bar {
 }
 #[stable(feature = "stable", since = "1.0.0")]
 impl const Bar for Foo {
-    //~^ ERROR implementation has missing const stability attribute
+    // ok because all users must enable `const_trait_impl`
     fn fun() {}
 }
 
diff --git a/tests/ui/stability-attribute/missing-const-stability.stderr b/tests/ui/stability-attribute/missing-const-stability.stderr
index ad8a1fa9d36..baa4c34af06 100644
--- a/tests/ui/stability-attribute/missing-const-stability.stderr
+++ b/tests/ui/stability-attribute/missing-const-stability.stderr
@@ -4,15 +4,6 @@ error: function has missing const stability attribute
 LL | pub const fn foo() {}
    | ^^^^^^^^^^^^^^^^^^^^^
 
-error: implementation has missing const stability attribute
-  --> $DIR/missing-const-stability.rs:29:1
-   |
-LL | / impl const Bar for Foo {
-LL | |
-LL | |     fn fun() {}
-LL | | }
-   | |_^
-
 error: function has missing const stability attribute
   --> $DIR/missing-const-stability.rs:36:1
    |
@@ -25,5 +16,5 @@ error: associated function has missing const stability attribute
 LL |     pub const fn foo() {}
    |     ^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/static/issue-1660.rs b/tests/ui/static/issue-1660.rs
index a114a908313..02a408d9a56 100644
--- a/tests/ui/static/issue-1660.rs
+++ b/tests/ui/static/issue-1660.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(non_upper_case_globals)]
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     static _x: isize = 1<<2;
diff --git a/tests/ui/statics/check-recursion-foreign.rs b/tests/ui/statics/check-recursion-foreign.rs
index 5a0ff7b5962..6804910f4cc 100644
--- a/tests/ui/statics/check-recursion-foreign.rs
+++ b/tests/ui/statics/check-recursion-foreign.rs
@@ -4,7 +4,6 @@
 
 //@ aux-build:check_static_recursion_foreign_helper.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate check_static_recursion_foreign_helper;
 
diff --git a/tests/ui/statics/issue-15261.rs b/tests/ui/statics/issue-15261.rs
index e168abce078..ed79a201488 100644
--- a/tests/ui/statics/issue-15261.rs
+++ b/tests/ui/statics/issue-15261.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
-//@ pretty-expanded FIXME #23616
 
 static mut n_mut: usize = 0;
 
diff --git a/tests/ui/statics/issue-15261.stderr b/tests/ui/statics/issue-15261.stderr
index 417dbae9db1..4067d151de3 100644
--- a/tests/ui/statics/issue-15261.stderr
+++ b/tests/ui/statics/issue-15261.stderr
@@ -1,5 +1,5 @@
 warning: creating a shared reference to mutable static is discouraged
-  --> $DIR/issue-15261.rs:9:37
+  --> $DIR/issue-15261.rs:8:37
    |
 LL | static n: &'static usize = unsafe { &n_mut };
    |                                     ^^^^^^ shared reference to mutable static
diff --git a/tests/ui/statics/issue-17718-static-unsafe-interior.rs b/tests/ui/statics/issue-17718-static-unsafe-interior.rs
index 82d5ec8db46..daff7ba873c 100644
--- a/tests/ui/statics/issue-17718-static-unsafe-interior.rs
+++ b/tests/ui/statics/issue-17718-static-unsafe-interior.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(unused_variables)]
 #![allow(unused_imports)]
-//@ pretty-expanded FIXME #23616
 
 use std::marker;
 use std::cell::UnsafeCell;
diff --git a/tests/ui/statics/static-fn-inline-xc.rs b/tests/ui/statics/static-fn-inline-xc.rs
index fe230f04d3d..e75083b2188 100644
--- a/tests/ui/statics/static-fn-inline-xc.rs
+++ b/tests/ui/statics/static-fn-inline-xc.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:static_fn_inline_xc_aux.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate static_fn_inline_xc_aux as mycore;
 
diff --git a/tests/ui/statics/static-fn-trait-xc.rs b/tests/ui/statics/static-fn-trait-xc.rs
index 78810eb5645..73747416c60 100644
--- a/tests/ui/statics/static-fn-trait-xc.rs
+++ b/tests/ui/statics/static-fn-trait-xc.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:static_fn_trait_xc_aux.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate static_fn_trait_xc_aux as mycore;
 
diff --git a/tests/ui/statics/static-methods-in-traits2.rs b/tests/ui/statics/static-methods-in-traits2.rs
index dbb7120d543..dbd5e77c1ba 100644
--- a/tests/ui/statics/static-methods-in-traits2.rs
+++ b/tests/ui/statics/static-methods-in-traits2.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub trait Number: NumConv {
     fn from<T:Number>(n: T) -> Self;
diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr
index 2cc2c8019fa..2adbcfab612 100644
--- a/tests/ui/stats/input-stats.stderr
+++ b/tests/ui/stats/input-stats.stderr
@@ -5,27 +5,27 @@ ast-stats-1 Crate                     40 ( 0.6%)             1            40
 ast-stats-1 GenericArgs               40 ( 0.6%)             1            40
 ast-stats-1 - AngleBracketed            40 ( 0.6%)             1
 ast-stats-1 ExprField                 48 ( 0.7%)             1            48
-ast-stats-1 WherePredicate            56 ( 0.8%)             1            56
-ast-stats-1 - BoundPredicate            56 ( 0.8%)             1
 ast-stats-1 Attribute                 64 ( 1.0%)             2            32
 ast-stats-1 - DocComment                32 ( 0.5%)             1
 ast-stats-1 - Normal                    32 ( 0.5%)             1
+ast-stats-1 WherePredicate            64 ( 1.0%)             1            64
+ast-stats-1 - BoundPredicate            64 ( 1.0%)             1
 ast-stats-1 Local                     80 ( 1.2%)             1            80
 ast-stats-1 ForeignItem               88 ( 1.3%)             1            88
 ast-stats-1 - Fn                        88 ( 1.3%)             1
 ast-stats-1 Arm                       96 ( 1.4%)             2            48
 ast-stats-1 FnDecl                   120 ( 1.8%)             5            24
-ast-stats-1 FieldDef                 160 ( 2.4%)             2            80
 ast-stats-1 Param                    160 ( 2.4%)             4            40
 ast-stats-1 Stmt                     160 ( 2.4%)             5            32
 ast-stats-1 - Let                       32 ( 0.5%)             1
 ast-stats-1 - MacCall                   32 ( 0.5%)             1
 ast-stats-1 - Expr                      96 ( 1.4%)             3
+ast-stats-1 FieldDef                 176 ( 2.6%)             2            88
 ast-stats-1 Block                    192 ( 2.9%)             6            32
 ast-stats-1 Variant                  208 ( 3.1%)             2           104
 ast-stats-1 AssocItem                352 ( 5.3%)             4            88
-ast-stats-1 - Type                     176 ( 2.7%)             2
-ast-stats-1 - Fn                       176 ( 2.7%)             2
+ast-stats-1 - Type                     176 ( 2.6%)             2
+ast-stats-1 - Fn                       176 ( 2.6%)             2
 ast-stats-1 GenericBound             352 ( 5.3%)             4            88
 ast-stats-1 - Trait                    352 ( 5.3%)             4
 ast-stats-1 GenericParam             480 ( 7.2%)             5            96
@@ -33,14 +33,14 @@ ast-stats-1 Pat                      504 ( 7.6%)             7            72
 ast-stats-1 - Struct                    72 ( 1.1%)             1
 ast-stats-1 - Wild                      72 ( 1.1%)             1
 ast-stats-1 - Ident                    360 ( 5.4%)             5
-ast-stats-1 Expr                     576 ( 8.7%)             8            72
+ast-stats-1 Expr                     576 ( 8.6%)             8            72
 ast-stats-1 - Path                      72 ( 1.1%)             1
 ast-stats-1 - Match                     72 ( 1.1%)             1
 ast-stats-1 - Struct                    72 ( 1.1%)             1
 ast-stats-1 - Lit                      144 ( 2.2%)             2
-ast-stats-1 - Block                    216 ( 3.3%)             3
+ast-stats-1 - Block                    216 ( 3.2%)             3
 ast-stats-1 PathSegment              744 (11.2%)            31            24
-ast-stats-1 Ty                       896 (13.5%)            14            64
+ast-stats-1 Ty                       896 (13.4%)            14            64
 ast-stats-1 - Ref                       64 ( 1.0%)             1
 ast-stats-1 - Ptr                       64 ( 1.0%)             1
 ast-stats-1 - ImplicitSelf             128 ( 1.9%)             2
@@ -53,7 +53,7 @@ ast-stats-1 - Enum                     136 ( 2.0%)             1
 ast-stats-1 - Fn                       272 ( 4.1%)             2
 ast-stats-1 - Use                      408 ( 6.1%)             3
 ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total                  6_640                   116
+ast-stats-1 Total                  6_664                   116
 ast-stats-1
 ast-stats-2 POST EXPANSION AST STATS
 ast-stats-2 Name                Accumulated Size         Count     Item Size
@@ -62,8 +62,8 @@ ast-stats-2 Crate                     40 ( 0.5%)             1            40
 ast-stats-2 GenericArgs               40 ( 0.5%)             1            40
 ast-stats-2 - AngleBracketed            40 ( 0.5%)             1
 ast-stats-2 ExprField                 48 ( 0.7%)             1            48
-ast-stats-2 WherePredicate            56 ( 0.8%)             1            56
-ast-stats-2 - BoundPredicate            56 ( 0.8%)             1
+ast-stats-2 WherePredicate            64 ( 0.9%)             1            64
+ast-stats-2 - BoundPredicate            64 ( 0.9%)             1
 ast-stats-2 Local                     80 ( 1.1%)             1            80
 ast-stats-2 ForeignItem               88 ( 1.2%)             1            88
 ast-stats-2 - Fn                        88 ( 1.2%)             1
@@ -73,14 +73,14 @@ ast-stats-2 InlineAsm                120 ( 1.6%)             1           120
 ast-stats-2 Attribute                128 ( 1.8%)             4            32
 ast-stats-2 - DocComment                32 ( 0.4%)             1
 ast-stats-2 - Normal                    96 ( 1.3%)             3
-ast-stats-2 FieldDef                 160 ( 2.2%)             2            80
 ast-stats-2 Param                    160 ( 2.2%)             4            40
 ast-stats-2 Stmt                     160 ( 2.2%)             5            32
 ast-stats-2 - Let                       32 ( 0.4%)             1
 ast-stats-2 - Semi                      32 ( 0.4%)             1
 ast-stats-2 - Expr                      96 ( 1.3%)             3
+ast-stats-2 FieldDef                 176 ( 2.4%)             2            88
 ast-stats-2 Block                    192 ( 2.6%)             6            32
-ast-stats-2 Variant                  208 ( 2.9%)             2           104
+ast-stats-2 Variant                  208 ( 2.8%)             2           104
 ast-stats-2 AssocItem                352 ( 4.8%)             4            88
 ast-stats-2 - Type                     176 ( 2.4%)             2
 ast-stats-2 - Fn                       176 ( 2.4%)             2
@@ -98,7 +98,7 @@ ast-stats-2 - Struct                    72 ( 1.0%)             1
 ast-stats-2 - InlineAsm                 72 ( 1.0%)             1
 ast-stats-2 - Lit                      144 ( 2.0%)             2
 ast-stats-2 - Block                    216 ( 3.0%)             3
-ast-stats-2 PathSegment              864 (11.9%)            36            24
+ast-stats-2 PathSegment              864 (11.8%)            36            24
 ast-stats-2 Ty                       896 (12.3%)            14            64
 ast-stats-2 - Ref                       64 ( 0.9%)             1
 ast-stats-2 - Ptr                       64 ( 0.9%)             1
@@ -111,9 +111,9 @@ ast-stats-2 - Impl                     136 ( 1.9%)             1
 ast-stats-2 - ExternCrate              136 ( 1.9%)             1
 ast-stats-2 - ForeignMod               136 ( 1.9%)             1
 ast-stats-2 - Fn                       272 ( 3.7%)             2
-ast-stats-2 - Use                      544 ( 7.5%)             4
+ast-stats-2 - Use                      544 ( 7.4%)             4
 ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total                  7_288                   127
+ast-stats-2 Total                  7_312                   127
 ast-stats-2
 hir-stats HIR STATS
 hir-stats Name                Accumulated Size         Count     Item Size
@@ -131,39 +131,39 @@ hir-stats Param                     64 ( 0.7%)             2            32
 hir-stats Body                      72 ( 0.8%)             3            24
 hir-stats ImplItemRef               72 ( 0.8%)             2            36
 hir-stats InlineAsm                 72 ( 0.8%)             1            72
+hir-stats WherePredicate            72 ( 0.8%)             3            24
+hir-stats - BoundPredicate            72 ( 0.8%)             3
 hir-stats Arm                       80 ( 0.9%)             2            40
-hir-stats FieldDef                  96 ( 1.1%)             2            48
 hir-stats Stmt                      96 ( 1.1%)             3            32
 hir-stats - Let                       32 ( 0.4%)             1
 hir-stats - Semi                      32 ( 0.4%)             1
 hir-stats - Expr                      32 ( 0.4%)             1
+hir-stats FieldDef                 112 ( 1.3%)             2            56
 hir-stats FnDecl                   120 ( 1.3%)             3            40
 hir-stats Attribute                128 ( 1.4%)             4            32
 hir-stats GenericArgs              144 ( 1.6%)             3            48
 hir-stats Variant                  144 ( 1.6%)             2            72
-hir-stats WherePredicate           192 ( 2.1%)             3            64
-hir-stats - BoundPredicate           192 ( 2.1%)             3
-hir-stats GenericBound             256 ( 2.8%)             4            64
-hir-stats - Trait                    256 ( 2.8%)             4
+hir-stats GenericBound             256 ( 2.9%)             4            64
+hir-stats - Trait                    256 ( 2.9%)             4
 hir-stats Block                    288 ( 3.2%)             6            48
 hir-stats GenericParam             360 ( 4.0%)             5            72
 hir-stats Pat                      360 ( 4.0%)             5            72
 hir-stats - Struct                    72 ( 0.8%)             1
 hir-stats - Wild                      72 ( 0.8%)             1
 hir-stats - Binding                  216 ( 2.4%)             3
-hir-stats Generics                 560 ( 6.2%)            10            56
-hir-stats Ty                       720 ( 8.0%)            15            48
+hir-stats Generics                 560 ( 6.3%)            10            56
+hir-stats Ty                       720 ( 8.1%)            15            48
 hir-stats - Ref                       48 ( 0.5%)             1
 hir-stats - Ptr                       48 ( 0.5%)             1
-hir-stats - Path                     624 ( 6.9%)            13
-hir-stats Expr                     768 ( 8.5%)            12            64
+hir-stats - Path                     624 ( 7.0%)            13
+hir-stats Expr                     768 ( 8.6%)            12            64
 hir-stats - Path                      64 ( 0.7%)             1
 hir-stats - Match                     64 ( 0.7%)             1
 hir-stats - Struct                    64 ( 0.7%)             1
 hir-stats - InlineAsm                 64 ( 0.7%)             1
 hir-stats - Lit                      128 ( 1.4%)             2
 hir-stats - Block                    384 ( 4.3%)             6
-hir-stats Item                     968 (10.7%)            11            88
+hir-stats Item                     968 (10.9%)            11            88
 hir-stats - Enum                      88 ( 1.0%)             1
 hir-stats - Trait                     88 ( 1.0%)             1
 hir-stats - Impl                      88 ( 1.0%)             1
@@ -171,8 +171,8 @@ hir-stats - ExternCrate               88 ( 1.0%)             1
 hir-stats - ForeignMod                88 ( 1.0%)             1
 hir-stats - Fn                       176 ( 2.0%)             2
 hir-stats - Use                      352 ( 3.9%)             4
-hir-stats Path                   1_240 (13.7%)            31            40
-hir-stats PathSegment            1_920 (21.3%)            40            48
+hir-stats Path                   1_240 (13.9%)            31            40
+hir-stats PathSegment            1_920 (21.5%)            40            48
 hir-stats ----------------------------------------------------------------
-hir-stats Total                  9_024                   180
+hir-stats Total                  8_920                   180
 hir-stats
diff --git a/tests/ui/structs-enums/class-dtor.rs b/tests/ui/structs-enums/class-dtor.rs
index ee6220b6fa4..a08f0f0b0a4 100644
--- a/tests/ui/structs-enums/class-dtor.rs
+++ b/tests/ui/structs-enums/class-dtor.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 struct cat {
   done : extern "C" fn(usize),
diff --git a/tests/ui/structs-enums/class-str-field.rs b/tests/ui/structs-enums/class-str-field.rs
index a33a635344e..24f648afc90 100644
--- a/tests/ui/structs-enums/class-str-field.rs
+++ b/tests/ui/structs-enums/class-str-field.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 struct cat {
 
diff --git a/tests/ui/structs-enums/class-typarams.rs b/tests/ui/structs-enums/class-typarams.rs
index 01cfa47024f..b5a3923983f 100644
--- a/tests/ui/structs-enums/class-typarams.rs
+++ b/tests/ui/structs-enums/class-typarams.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 use std::marker::PhantomData;
 
diff --git a/tests/ui/structs-enums/classes-self-referential.rs b/tests/ui/structs-enums/classes-self-referential.rs
index 35696a9cff9..f819e558aa2 100644
--- a/tests/ui/structs-enums/classes-self-referential.rs
+++ b/tests/ui/structs-enums/classes-self-referential.rs
@@ -3,7 +3,6 @@
 #![allow(non_camel_case_types)]
 
 
-//@ pretty-expanded FIXME #23616
 
 struct kitten {
     cat: Option<cat>,
diff --git a/tests/ui/structs-enums/enum-discrim-range-overflow.rs b/tests/ui/structs-enums/enum-discrim-range-overflow.rs
index 51cabd10e30..91be8014ebd 100644
--- a/tests/ui/structs-enums/enum-discrim-range-overflow.rs
+++ b/tests/ui/structs-enums/enum-discrim-range-overflow.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(overflowing_literals)]
 
-//@ pretty-expanded FIXME #23616
 
 pub enum E64 {
     H64 = 0x7FFF_FFFF_FFFF_FFFF,
diff --git a/tests/ui/structs-enums/enum-export-inheritance.rs b/tests/ui/structs-enums/enum-export-inheritance.rs
index 5bb689260c2..1fd697830db 100644
--- a/tests/ui/structs-enums/enum-export-inheritance.rs
+++ b/tests/ui/structs-enums/enum-export-inheritance.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 mod a {
     pub enum Foo {
diff --git a/tests/ui/structs-enums/enum-variants.rs b/tests/ui/structs-enums/enum-variants.rs
index 1f5206b8de5..d9639b32941 100644
--- a/tests/ui/structs-enums/enum-variants.rs
+++ b/tests/ui/structs-enums/enum-variants.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_assignments)]
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_variables)]
 
diff --git a/tests/ui/structs-enums/enum-vec-initializer.rs b/tests/ui/structs-enums/enum-vec-initializer.rs
index 2fa77ec6ecd..8c610456c22 100644
--- a/tests/ui/structs-enums/enum-vec-initializer.rs
+++ b/tests/ui/structs-enums/enum-vec-initializer.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 enum Flopsy {
     Bunny = 2
diff --git a/tests/ui/structs-enums/export-abstract-tag.rs b/tests/ui/structs-enums/export-abstract-tag.rs
index ff36fa95903..e6d35980385 100644
--- a/tests/ui/structs-enums/export-abstract-tag.rs
+++ b/tests/ui/structs-enums/export-abstract-tag.rs
@@ -4,7 +4,6 @@
 // We can export tags without exporting the variants to create a simple
 // sort of ADT.
 
-//@ pretty-expanded FIXME #23616
 
 mod foo {
     pub enum t { t1, }
diff --git a/tests/ui/structs-enums/export-tag-variant.rs b/tests/ui/structs-enums/export-tag-variant.rs
index bd762a0166e..c6216d1b567 100644
--- a/tests/ui/structs-enums/export-tag-variant.rs
+++ b/tests/ui/structs-enums/export-tag-variant.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(non_camel_case_types)]
-//@ pretty-expanded FIXME #23616
 
 mod foo {
     pub enum t { t1, }
diff --git a/tests/ui/structs-enums/foreign-struct.rs b/tests/ui/structs-enums/foreign-struct.rs
index 4f2e413ab40..f339c191ae8 100644
--- a/tests/ui/structs-enums/foreign-struct.rs
+++ b/tests/ui/structs-enums/foreign-struct.rs
@@ -4,7 +4,6 @@
 
 // Passing enums by value
 
-//@ pretty-expanded FIXME #23616
 
 pub enum void {}
 
diff --git a/tests/ui/structs-enums/module-qualified-struct-destructure.rs b/tests/ui/structs-enums/module-qualified-struct-destructure.rs
index b90acb1b98c..9d06980fca9 100644
--- a/tests/ui/structs-enums/module-qualified-struct-destructure.rs
+++ b/tests/ui/structs-enums/module-qualified-struct-destructure.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 mod m {
     pub struct S {
diff --git a/tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs b/tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs
index ea56faef09c..fca89728f21 100644
--- a/tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs
+++ b/tests/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs
@@ -3,7 +3,6 @@
 
 //@ aux-build:namespaced_enum_emulate_flat.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate namespaced_enum_emulate_flat;
 
diff --git a/tests/ui/structs-enums/namespaced-enum-emulate-flat.rs b/tests/ui/structs-enums/namespaced-enum-emulate-flat.rs
index 4a6352b328a..774cfa1a380 100644
--- a/tests/ui/structs-enums/namespaced-enum-emulate-flat.rs
+++ b/tests/ui/structs-enums/namespaced-enum-emulate-flat.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub use Foo::*;
 use nest::{Bar, D, E, F};
diff --git a/tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs b/tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs
index 4e58c1f717f..80d5231fc85 100644
--- a/tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs
+++ b/tests/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:namespaced_enums.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate namespaced_enums;
 
diff --git a/tests/ui/structs-enums/namespaced-enum-glob-import.rs b/tests/ui/structs-enums/namespaced-enum-glob-import.rs
index d02ee5a122d..e8a709d5bd0 100644
--- a/tests/ui/structs-enums/namespaced-enum-glob-import.rs
+++ b/tests/ui/structs-enums/namespaced-enum-glob-import.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 mod m2 {
     pub enum Foo {
diff --git a/tests/ui/structs-enums/namespaced-enums-xcrate.rs b/tests/ui/structs-enums/namespaced-enums-xcrate.rs
index b5655e68a47..36bc973749c 100644
--- a/tests/ui/structs-enums/namespaced-enums-xcrate.rs
+++ b/tests/ui/structs-enums/namespaced-enums-xcrate.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:namespaced_enums.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate namespaced_enums;
 
diff --git a/tests/ui/structs-enums/namespaced-enums.rs b/tests/ui/structs-enums/namespaced-enums.rs
index 1ce9319b8ec..3e2e0b5ffa8 100644
--- a/tests/ui/structs-enums/namespaced-enums.rs
+++ b/tests/ui/structs-enums/namespaced-enums.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 enum Foo {
     A,
diff --git a/tests/ui/structs-enums/nested-enum-same-names.rs b/tests/ui/structs-enums/nested-enum-same-names.rs
index e24073c38e9..5ff730aff44 100644
--- a/tests/ui/structs-enums/nested-enum-same-names.rs
+++ b/tests/ui/structs-enums/nested-enum-same-names.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 /*
 
diff --git a/tests/ui/structs-enums/newtype-struct-with-dtor.rs b/tests/ui/structs-enums/newtype-struct-with-dtor.rs
index 19672e41c9a..35476c5ed2d 100644
--- a/tests/ui/structs-enums/newtype-struct-with-dtor.rs
+++ b/tests/ui/structs-enums/newtype-struct-with-dtor.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_unsafe)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 pub struct Fd(u32);
 
diff --git a/tests/ui/structs-enums/newtype-struct-xc-2.rs b/tests/ui/structs-enums/newtype-struct-xc-2.rs
index e83025346d7..a52c41dde27 100644
--- a/tests/ui/structs-enums/newtype-struct-xc-2.rs
+++ b/tests/ui/structs-enums/newtype-struct-xc-2.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:newtype_struct_xc.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate newtype_struct_xc;
 use newtype_struct_xc::Au;
diff --git a/tests/ui/structs-enums/newtype-struct-xc.rs b/tests/ui/structs-enums/newtype-struct-xc.rs
index 6f90cfe8e4a..138bf4878f0 100644
--- a/tests/ui/structs-enums/newtype-struct-xc.rs
+++ b/tests/ui/structs-enums/newtype-struct-xc.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //@ aux-build:newtype_struct_xc.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate newtype_struct_xc;
 
diff --git a/tests/ui/structs-enums/simple-generic-tag.rs b/tests/ui/structs-enums/simple-generic-tag.rs
index 59521a446f4..b78505edd1f 100644
--- a/tests/ui/structs-enums/simple-generic-tag.rs
+++ b/tests/ui/structs-enums/simple-generic-tag.rs
@@ -4,7 +4,6 @@
 
 
 
-//@ pretty-expanded FIXME #23616
 
 enum clam<T> { a(T), }
 
diff --git a/tests/ui/structs-enums/struct-like-variant-construct.rs b/tests/ui/structs-enums/struct-like-variant-construct.rs
index 5a49d715b21..ec60fef9d3f 100644
--- a/tests/ui/structs-enums/struct-like-variant-construct.rs
+++ b/tests/ui/structs-enums/struct-like-variant-construct.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 enum Foo {
     Bar {
diff --git a/tests/ui/structs-enums/struct-variant-field-visibility.rs b/tests/ui/structs-enums/struct-variant-field-visibility.rs
index 02d1ceb0513..a6528f9a2b1 100644
--- a/tests/ui/structs-enums/struct-variant-field-visibility.rs
+++ b/tests/ui/structs-enums/struct-variant-field-visibility.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 mod foo {
     pub enum Foo {
diff --git a/tests/ui/structs-enums/struct_variant_xc.rs b/tests/ui/structs-enums/struct_variant_xc.rs
index 4723f229185..bf69a2aead9 100644
--- a/tests/ui/structs-enums/struct_variant_xc.rs
+++ b/tests/ui/structs-enums/struct_variant_xc.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 //@ aux-build:struct_variant_xc_aux.rs
-//@ pretty-expanded FIXME #23616
 
 extern crate struct_variant_xc_aux;
 
diff --git a/tests/ui/structs-enums/tag-exports.rs b/tests/ui/structs-enums/tag-exports.rs
index a01b951e675..bac428e6723 100644
--- a/tests/ui/structs-enums/tag-exports.rs
+++ b/tests/ui/structs-enums/tag-exports.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 use alder::*;
 
diff --git a/tests/ui/structs-enums/tag-in-block.rs b/tests/ui/structs-enums/tag-in-block.rs
index 944a611c71a..27b48aae51f 100644
--- a/tests/ui/structs-enums/tag-in-block.rs
+++ b/tests/ui/structs-enums/tag-in-block.rs
@@ -4,7 +4,6 @@
 
 
 
-//@ pretty-expanded FIXME #23616
 
 fn foo() {
     fn zed(_z: bar) { }
diff --git a/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs b/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs
index 9205ac81650..f4c202d91a7 100644
--- a/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs
+++ b/tests/ui/structs-enums/tag-variant-disr-type-mismatch.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 enum color {
     red = 1,
diff --git a/tests/ui/structs-enums/tuple-struct-trivial.rs b/tests/ui/structs-enums/tuple-struct-trivial.rs
index 329f80a462e..e2395036551 100644
--- a/tests/ui/structs-enums/tuple-struct-trivial.rs
+++ b/tests/ui/structs-enums/tuple-struct-trivial.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 struct Foo(isize, isize, isize);
 
diff --git a/tests/ui/structs-enums/variant-structs-trivial.rs b/tests/ui/structs-enums/variant-structs-trivial.rs
index 8ca86fa35ee..a7b05751184 100644
--- a/tests/ui/structs-enums/variant-structs-trivial.rs
+++ b/tests/ui/structs-enums/variant-structs-trivial.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 enum Foo {
     Bar { x: isize },
diff --git a/tests/ui/structs/large-records.rs b/tests/ui/structs/large-records.rs
index c78b6259667..d02a9f488c6 100644
--- a/tests/ui/structs/large-records.rs
+++ b/tests/ui/structs/large-records.rs
@@ -5,7 +5,6 @@
 
 
 
-//@ pretty-expanded FIXME #23616
 
 struct Large {a: isize,
              b: isize,
diff --git a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
index a275d8e4e83..4f92d3aceef 100644
--- a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
+++ b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
@@ -8,7 +8,7 @@ LL |     const A: i32 = 2;
    |     ------------ missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: introduce a variable instead
    |
diff --git a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
index ed262fd39a5..c2387bf5411 100644
--- a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
+++ b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
@@ -5,8 +5,7 @@ pub trait T<X, Y> {
 }
 pub struct Foo {
     i: Box<dyn T<usize, usize, usize, usize, B=usize>>,
-    //~^ ERROR must be specified
-    //~| ERROR trait takes 2 generic arguments but 4 generic arguments were supplied
+    //~^ ERROR trait takes 2 generic arguments but 4 generic arguments were supplied
 }
 
 
diff --git a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
index 7c84dd4b8ff..18cf0674f02 100644
--- a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
+++ b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
@@ -14,19 +14,6 @@ help: replace the generic bounds with the associated types
 LL |     i: Box<dyn T<usize, usize, A = usize, C = usize, B=usize>>,
    |                                +++        +++
 
-error[E0191]: the value of the associated types `C` and `A` in `T` must be specified
-  --> $DIR/use-type-argument-instead-of-assoc-type.rs:7:16
-   |
-LL |     type A;
-   |     ------ `A` defined here
-LL |     type B;
-LL |     type C;
-   |     ------ `C` defined here
-...
-LL |     i: Box<dyn T<usize, usize, usize, usize, B=usize>>,
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated types `A`, `C` must be specified
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0107, E0191.
-For more information about an error, try `rustc --explain E0107`.
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/super.rs b/tests/ui/super.rs
index 5d2ea92e921..69aff4f98e0 100644
--- a/tests/ui/super.rs
+++ b/tests/ui/super.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub mod a {
     pub fn f() {}
diff --git a/tests/ui/svh-add-nothing.rs b/tests/ui/svh-add-nothing.rs
index 75ef82d0fa3..6e4b9fa7f4c 100644
--- a/tests/ui/svh-add-nothing.rs
+++ b/tests/ui/svh-add-nothing.rs
@@ -4,7 +4,6 @@
 //@ aux-build:svh-b.rs
 //@ aux-build:svh-a-base.rs
 
-//@ pretty-expanded FIXME #23616
 
 extern crate a;
 extern crate b;
diff --git a/tests/ui/swap-overlapping.rs b/tests/ui/swap-overlapping.rs
index f7720e0470d..38d5a8109d1 100644
--- a/tests/ui/swap-overlapping.rs
+++ b/tests/ui/swap-overlapping.rs
@@ -3,7 +3,6 @@
 #![allow(dead_code)]
 // Issue #5041 - avoid overlapping memcpy when src and dest of a swap are the same
 
-//@ pretty-expanded FIXME #23616
 
 use std::ptr;
 
diff --git a/tests/ui/tail-call-arg-leak.rs b/tests/ui/tail-call-arg-leak.rs
index 003fb212fcb..234924307c3 100644
--- a/tests/ui/tail-call-arg-leak.rs
+++ b/tests/ui/tail-call-arg-leak.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 // use of tail calls causes arg slot leaks, issue #160.
-//@ pretty-expanded FIXME #23616
 
 fn inner(dummy: String, b: bool) { if b { return inner(dummy, false); } }
 
diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout
index a9d6985928a..d56f15fb221 100644
--- a/tests/ui/thir-print/thir-tree-match.stdout
+++ b/tests/ui/thir-print/thir-tree-match.stdout
@@ -92,7 +92,7 @@ body:
                                                                                         adt_def: 
                                                                                             AdtDef {
                                                                                                 did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo)
-                                                                                                variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags:  }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags:  }]
+                                                                                                variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe }], tainted: None, flags:  }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags:  }]
                                                                                                 flags: IS_ENUM
                                                                                                 repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 }
                                                                                         args: []
@@ -154,7 +154,7 @@ body:
                                                                                         adt_def: 
                                                                                             AdtDef {
                                                                                                 did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo)
-                                                                                                variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags:  }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags:  }]
+                                                                                                variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe }], tainted: None, flags:  }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags:  }]
                                                                                                 flags: IS_ENUM
                                                                                                 repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 }
                                                                                         args: []
@@ -206,7 +206,7 @@ body:
                                                                                         adt_def: 
                                                                                             AdtDef {
                                                                                                 did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo)
-                                                                                                variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags:  }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags:  }]
+                                                                                                variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe }], tainted: None, flags:  }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags:  }]
                                                                                                 flags: IS_ENUM
                                                                                                 repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 }
                                                                                         args: []
diff --git a/tests/ui/threads-sendsync/child-outlives-parent.rs b/tests/ui/threads-sendsync/child-outlives-parent.rs
index e965bac5713..fd6e0c4630d 100644
--- a/tests/ui/threads-sendsync/child-outlives-parent.rs
+++ b/tests/ui/threads-sendsync/child-outlives-parent.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Reported as issue #126, child leaks the string.
 
-//@ pretty-expanded FIXME #23616
 //@ needs-threads
 
 use std::thread;
diff --git a/tests/ui/threads-sendsync/send-resource.rs b/tests/ui/threads-sendsync/send-resource.rs
index c02a3717d3d..e4c08dd598f 100644
--- a/tests/ui/threads-sendsync/send-resource.rs
+++ b/tests/ui/threads-sendsync/send-resource.rs
@@ -3,7 +3,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 //@ needs-threads
 
 use std::sync::mpsc::channel;
diff --git a/tests/ui/threads-sendsync/send-type-inference.rs b/tests/ui/threads-sendsync/send-type-inference.rs
index 7608c19b575..c6150026c0a 100644
--- a/tests/ui/threads-sendsync/send-type-inference.rs
+++ b/tests/ui/threads-sendsync/send-type-inference.rs
@@ -2,7 +2,6 @@
 #![allow(unused_must_use)]
 #![allow(dead_code)]
 #![allow(unused_mut)]
-//@ pretty-expanded FIXME #23616
 
 use std::sync::mpsc::{channel, Sender};
 
diff --git a/tests/ui/threads-sendsync/sendable-class.rs b/tests/ui/threads-sendsync/sendable-class.rs
index 8e5e76d826a..da61ea6be2c 100644
--- a/tests/ui/threads-sendsync/sendable-class.rs
+++ b/tests/ui/threads-sendsync/sendable-class.rs
@@ -6,7 +6,6 @@
 
 // Test that a class with only sendable fields can be sent
 
-//@ pretty-expanded FIXME #23616
 
 use std::sync::mpsc::channel;
 
diff --git a/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs b/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs
index a443785a678..b2d22631c1a 100644
--- a/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs
+++ b/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::sync;
 
diff --git a/tests/ui/threads-sendsync/sync-send-atomics.rs b/tests/ui/threads-sendsync/sync-send-atomics.rs
index f64506af0a3..fc7f3971e76 100644
--- a/tests/ui/threads-sendsync/sync-send-atomics.rs
+++ b/tests/ui/threads-sendsync/sync-send-atomics.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 
-//@ pretty-expanded FIXME #23616
 
 use std::sync::atomic::*;
 
diff --git a/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs b/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs
index 512c81a85fc..4baf123295e 100644
--- a/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs
+++ b/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(warnings)]
 
diff --git a/tests/ui/threads-sendsync/task-comm-11.rs b/tests/ui/threads-sendsync/task-comm-11.rs
index 7c349c716fa..1585ec3b4f6 100644
--- a/tests/ui/threads-sendsync/task-comm-11.rs
+++ b/tests/ui/threads-sendsync/task-comm-11.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ pretty-expanded FIXME #23616
 //@ needs-threads
 
 use std::sync::mpsc::{channel, Sender};
diff --git a/tests/ui/threads-sendsync/task-comm-15.rs b/tests/ui/threads-sendsync/task-comm-15.rs
index 1308446893b..54e7b08b6a6 100644
--- a/tests/ui/threads-sendsync/task-comm-15.rs
+++ b/tests/ui/threads-sendsync/task-comm-15.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
 //@ needs-threads
-//@ pretty-expanded FIXME #23616
 
 use std::sync::mpsc::{channel, Sender};
 use std::thread;
diff --git a/tests/ui/threads-sendsync/task-comm-17.rs b/tests/ui/threads-sendsync/task-comm-17.rs
index a545beee599..37208265266 100644
--- a/tests/ui/threads-sendsync/task-comm-17.rs
+++ b/tests/ui/threads-sendsync/task-comm-17.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
 //@ needs-threads
-//@ pretty-expanded FIXME #23616
 
 // Issue #922
 
diff --git a/tests/ui/threads-sendsync/task-life-0.rs b/tests/ui/threads-sendsync/task-life-0.rs
index f08a281e76c..c2440bc44bc 100644
--- a/tests/ui/threads-sendsync/task-life-0.rs
+++ b/tests/ui/threads-sendsync/task-life-0.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
 //@ needs-threads
-//@ pretty-expanded FIXME #23616
 
 use std::thread;
 
diff --git a/tests/ui/trailing-comma.rs b/tests/ui/trailing-comma.rs
index 95a8b366ad9..53b76fb6037 100644
--- a/tests/ui/trailing-comma.rs
+++ b/tests/ui/trailing-comma.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn f<T,>(_: T,) {}
 
diff --git a/tests/ui/traits/astconv-cycle-between-and-type.rs b/tests/ui/traits/astconv-cycle-between-and-type.rs
index 1d45028657e..cb2e172f02e 100644
--- a/tests/ui/traits/astconv-cycle-between-and-type.rs
+++ b/tests/ui/traits/astconv-cycle-between-and-type.rs
@@ -4,7 +4,6 @@
 // carries a predicate that references the trait (`u32 : Trait1`,
 // substituted).
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/traits/bad-sized.rs b/tests/ui/traits/bad-sized.rs
index a1521967978..7e4f37e4ae2 100644
--- a/tests/ui/traits/bad-sized.rs
+++ b/tests/ui/traits/bad-sized.rs
@@ -3,7 +3,4 @@ trait Trait {}
 pub fn main() {
     let x: Vec<dyn Trait + Sized> = Vec::new();
     //~^ ERROR only auto traits can be used as additional traits in a trait object
-    //~| ERROR the size for values of type
-    //~| ERROR the size for values of type
-    //~| ERROR the size for values of type
 }
diff --git a/tests/ui/traits/bad-sized.stderr b/tests/ui/traits/bad-sized.stderr
index 4c1835dfed0..0e82867ef03 100644
--- a/tests/ui/traits/bad-sized.stderr
+++ b/tests/ui/traits/bad-sized.stderr
@@ -9,37 +9,6 @@ LL |     let x: Vec<dyn Trait + Sized> = Vec::new();
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Trait + Sized {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
-error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
-  --> $DIR/bad-sized.rs:4:12
-   |
-LL |     let x: Vec<dyn Trait + Sized> = Vec::new();
-   |            ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `dyn Trait`
-note: required by an implicit `Sized` bound in `Vec`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-
-error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
-  --> $DIR/bad-sized.rs:4:37
-   |
-LL |     let x: Vec<dyn Trait + Sized> = Vec::new();
-   |                                     ^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `dyn Trait`
-note: required by a bound in `Vec::<T>::new`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-
-error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
-  --> $DIR/bad-sized.rs:4:37
-   |
-LL |     let x: Vec<dyn Trait + Sized> = Vec::new();
-   |                                     ^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `dyn Trait`
-note: required by an implicit `Sized` bound in `Vec`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-
-error: aborting due to 4 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0225, E0277.
-For more information about an error, try `rustc --explain E0225`.
+For more information about this error, try `rustc --explain E0225`.
diff --git a/tests/ui/traits/bound/basic.rs b/tests/ui/traits/bound/basic.rs
index 85157fdbf62..acd8056bee0 100644
--- a/tests/ui/traits/bound/basic.rs
+++ b/tests/ui/traits/bound/basic.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(unconditional_recursion)]
 
-//@ pretty-expanded FIXME #23616
 
 trait Foo {
 }
diff --git a/tests/ui/traits/bound/impl-comparison-duplicates.rs b/tests/ui/traits/bound/impl-comparison-duplicates.rs
index 68b64de3e96..14553ed27b7 100644
--- a/tests/ui/traits/bound/impl-comparison-duplicates.rs
+++ b/tests/ui/traits/bound/impl-comparison-duplicates.rs
@@ -3,7 +3,6 @@
 // trait exactly, as long as the implementation doesn't demand *more* bounds
 // than the trait.
 
-//@ pretty-expanded FIXME #23616
 
 trait A {
     fn foo<T: Eq + Ord>(&self);
diff --git a/tests/ui/traits/bound/multiple.rs b/tests/ui/traits/bound/multiple.rs
index 385fa8851c1..30f229b285a 100644
--- a/tests/ui/traits/bound/multiple.rs
+++ b/tests/ui/traits/bound/multiple.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn f<T:PartialEq + PartialOrd>(_: T) {
 }
diff --git a/tests/ui/traits/bound/on-structs-and-enums-rpass.rs b/tests/ui/traits/bound/on-structs-and-enums-rpass.rs
index 25e1b6b4bc3..8dd24301505 100644
--- a/tests/ui/traits/bound/on-structs-and-enums-rpass.rs
+++ b/tests/ui/traits/bound/on-structs-and-enums-rpass.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 trait U {}
 trait T<X: U> { fn get(self) -> X; }
diff --git a/tests/ui/traits/bound/recursion.rs b/tests/ui/traits/bound/recursion.rs
index 1d9832ac917..90cdfed0c99 100644
--- a/tests/ui/traits/bound/recursion.rs
+++ b/tests/ui/traits/bound/recursion.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait I { fn i(&self) -> Self; }
 
diff --git a/tests/ui/traits/bug-7295.rs b/tests/ui/traits/bug-7295.rs
index bd4e126c220..a1cbcf1601e 100644
--- a/tests/ui/traits/bug-7295.rs
+++ b/tests/ui/traits/bug-7295.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub trait Foo<T> {
     fn func1<U>(&self, t: U, w: T);
diff --git a/tests/ui/traits/cache-issue-18209.rs b/tests/ui/traits/cache-issue-18209.rs
index e0c309ed97d..6a027d6b3f3 100644
--- a/tests/ui/traits/cache-issue-18209.rs
+++ b/tests/ui/traits/cache-issue-18209.rs
@@ -4,7 +4,6 @@
 //
 // See issue #18209.
 
-//@ pretty-expanded FIXME #23616
 
 pub trait Foo {
     fn load_from() -> Box<Self>;
diff --git a/tests/ui/traits/composition-trivial.rs b/tests/ui/traits/composition-trivial.rs
index 26f7673e616..8a5a36f4cfd 100644
--- a/tests/ui/traits/composition-trivial.rs
+++ b/tests/ui/traits/composition-trivial.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Foo {
     fn foo(&self);
diff --git a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
index 9ae1ed18e35..1e48a0331cc 100644
--- a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
+++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
@@ -1,12 +1,3 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/call-const-trait-method-pass.rs:7:12
-   |
-LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
   --> $DIR/call-const-trait-method-pass.rs:15:12
    |
@@ -16,14 +7,6 @@ LL | impl const PartialEq for Int {
    = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
    = note: adding a non-const method body in the future would be a breaking change
 
-error[E0015]: cannot call non-const operator in constants
-  --> $DIR/call-const-trait-method-pass.rs:39:22
-   |
-LL | const ADD_INT: Int = Int(1i32) + Int(2i32);
-   |                      ^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
-
 error[E0015]: cannot call non-const fn `<Int as PartialEq>::eq` in constant functions
   --> $DIR/call-const-trait-method-pass.rs:20:15
    |
@@ -32,6 +15,6 @@ LL |         !self.eq(other)
    |
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-and-non-const-impl.stderr b/tests/ui/traits/const-traits/const-and-non-const-impl.stderr
index cf7af41cd4e..4eb15177347 100644
--- a/tests/ui/traits/const-traits/const-and-non-const-impl.stderr
+++ b/tests/ui/traits/const-traits/const-and-non-const-impl.stderr
@@ -1,21 +1,3 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/const-and-non-const-impl.rs:7:12
-   |
-LL | impl const std::ops::Add for i32 {
-   |            ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/const-and-non-const-impl.rs:23:12
-   |
-LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error[E0119]: conflicting implementations of trait `Add` for type `Int`
   --> $DIR/const-and-non-const-impl.rs:23:1
    |
@@ -38,7 +20,7 @@ LL | impl const std::ops::Add for i32 {
    = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
    = note: define and implement a trait or new type instead
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0117, E0119.
 For more information about an error, try `rustc --explain E0117`.
diff --git a/tests/ui/traits/const-traits/const-drop-bound.rs b/tests/ui/traits/const-traits/const-drop-bound.rs
index b0790f86ef5..398fb390640 100644
--- a/tests/ui/traits/const-traits/const-drop-bound.rs
+++ b/tests/ui/traits/const-traits/const-drop-bound.rs
@@ -2,7 +2,7 @@
 // FIXME check-pass
 
 #![feature(const_trait_impl)]
-#![feature(const_precise_live_drops)]
+#![feature(const_precise_live_drops, const_destruct)]
 
 use std::marker::Destruct;
 
diff --git a/tests/ui/traits/const-traits/const-drop-bound.stderr b/tests/ui/traits/const-traits/const-drop-bound.stderr
index 3f718645433..60718cc84c1 100644
--- a/tests/ui/traits/const-traits/const-drop-bound.stderr
+++ b/tests/ui/traits/const-traits/const-drop-bound.stderr
@@ -1,51 +1,9 @@
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-bound.rs:9:61
+error[E0277]: the trait bound `Foo<E>: ~const Destruct` is not satisfied
+  --> $DIR/const-drop-bound.rs:23:5
    |
-LL | const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Destruct {
-   |                                                             ^^^^^^
+LL |     foo(res)
+   |     ^^^^^^^^
 
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-bound.rs:9:61
-   |
-LL | const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Destruct {
-   |                                                             ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-bound.rs:20:8
-   |
-LL |     T: ~const Destruct,
-   |        ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-bound.rs:21:8
-   |
-LL |     E: ~const Destruct,
-   |        ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-bound.rs:20:8
-   |
-LL |     T: ~const Destruct,
-   |        ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-bound.rs:21:8
-   |
-LL |     E: ~const Destruct,
-   |        ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0493]: destructor of `E` cannot be evaluated at compile-time
-  --> $DIR/const-drop-bound.rs:12:13
-   |
-LL |         Err(_e) => None,
-   |             ^^ the destructor for this type cannot be evaluated in constant functions
-
-error: aborting due to 7 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0493`.
+For more information about this error, try `rustc --explain E0277`.
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 7529af9293d..bb9966c7ec3 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
@@ -1,26 +1,13 @@
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop-fail-2.rs:23:25
+error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: const Destruct` is not satisfied
+  --> $DIR/const-drop-fail-2.rs:31:15
    |
-LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
-   |                         ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-fail-2.rs:29:26
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                          ^^^^^^^^
-
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop-fail-2.rs:39:25
-   |
-LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
-   |                         ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL |   const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>(
+   |  _______________^
+LL | |
+LL | |     ConstDropImplWithBounds(PhantomData)
+LL | | );
+   | |_^
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.rs b/tests/ui/traits/const-traits/const-drop-fail-2.rs
index 5d7bafa3887..1bcc87e9070 100644
--- a/tests/ui/traits/const-traits/const-drop-fail-2.rs
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.rs
@@ -1,6 +1,7 @@
-//@ known-bug: #110395
-#![feature(const_trait_impl)]
-// #![cfg_attr(precise, feature(const_precise_live_drops))]
+//@ revisions: stock precise
+
+#![feature(const_trait_impl, const_destruct)]
+#![cfg_attr(precise, feature(const_precise_live_drops))]
 
 use std::marker::{Destruct, PhantomData};
 
@@ -19,9 +20,7 @@ impl A for NonTrivialDrop {}
 
 const fn check<T: ~const Destruct>(_: T) {}
 
-
-/* FIXME(const_trait_impl)
-struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
+struct ConstDropImplWithBounds<T: A>(PhantomData<T>);
 
 impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
     fn drop(&mut self) {
@@ -30,9 +29,9 @@ impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
 }
 
 const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>(
+    //~^ ERROR the trait bound
     ConstDropImplWithBounds(PhantomData)
 );
-*/
 
 struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stderr
deleted file mode 100644
index fde106599c2..00000000000
--- a/tests/ui/traits/const-traits/const-drop-fail-2.stderr
+++ /dev/null
@@ -1,41 +0,0 @@
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop-fail-2.rs:39:25
-   |
-LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
-   |                         ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-fail-2.rs:20:19
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-fail-2.rs:20:19
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0277]: the trait bound `T: ~const A` is not satisfied
-  --> $DIR/const-drop-fail-2.rs:41:9
-   |
-LL |         T::a();
-   |         ^^^^^^
-
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/const-drop-fail-2.rs:20:36
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                                    ^      - value is dropped here
-   |                                    |
-   |                                    the destructor for this type cannot be evaluated in constant functions
-
-error: aborting due to 5 previous errors
-
-Some errors have detailed explanations: E0277, E0493.
-For more information about an error, try `rustc --explain E0277`.
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 7529af9293d..bb9966c7ec3 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
@@ -1,26 +1,13 @@
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop-fail-2.rs:23:25
+error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: const Destruct` is not satisfied
+  --> $DIR/const-drop-fail-2.rs:31:15
    |
-LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
-   |                         ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-fail-2.rs:29:26
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                          ^^^^^^^^
-
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop-fail-2.rs:39:25
-   |
-LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
-   |                         ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL |   const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>(
+   |  _______________^
+LL | |
+LL | |     ConstDropImplWithBounds(PhantomData)
+LL | | );
+   | |_^
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr
index 859fdfae81a..67e774fbd05 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr
@@ -1,45 +1,4 @@
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop-fail.rs:19:12
-   |
-LL | impl const Drop for ConstImplWithDropGlue {
-   |            ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-fail.rs:23:19
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-fail.rs:23:19
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/const-drop-fail.rs:23:36
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                                    ^ the destructor for this type cannot be evaluated in constant functions
-
-error[E0080]: evaluation of constant value failed
-  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |
-   = note: calling non-const function `<NonTrivialDrop as Drop>::drop`
-   |
-note: inside `std::ptr::drop_in_place::<NonTrivialDrop> - shim(Some(NonTrivialDrop))`
-  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-note: inside `check::<NonTrivialDrop>`
-  --> $DIR/const-drop-fail.rs:23:43
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                                           ^
-note: inside `_`
+error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
   --> $DIR/const-drop-fail.rs:27:23
    |
 LL |           const _: () = check($exp);
@@ -50,23 +9,10 @@ LL | |     NonTrivialDrop,
 LL | |     ConstImplWithDropGlue(NonTrivialDrop),
 LL | | }
    | |_- in this macro invocation
+   |
    = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0080]: evaluation of constant value failed
-  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |
-   = note: calling non-const function `<NonTrivialDrop as Drop>::drop`
-   |
-note: inside `std::ptr::drop_in_place::<NonTrivialDrop> - shim(Some(NonTrivialDrop))`
-  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-note: inside `std::ptr::drop_in_place::<ConstImplWithDropGlue> - shim(Some(ConstImplWithDropGlue))`
-  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-note: inside `check::<ConstImplWithDropGlue>`
-  --> $DIR/const-drop-fail.rs:23:43
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                                           ^
-note: inside `_`
+error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
   --> $DIR/const-drop-fail.rs:27:23
    |
 LL |           const _: () = check($exp);
@@ -77,9 +23,10 @@ LL | |     NonTrivialDrop,
 LL | |     ConstImplWithDropGlue(NonTrivialDrop),
 LL | | }
    | |_- in this macro invocation
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
    = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0080, E0493.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-drop-fail.rs b/tests/ui/traits/const-traits/const-drop-fail.rs
index 5a98c32e838..08435266e1f 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.rs
+++ b/tests/ui/traits/const-traits/const-drop-fail.rs
@@ -1,7 +1,7 @@
-//@ known-bug: #110395
-
+//@ compile-flags: -Znext-solver
 //@ revisions: stock precise
-#![feature(const_trait_impl)]
+
+#![feature(const_trait_impl, const_destruct)]
 #![cfg_attr(precise, feature(const_precise_live_drops))]
 
 use std::marker::{Destruct, PhantomData};
@@ -25,6 +25,8 @@ const fn check<T: ~const Destruct>(_: T) {}
 macro_rules! check_all {
     ($($exp:expr),*$(,)?) => {$(
         const _: () = check($exp);
+        //~^ ERROR the trait bound `NonTrivialDrop: const Destruct` is not satisfied
+        //~| ERROR the trait bound `NonTrivialDrop: const Destruct` is not satisfied
     )*};
 }
 
diff --git a/tests/ui/traits/const-traits/const-drop-fail.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr
index 20dea28922b..67e774fbd05 100644
--- a/tests/ui/traits/const-traits/const-drop-fail.stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr
@@ -1,34 +1,32 @@
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop-fail.rs:19:12
+error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
+  --> $DIR/const-drop-fail.rs:27:23
    |
-LL | impl const Drop for ConstImplWithDropGlue {
-   |            ^^^^
+LL |           const _: () = check($exp);
+   |                         ^^^^^^^^^^^
+...
+LL | / check_all! {
+LL | |     NonTrivialDrop,
+LL | |     ConstImplWithDropGlue(NonTrivialDrop),
+LL | | }
+   | |_- in this macro invocation
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+   = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-fail.rs:23:19
+error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
+  --> $DIR/const-drop-fail.rs:27:23
    |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop-fail.rs:23:19
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                   ^^^^^^
+LL |           const _: () = check($exp);
+   |                         ^^^^^^^^^^^
+...
+LL | / check_all! {
+LL | |     NonTrivialDrop,
+LL | |     ConstImplWithDropGlue(NonTrivialDrop),
+LL | | }
+   | |_- in this macro invocation
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+   = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/const-drop-fail.rs:23:36
-   |
-LL | const fn check<T: ~const Destruct>(_: T) {}
-   |                                    ^      - value is dropped here
-   |                                    |
-   |                                    the destructor for this type cannot be evaluated in constant functions
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0493`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-drop.precise.stderr b/tests/ui/traits/const-traits/const-drop.precise.stderr
deleted file mode 100644
index ed90b234761..00000000000
--- a/tests/ui/traits/const-traits/const-drop.precise.stderr
+++ /dev/null
@@ -1,90 +0,0 @@
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop.rs:12:16
-   |
-LL | impl<'a> const Drop for S<'a> {
-   |                ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop.rs:46:16
-   |
-LL |     impl const Drop for ConstDrop {
-   |                ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop.rs:67:37
-   |
-LL |     impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
-   |                                     ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop.rs:75:30
-   |
-LL |     impl<T: SomeTrait> const Drop for ConstDropWithNonconstBound<T> {
-   |                              ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop.rs:18:15
-   |
-LL | const fn a<T: ~const Destruct>(_: T) {}
-   |               ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop.rs:18:15
-   |
-LL | const fn a<T: ~const Destruct>(_: T) {}
-   |               ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
-  --> $DIR/const-drop.rs:67:46
-   |
-LL |     impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
-   |                                              ^^^^^^^^^^^^^^^^^^^^^
-   |
-note: required by a bound in `t::ConstDropWithBound`
-  --> $DIR/const-drop.rs:65:38
-   |
-LL |     pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
-   |                                      ^^^^^ required by this bound in `ConstDropWithBound`
-
-error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
-  --> $DIR/const-drop.rs:68:22
-   |
-LL |         fn drop(&mut self) {
-   |                      ^^^^
-   |
-note: required by a bound in `t::ConstDropWithBound`
-  --> $DIR/const-drop.rs:65:38
-   |
-LL |     pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
-   |                                      ^^^^^ required by this bound in `ConstDropWithBound`
-
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/const-drop.rs:18:32
-   |
-LL | const fn a<T: ~const Destruct>(_: T) {}
-   |                                ^ the destructor for this type cannot be evaluated in constant functions
-
-error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied
-  --> $DIR/const-drop.rs:69:13
-   |
-LL |             T::foo();
-   |             ^^^^^^^^
-
-error: aborting due to 10 previous errors
-
-Some errors have detailed explanations: E0277, E0493.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-drop.rs b/tests/ui/traits/const-traits/const-drop.rs
index 5bd81fb3ab6..e2d87aeff47 100644
--- a/tests/ui/traits/const-traits/const-drop.rs
+++ b/tests/ui/traits/const-traits/const-drop.rs
@@ -1,7 +1,8 @@
-// FIXME run-pass
-//@ known-bug: #110395
+//@ run-pass
+//@ compile-flags: -Znext-solver
 //@ revisions: stock precise
-#![feature(const_trait_impl)]
+
+#![feature(const_trait_impl, const_destruct)]
 #![feature(never_type)]
 #![cfg_attr(precise, feature(const_precise_live_drops))]
 
@@ -64,7 +65,7 @@ mod t {
 
     pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
 
-    impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
+    impl<T: const SomeTrait> const Drop for ConstDropWithBound<T> {
         fn drop(&mut self) {
             T::foo();
         }
diff --git a/tests/ui/traits/const-traits/const-drop.stock.stderr b/tests/ui/traits/const-traits/const-drop.stock.stderr
deleted file mode 100644
index 2b46b048e90..00000000000
--- a/tests/ui/traits/const-traits/const-drop.stock.stderr
+++ /dev/null
@@ -1,92 +0,0 @@
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop.rs:12:16
-   |
-LL | impl<'a> const Drop for S<'a> {
-   |                ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop.rs:46:16
-   |
-LL |     impl const Drop for ConstDrop {
-   |                ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop.rs:67:37
-   |
-LL |     impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
-   |                                     ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
-  --> $DIR/const-drop.rs:75:30
-   |
-LL |     impl<T: SomeTrait> const Drop for ConstDropWithNonconstBound<T> {
-   |                              ^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop.rs:18:15
-   |
-LL | const fn a<T: ~const Destruct>(_: T) {}
-   |               ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-drop.rs:18:15
-   |
-LL | const fn a<T: ~const Destruct>(_: T) {}
-   |               ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
-  --> $DIR/const-drop.rs:67:46
-   |
-LL |     impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
-   |                                              ^^^^^^^^^^^^^^^^^^^^^
-   |
-note: required by a bound in `t::ConstDropWithBound`
-  --> $DIR/const-drop.rs:65:38
-   |
-LL |     pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
-   |                                      ^^^^^ required by this bound in `ConstDropWithBound`
-
-error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
-  --> $DIR/const-drop.rs:68:22
-   |
-LL |         fn drop(&mut self) {
-   |                      ^^^^
-   |
-note: required by a bound in `t::ConstDropWithBound`
-  --> $DIR/const-drop.rs:65:38
-   |
-LL |     pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
-   |                                      ^^^^^ required by this bound in `ConstDropWithBound`
-
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/const-drop.rs:18:32
-   |
-LL | const fn a<T: ~const Destruct>(_: T) {}
-   |                                ^      - value is dropped here
-   |                                |
-   |                                the destructor for this type cannot be evaluated in constant functions
-
-error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied
-  --> $DIR/const-drop.rs:69:13
-   |
-LL |             T::foo();
-   |             ^^^^^^^^
-
-error: aborting due to 10 previous errors
-
-Some errors have detailed explanations: E0277, E0493.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs b/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs
index 209a111c243..aaa61e21155 100644
--- a/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs
+++ b/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs
@@ -11,7 +11,8 @@
     rustc_attrs,
     fundamental,
     marker_trait_attr,
-    const_trait_impl
+    const_trait_impl,
+    const_destruct
 )]
 #![allow(internal_features, incomplete_features)]
 #![no_std]
@@ -444,12 +445,12 @@ impl<T: ?Sized> Deref for Ref<'_, T> {
 
 #[lang = "clone"]
 #[rustc_trivial_field_reads]
-// FIXME: #[const_trait]
+#[const_trait]
 pub trait Clone: Sized {
     fn clone(&self) -> Self;
     fn clone_from(&mut self, source: &Self)
     where
-    // FIXME: Self: ~const Destruct,
+        Self: ~const Destruct,
     {
         *self = source.clone()
     }
@@ -458,7 +459,7 @@ pub trait Clone: Sized {
 #[lang = "structural_peq"]
 pub trait StructuralPartialEq {}
 
-// FIXME: const fn drop<T: ~const Destruct>(_: T) {}
+pub const fn drop<T: ~const Destruct>(_: T) {}
 
 #[rustc_intrinsic_must_be_overridden]
 #[rustc_intrinsic]
diff --git a/tests/ui/traits/const-traits/effects/dont-prefer-param-env-for-infer-self-ty.rs b/tests/ui/traits/const-traits/effects/dont-prefer-param-env-for-infer-self-ty.rs
new file mode 100644
index 00000000000..08dcd7d80b3
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/dont-prefer-param-env-for-infer-self-ty.rs
@@ -0,0 +1,16 @@
+//@ check-pass
+
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait Foo {}
+
+impl<T> const Foo for (T,) where T: ~const Foo {}
+
+const fn needs_const_foo(_: impl ~const Foo + Copy) {}
+
+const fn test<T: ~const Foo + Copy>(t: T) {
+    needs_const_foo((t,));
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-fail.rs b/tests/ui/traits/const-traits/effects/minicore-drop-fail.rs
new file mode 100644
index 00000000000..274e5db21c4
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/minicore-drop-fail.rs
@@ -0,0 +1,37 @@
+//@ aux-build:minicore.rs
+//@ compile-flags: --crate-type=lib -Znext-solver
+
+#![feature(no_core, const_trait_impl, const_destruct)]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+struct Contains<T>(T);
+
+struct NotDropImpl;
+impl Drop for NotDropImpl {
+    fn drop(&mut self) {}
+}
+
+#[const_trait] trait Foo {}
+impl Foo for () {}
+
+struct Conditional<T: Foo>(T);
+impl<T> const Drop for Conditional<T> where T: ~const Foo {
+    fn drop(&mut self) {}
+}
+
+const fn test() {
+    let _ = NotDropImpl;
+    //~^ ERROR destructor of `NotDropImpl` cannot be evaluated at compile-time
+    let _ = Contains(NotDropImpl);
+    //~^ ERROR destructor of `Contains<NotDropImpl>` cannot be evaluated at compile-time
+    let _ = Conditional(());
+    //~^ ERROR destructor of `Conditional<()>` cannot be evaluated at compile-time
+}
+
+const fn drop_arbitrary<T>(_: T) {
+    //~^ ERROR destructor of `T` cannot be evaluated at compile-time
+}
diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-fail.stderr b/tests/ui/traits/const-traits/effects/minicore-drop-fail.stderr
new file mode 100644
index 00000000000..12d1877a18a
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/minicore-drop-fail.stderr
@@ -0,0 +1,36 @@
+error[E0493]: destructor of `NotDropImpl` cannot be evaluated at compile-time
+  --> $DIR/minicore-drop-fail.rs:27:13
+   |
+LL |     let _ = NotDropImpl;
+   |             ^^^^^^^^^^^- value is dropped here
+   |             |
+   |             the destructor for this type cannot be evaluated in constant functions
+
+error[E0493]: destructor of `Contains<NotDropImpl>` cannot be evaluated at compile-time
+  --> $DIR/minicore-drop-fail.rs:29:13
+   |
+LL |     let _ = Contains(NotDropImpl);
+   |             ^^^^^^^^^^^^^^^^^^^^^- value is dropped here
+   |             |
+   |             the destructor for this type cannot be evaluated in constant functions
+
+error[E0493]: destructor of `Conditional<()>` cannot be evaluated at compile-time
+  --> $DIR/minicore-drop-fail.rs:31:13
+   |
+LL |     let _ = Conditional(());
+   |             ^^^^^^^^^^^^^^^- value is dropped here
+   |             |
+   |             the destructor for this type cannot be evaluated in constant functions
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/minicore-drop-fail.rs:35:28
+   |
+LL | const fn drop_arbitrary<T>(_: T) {
+   |                            ^ the destructor for this type cannot be evaluated in constant functions
+LL |
+LL | }
+   | - value is dropped here
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.no.stderr b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.no.stderr
new file mode 100644
index 00000000000..218f3661e39
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.no.stderr
@@ -0,0 +1,15 @@
+error[E0493]: destructor of `ConstDrop` cannot be evaluated at compile-time
+  --> $DIR/minicore-drop-without-feature-gate.rs:24:13
+   |
+LL |     let _ = ConstDrop;
+   |             ^^^^^^^^^- value is dropped here
+   |             |
+   |             the destructor for this type cannot be evaluated in constant functions
+   |
+   = note: see issue #133214 <https://github.com/rust-lang/rust/issues/133214> for more information
+   = help: add `#![feature(const_destruct)]` 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 E0493`.
diff --git a/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.rs b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.rs
new file mode 100644
index 00000000000..e75bf3db007
--- /dev/null
+++ b/tests/ui/traits/const-traits/effects/minicore-drop-without-feature-gate.rs
@@ -0,0 +1,26 @@
+//@ aux-build:minicore.rs
+//@ compile-flags: --crate-type=lib -Znext-solver
+//@ revisions: yes no
+//@[yes] check-pass
+// gate-test-const_destruct
+
+#![feature(no_core, const_trait_impl)]
+#![cfg_attr(yes, feature(const_destruct))]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+struct ConstDrop;
+impl const Drop for ConstDrop {
+    fn drop(&mut self) {}
+}
+
+// Make sure that `ConstDrop` can only be dropped when the `const_drop`
+// feature gate is enabled. Otherwise, we should error if there is a drop
+// impl at all.
+const fn test() {
+    let _ = ConstDrop;
+    //[no]~^ ERROR destructor of `ConstDrop` cannot be evaluated at compile-time
+}
diff --git a/tests/ui/traits/const-traits/generic-bound.rs b/tests/ui/traits/const-traits/generic-bound.rs
index 620e3259917..5eb236acde2 100644
--- a/tests/ui/traits/const-traits/generic-bound.rs
+++ b/tests/ui/traits/const-traits/generic-bound.rs
@@ -1,4 +1,4 @@
-//@ known-bug: #110395
+//@ check-pass
 
 #![feature(const_trait_impl)]
 
@@ -26,5 +26,6 @@ const fn twice<T: std::ops::Add>(arg: S<T>) -> S<T> {
 }
 
 fn main() {
+    const _: S<i32> = twice(S(PhantomData));
     let _ = twice(S(PhantomData::<i32>));
 }
diff --git a/tests/ui/traits/const-traits/generic-bound.stderr b/tests/ui/traits/const-traits/generic-bound.stderr
deleted file mode 100644
index 0444c319577..00000000000
--- a/tests/ui/traits/const-traits/generic-bound.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/generic-bound.rs:16:15
-   |
-LL | impl<T> const std::ops::Add for S<T> {
-   |               ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error[E0015]: cannot call non-const operator in constant functions
-  --> $DIR/generic-bound.rs:25:5
-   |
-LL |     arg + arg
-   |     ^^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/issue-92111.rs b/tests/ui/traits/const-traits/issue-92111.rs
index 64fa32156c3..c8db5cc9e7a 100644
--- a/tests/ui/traits/const-traits/issue-92111.rs
+++ b/tests/ui/traits/const-traits/issue-92111.rs
@@ -1,9 +1,6 @@
-// Regression test for #92111.
-//
-//@ known-bug: #110395
-// FIXME check-pass
+//@ check-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, const_destruct)]
 
 use std::marker::Destruct;
 
diff --git a/tests/ui/traits/const-traits/issue-92111.stderr b/tests/ui/traits/const-traits/issue-92111.stderr
deleted file mode 100644
index 51c6a22b43b..00000000000
--- a/tests/ui/traits/const-traits/issue-92111.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/issue-92111.rs:20:15
-   |
-LL | const fn a<T: ~const Destruct>(t: T) {}
-   |               ^^^^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/issue-92111.rs:20:15
-   |
-LL | const fn a<T: ~const Destruct>(t: T) {}
-   |               ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/issue-92111.rs:20:32
-   |
-LL | const fn a<T: ~const Destruct>(t: T) {}
-   |                                ^      - value is dropped here
-   |                                |
-   |                                the destructor for this type cannot be evaluated in constant functions
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/cycle-generic-bound.rs b/tests/ui/traits/cycle-generic-bound.rs
index dec51ef35bc..0fb0f74a6ea 100644
--- a/tests/ui/traits/cycle-generic-bound.rs
+++ b/tests/ui/traits/cycle-generic-bound.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 // Regression test for #15477. This test just needs to compile.
 
-//@ pretty-expanded FIXME #23616
 
 trait Chromosome<X: Chromosome<i32>> {
 }
diff --git a/tests/ui/traits/cycle-type-trait.rs b/tests/ui/traits/cycle-type-trait.rs
index f1125c9274a..3a6cd2eccc2 100644
--- a/tests/ui/traits/cycle-type-trait.rs
+++ b/tests/ui/traits/cycle-type-trait.rs
@@ -3,7 +3,6 @@
 // Test a case where a supertrait references a type that references
 // the original trait. This poses no problem at the moment.
 
-//@ pretty-expanded FIXME #23616
 
 trait Chromosome: Get<Struct<i32>> {
 }
diff --git a/tests/ui/traits/default-method/mut.rs b/tests/ui/traits/default-method/mut.rs
index fd8b788035f..1130ca0b4be 100644
--- a/tests/ui/traits/default-method/mut.rs
+++ b/tests/ui/traits/default-method/mut.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(unused_assignments)]
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_variables)]
 
diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs
index a08407683d8..85c70a21f68 100644
--- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs
+++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs
@@ -1,5 +1,6 @@
 fn function<T: PartialEq>() {
     foo == 2; //~ ERROR cannot find value `foo` in this scope [E0425]
+    //~^ ERROR mismatched types
 }
 
 fn main() {}
diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr
index 2da731dcc4b..8010c0842ba 100644
--- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr
+++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr
@@ -4,6 +4,18 @@ error[E0425]: cannot find value `foo` in this scope
 LL |     foo == 2;
    |     ^^^ not found in this scope
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs:2:12
+   |
+LL | fn function<T: PartialEq>() {
+   |             - expected this type parameter
+LL |     foo == 2;
+   |            ^ expected type parameter `T`, found integer
+   |
+   = note: expected type parameter `T`
+                        found type `{integer}`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0425`.
+Some errors have detailed explanations: E0308, E0425.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/early-vtbl-resolution.rs b/tests/ui/traits/early-vtbl-resolution.rs
index f2dd2b8a660..bf3cc04cdc2 100644
--- a/tests/ui/traits/early-vtbl-resolution.rs
+++ b/tests/ui/traits/early-vtbl-resolution.rs
@@ -2,7 +2,6 @@
 
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 trait thing<A> {
     fn foo(&self) -> Option<A>;
diff --git a/tests/ui/traits/false-ambiguity-where-clause-builtin-bound.rs b/tests/ui/traits/false-ambiguity-where-clause-builtin-bound.rs
index b41d719d0ec..ab9d10d14fd 100644
--- a/tests/ui/traits/false-ambiguity-where-clause-builtin-bound.rs
+++ b/tests/ui/traits/false-ambiguity-where-clause-builtin-bound.rs
@@ -3,7 +3,6 @@
 // between the builtin rules for Sized and the where clause. Issue
 // #20959.
 
-//@ pretty-expanded FIXME #23616
 
 fn foo<K>(x: Option<K>)
     where Option<K> : Sized
diff --git a/tests/ui/traits/impl-2.rs b/tests/ui/traits/impl-2.rs
index 6cc702800e3..c6f60a9081c 100644
--- a/tests/ui/traits/impl-2.rs
+++ b/tests/ui/traits/impl-2.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_snake_case)]
 
-//@ pretty-expanded FIXME #23616
 
 pub mod Foo {
     pub trait Trait {
diff --git a/tests/ui/traits/impl-implicit-trait.rs b/tests/ui/traits/impl-implicit-trait.rs
index 03c1ec8a53b..ff62858dcc2 100644
--- a/tests/ui/traits/impl-implicit-trait.rs
+++ b/tests/ui/traits/impl-implicit-trait.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
-//@ pretty-expanded FIXME #23616
 
 enum option_<T> {
     none_,
diff --git a/tests/ui/traits/inheritance/num.rs b/tests/ui/traits/inheritance/num.rs
index 339ff04ff53..58564147a29 100644
--- a/tests/ui/traits/inheritance/num.rs
+++ b/tests/ui/traits/inheritance/num.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 pub trait NumExt: PartialEq + PartialOrd {}
 
diff --git a/tests/ui/traits/inheritance/num0.rs b/tests/ui/traits/inheritance/num0.rs
index a2ebc5c62d7..a170388b494 100644
--- a/tests/ui/traits/inheritance/num0.rs
+++ b/tests/ui/traits/inheritance/num0.rs
@@ -2,7 +2,6 @@
 #![allow(dead_code)]
 // Extending Num and using inherited static methods
 
-//@ pretty-expanded FIXME #23616
 
 pub trait NumCast: Sized {
     fn from(i: i32) -> Option<Self>;
diff --git a/tests/ui/traits/inheritance/num1.rs b/tests/ui/traits/inheritance/num1.rs
index 9fa2cde6d22..d02cff70842 100644
--- a/tests/ui/traits/inheritance/num1.rs
+++ b/tests/ui/traits/inheritance/num1.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub trait NumCast: Sized {
     fn from(i: i32) -> Option<Self>;
diff --git a/tests/ui/traits/inheritance/num5.rs b/tests/ui/traits/inheritance/num5.rs
index b38fb441cff..8ac4c86c392 100644
--- a/tests/ui/traits/inheritance/num5.rs
+++ b/tests/ui/traits/inheritance/num5.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub trait NumCast: Sized {
     fn from(i: i32) -> Option<Self>;
diff --git a/tests/ui/traits/issue-22019.rs b/tests/ui/traits/issue-22019.rs
index 120f611ccb6..191c345e2d1 100644
--- a/tests/ui/traits/issue-22019.rs
+++ b/tests/ui/traits/issue-22019.rs
@@ -3,7 +3,6 @@
 // distinct scopes to be compared (`'g` and `'h`). The only important
 // thing is that compilation succeeds here.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(missing_copy_implementations)]
 #![allow(unused_variables)]
diff --git a/tests/ui/traits/issue-22110.rs b/tests/ui/traits/issue-22110.rs
index b0b584bd49d..f16f5328ad3 100644
--- a/tests/ui/traits/issue-22110.rs
+++ b/tests/ui/traits/issue-22110.rs
@@ -3,7 +3,6 @@
 // and the blanket impl. The only important thing is that compilation
 // succeeds here. Issue #22110.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/traits/issue-22655.rs b/tests/ui/traits/issue-22655.rs
index aaf1b05b6e5..dfba8011a1e 100644
--- a/tests/ui/traits/issue-22655.rs
+++ b/tests/ui/traits/issue-22655.rs
@@ -3,7 +3,6 @@
 // Regression test for issue #22655: This test should not lead to
 // infinite recursion.
 
-//@ pretty-expanded FIXME #23616
 
 unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
 
diff --git a/tests/ui/traits/issue-23003.rs b/tests/ui/traits/issue-23003.rs
index cb05a5dfb6b..93c5bfe32ce 100644
--- a/tests/ui/traits/issue-23003.rs
+++ b/tests/ui/traits/issue-23003.rs
@@ -4,7 +4,6 @@
 // Async>::Cancel` be WF. This normalizes to `Receipt<Complete>`
 // again, leading to an infinite cycle. Issue #23003.
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 #![allow(unused_variables)]
diff --git a/tests/ui/traits/issue-32963.rs b/tests/ui/traits/issue-32963.rs
index 56a68f3a231..4c4cd91d72e 100644
--- a/tests/ui/traits/issue-32963.rs
+++ b/tests/ui/traits/issue-32963.rs
@@ -7,5 +7,4 @@ fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
 fn main() {
     size_of_copy::<dyn Misc + Copy>();
     //~^ ERROR only auto traits can be used as additional traits in a trait object
-    //~| ERROR the trait bound `dyn Misc: Copy` is not satisfied
 }
diff --git a/tests/ui/traits/issue-32963.stderr b/tests/ui/traits/issue-32963.stderr
index bad45e54d64..1c70d0aaa0a 100644
--- a/tests/ui/traits/issue-32963.stderr
+++ b/tests/ui/traits/issue-32963.stderr
@@ -9,19 +9,6 @@ LL |     size_of_copy::<dyn Misc + Copy>();
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Misc + Copy {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
-error[E0277]: the trait bound `dyn Misc: Copy` is not satisfied
-  --> $DIR/issue-32963.rs:8:20
-   |
-LL |     size_of_copy::<dyn Misc + Copy>();
-   |                    ^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `dyn Misc`
-   |
-note: required by a bound in `size_of_copy`
-  --> $DIR/issue-32963.rs:5:20
-   |
-LL | fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
-   |                    ^^^^ required by this bound in `size_of_copy`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0225, E0277.
-For more information about an error, try `rustc --explain E0225`.
+For more information about this error, try `rustc --explain E0225`.
diff --git a/tests/ui/traits/issue-78372.rs b/tests/ui/traits/issue-78372.rs
index 82b13cc0b62..f03baf2ceca 100644
--- a/tests/ui/traits/issue-78372.rs
+++ b/tests/ui/traits/issue-78372.rs
@@ -10,5 +10,4 @@ trait X<T> {
 }
 trait Marker {}
 impl Marker for dyn Foo {}
-//~^ ERROR cannot be made into an object
 fn main() {}
diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr
index 4cc2c59fd8d..86234d15a5d 100644
--- a/tests/ui/traits/issue-78372.stderr
+++ b/tests/ui/traits/issue-78372.stderr
@@ -55,24 +55,6 @@ LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
    = help: add `#![feature(dispatch_from_dyn)]` 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[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/issue-78372.rs:12:17
-   |
-LL |     fn foo(self: Smaht<Self, T>);
-   |                  -------------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
-...
-LL | impl Marker for dyn Foo {}
-   |                 ^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/issue-78372.rs:9:18
-   |
-LL | trait Foo: X<u32> {}
-   |       --- this trait cannot be made into an object...
-LL | trait X<T> {
-LL |     fn foo(self: Smaht<Self, T>);
-   |                  ^^^^^^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
-
 error[E0307]: invalid `self` parameter type: `Smaht<Self, T>`
   --> $DIR/issue-78372.rs:9:18
    |
@@ -88,7 +70,7 @@ error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion
 LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0038, E0307, E0378, E0412, E0658.
-For more information about an error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0307, E0378, E0412, E0658.
+For more information about an error, try `rustc --explain E0307`.
diff --git a/tests/ui/traits/monomorphized-callees-with-ty-params-3314.rs b/tests/ui/traits/monomorphized-callees-with-ty-params-3314.rs
index 35d6dddfa30..9d33ec8c172 100644
--- a/tests/ui/traits/monomorphized-callees-with-ty-params-3314.rs
+++ b/tests/ui/traits/monomorphized-callees-with-ty-params-3314.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 trait Serializer {
 }
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
index 1260cca5106..cbd591eec96 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
@@ -14,13 +14,7 @@ fn main() {
 
 fn weird0() -> impl Sized + !Sized {}
 //~^ ERROR the trait bound `(): !Sized` is not satisfied
-//~| ERROR the trait bound `(): !Sized` is not satisfied
-//~| ERROR the trait bound `(): !Sized` is not satisfied
 fn weird1() -> impl !Sized + Sized {}
 //~^ ERROR the trait bound `(): !Sized` is not satisfied
-//~| ERROR the trait bound `(): !Sized` is not satisfied
-//~| ERROR the trait bound `(): !Sized` is not satisfied
 fn weird2() -> impl !Sized {}
 //~^ ERROR the trait bound `(): !Sized` is not satisfied
-//~| ERROR the trait bound `(): !Sized` is not satisfied
-//~| ERROR the trait bound `(): !Sized` is not satisfied
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
index 4ec578a3b7b..3dad6d534fd 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
@@ -5,53 +5,17 @@ LL | fn weird0() -> impl Sized + !Sized {}
    |                ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the trait bound `(): !Sized` is not satisfied
-  --> $DIR/opaque-type-unsatisfied-bound.rs:15:36
-   |
-LL | fn weird0() -> impl Sized + !Sized {}
-   |                                    ^^ the trait bound `(): !Sized` is not satisfied
-
-error[E0277]: the trait bound `(): !Sized` is not satisfied
-  --> $DIR/opaque-type-unsatisfied-bound.rs:15:1
-   |
-LL | fn weird0() -> impl Sized + !Sized {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
-
-error[E0277]: the trait bound `(): !Sized` is not satisfied
-  --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
+  --> $DIR/opaque-type-unsatisfied-bound.rs:17:16
    |
 LL | fn weird1() -> impl !Sized + Sized {}
    |                ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the trait bound `(): !Sized` is not satisfied
-  --> $DIR/opaque-type-unsatisfied-bound.rs:19:36
-   |
-LL | fn weird1() -> impl !Sized + Sized {}
-   |                                    ^^ the trait bound `(): !Sized` is not satisfied
-
-error[E0277]: the trait bound `(): !Sized` is not satisfied
-  --> $DIR/opaque-type-unsatisfied-bound.rs:19:1
-   |
-LL | fn weird1() -> impl !Sized + Sized {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
-
-error[E0277]: the trait bound `(): !Sized` is not satisfied
-  --> $DIR/opaque-type-unsatisfied-bound.rs:23:16
+  --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
    |
 LL | fn weird2() -> impl !Sized {}
    |                ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the trait bound `(): !Sized` is not satisfied
-  --> $DIR/opaque-type-unsatisfied-bound.rs:23:28
-   |
-LL | fn weird2() -> impl !Sized {}
-   |                            ^^ the trait bound `(): !Sized` is not satisfied
-
-error[E0277]: the trait bound `(): !Sized` is not satisfied
-  --> $DIR/opaque-type-unsatisfied-bound.rs:23:1
-   |
-LL | fn weird2() -> impl !Sized {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
-
 error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:12:13
    |
@@ -66,6 +30,6 @@ note: required by a bound in `consume`
 LL | fn consume(_: impl Trait) {}
    |                    ^^^^^ required by this bound in `consume`
 
-error: aborting due to 10 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
index c6826578658..39422914afc 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
@@ -4,7 +4,5 @@
 
 fn produce() -> impl !Fn<(u32,)> {}
 //~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied
-//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
-//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
index f81f0a23ac3..760e5aa62f2 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
@@ -4,18 +4,6 @@ error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
 LL | fn produce() -> impl !Fn<(u32,)> {}
    |                 ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
 
-error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
-  --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
-   |
-LL | fn produce() -> impl !Fn<(u32,)> {}
-   |                                  ^^ the trait bound `(): !Fn(u32)` is not satisfied
-
-error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
-  --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1
-   |
-LL | fn produce() -> impl !Fn<(u32,)> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs
index 272e5db3b7a..0236826c3ed 100644
--- a/tests/ui/traits/next-solver/alias-bound-unsound.rs
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs
@@ -28,5 +28,6 @@ fn main() {
     //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
     //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
     //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
+    //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
     println!("{x}");
 }
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
index e5cf5b6bc3d..7e3737d120b 100644
--- a/tests/ui/traits/next-solver/alias-bound-unsound.stderr
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
@@ -24,6 +24,14 @@ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
 LL |     drop(<() as Foo>::copy_me(&x));
    |          ^^^^^^^^^^^^^^^^^^^^^^^^
 
+error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
+  --> $DIR/alias-bound-unsound.rs:24:10
+   |
+LL |     drop(<() as Foo>::copy_me(&x));
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed`
   --> $DIR/alias-bound-unsound.rs:24:31
    |
@@ -50,6 +58,6 @@ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
 LL |     drop(<() as Foo>::copy_me(&x));
    |                               ^^
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/destruct.rs b/tests/ui/traits/next-solver/destruct.rs
index f595cb30db8..fd14132124c 100644
--- a/tests/ui/traits/next-solver/destruct.rs
+++ b/tests/ui/traits/next-solver/destruct.rs
@@ -1,7 +1,7 @@
 //@ compile-flags: -Znext-solver
 //@ check-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, const_destruct)]
 
 fn foo(_: impl std::marker::Destruct) {}
 
diff --git a/tests/ui/traits/next-solver/normalization-shadowing/alias-bound-shadowed-by-env.rs b/tests/ui/traits/next-solver/normalization-shadowing/alias-bound-shadowed-by-env.rs
new file mode 100644
index 00000000000..c0b169abcd5
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalization-shadowing/alias-bound-shadowed-by-env.rs
@@ -0,0 +1,19 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+trait Super {
+    type Assoc;
+}
+trait Bound {
+    type Assoc: Super<Assoc = u32>;
+}
+trait Trait: Super {}
+
+// Elaborating the environment results in a `T::Assoc: Super` where-bound.
+// This where-bound must not prevent normalization via the `Super<Assoc = u32>`
+// item bound.
+fn heck<T: Bound<Assoc: Trait>>(x: <T::Assoc as Super>::Assoc) -> u32 {
+    x
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs b/tests/ui/traits/next-solver/normalization-shadowing/ambig-env-no-shadow.rs
index 362f911c144..362f911c144 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs
+++ b/tests/ui/traits/next-solver/normalization-shadowing/ambig-env-no-shadow.rs
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-1.rs b/tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-1.rs
index ce2d6304875..ce2d6304875 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-1.rs
+++ b/tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-1.rs
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-2.rs b/tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-2.rs
index 20329f467db..20329f467db 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-2.rs
+++ b/tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-2.rs
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-3.rs b/tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-3.rs
index da6f2908ab1..da6f2908ab1 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-3.rs
+++ b/tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-3.rs
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.rs b/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.rs
index e66d1c485f8..e66d1c485f8 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.rs
+++ b/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.rs
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.stderr b/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr
index 36d281e11dd..36d281e11dd 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.stderr
+++ b/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs b/tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.rs
index d11150ca55a..d11150ca55a 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs
+++ b/tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.rs
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr b/tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.stderr
index 0c72fc25dca..0c72fc25dca 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr
+++ b/tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.stderr
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-env-impl-conflict.rs b/tests/ui/traits/next-solver/normalization-shadowing/param-env-impl-conflict.rs
index 1b9e9866cd6..1b9e9866cd6 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/param-env-impl-conflict.rs
+++ b/tests/ui/traits/next-solver/normalization-shadowing/param-env-impl-conflict.rs
diff --git a/tests/ui/traits/next-solver/typeck/resolve-before-checking-builtin-ptr.rs b/tests/ui/traits/next-solver/typeck/resolve-before-checking-builtin-ptr.rs
new file mode 100644
index 00000000000..d47f705a8ab
--- /dev/null
+++ b/tests/ui/traits/next-solver/typeck/resolve-before-checking-builtin-ptr.rs
@@ -0,0 +1,20 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+
+trait Mirror {
+    type Assoc;
+}
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+struct Place {
+    field: <&'static [u8] as Mirror>::Assoc,
+}
+
+fn main() {
+    let local = Place { field: &[] };
+    let z = || {
+        let y = &local.field[0];
+    };
+}
diff --git a/tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs b/tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs
new file mode 100644
index 00000000000..6df1fd5d4ba
--- /dev/null
+++ b/tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs
@@ -0,0 +1,20 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+
+#![feature(never_type)]
+
+trait Mirror {
+    type Assoc;
+}
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+fn diverge() -> <! as Mirror>::Assoc { todo!() }
+
+fn main() {
+    let close = || {
+        diverge();
+    };
+    let x: u32 = close();
+}
diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs
index 3af299e5b11..4aadd45c49c 100644
--- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs
+++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs
@@ -10,6 +10,7 @@ fn w<'a, T: 'a, F: Fn(&'a T)>() {
     let b: &dyn FromResidual = &();
     //~^ ERROR: the trait `FromResidual` cannot be made into an object
     //~| ERROR: the trait `FromResidual` cannot be made into an object
+    //~| ERROR: the trait `FromResidual` cannot be made into an object
 }
 
 fn main() {}
diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
index 960802e2f8f..c67a8c05379 100644
--- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
+++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
@@ -7,6 +7,29 @@ LL |     let b: &dyn FromResidual = &();
    = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
 
 error[E0038]: the trait `FromResidual` cannot be made into an object
+  --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:32
+   |
+LL |     let b: &dyn FromResidual = &();
+   |                                ^^^ `FromResidual` cannot be made into an object
+   |
+note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:2:8
+   |
+LL | trait FromResidual<R = <Self as Try>::Residual> {
+   |       ------------ this trait cannot be made into an object...
+LL |     fn from_residual(residual: R) -> Self;
+   |        ^^^^^^^^^^^^^ ...because associated function `from_residual` has no `self` parameter
+   = note: required for the cast from `&()` to `&dyn FromResidual<{type error}>`
+help: consider turning `from_residual` into a method by giving it a `&self` argument
+   |
+LL |     fn from_residual(&self, residual: R) -> Self;
+   |                      ++++++
+help: alternatively, consider constraining `from_residual` so it does not apply to trait objects
+   |
+LL |     fn from_residual(residual: R) -> Self where Self: Sized;
+   |                                           +++++++++++++++++
+
+error[E0038]: the trait `FromResidual` cannot be made into an object
   --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:12
    |
 LL |     let b: &dyn FromResidual = &();
@@ -28,6 +51,6 @@ help: alternatively, consider constraining `from_residual` so it does not apply
 LL |     fn from_residual(residual: R) -> Self where Self: Sized;
    |                                           +++++++++++++++++
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/traits/parameterized-with-bounds.rs b/tests/ui/traits/parameterized-with-bounds.rs
index 2de9bf3d04c..54e2d6e096d 100644
--- a/tests/ui/traits/parameterized-with-bounds.rs
+++ b/tests/ui/traits/parameterized-with-bounds.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
 
diff --git a/tests/ui/traits/solver-cycles/100347-recursive-enum-cow-slice.rs b/tests/ui/traits/solver-cycles/100347-recursive-enum-cow-slice.rs
new file mode 100644
index 00000000000..26ae42b3e08
--- /dev/null
+++ b/tests/ui/traits/solver-cycles/100347-recursive-enum-cow-slice.rs
@@ -0,0 +1,11 @@
+//@ check-pass
+
+use std::borrow::Cow;
+
+#[derive(Clone)]
+enum Test<'a> {
+    Int(u8),
+    Array(Cow<'a, [Test<'a>]>),
+}
+
+fn main() {}
diff --git a/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs
new file mode 100644
index 00000000000..197207dfb4b
--- /dev/null
+++ b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.rs
@@ -0,0 +1,22 @@
+// Regression test for #129541
+//~^ ERROR cycle detected when computing layout of `<[Hello] as Normalize>::Assoc` [E0391]
+
+trait Bound {}
+trait Normalize {
+    type Assoc;
+}
+
+impl<T: Bound> Normalize for T {
+    type Assoc = T;
+}
+
+impl<T: Bound> Normalize for [T] {
+    type Assoc = T;
+}
+
+impl Bound for Hello {}
+enum Hello {
+    Variant(<[Hello] as Normalize>::Assoc),
+}
+
+fn main() {}
diff --git a/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.stderr b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.stderr
new file mode 100644
index 00000000000..50dcea0bfac
--- /dev/null
+++ b/tests/ui/traits/solver-cycles/129541-recursive-enum-and-array-impl.stderr
@@ -0,0 +1,10 @@
+error[E0391]: cycle detected when computing layout of `<[Hello] as Normalize>::Assoc`
+   |
+   = note: ...which requires computing layout of `Hello`...
+   = note: ...which again requires computing layout of `<[Hello] as Normalize>::Assoc`, completing the cycle
+   = note: cycle used when computing layout of `Hello`
+   = 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
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs
new file mode 100644
index 00000000000..defb39aae06
--- /dev/null
+++ b/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs
@@ -0,0 +1,23 @@
+// Regression test for #129541
+
+//@ check-pass
+
+trait Bound {}
+trait Normalize {
+    type Assoc;
+}
+
+impl<T: Bound> Normalize for T {
+    type Assoc = T;
+}
+
+impl<T: Bound> Normalize for [T] {
+    type Assoc = T;
+}
+
+impl Bound for Hello {}
+struct Hello {
+    a: <[Hello] as Normalize>::Assoc,
+}
+
+fn main() {}
diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
new file mode 100644
index 00000000000..d4339dd54d6
--- /dev/null
+++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
@@ -0,0 +1,19 @@
+// Regression test for #129541
+
+//@ check-pass
+
+trait Bound {}
+trait Normalize {
+    type Assoc;
+}
+
+impl<T: Bound> Normalize for [T] {
+    type Assoc = T;
+}
+
+impl Bound for Hello {}
+struct Hello {
+    a: <[Hello] as Normalize>::Assoc,
+}
+
+fn main() {}
diff --git a/tests/ui/traits/span-bug-issue-121414.rs b/tests/ui/traits/span-bug-issue-121414.rs
index ec38d8c2de6..2f4ad34f0c8 100644
--- a/tests/ui/traits/span-bug-issue-121414.rs
+++ b/tests/ui/traits/span-bug-issue-121414.rs
@@ -6,8 +6,7 @@ impl<'a> Bar for Foo<'f> { //~ ERROR undeclared lifetime
     type Type = u32;
 }
 
-fn test() //~ ERROR the trait bound `for<'a> Foo<'a>: Bar` is not satisfied
-          //~| ERROR the trait bound `for<'a> Foo<'a>: Bar` is not satisfied
+fn test()
 where
     for<'a> <Foo<'a> as Bar>::Type: Sized,
 {
diff --git a/tests/ui/traits/span-bug-issue-121414.stderr b/tests/ui/traits/span-bug-issue-121414.stderr
index e2ef6672cd5..744806a3415 100644
--- a/tests/ui/traits/span-bug-issue-121414.stderr
+++ b/tests/ui/traits/span-bug-issue-121414.stderr
@@ -6,22 +6,6 @@ LL | impl<'a> Bar for Foo<'f> {
    |      |
    |      help: consider introducing lifetime `'f` here: `'f,`
 
-error[E0277]: the trait bound `for<'a> Foo<'a>: Bar` is not satisfied
-  --> $DIR/span-bug-issue-121414.rs:9:1
-   |
-LL | / fn test()
-LL | |
-LL | | where
-LL | |     for<'a> <Foo<'a> as Bar>::Type: Sized,
-   | |__________________________________________^ the trait `for<'a> Bar` is not implemented for `Foo<'a>`
-
-error[E0277]: the trait bound `for<'a> Foo<'a>: Bar` is not satisfied
-  --> $DIR/span-bug-issue-121414.rs:9:4
-   |
-LL | fn test()
-   |    ^^^^ the trait `for<'a> Bar` is not implemented for `Foo<'a>`
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0261, E0277.
-For more information about an error, try `rustc --explain E0261`.
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/traits/syntax-polarity.rs b/tests/ui/traits/syntax-polarity.rs
index 80ad40bad80..c6506e916ed 100644
--- a/tests/ui/traits/syntax-polarity.rs
+++ b/tests/ui/traits/syntax-polarity.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 #![feature(negative_impls)]
 
diff --git a/tests/ui/traits/use-before-def.rs b/tests/ui/traits/use-before-def.rs
index fb7e540db18..2c7c6b19d67 100644
--- a/tests/ui/traits/use-before-def.rs
+++ b/tests/ui/traits/use-before-def.rs
@@ -3,7 +3,6 @@
 
 // Issue #1761
 
-//@ pretty-expanded FIXME #23616
 
 impl foo for isize { fn foo(&self) -> isize { 10 } }
 trait foo { fn foo(&self) -> isize; }
diff --git a/tests/ui/traits/where-clause-vs-impl.rs b/tests/ui/traits/where-clause-vs-impl.rs
index 074c27036c2..639347b3bc3 100644
--- a/tests/ui/traits/where-clause-vs-impl.rs
+++ b/tests/ui/traits/where-clause-vs-impl.rs
@@ -6,7 +6,6 @@
 //
 // Issue #18453.
 
-//@ pretty-expanded FIXME #23616
 
 use std::rc::Rc;
 
diff --git a/tests/ui/transmute-non-immediate-to-immediate.rs b/tests/ui/transmute-non-immediate-to-immediate.rs
index f5ddf0cfa33..d99bbcc600f 100644
--- a/tests/ui/transmute-non-immediate-to-immediate.rs
+++ b/tests/ui/transmute-non-immediate-to-immediate.rs
@@ -2,7 +2,6 @@
 // Issue #7988
 // Transmuting non-immediate type to immediate type
 
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     unsafe {
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
new file mode 100644
index 00000000000..18cfb1c1f93
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs
@@ -0,0 +1,21 @@
+// regression test for #127353
+
+#![feature(type_alias_impl_trait)]
+trait Trait<T> {}
+type Alias<'a, U> = impl Trait<U>;
+//~^ ERROR unconstrained opaque type
+
+pub enum UninhabitedVariants {
+    Tuple(Alias),
+    //~^ ERROR missing lifetime specifier
+    //~| ERROR missing generics
+    //~| ERROR non-defining opaque type use in defining scope
+}
+
+fn uwu(x: UninhabitedVariants) {
+    //~^ ERROR item does not constrain
+    match x {}
+    //~^ ERROR non-exhaustive patterns
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..cf366c55ea8
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr
@@ -0,0 +1,86 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/bad-tait-no-substs.rs:9:11
+   |
+LL |     Tuple(Alias),
+   |           ^^^^^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL ~ pub enum UninhabitedVariants<'a> {
+LL ~     Tuple(Alias<'a>),
+   |
+
+error[E0107]: missing generics for type alias `Alias`
+  --> $DIR/bad-tait-no-substs.rs:9:11
+   |
+LL |     Tuple(Alias),
+   |           ^^^^^ expected 1 generic argument
+   |
+note: type alias defined here, with 1 generic parameter: `U`
+  --> $DIR/bad-tait-no-substs.rs:5:6
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |      ^^^^^     -
+help: add missing generic argument
+   |
+LL |     Tuple(Alias<U>),
+   |                +++
+
+error[E0792]: non-defining opaque type use in defining scope
+  --> $DIR/bad-tait-no-substs.rs:9:11
+   |
+LL |     Tuple(Alias),
+   |           ^^^^^ argument `'_` is not a generic parameter
+   |
+note: for this opaque type
+  --> $DIR/bad-tait-no-substs.rs:5:21
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |                     ^^^^^^^^^^^^^
+
+error: item does not constrain `Alias::{opaque#0}`, but has it in its signature
+  --> $DIR/bad-tait-no-substs.rs:15:4
+   |
+LL | fn uwu(x: UninhabitedVariants) {
+   |    ^^^
+   |
+   = note: consider moving the opaque type's declaration and defining uses into a separate module
+note: this opaque type is in the signature
+  --> $DIR/bad-tait-no-substs.rs:5:21
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |                     ^^^^^^^^^^^^^
+
+error: unconstrained opaque type
+  --> $DIR/bad-tait-no-substs.rs:5:21
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |                     ^^^^^^^^^^^^^
+   |
+   = note: `Alias` must be used in combination with a concrete type within the same module
+
+error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` not covered
+  --> $DIR/bad-tait-no-substs.rs:17:11
+   |
+LL |     match x {}
+   |           ^ pattern `UninhabitedVariants::Tuple(_)` not covered
+   |
+note: `UninhabitedVariants` defined here
+  --> $DIR/bad-tait-no-substs.rs:8:10
+   |
+LL | pub enum UninhabitedVariants {
+   |          ^^^^^^^^^^^^^^^^^^^
+LL |     Tuple(Alias),
+   |     ----- not covered
+   = note: the matched value is of type `UninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~     match x {
+LL +         UninhabitedVariants::Tuple(_) => todo!(),
+LL +     }
+   |
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0004, E0106, E0107, E0792.
+For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs
new file mode 100644
index 00000000000..8314b28eeac
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs
@@ -0,0 +1,22 @@
+// regression test for rust-lang/rust#125758
+
+#![feature(impl_trait_in_assoc_type)]
+
+trait Trait {
+    type Assoc2;
+}
+
+struct Bar;
+impl Trait for Bar {
+    type Assoc2 = impl std::fmt::Debug;
+    //~^ ERROR unconstrained opaque type
+}
+
+struct Foo {
+    field: <Bar as Trait>::Assoc2,
+}
+
+static BAR: u8 = 42;
+static FOO2: &Foo = unsafe { std::mem::transmute(&BAR) };
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr
new file mode 100644
index 00000000000..6cbf6c83ff4
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+  --> $DIR/bad-transmute-itiat.rs:11:19
+   |
+LL |     type Assoc2 = impl std::fmt::Debug;
+   |                   ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Assoc2` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 1 previous error
+
diff --git a/tests/crashes/130956.rs b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs
index ebb986d123f..4332f1264a8 100644
--- a/tests/crashes/130956.rs
+++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs
@@ -1,8 +1,11 @@
-//@ known-bug: #130956
+// Regression test for #130956
+
+#![feature(type_alias_impl_trait)]
 
 mod impl_trait_mod {
     use super::*;
     pub type OpaqueBlock = impl Trait;
+    //~^ ERROR unconstrained opaque type
     pub type OpaqueIf = impl Trait;
 
     pub struct BlockWrapper(OpaqueBlock);
diff --git a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr
new file mode 100644
index 00000000000..8e5838d5ddf
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+  --> $DIR/drop-analysis-on-unconstrained-tait.rs:7:28
+   |
+LL |     pub type OpaqueBlock = impl Trait;
+   |                            ^^^^^^^^^^
+   |
+   = note: `OpaqueBlock` must be used in combination with a concrete type within the same module
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.rs b/tests/ui/type-alias-impl-trait/in-where-clause.rs
index a089fdc9075..065af57a864 100644
--- a/tests/ui/type-alias-impl-trait/in-where-clause.rs
+++ b/tests/ui/type-alias-impl-trait/in-where-clause.rs
@@ -1,4 +1,4 @@
-//! We evaluate `1 + 2` with `Reveal::All` during typeck, causing
+//! We evaluate `1 + 2` with `TypingMode::PostAnalysis` during typeck, causing
 //! us to get the concrete type of `Bar` while computing it.
 //! This again requires type checking `foo`.
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs b/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs
index 9901c8fe25d..c52dbd32539 100644
--- a/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs
+++ b/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs
@@ -1,7 +1,7 @@
 //@ compile-flags: -Zvalidate-mir
 //@ check-pass
 
-// Check that we don't cause cycle errors when validating pre-`Reveal::All` MIR
+// Check that we don't cause cycle errors when validating pre-`RevealOpaques` MIR
 // that assigns opaques through normalized projections.
 
 #![feature(impl_trait_in_assoc_type)]
diff --git a/tests/ui/type-alias/issue-14933.rs b/tests/ui/type-alias/issue-14933.rs
index ddad6071017..198a25e8964 100644
--- a/tests/ui/type-alias/issue-14933.rs
+++ b/tests/ui/type-alias/issue-14933.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 pub type BigRat<T = isize> = T;
 
diff --git a/tests/ui/type-param-constraints.rs b/tests/ui/type-param-constraints.rs
index a5c36af63fa..83d81c0d833 100644
--- a/tests/ui/type-param-constraints.rs
+++ b/tests/ui/type-param-constraints.rs
@@ -2,7 +2,6 @@
 
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn p_foo<T>(_pinned: T) { }
 fn s_foo<T>(_shared: T) { }
diff --git a/tests/ui/type-param.rs b/tests/ui/type-param.rs
index fdb56feab82..e7cf0e5446b 100644
--- a/tests/ui/type-param.rs
+++ b/tests/ui/type-param.rs
@@ -4,7 +4,6 @@
 #![allow(dead_code)]
 
 
-//@ pretty-expanded FIXME #23616
 
 type lteq<T> = extern "C" fn(T) -> bool;
 
diff --git a/tests/ui/type-ptr.rs b/tests/ui/type-ptr.rs
index 8f3868fc609..5c8ed344ab3 100644
--- a/tests/ui/type-ptr.rs
+++ b/tests/ui/type-ptr.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 fn f(a: *const isize) -> *const isize { return a; }
 
diff --git a/tests/ui/type-use-i1-versus-i8.rs b/tests/ui/type-use-i1-versus-i8.rs
index 916a77d9934..4eb25329223 100644
--- a/tests/ui/type-use-i1-versus-i8.rs
+++ b/tests/ui/type-use-i1-versus-i8.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 use std::ptr;
 
diff --git a/tests/ui/type/issue-7607-2.rs b/tests/ui/type/issue-7607-2.rs
index 654f26bf298..ebc4fe1c2d3 100644
--- a/tests/ui/type/issue-7607-2.rs
+++ b/tests/ui/type/issue-7607-2.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![allow(dead_code)]
-//@ pretty-expanded FIXME #23616
 
 pub mod a {
     pub struct Foo { a: usize }
diff --git a/tests/ui/typeck/ufcs-type-params.rs b/tests/ui/typeck/ufcs-type-params.rs
index ef8b983b3e9..5a6db4620fc 100644
--- a/tests/ui/typeck/ufcs-type-params.rs
+++ b/tests/ui/typeck/ufcs-type-params.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 trait Foo<T> {
     fn get(&self) -> T;
diff --git a/tests/ui/typeck/unify-return-ty.rs b/tests/ui/typeck/unify-return-ty.rs
index 849b72e63e5..d33a1674e08 100644
--- a/tests/ui/typeck/unify-return-ty.rs
+++ b/tests/ui/typeck/unify-return-ty.rs
@@ -3,7 +3,6 @@
 // unified with the type *T, and so the type variable
 // in that type gets resolved.
 
-//@ pretty-expanded FIXME #23616
 
 use std::mem;
 
diff --git a/tests/ui/unboxed-closures/issue-18661.rs b/tests/ui/unboxed-closures/issue-18661.rs
index 44b4c499352..dc965809ea1 100644
--- a/tests/ui/unboxed-closures/issue-18661.rs
+++ b/tests/ui/unboxed-closures/issue-18661.rs
@@ -2,7 +2,6 @@
 // Test that param substitutions from the correct environment are
 // used when codegenning unboxed closure calls.
 
-//@ pretty-expanded FIXME #23616
 
 pub fn inside<F: Fn()>(c: F) {
     c();
diff --git a/tests/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs b/tests/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs
index 632bffbea18..265e8e49f0d 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs
+++ b/tests/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_mut)]
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let mut unboxed = || {};
diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs
index c7c50b7b50e..8c27c4151ac 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs
+++ b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs
@@ -2,7 +2,6 @@
 // Test that we are able to infer that the type of `x` is `isize` based
 // on the expected type from the object.
 
-//@ pretty-expanded FIXME #23616
 
 pub trait ToPrimitive {
     fn to_int(&self) {}
diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs
index a54048d2518..10f21908902 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs
+++ b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs
@@ -2,7 +2,6 @@
 // Test that we are able to infer that the type of `x` is `isize` based
 // on the expected type from the object.
 
-//@ pretty-expanded FIXME #23616
 
 pub trait ToPrimitive {
     fn to_int(&self) {}
diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs
index 8c7b1c7534b..d3a6ff91a94 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs
+++ b/tests/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs
@@ -2,7 +2,6 @@
 // Test that we are able to infer that the type of `x` is `isize` based
 // on the expected type from the object.
 
-//@ pretty-expanded FIXME #23616
 
 pub trait ToPrimitive {
     fn to_int(&self) {}
diff --git a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs
index d883053d276..f27461808c3 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs
+++ b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 #![deny(unused_mut)]
 #![allow(unused_must_use)]
diff --git a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr
index 5c06f4e621c..813e2eea568 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr
@@ -1,5 +1,5 @@
 warning: unused variable: `x`
-  --> $DIR/unboxed-closures-move-mutable.rs:17:17
+  --> $DIR/unboxed-closures-move-mutable.rs:16:17
    |
 LL |         move || x += 1;
    |                 ^
@@ -8,7 +8,7 @@ LL |         move || x += 1;
    = note: `#[warn(unused_variables)]` on by default
 
 warning: unused variable: `x`
-  --> $DIR/unboxed-closures-move-mutable.rs:21:17
+  --> $DIR/unboxed-closures-move-mutable.rs:20:17
    |
 LL |         move || x += 1;
    |                 ^
diff --git a/tests/ui/unboxed-closures/unboxed-closures-prelude.rs b/tests/ui/unboxed-closures/unboxed-closures-prelude.rs
index ca0ca66c035..ae90a51c488 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-prelude.rs
+++ b/tests/ui/unboxed-closures/unboxed-closures-prelude.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 // Tests that the re-exports of `FnOnce` et al from the prelude work.
 
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let task: Box<dyn Fn(isize) -> isize> = Box::new(|x| x);
diff --git a/tests/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs b/tests/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs
index 6103dbd9959..c63594dc878 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs
+++ b/tests/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let onetime = |x| x;
diff --git a/tests/ui/unboxed-closures/unboxed-closures-zero-args.rs b/tests/ui/unboxed-closures/unboxed-closures-zero-args.rs
index 81fe12afccf..c808189b658 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-zero-args.rs
+++ b/tests/ui/unboxed-closures/unboxed-closures-zero-args.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_mut)]
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let mut zero = || {};
diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr
index 50f33607c06..0e87f14aa14 100644
--- a/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr
+++ b/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr
@@ -5,7 +5,7 @@ LL |     let Foo::D(_y, _z) = x;
    |         ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Foo` defined here
   --> $DIR/uninhabited-irrefutable.rs:19:6
    |
diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr
index bc1a9fa4191..67527ce1ac4 100644
--- a/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr
+++ b/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr
@@ -5,7 +5,7 @@ LL |     let Foo::D(_y, _z) = x;
    |         ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Foo` defined here
   --> $DIR/uninhabited-irrefutable.rs:20:6
    |
diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr
index 50f33607c06..0e87f14aa14 100644
--- a/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr
+++ b/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr
@@ -5,7 +5,7 @@ LL |     let Foo::D(_y, _z) = x;
    |         ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Foo` defined here
   --> $DIR/uninhabited-irrefutable.rs:19:6
    |
diff --git a/tests/ui/uninit-empty-types.rs b/tests/ui/uninit-empty-types.rs
index a6c11c4999a..82474d873b7 100644
--- a/tests/ui/uninit-empty-types.rs
+++ b/tests/ui/uninit-empty-types.rs
@@ -1,7 +1,6 @@
 //@ build-pass
 // Test the uninit() construct returning various empty types.
 
-//@ pretty-expanded FIXME #23616
 
 use std::mem::MaybeUninit;
 
diff --git a/tests/ui/unit.rs b/tests/ui/unit.rs
index 98ac164b1d4..04404fc3f5e 100644
--- a/tests/ui/unit.rs
+++ b/tests/ui/unit.rs
@@ -2,7 +2,6 @@
 
 #![allow(unused_assignments)]
 #![allow(unknown_lints)]
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_variables)]
 #![allow(dead_assignment)]
diff --git a/tests/ui/unnamed_argument_mode.rs b/tests/ui/unnamed_argument_mode.rs
index ba6f84c4dde..2014e0d23d8 100644
--- a/tests/ui/unnamed_argument_mode.rs
+++ b/tests/ui/unnamed_argument_mode.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn good(_a: &isize) {
 }
diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs
index 799e8071d02..891021e8766 100644
--- a/tests/ui/unpretty/expanded-exhaustive.rs
+++ b/tests/ui/unpretty/expanded-exhaustive.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -Zunpretty=expanded -Zunstable-options
+//@ compile-flags: -Zunpretty=expanded
 //@ edition:2024
 //@ check-pass
 
diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout
index d8384951e12..007626e2c44 100644
--- a/tests/ui/unpretty/expanded-exhaustive.stdout
+++ b/tests/ui/unpretty/expanded-exhaustive.stdout
@@ -1,5 +1,5 @@
 #![feature(prelude_import)]
-//@ compile-flags: -Zunpretty=expanded -Zunstable-options
+//@ compile-flags: -Zunpretty=expanded
 //@ edition:2024
 //@ check-pass
 
diff --git a/tests/ui/unsafe-fields-crate.rs b/tests/ui/unsafe-fields-crate.rs
new file mode 100644
index 00000000000..cfb9ad6b544
--- /dev/null
+++ b/tests/ui/unsafe-fields-crate.rs
@@ -0,0 +1,62 @@
+//@ compile-flags: --crate-type=lib
+//@ aux-build: unsafe-fields-crate-dep.rs
+
+extern crate unsafe_fields_crate_dep;
+
+use unsafe_fields_crate_dep::WithUnsafeField;
+
+fn new_without_unsafe() -> WithUnsafeField {
+    WithUnsafeField {
+        //~^ ERROR
+        unsafe_field: 0,
+        safe_field: 0,
+    }
+}
+
+fn operate_on_safe_field(s: &mut WithUnsafeField) {
+    s.safe_field = 2;
+    &s.safe_field;
+    s.safe_field;
+}
+
+fn set_unsafe_field(s: &mut WithUnsafeField) {
+    unsafe {
+        s.unsafe_field = 2;
+    }
+}
+
+fn read_unsafe_field(s: &WithUnsafeField) -> u32 {
+    unsafe { s.unsafe_field }
+}
+
+fn ref_unsafe_field(s: &WithUnsafeField) -> &u32 {
+    unsafe { &s.unsafe_field }
+}
+
+fn destructure(s: &WithUnsafeField) {
+    unsafe {
+        let WithUnsafeField { safe_field, unsafe_field } = s;
+    }
+}
+
+fn set_unsafe_field_without_unsafe(s: &mut WithUnsafeField) {
+    s.unsafe_field = 2;
+    //~^ ERROR
+}
+
+fn read_unsafe_field_without_unsafe(s: &WithUnsafeField) -> u32 {
+    s.unsafe_field
+    //~^ ERROR
+}
+
+fn ref_unsafe_field_without_unsafe(s: &WithUnsafeField) -> &u32 {
+    &s.unsafe_field
+    //~^ ERROR
+}
+
+fn destructure_without_unsafe(s: &WithUnsafeField) {
+    let WithUnsafeField { safe_field, unsafe_field } = s;
+    //~^ ERROR
+
+    let WithUnsafeField { safe_field, .. } = s;
+}
diff --git a/tests/ui/unsafe-fields-crate.stderr b/tests/ui/unsafe-fields-crate.stderr
new file mode 100644
index 00000000000..778c26e0a43
--- /dev/null
+++ b/tests/ui/unsafe-fields-crate.stderr
@@ -0,0 +1,47 @@
+error[E0133]: initializing type with an unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields-crate.rs:9:5
+   |
+LL | /     WithUnsafeField {
+LL | |
+LL | |         unsafe_field: 0,
+LL | |         safe_field: 0,
+LL | |     }
+   | |_____^ initialization of struct with unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error[E0133]: use of unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields-crate.rs:43:5
+   |
+LL |     s.unsafe_field = 2;
+   |     ^^^^^^^^^^^^^^ use of unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error[E0133]: use of unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields-crate.rs:48:5
+   |
+LL |     s.unsafe_field
+   |     ^^^^^^^^^^^^^^ use of unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error[E0133]: use of unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields-crate.rs:53:6
+   |
+LL |     &s.unsafe_field
+   |      ^^^^^^^^^^^^^^ use of unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error[E0133]: use of unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields-crate.rs:58:39
+   |
+LL |     let WithUnsafeField { safe_field, unsafe_field } = s;
+   |                                       ^^^^^^^^^^^^ use of unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/unsafe-fields-parse.rs b/tests/ui/unsafe-fields-parse.rs
new file mode 100644
index 00000000000..67277731293
--- /dev/null
+++ b/tests/ui/unsafe-fields-parse.rs
@@ -0,0 +1,10 @@
+//@ compile-flags: --crate-type=lib
+#![allow(incomplete_features)]
+#![feature(unsafe_fields)]
+
+// Parse errors even *with* unsafe_fields, which would make the compiler early-exit otherwise.
+enum A {
+    TupleLike(unsafe u32), //~ ERROR
+}
+
+struct B(unsafe u32); //~ ERROR
diff --git a/tests/ui/unsafe-fields-parse.stderr b/tests/ui/unsafe-fields-parse.stderr
new file mode 100644
index 00000000000..5a45ab03ffe
--- /dev/null
+++ b/tests/ui/unsafe-fields-parse.stderr
@@ -0,0 +1,18 @@
+error: expected type, found keyword `unsafe`
+  --> $DIR/unsafe-fields-parse.rs:7:15
+   |
+LL | enum A {
+   |      - while parsing this enum
+LL |     TupleLike(unsafe u32),
+   |               ^^^^^^ expected type
+   |
+   = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
+
+error: expected type, found keyword `unsafe`
+  --> $DIR/unsafe-fields-parse.rs:10:10
+   |
+LL | struct B(unsafe u32);
+   |          ^^^^^^ expected type
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/unsafe-fields.rs b/tests/ui/unsafe-fields.rs
new file mode 100644
index 00000000000..637471582d7
--- /dev/null
+++ b/tests/ui/unsafe-fields.rs
@@ -0,0 +1,109 @@
+//@ compile-flags: --crate-type=lib
+#![allow(incomplete_features)]
+#![feature(unsafe_fields)]
+
+struct WithUnsafeField {
+    unsafe unsafe_field: u32,
+    safe_field: u32,
+}
+
+enum A {
+    WithUnsafeField { unsafe unsafe_field: u32, safe_field: u32 },
+}
+
+fn f(a: A) {
+    let A::WithUnsafeField { unsafe_field, safe_field } = a;
+    //~^ ERROR
+}
+
+struct WithInvalidUnsafeField {
+    unsafe unsafe_noncopy_field: Vec<u32>, //~ ERROR
+}
+
+struct WithManuallyDropUnsafeField {
+    unsafe unsafe_noncopy_field: std::mem::ManuallyDrop<Vec<u32>>,
+}
+
+union WithUnsafeFieldUnion {
+    unsafe unsafe_field: u32,
+    safe_field: u32,
+}
+
+impl WithUnsafeField {
+    fn new() -> WithUnsafeField {
+        unsafe {
+            WithUnsafeField {
+                unsafe_field: 0,
+                safe_field: 0,
+            }
+        }
+    }
+
+    fn new_without_unsafe() -> WithUnsafeField {
+        WithUnsafeField { //~ ERROR
+            unsafe_field: 0,
+            safe_field: 0,
+        }
+    }
+
+    fn operate_on_safe_field(&mut self) {
+        self.safe_field = 2;
+        &self.safe_field;
+        self.safe_field;
+    }
+
+    fn set_unsafe_field(&mut self) {
+        unsafe {
+            self.unsafe_field = 2;
+        }
+    }
+
+    fn read_unsafe_field(&self) -> u32 {
+        unsafe {
+            self.unsafe_field
+        }
+    }
+
+    fn ref_unsafe_field(&self) -> &u32 {
+        unsafe {
+            &self.unsafe_field
+        }
+    }
+
+    fn destructure(&self) {
+        unsafe {
+            let Self { safe_field, unsafe_field } = self;
+        }
+    }
+
+    fn set_unsafe_field_without_unsafe(&mut self) {
+        self.unsafe_field = 2;
+        //~^ ERROR
+    }
+
+    fn read_unsafe_field_without_unsafe(&self) -> u32 {
+        self.unsafe_field
+        //~^ ERROR
+    }
+
+    fn ref_unsafe_field_without_unsafe(&self) -> &u32 {
+        &self.unsafe_field
+        //~^ ERROR
+    }
+
+    fn destructure_without_unsafe(&self) {
+        let Self { safe_field, unsafe_field } = self;
+        //~^ ERROR
+
+        let WithUnsafeField { safe_field, .. } = self;
+    }
+
+    fn offset_of(&self) -> usize {
+        std::mem::offset_of!(WithUnsafeField, unsafe_field)
+    }
+
+    fn raw_const(&self) -> *const u32 {
+        &raw const self.unsafe_field
+        //~^ ERROR
+    }
+}
diff --git a/tests/ui/unsafe-fields.stderr b/tests/ui/unsafe-fields.stderr
new file mode 100644
index 00000000000..a1c5d2b44cd
--- /dev/null
+++ b/tests/ui/unsafe-fields.stderr
@@ -0,0 +1,75 @@
+error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe
+  --> $DIR/unsafe-fields.rs:20:5
+   |
+LL |     unsafe unsafe_noncopy_field: Vec<u32>,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
+help: wrap the field type in `ManuallyDrop<...>`
+   |
+LL |     unsafe unsafe_noncopy_field: std::mem::ManuallyDrop<Vec<u32>>,
+   |                                  +++++++++++++++++++++++        +
+
+error[E0133]: use of unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields.rs:15:30
+   |
+LL |     let A::WithUnsafeField { unsafe_field, safe_field } = a;
+   |                              ^^^^^^^^^^^^ use of unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error[E0133]: initializing type with an unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields.rs:43:9
+   |
+LL | /         WithUnsafeField {
+LL | |             unsafe_field: 0,
+LL | |             safe_field: 0,
+LL | |         }
+   | |_________^ initialization of struct with unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error[E0133]: use of unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields.rs:80:9
+   |
+LL |         self.unsafe_field = 2;
+   |         ^^^^^^^^^^^^^^^^^ use of unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error[E0133]: use of unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields.rs:85:9
+   |
+LL |         self.unsafe_field
+   |         ^^^^^^^^^^^^^^^^^ use of unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error[E0133]: use of unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields.rs:90:10
+   |
+LL |         &self.unsafe_field
+   |          ^^^^^^^^^^^^^^^^^ use of unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error[E0133]: use of unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields.rs:95:32
+   |
+LL |         let Self { safe_field, unsafe_field } = self;
+   |                                ^^^^^^^^^^^^ use of unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error[E0133]: use of unsafe field is unsafe and requires unsafe block
+  --> $DIR/unsafe-fields.rs:106:20
+   |
+LL |         &raw const self.unsafe_field
+   |                    ^^^^^^^^^^^^^^^^^ use of unsafe field
+   |
+   = note: unsafe fields may carry library invariants
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0133, E0740.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs
index f12c38939dd..2fb73d3a1fa 100644
--- a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs
+++ b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 //@ check-pass
 #![crate_type = "lib"]
 #![deny(unused_unsafe)]
diff --git a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr
index fe12dd72d9e..321d0ca2936 100644
--- a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr
+++ b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr
@@ -1,5 +1,5 @@
 warning[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block
-  --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:10:5
+  --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:9:5
    |
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
@@ -7,7 +7,7 @@ LL |     unsf();
    = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
    = note: consult the function's documentation for information on how to avoid undefined behavior
 note: an unsafe function restricts its caller, but its body is safe by default
-  --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:9:1
+  --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:8:1
    |
 LL | unsafe fn foo() {
    | ^^^^^^^^^^^^^^^
diff --git a/tests/ui/unsafe/new-unsafe-pointers.rs b/tests/ui/unsafe/new-unsafe-pointers.rs
index 39566cda90a..07c54ae9692 100644
--- a/tests/ui/unsafe/new-unsafe-pointers.rs
+++ b/tests/ui/unsafe/new-unsafe-pointers.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 fn main() {
     let _a: *const isize = 3 as *const isize;
diff --git a/tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs b/tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs
index d9f244bc4d2..d45f5c523c2 100644
--- a/tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs
+++ b/tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs
@@ -4,7 +4,6 @@
 //
 // See also: ui/unsafe/unsafe-fn-called-from-safe.rs
 
-//@ pretty-expanded FIXME #23616
 
 unsafe fn f() { return; }
 
diff --git a/tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs b/tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs
index bb7715b7b5c..168c60dfc84 100644
--- a/tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs
+++ b/tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs
@@ -4,7 +4,6 @@
 //
 // See also: ui/unsafe/unsafe-fn-called-from-safe.rs
 
-//@ pretty-expanded FIXME #23616
 
 unsafe fn f() { return; }
 
diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.rs b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.rs
index 06a46b9812d..261427d1eab 100644
--- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.rs
+++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.rs
@@ -1,5 +1,4 @@
 //@ edition: 2024
-//@ compile-flags: -Zunstable-options
 //@ check-pass
 
 // Tests that `unsafe_op_in_unsafe_fn` is warn-by-default in edition 2024 and that the
diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr
index 05f36ab47cb..d91b76e7937 100644
--- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr
+++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr
@@ -1,5 +1,5 @@
 warning[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block
-  --> $DIR/edition_2024_default.rs:13:5
+  --> $DIR/edition_2024_default.rs:12:5
    |
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
@@ -7,7 +7,7 @@ LL |     unsf();
    = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
    = note: consult the function's documentation for information on how to avoid undefined behavior
 note: an unsafe function restricts its caller, but its body is safe by default
-  --> $DIR/edition_2024_default.rs:12:1
+  --> $DIR/edition_2024_default.rs:11:1
    |
 LL | unsafe fn foo() {
    | ^^^^^^^^^^^^^^^
diff --git a/tests/ui/unused-move-capture.rs b/tests/ui/unused-move-capture.rs
index c295f8d7914..5f42bcbe280 100644
--- a/tests/ui/unused-move-capture.rs
+++ b/tests/ui/unused-move-capture.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 pub fn main() {
     let _x: Box<_> = Box::new(1);
diff --git a/tests/ui/unused-move.rs b/tests/ui/unused-move.rs
index 87398652e93..3d5eff2c48d 100644
--- a/tests/ui/unused-move.rs
+++ b/tests/ui/unused-move.rs
@@ -3,7 +3,6 @@
 // Issue Name: Unused move causes a crash
 // Abstract: zero-fill to block after drop
 
-//@ pretty-expanded FIXME #23616
 
 #![allow(path_statements)]
 
diff --git a/tests/ui/use-import-export.rs b/tests/ui/use-import-export.rs
index f784194c505..d948ffc1520 100644
--- a/tests/ui/use-import-export.rs
+++ b/tests/ui/use-import-export.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ pretty-expanded FIXME #23616
 
 mod foo {
     pub fn x() -> isize { return 1; }
diff --git a/tests/ui/use/use.rs b/tests/ui/use/use.rs
index 826a049f2bb..db031500a4a 100644
--- a/tests/ui/use/use.rs
+++ b/tests/ui/use/use.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 
 #![allow(stable_features)]
-//@ pretty-expanded FIXME #23616
 
 #![allow(unused_imports)]
 #![feature(start, no_core, core)]
diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs
index 53363319ba0..a95e10b7265 100644
--- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs
+++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs
@@ -1,11 +1,6 @@
 trait Trait<const N: Trait = bar> {
     //~^ ERROR cannot find value `bar` in this scope
     //~| ERROR cycle detected when computing type of `Trait::N`
-    //~| ERROR the trait `Trait` cannot be made into an object
-    //~| ERROR the trait `Trait` cannot be made into an object
-    //~| ERROR the trait `Trait` cannot be made into an object
-    //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
     //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
     //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
     fn fnc<const N: Trait = u32>(&self) -> Trait {
@@ -13,9 +8,6 @@ trait Trait<const N: Trait = bar> {
         //~| ERROR expected value, found builtin type `u32`
         //~| ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
         //~| ERROR associated item referring to unboxed trait object for its own trait
-        //~| ERROR the trait `Trait` cannot be made into an object
-        //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-        //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
         //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
         //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
         //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr
index fefb788fac7..339f7b2cc82 100644
--- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr
+++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr
@@ -1,5 +1,5 @@
 error[E0403]: the name `N` is already used for a generic parameter in this item's generic parameters
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:18
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:18
    |
 LL | trait Trait<const N: Trait = bar> {
    |                   - first use of `N`
@@ -14,13 +14,13 @@ LL | trait Trait<const N: Trait = bar> {
    |                              ^^^ not found in this scope
 
 error[E0423]: expected value, found builtin type `u32`
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:29
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:29
    |
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    |                             ^^^ not a value
 
 error[E0425]: cannot find value `bar` in this scope
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:23:9
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:15:9
    |
 LL |         bar
    |         ^^^ not found in this scope
@@ -53,27 +53,8 @@ LL | trait Trait<const N: Trait = bar> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:12
-   |
-LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
-   |            ^^^^^^^^^^^^^^^^^^^^
-
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:21
-   |
-LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
-   |                     ^^^^^
-   |
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: if this is a dyn-compatible trait, use `dyn`
-   |
-LL |     fn fnc<const N: dyn Trait = u32>(&self) -> Trait {
-   |                     +++
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:44
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:44
    |
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    |                                            ^^^^^
@@ -85,114 +66,40 @@ help: if this is a dyn-compatible trait, use `dyn`
 LL |     fn fnc<const N: Trait = u32>(&self) -> dyn Trait {
    |                                            +++
 
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:22
-   |
-LL | trait Trait<const N: Trait = bar> {
-   |                      ^^^^^
-   |
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: if this is a dyn-compatible trait, use `dyn`
-   |
-LL | trait Trait<const N: dyn Trait = bar> {
-   |                      +++
-
-error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:22
-   |
-LL | trait Trait<const N: Trait = bar> {
-   |                      ^^^^^ `Trait` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:8
-   |
-LL | trait Trait<const N: Trait = bar> {
-   |       ----- this trait cannot be made into an object...
-...
-LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
-   |        ^^^ ...because method `fnc` has generic type parameters
-   = help: consider moving `fnc` to another trait
-
-error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:13
-   |
-LL | trait Trait<const N: Trait = bar> {
-   |             ^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:8
-   |
-LL | trait Trait<const N: Trait = bar> {
-   |       ----- this trait cannot be made into an object...
-...
-LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
-   |        ^^^ ...because method `fnc` has generic type parameters
-   = help: consider moving `fnc` to another trait
-
-error: associated item referring to unboxed trait object for its own trait
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:44
+error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:12
    |
-LL | trait Trait<const N: Trait = bar> {
-   |       ----- in this trait
-...
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
-   |                                            ^^^^^
-   |
-help: you might have meant to use `Self` to refer to the implementing type
-   |
-LL |     fn fnc<const N: Trait = u32>(&self) -> Self {
-   |                                            ~~~~
+   |            ^^^^^^^^^^^^^^^^^^^^
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:21
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:21
    |
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    |                     ^^^^^
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: if this is a dyn-compatible trait, use `dyn`
    |
 LL |     fn fnc<const N: dyn Trait = u32>(&self) -> Trait {
    |                     +++
 
-error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:21
-   |
-LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
-   |                     ^^^^^ `Trait` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:8
+error: associated item referring to unboxed trait object for its own trait
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:6:44
    |
 LL | trait Trait<const N: Trait = bar> {
-   |       ----- this trait cannot be made into an object...
+   |       ----- in this trait
 ...
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
-   |        ^^^ ...because method `fnc` has generic type parameters
-   = help: consider moving `fnc` to another trait
-
-error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:13
-   |
-LL | trait Trait<const N: Trait = bar> {
-   |             ^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
+   |                                            ^^^^^
    |
-note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:11:8
+help: you might have meant to use `Self` to refer to the implementing type
    |
-LL | trait Trait<const N: Trait = bar> {
-   |       ----- this trait cannot be made into an object...
-...
-LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
-   |        ^^^ ...because method `fnc` has generic type parameters
-   = help: consider moving `fnc` to another trait
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+LL |     fn fnc<const N: Trait = u32>(&self) -> Self {
+   |                                            ~~~~
 
-error: aborting due to 11 previous errors; 5 warnings emitted
+error: aborting due to 7 previous errors; 3 warnings emitted
 
-Some errors have detailed explanations: E0038, E0391, E0403, E0423, E0425.
-For more information about an error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0391, E0403, E0423, E0425.
+For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
index e6d4e2ee01a..0be5127dcc4 100644
--- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
+++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
@@ -14,5 +14,4 @@ impl Trait for Ref {} //~ ERROR:  implicit elided lifetime not allowed here
 
 extern "C" {
     pub fn repro(_: Wrapper<Ref>);
-    //~^ ERROR the trait bound `Ref<'_>: Trait` is not satisfied
 }
diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
index 59b55b2732d..0af4ab022e1 100644
--- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
+++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
@@ -9,19 +9,6 @@ help: indicate the anonymous lifetime
 LL | impl Trait for Ref<'_> {}
    |                   ++++
 
-error[E0277]: the trait bound `Ref<'_>: Trait` is not satisfied
-  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21
-   |
-LL |     pub fn repro(_: Wrapper<Ref>);
-   |                     ^^^^^^^^^^^^ the trait `Trait` is not implemented for `Ref<'_>`
-   |
-note: required by a bound in `Wrapper`
-  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23
-   |
-LL | pub struct Wrapper<T: Trait>(T);
-   |                       ^^^^^ required by this bound in `Wrapper`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0726.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0726`.
diff --git a/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs b/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs
index be003cbf585..cf9c661582e 100644
--- a/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs
+++ b/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-//@ pretty-expanded FIXME #23616
 
 trait Bound {
     fn dummy(&self) { }
diff --git a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs
index 67088a9818e..153fa8a5715 100644
--- a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs
+++ b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(non_upper_case_globals)]
 
-//@ pretty-expanded FIXME #23616
 
 trait TheTrait { fn dummy(&self) { } } //~ WARN method `dummy` is never used
 
diff --git a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr
index a9fe11ea6b3..34ed8bd2146 100644
--- a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr
+++ b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr
@@ -1,5 +1,5 @@
 warning: method `dummy` is never used
-  --> $DIR/where-clause-early-bound-lifetimes.rs:6:21
+  --> $DIR/where-clause-early-bound-lifetimes.rs:5:21
    |
 LL | trait TheTrait { fn dummy(&self) { } }
    |       --------      ^^^^^
diff --git a/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs b/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs
index ba409182809..da75ed796c0 100644
--- a/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs
+++ b/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 trait Foo<T> { fn dummy(&self, arg: T) { } } //~ WARN method `dummy` is never used
 
diff --git a/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr b/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr
index 0d09cb9de3f..9a8faf7a64e 100644
--- a/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr
+++ b/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr
@@ -1,5 +1,5 @@
 warning: method `dummy` is never used
-  --> $DIR/where-clause-method-substituion-rpass.rs:5:19
+  --> $DIR/where-clause-method-substituion-rpass.rs:4:19
    |
 LL | trait Foo<T> { fn dummy(&self, arg: T) { } }
    |       ---         ^^^^^
diff --git a/tests/ui/where-clauses/where-clause-region-outlives.rs b/tests/ui/where-clauses/where-clause-region-outlives.rs
index db61638ca2d..47a6d468204 100644
--- a/tests/ui/where-clauses/where-clause-region-outlives.rs
+++ b/tests/ui/where-clauses/where-clause-region-outlives.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 struct A<'a, 'b> where 'a : 'b { x: &'a isize, y: &'b isize }
 
diff --git a/tests/ui/where-clauses/where-clauses-lifetimes.rs b/tests/ui/where-clauses/where-clauses-lifetimes.rs
index 8e8c73a3925..63ab9bafa23 100644
--- a/tests/ui/where-clauses/where-clauses-lifetimes.rs
+++ b/tests/ui/where-clauses/where-clauses-lifetimes.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_mut)]
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 fn foo<'a, I>(mut it: I) where I: Iterator<Item=&'a isize> {}
 
diff --git a/tests/ui/where-clauses/where-clauses-unboxed-closures.rs b/tests/ui/where-clauses/where-clauses-unboxed-closures.rs
index c2ef65ab0a6..5961a516457 100644
--- a/tests/ui/where-clauses/where-clauses-unboxed-closures.rs
+++ b/tests/ui/where-clauses/where-clauses-unboxed-closures.rs
@@ -1,6 +1,5 @@
 //@ run-pass
 #![allow(unused_variables)]
-//@ pretty-expanded FIXME #23616
 
 struct Bencher;
 
diff --git a/triagebot.toml b/triagebot.toml
index b7a9b794c8b..47b96824098 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -428,8 +428,14 @@ trigger_files = [
     "triagebot.toml",
     "rustfmt.toml",
     "LICENSES",
+    "COPYRIGHT",
+    "LICENSE-APACHE",
+    "LICENSE-MIT",
+    "CODE_OF_CONDUCT.md",
     "README.md",
     "CONTRIBUTING.md",
+    "INSTALL.md",
+    "REUSE.toml",
     ".reuse",
     ".mailmap",
     ".git-blame-ignore-revs",
@@ -991,7 +997,6 @@ contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
 users_on_vacation = [
     "jyn514",
     "oli-obk",
-    "onur-ozkan",
 ]
 
 [assign.adhoc_groups]