about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock168
-rw-r--r--Cargo.toml1
-rw-r--r--compiler/rustc_ast/src/ast.rs11
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs19
-rw-r--r--compiler/rustc_ast/src/visit.rs17
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs70
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs93
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs32
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs81
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs2
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs21
-rw-r--r--compiler/rustc_attr_data_structures/src/stability.rs15
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/stability.rs18
-rw-r--r--compiler/rustc_borrowck/messages.ftl3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs25
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs133
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs27
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs24
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs3
-rw-r--r--compiler/rustc_borrowck/src/lib.rs24
-rw-r--r--compiler/rustc_borrowck/src/nll.rs11
-rw-r--r--compiler/rustc_borrowck/src/places_conflict.rs7
-rw-r--r--compiler/rustc_borrowck/src/polonius/dump.rs14
-rw-r--r--compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs4
-rw-r--r--compiler/rustc_borrowck/src/polonius/liveness_constraints.rs24
-rw-r--r--compiler/rustc_borrowck/src/polonius/mod.rs87
-rw-r--r--compiler/rustc_borrowck/src/prefixes.rs4
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs7
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/mod.rs37
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/trace.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs72
-rw-r--r--compiler/rustc_builtin_macros/src/alloc_error_handler.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/contracts.rs176
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs215
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/encodable.rs284
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs27
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/ty.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs18
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs7
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs19
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/aot.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs18
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/utils.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs143
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs5
-rw-r--r--compiler/rustc_const_eval/messages.ftl4
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs10
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs5
-rw-r--r--compiler/rustc_const_eval/src/check_consts/resolver.rs3
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs9
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs42
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs20
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs11
-rw-r--r--compiler/rustc_const_eval/src/lib.rs10
-rw-r--r--compiler/rustc_const_eval/src/util/caller_location.rs9
-rw-r--r--compiler/rustc_data_structures/src/vec_cache.rs13
-rw-r--r--compiler/rustc_driver_impl/src/args.rs19
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs14
-rw-r--r--compiler/rustc_driver_impl/src/pretty.rs6
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs51
-rw-r--r--compiler/rustc_errors/src/emitter.rs17
-rw-r--r--compiler/rustc_errors/src/lib.rs67
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs3
-rw-r--r--compiler/rustc_feature/src/unstable.rs10
-rw-r--r--compiler/rustc_hir/src/hir.rs64
-rw-r--r--compiler/rustc_hir/src/intravisit.rs18
-rw-r--r--compiler/rustc_hir/src/lang_items.rs9
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl7
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs70
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs150
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/errors/pattern_types.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs46
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs76
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs22
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs51
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs41
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs265
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs24
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs43
-rw-r--r--compiler/rustc_incremental/src/lib.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs3
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs2
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/fudge.rs2
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/undo_log.rs2
-rw-r--r--compiler/rustc_infer/src/infer/unify_key.rs (renamed from compiler/rustc_middle/src/infer/unify_key.rs)20
-rw-r--r--compiler/rustc_interface/src/passes.rs48
-rw-r--r--compiler/rustc_lint/src/builtin.rs3
-rw-r--r--compiler/rustc_lint/src/context.rs26
-rw-r--r--compiler/rustc_lint/src/early/diagnostics/check_cfg.rs4
-rw-r--r--compiler/rustc_lint/src/late.rs2
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs10
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs17
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp36
-rw-r--r--compiler/rustc_macros/src/query.rs26
-rw-r--r--compiler/rustc_metadata/messages.ftl10
-rw-r--r--compiler/rustc_metadata/src/creader.rs97
-rw-r--r--compiler/rustc_metadata/src/errors.rs25
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs15
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs8
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs16
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs5
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs146
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_middle/src/hooks/mod.rs20
-rw-r--r--compiler/rustc_middle/src/infer/mod.rs1
-rw-r--r--compiler/rustc_middle/src/lib.rs7
-rw-r--r--compiler/rustc_middle/src/lint.rs40
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs66
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs4
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs121
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs22
-rw-r--r--compiler/rustc_middle/src/mir/statement.rs12
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs10
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs9
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs2
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs13
-rw-r--r--compiler/rustc_middle/src/query/keys.rs6
-rw-r--r--compiler/rustc_middle/src/query/mod.rs22
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs81
-rw-r--r--compiler/rustc_middle/src/thir.rs73
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs8
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs3
-rw-r--r--compiler/rustc_middle/src/traits/query.rs3
-rw-r--r--compiler/rustc_middle/src/ty/consts/valtree.rs47
-rw-r--r--compiler/rustc_middle/src/ty/context.rs6
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs16
-rw-r--r--compiler/rustc_middle/src/ty/error.rs37
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs135
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs2
-rw-r--r--compiler/rustc_middle/src/ty/util.rs4
-rw-r--r--compiler/rustc_mir_build/messages.ftl14
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_place.rs23
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs17
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/category.rs7
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/into.rs7
-rw-r--r--compiler/rustc_mir_build/src/builder/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/check_tail_calls.rs13
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs36
-rw-r--r--compiler/rustc_mir_build/src/errors.rs42
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/block.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs100
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs29
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs15
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs115
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs18
-rw-r--r--compiler/rustc_mir_build/src/thir/util.rs44
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs12
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs4
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs3
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs3
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs9
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs6
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs8
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs12
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs11
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs8
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs42
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs6
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs18
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs38
-rw-r--r--compiler/rustc_parse/src/parser/item.rs13
-rw-r--r--compiler/rustc_parse/src/parser/token_type.rs8
-rw-r--r--compiler/rustc_passes/src/hir_id_validator.rs4
-rw-r--r--compiler/rustc_passes/src/stability.rs154
-rw-r--r--compiler/rustc_privacy/src/lib.rs24
-rw-r--r--compiler/rustc_query_impl/src/lib.rs5
-rw-r--r--compiler/rustc_query_system/src/dep_graph/dep_node.rs39
-rw-r--r--compiler/rustc_query_system/src/query/caches.rs20
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs8
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs5
-rw-r--r--compiler/rustc_resolve/src/late.rs6
-rw-r--r--compiler/rustc_session/src/config.rs13
-rw-r--r--compiler/rustc_session/src/config/cfg.rs7
-rw-r--r--compiler/rustc_session/src/lib.rs3
-rw-r--r--compiler/rustc_session/src/options.rs339
-rw-r--r--compiler/rustc_session/src/parse.rs19
-rw-r--r--compiler/rustc_session/src/session.rs19
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs3
-rw-r--r--compiler/rustc_span/src/hygiene.rs3
-rw-r--r--compiler/rustc_span/src/lib.rs32
-rw-r--r--compiler/rustc_span/src/symbol.rs20
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs3
-rw-r--r--compiler/rustc_target/src/spec/json.rs15
-rw-r--r--compiler/rustc_target/src/spec/mod.rs49
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs5
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs3
-rw-r--r--compiler/rustc_target/src/target_features.rs54
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs93
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/note.rs422
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/region.rs10
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs9
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs28
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs91
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs11
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs12
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs119
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs107
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs21
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs8
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs2
-rw-r--r--compiler/rustc_type_ir/src/fold.rs2
-rw-r--r--compiler/rustc_type_ir/src/visit.rs2
-rw-r--r--compiler/stable_mir/src/mir/body.rs5
-rw-r--r--library/alloc/src/string.rs16
-rw-r--r--library/core/src/cell.rs84
-rw-r--r--library/core/src/cell/once.rs53
-rw-r--r--library/core/src/char/methods.rs6
-rw-r--r--library/core/src/cmp.rs170
-rw-r--r--library/core/src/contracts.rs21
-rw-r--r--library/core/src/ffi/mod.rs175
-rw-r--r--library/core/src/ffi/primitives.rs174
-rw-r--r--library/core/src/fmt/num.rs143
-rw-r--r--library/core/src/intrinsics/fallback.rs38
-rw-r--r--library/core/src/intrinsics/mod.rs72
-rw-r--r--library/core/src/lib.rs6
-rw-r--r--library/core/src/macros/mod.rs54
-rw-r--r--library/core/src/marker.rs3
-rw-r--r--library/core/src/num/nonzero.rs66
-rw-r--r--library/core/src/num/uint_macros.rs57
-rw-r--r--library/core/src/prelude/mod.rs10
-rw-r--r--library/core/src/primitive_docs.rs14
-rw-r--r--library/core/src/ptr/const_ptr.rs6
-rw-r--r--library/core/src/ptr/mut_ptr.rs5
-rw-r--r--library/core/src/range.rs3
-rw-r--r--library/core/src/str/mod.rs3
-rw-r--r--library/coretests/benches/fmt.rs13
-rw-r--r--library/std/Cargo.toml13
-rw-r--r--library/std/benches/lib.rs2
-rw-r--r--library/std/benches/path.rs114
-rw-r--r--library/std/benches/time.rs47
-rw-r--r--library/std/src/env.rs3
-rw-r--r--library/std/src/env/tests.rs120
-rw-r--r--library/std/src/error.rs3
-rw-r--r--library/std/src/f128.rs3
-rw-r--r--library/std/src/f16.rs3
-rw-r--r--library/std/src/f32.rs3
-rw-r--r--library/std/src/f64.rs3
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/macros.rs15
-rw-r--r--library/std/src/num.rs28
-rw-r--r--library/std/src/panic.rs3
-rw-r--r--library/std/src/path.rs3
-rw-r--r--library/std/src/prelude/mod.rs10
-rw-r--r--library/std/src/process.rs12
-rw-r--r--library/std/src/sync/barrier.rs3
-rw-r--r--library/std/src/sync/lazy_lock.rs3
-rw-r--r--library/std/src/sync/mpsc.rs (renamed from library/std/src/sync/mpsc/mod.rs)13
-rw-r--r--library/std/src/sync/once_lock.rs72
-rw-r--r--library/std/src/sync/poison/condvar.rs3
-rw-r--r--library/std/src/sync/poison/mutex.rs35
-rw-r--r--library/std/src/sync/poison/once.rs9
-rw-r--r--library/std/src/sync/poison/rwlock.rs3
-rw-r--r--library/std/src/sync/reentrant_lock.rs8
-rw-r--r--library/std/src/sys/pal/unix/fs.rs14
-rw-r--r--library/std/src/thread/local.rs6
-rw-r--r--library/std/src/time.rs3
-rw-r--r--library/std/tests/env.rs218
-rw-r--r--library/std/tests/env_modify.rs166
-rw-r--r--library/std/tests/error.rs (renamed from library/std/src/error/tests.rs)10
-rw-r--r--library/std/tests/floats/f128.rs (renamed from library/std/src/f128/tests.rs)10
-rw-r--r--library/std/tests/floats/f16.rs (renamed from library/std/src/f16/tests.rs)7
-rw-r--r--library/std/tests/floats/f32.rs (renamed from library/std/src/f32/tests.rs)8
-rw-r--r--library/std/tests/floats/f64.rs (renamed from library/std/src/f64/tests.rs)7
-rw-r--r--library/std/tests/floats/lib.rs42
-rw-r--r--library/std/tests/num.rs (renamed from library/std/src/num/tests.rs)6
-rw-r--r--library/std/tests/panic.rs (renamed from library/std/src/panic/tests.rs)8
-rw-r--r--library/std/tests/path.rs (renamed from library/std/src/path/tests.rs)149
-rw-r--r--library/std/tests/sync/barrier.rs (renamed from library/std/src/sync/barrier/tests.rs)6
-rw-r--r--library/std/tests/sync/condvar.rs (renamed from library/std/src/sync/poison/condvar/tests.rs)10
-rw-r--r--library/std/tests/sync/lazy_lock.rs (renamed from library/std/src/sync/lazy_lock/tests.rs)12
-rw-r--r--library/std/tests/sync/lib.rs31
-rw-r--r--library/std/tests/sync/mpmc.rs (renamed from library/std/src/sync/mpmc/tests.rs)5
-rw-r--r--library/std/tests/sync/mpsc.rs (renamed from library/std/src/sync/mpsc/tests.rs)5
-rw-r--r--library/std/tests/sync/mpsc_sync.rs (renamed from library/std/src/sync/mpsc/sync_tests.rs)9
-rw-r--r--library/std/tests/sync/mutex.rs (renamed from library/std/src/sync/poison/mutex/tests.rs)14
-rw-r--r--library/std/tests/sync/once.rs (renamed from library/std/src/sync/poison/once/tests.rs)12
-rw-r--r--library/std/tests/sync/once_lock.rs (renamed from library/std/src/sync/once_lock/tests.rs)22
-rw-r--r--library/std/tests/sync/reentrant_lock.rs (renamed from library/std/src/sync/reentrant_lock/tests.rs)7
-rw-r--r--library/std/tests/sync/rwlock.rs (renamed from library/std/src/sync/poison/rwlock/tests.rs)22
-rw-r--r--library/std/tests/thread_local/dynamic_tests.rs (renamed from library/std/src/thread/local/dynamic_tests.rs)6
-rw-r--r--library/std/tests/thread_local/lib.rs4
-rw-r--r--library/std/tests/thread_local/tests.rs (renamed from library/std/src/thread/local/tests.rs)10
-rw-r--r--library/std/tests/time.rs (renamed from library/std/src/time/tests.rs)55
-rw-r--r--src/bootstrap/src/bin/main.rs12
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/run.rs31
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs1
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs6
-rw-r--r--src/bootstrap/src/core/builder/mod.rs2
-rw-r--r--src/bootstrap/src/core/config/config.rs13
-rw-r--r--src/bootstrap/src/lib.rs87
-rw-r--r--src/bootstrap/src/utils/mod.rs2
-rw-r--r--src/bootstrap/src/utils/tracing.rs49
-rwxr-xr-xsrc/ci/docker/scripts/rfl-build.sh4
-rw-r--r--src/ci/github-actions/jobs.yml17
-rwxr-xr-xsrc/ci/scripts/free-disk-space.sh94
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs8
-rw-r--r--src/doc/rustc/src/platform-support.md40
-rw-r--r--src/doc/unstable-book/src/language-features/new-range.md9
-rw-r--r--src/librustdoc/clean/mod.rs24
-rw-r--r--src/librustdoc/clean/types.rs12
-rw-r--r--src/librustdoc/clean/utils.rs6
-rw-r--r--src/librustdoc/config.rs9
-rw-r--r--src/librustdoc/core.rs6
-rw-r--r--src/librustdoc/html/format.rs4
-rw-r--r--src/librustdoc/html/layout.rs2
-rw-r--r--src/librustdoc/html/render/context.rs4
-rw-r--r--src/librustdoc/html/render/mod.rs4
-rw-r--r--src/librustdoc/html/render/print_item.rs2
-rw-r--r--src/librustdoc/html/static/js/main.js280
-rw-r--r--src/librustdoc/html/static/js/rustdoc.d.ts22
-rw-r--r--src/librustdoc/html/static/js/search.js11
-rw-r--r--src/librustdoc/html/static/js/storage.js16
-rw-r--r--src/librustdoc/html/templates/type_layout.html2
-rw-r--r--src/librustdoc/html/templates/type_layout_size.html2
-rw-r--r--src/librustdoc/lib.rs7
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--src/rustdoc-json-types/lib.rs7
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/book/src/development/adding_lints.md2
-rw-r--r--src/tools/clippy/book/src/development/common_tools_writing_lints.md6
-rw-r--r--src/tools/clippy/book/src/development/macro_expansions.md6
-rw-r--r--src/tools/clippy/clippy_lints/src/almost_complete_range.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/as_conversions.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/box_default.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/checked_conversions.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/ctfe.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/dbg_macro.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/else_if_without_else.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/endian_bytes.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/equatable_if_let.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_nesting.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/formatting.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/result.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_return.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/items_after_statements.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/large_enum_variant.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/let_underscore.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/literal_representation.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_float_methods.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_let_else.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_range_patterns.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_replace.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/is_empty.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/min_ident_chars.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/mod.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_mut.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_if.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/new_without_default.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/non_canonical_impls.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/non_expressive_names.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/octal_escapes.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/panicking_overflow_checks.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/raw_strings.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_async_block.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_else.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_field_names.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_locals.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/single_call_fn.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/swap.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/uninhabited_references.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/uninit_vec.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_result_ok.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_trait_names.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/vec_init_then_push.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/visibility.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils/mod.rs20
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs20
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs6
-rw-r--r--src/tools/clippy/src/driver.rs5
-rw-r--r--src/tools/compiletest/src/directive-list.rs4
-rw-r--r--src/tools/compiletest/src/header.rs8
-rw-r--r--src/tools/compiletest/src/runtest.rs4
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc_json.rs3
-rw-r--r--src/tools/features-status-dump/Cargo.toml12
-rw-r--r--src/tools/features-status-dump/src/main.rs53
-rw-r--r--src/tools/miri/Cargo.lock96
-rw-r--r--src/tools/miri/Cargo.toml6
-rwxr-xr-xsrc/tools/miri/ci/ci.sh4
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs2
-rw-r--r--src/tools/miri/src/alloc_addresses/reuse_pool.rs8
-rw-r--r--src/tools/miri/src/bin/miri.rs12
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs22
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs20
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs40
-rw-r--r--src/tools/miri/src/concurrency/data_race.rs2
-rw-r--r--src/tools/miri/src/concurrency/sync.rs64
-rw-r--r--src/tools/miri/src/concurrency/thread.rs2
-rw-r--r--src/tools/miri/src/eval.rs6
-rw-r--r--src/tools/miri/src/helpers.rs65
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs6
-rw-r--r--src/tools/miri/src/intrinsics/simd.rs5
-rw-r--r--src/tools/miri/src/lib.rs3
-rw-r--r--src/tools/miri/src/machine.rs20
-rw-r--r--src/tools/miri/src/math.rs20
-rw-r--r--src/tools/miri/src/operator.rs4
-rw-r--r--src/tools/miri/src/shims/alloc.rs11
-rw-r--r--src/tools/miri/src/shims/backtrace.rs41
-rw-r--r--src/tools/miri/src/shims/extern_static.rs8
-rw-r--r--src/tools/miri/src/shims/files.rs101
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs12
-rw-r--r--src/tools/miri/src/shims/panic.rs11
-rw-r--r--src/tools/miri/src/shims/time.rs15
-rw-r--r--src/tools/miri/src/shims/unix/android/thread.rs11
-rw-r--r--src/tools/miri/src/shims/unix/fd.rs67
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs95
-rw-r--r--src/tools/miri/src/shims/unix/freebsd/foreign_items.rs6
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs89
-rw-r--r--src/tools/miri/src/shims/unix/linux/mem.rs2
-rw-r--r--src/tools/miri/src/shims/unix/linux_like/eventfd.rs37
-rw-r--r--src/tools/miri/src/shims/unix/linux_like/sync.rs52
-rw-r--r--src/tools/miri/src/shims/unix/linux_like/syscall.rs13
-rw-r--r--src/tools/miri/src/shims/unix/macos/foreign_items.rs88
-rw-r--r--src/tools/miri/src/shims/unix/macos/sync.rs218
-rw-r--r--src/tools/miri/src/shims/unix/mem.rs2
-rw-r--r--src/tools/miri/src/shims/unix/solarish/foreign_items.rs8
-rw-r--r--src/tools/miri/src/shims/unix/sync.rs15
-rw-r--r--src/tools/miri/src/shims/unix/unnamed_socket.rs60
-rw-r--r--src/tools/miri/src/shims/windows/env.rs2
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs10
-rw-r--r--src/tools/miri/src/shims/windows/sync.rs31
-rw-r--r--src/tools/miri/src/shims/windows/thread.rs2
-rw-r--r--src/tools/miri/test_dependencies/Cargo.lock31
-rw-r--r--src/tools/miri/test_dependencies/Cargo.toml3
-rw-r--r--src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/disjoint_bitor.rs5
-rw-r--r--src/tools/miri/tests/fail/intrinsics/disjoint_bitor.stderr15
-rw-r--r--src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.rs5
-rw-r--r--src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr15
-rw-r--r--src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs2
-rw-r--r--src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr4
-rw-r--r--src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.rs7
-rw-r--r--src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr15
-rw-r--r--src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-decl.rs7
-rw-r--r--src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.rs17
-rw-r--r--src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr15
-rw-r--r--src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs16
-rw-r--r--src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr15
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/apple-futex.rs276
-rw-r--r--src/tools/miri/tests/pass-dep/getrandom.rs4
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs24
-rw-r--r--src/tools/miri/tests/ui.rs73
-rw-r--r--src/tools/rustfmt/src/parse/session.rs16
-rw-r--r--src/tools/tidy/Cargo.toml4
-rw-r--r--src/tools/tidy/src/features.rs2
-rw-r--r--src/tools/tidy/src/features/version.rs1
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--src/tools/tidy/src/pal.rs3
-rw-r--r--tests/assembly/small_data_threshold.rs60
-rw-r--r--tests/codegen/bigint-helpers.rs13
-rw-r--r--tests/codegen/debug-column.rs2
-rw-r--r--tests/codegen/force-no-unwind-tables.rs2
-rw-r--r--tests/codegen/intrinsics/disjoint_bitor.rs30
-rw-r--r--tests/codegen/issues/issue-136329-optnone-noinline.rs21
-rw-r--r--tests/codegen/thread-local.rs2
-rw-r--r--tests/crashes/125810.rs10
-rw-r--r--tests/crashes/132981.rs4
-rw-r--r--tests/crashes/134355.rs6
-rw-r--r--tests/crashes/135124.rs9
-rw-r--r--tests/crashes/90110.rs57
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir10
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir10
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-abort.mir6
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir6
-rw-r--r--tests/rustdoc-json/primitives/primitive_impls.rs5
-rw-r--r--tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs5
-rw-r--r--tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr4
-rw-r--r--tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs2
-rw-r--r--tests/rustdoc/assoc-consts.rs2
-rw-r--r--tests/rustdoc/cfg_doc_reexport.rs5
-rw-r--r--tests/rustdoc/cross-crate-primitive-doc.rs5
-rw-r--r--tests/rustdoc/fn-pointer-arg-name.rs8
-rw-r--r--tests/rustdoc/inherent-projections.rs2
-rw-r--r--tests/rustdoc/inline_local/fully-stable-path-is-better.rs4
-rw-r--r--tests/rustdoc/intra-doc/no-doc-primitive.rs5
-rw-r--r--tests/rustdoc/macro-higher-kinded-function.rs8
-rw-r--r--tests/rustdoc/reexport-trait-from-hidden-111064-2.rs5
-rw-r--r--tests/rustdoc/safe-intrinsic.rs5
-rw-r--r--tests/rustdoc/stability.rs2
-rw-r--r--tests/rustdoc/type-layout.rs4
-rw-r--r--tests/ui-fulldeps/obtain-borrowck.rs1
-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_foreign.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_internal.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/smir_serde.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/smir_visitor.rs1
-rw-r--r--tests/ui/abi/abi-sysv64-arg-passing.rs3
-rw-r--r--tests/ui/abi/large-byval-align.rs1
-rw-r--r--tests/ui/associated-consts/issue-58022.stderr18
-rw-r--r--tests/ui/async-await/async-closures/is-not-fn.current.stderr2
-rw-r--r--tests/ui/async-await/async-closures/is-not-fn.next.stderr2
-rw-r--r--tests/ui/async-await/async-closures/is-not-fn.rs2
-rw-r--r--tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr2
-rw-r--r--tests/ui/async-await/issue-98634.rs6
-rw-r--r--tests/ui/async-await/issue-98634.stderr6
-rw-r--r--tests/ui/borrowck/already-borrowed-as-mutable-if-let-133941.rs46
-rw-r--r--tests/ui/borrowck/already-borrowed-as-mutable-if-let-133941.stderr89
-rw-r--r--tests/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.stderr2
-rw-r--r--tests/ui/check-cfg/cargo-build-script.stderr2
-rw-r--r--tests/ui/check-cfg/cargo-feature.none.stderr2
-rw-r--r--tests/ui/check-cfg/cargo-feature.some.stderr2
-rw-r--r--tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr2
-rw-r--r--tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr2
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.feature.stderr2
-rw-r--r--tests/ui/check-cfg/exhaustive-names-values.full.stderr2
-rw-r--r--tests/ui/check-cfg/mix.stderr2
-rw-r--r--tests/ui/check-cfg/raw-keywords.edition2015.stderr2
-rw-r--r--tests/ui/check-cfg/raw-keywords.edition2021.stderr2
-rw-r--r--tests/ui/check-cfg/report-in-external-macros.cargo.stderr2
-rw-r--r--tests/ui/check-cfg/report-in-external-macros.rustc.stderr2
-rw-r--r--tests/ui/check-cfg/target_feature.stderr2
-rw-r--r--tests/ui/check-cfg/well-known-names.stderr1
-rw-r--r--tests/ui/closures/return-type-doesnt-match-bound.rs4
-rw-r--r--tests/ui/closures/return-type-doesnt-match-bound.stderr4
-rw-r--r--tests/ui/coercion/coerce-expect-unsized-ascribed.stderr6
-rw-r--r--tests/ui/const-generics/std/const-generics-range.full.stderr4
-rw-r--r--tests/ui/const-generics/std/const-generics-range.min.stderr4
-rw-r--r--tests/ui/const-generics/std/const-generics-range.rs4
-rw-r--r--tests/ui/const-ptr/forbidden_slices.stderr4
-rw-r--r--tests/ui/consts/const-slice-array-deref.rs1
-rw-r--r--tests/ui/consts/const-slice-array-deref.stderr13
-rw-r--r--tests/ui/consts/const-unsized.rs8
-rw-r--r--tests/ui/consts/const-unsized.stderr54
-rw-r--r--tests/ui/consts/const_refs_to_static-ice-121413.rs2
-rw-r--r--tests/ui/consts/const_refs_to_static-ice-121413.stderr11
-rw-r--r--tests/ui/consts/offset_from_ub.rs10
-rw-r--r--tests/ui/consts/offset_from_ub.stderr14
-rw-r--r--tests/ui/contracts/contract-annotation-limitations.rs28
-rw-r--r--tests/ui/contracts/contract-annotation-limitations.stderr23
-rw-r--r--tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-generics.chk_pass.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-generics.rs71
-rw-r--r--tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-nest.chk_pass.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-nest.rs45
-rw-r--r--tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-tail.chk_pass.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-tail.rs43
-rw-r--r--tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr11
-rw-r--r--tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr11
-rw-r--r--tests/ui/contracts/contract-captures-via-closure-copy.rs26
-rw-r--r--tests/ui/contracts/contract-captures-via-closure-copy.stderr11
-rw-r--r--tests/ui/contracts/contract-captures-via-closure-noncopy.rs23
-rw-r--r--tests/ui/contracts/contract-captures-via-closure-noncopy.stderr36
-rw-r--r--tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr11
-rw-r--r--tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr11
-rw-r--r--tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr11
-rw-r--r--tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr11
-rw-r--r--tests/ui/contracts/contracts-ensures-early-fn-exit.rs49
-rw-r--r--tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr11
-rw-r--r--tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs15
-rw-r--r--tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr11
-rw-r--r--tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs17
-rw-r--r--tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr11
-rw-r--r--tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs53
-rw-r--r--tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr53
-rw-r--r--tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs44
-rw-r--r--tests/ui/contracts/internal_machinery/contract-ast-extensions-tail.rs42
-rw-r--r--tests/ui/contracts/internal_machinery/contract-intrinsics.rs36
-rw-r--r--tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr11
-rw-r--r--tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr11
-rw-r--r--tests/ui/contracts/internal_machinery/contract-lang-items.rs39
-rw-r--r--tests/ui/contracts/internal_machinery/contract-lang-items.unchk_fail_post.stderr11
-rw-r--r--tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr11
-rw-r--r--tests/ui/contracts/internal_machinery/contracts-lowering-ensures-is-not-inherited-when-nesting.rs15
-rw-r--r--tests/ui/contracts/internal_machinery/contracts-lowering-requires-is-not-inherited-when-nesting.rs17
-rw-r--r--tests/ui/contracts/internal_machinery/internal-feature-gating.rs20
-rw-r--r--tests/ui/contracts/internal_machinery/internal-feature-gating.stderr63
-rw-r--r--tests/ui/crate-loading/crateresolve1.rs4
-rw-r--r--tests/ui/crate-loading/crateresolve2.rs2
-rw-r--r--tests/ui/derives/rustc-decodable-issue-123156.rs11
-rw-r--r--tests/ui/derives/rustc-decodable-issue-123156.stderr10
-rw-r--r--tests/ui/diagnostic-width/E0271.ascii.stderr8
-rw-r--r--tests/ui/diagnostic-width/E0271.rs6
-rw-r--r--tests/ui/diagnostic-width/E0271.unicode.stderr8
-rw-r--r--tests/ui/diagnostic-width/long-E0308.ascii.stderr28
-rw-r--r--tests/ui/diagnostic-width/long-E0308.unicode.stderr28
-rw-r--r--tests/ui/diagnostic-width/long-e0277.rs15
-rw-r--r--tests/ui/diagnostic-width/long-e0277.stderr23
-rw-r--r--tests/ui/diagnostic-width/non-copy-type-moved.stderr4
-rw-r--r--tests/ui/diagnostic-width/secondary-label-with-long-type.rs2
-rw-r--r--tests/ui/diagnostic-width/secondary-label-with-long-type.stderr2
-rw-r--r--tests/ui/error-codes/E0462.rs2
-rw-r--r--tests/ui/error-codes/E0464.rs2
-rw-r--r--tests/ui/error-codes/E0523.rs2
-rw-r--r--tests/ui/error-codes/E0746.stderr4
-rw-r--r--tests/ui/error-codes/E0789.rs2
-rw-r--r--tests/ui/error-emitter/E0308-clarification.rs16
-rw-r--r--tests/ui/error-emitter/E0308-clarification.svg97
-rw-r--r--tests/ui/extern-flag/empty-extern-arg.stderr4
-rw-r--r--tests/ui/feature-gates/feature-gate-cfg-contract-checks.rs5
-rw-r--r--tests/ui/feature-gates/feature-gate-cfg-contract-checks.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-contracts.rs11
-rw-r--r--tests/ui/feature-gates/feature-gate-contracts.stderr43
-rw-r--r--tests/ui/feature-gates/feature-gate-keylocker_x86.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-keylocker_x86.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-new_range.rs10
-rw-r--r--tests/ui/feature-gates/feature-gate-new_range.stderr48
-rw-r--r--tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.rs16
-rw-r--r--tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.stderr66
-rw-r--r--tests/ui/fn/error-recovery-mismatch.rs20
-rw-r--r--tests/ui/fn/error-recovery-mismatch.stderr46
-rw-r--r--tests/ui/fn/fn-pointer-mismatch.stderr2
-rw-r--r--tests/ui/fn/param-mismatch-trait-fn.rs10
-rw-r--r--tests/ui/fn/param-mismatch-trait-fn.stderr23
-rw-r--r--tests/ui/force-inlining/cast.stderr4
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr2
-rw-r--r--tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.rs2
-rw-r--r--tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr37
-rw-r--r--tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs2
-rw-r--r--tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr198
-rw-r--r--tests/ui/impl-trait/impl-trait-in-macro.stderr4
-rw-r--r--tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs6
-rw-r--r--tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr115
-rw-r--r--tests/ui/impl-trait/universal-two-impl-traits.stderr4
-rw-r--r--tests/ui/inference/issue-71584.rs2
-rw-r--r--tests/ui/intrinsics/const-eval-select-bad.rs2
-rw-r--r--tests/ui/intrinsics/const-eval-select-bad.stderr2
-rw-r--r--tests/ui/issues/issue-17954.stderr2
-rw-r--r--tests/ui/issues/issue-18107.rs2
-rw-r--r--tests/ui/issues/issue-18107.stderr2
-rw-r--r--tests/ui/issues/issue-5883.rs2
-rw-r--r--tests/ui/issues/issue-5883.stderr16
-rw-r--r--tests/ui/issues/issue-76191.stderr4
-rw-r--r--tests/ui/json/json-multiple.rs1
-rw-r--r--tests/ui/json/json-options.rs1
-rw-r--r--tests/ui/lang-items/lang-item-missing.stderr4
-rw-r--r--tests/ui/lazy-type-alias/def-site-param-defaults-wf.rs9
-rw-r--r--tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr20
-rw-r--r--tests/ui/lazy-type-alias/def-site-predicates-wf.rs13
-rw-r--r--tests/ui/lazy-type-alias/def-site-predicates-wf.stderr23
-rw-r--r--tests/ui/lifetimes/tail-expr-lock-poisoning.rs1
-rw-r--r--tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs3
-rw-r--r--tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs1
-rw-r--r--tests/ui/lint/issue-106991.rs2
-rw-r--r--tests/ui/lint/issue-106991.stderr2
-rw-r--r--tests/ui/logging-only-prints-once.rs1
-rw-r--r--tests/ui/lto/weak-works.rs3
-rw-r--r--tests/ui/methods/issues/issue-61525.stderr2
-rw-r--r--tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed4
-rw-r--r--tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr16
-rw-r--r--tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs4
-rw-r--r--tests/ui/never_type/fallback-closure-wrap.fallback.stderr2
-rw-r--r--tests/ui/never_type/fallback-closure-wrap.rs2
-rw-r--r--tests/ui/never_type/issue-52443.stderr4
-rw-r--r--tests/ui/new-range/disabled.rs27
-rw-r--r--tests/ui/new-range/enabled.rs24
-rw-r--r--tests/ui/nll/get_default.legacy.stderr18
-rw-r--r--tests/ui/nll/get_default.nll.stderr (renamed from tests/ui/nll/get_default.stderr)10
-rw-r--r--tests/ui/nll/get_default.polonius.stderr18
-rw-r--r--tests/ui/nll/get_default.rs17
-rw-r--r--tests/ui/nll/issue-46589.nll.stderr (renamed from tests/ui/nll/issue-46589.stderr)2
-rw-r--r--tests/ui/nll/issue-46589.rs13
-rw-r--r--tests/ui/nll/polonius/assignment-kills-loans.rs5
-rw-r--r--tests/ui/nll/polonius/assignment-to-differing-field.legacy.stderr (renamed from tests/ui/nll/polonius/assignment-to-differing-field.stderr)8
-rw-r--r--tests/ui/nll/polonius/assignment-to-differing-field.polonius.stderr51
-rw-r--r--tests/ui/nll/polonius/assignment-to-differing-field.rs5
-rw-r--r--tests/ui/nll/polonius/call-kills-loans.rs5
-rw-r--r--tests/ui/nll/polonius/issue-46589.rs31
-rw-r--r--tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs6
-rw-r--r--tests/ui/nll/polonius/polonius-smoke-test.legacy.stderr (renamed from tests/ui/nll/polonius/polonius-smoke-test.stderr)8
-rw-r--r--tests/ui/nll/polonius/polonius-smoke-test.polonius.stderr59
-rw-r--r--tests/ui/nll/polonius/polonius-smoke-test.rs8
-rw-r--r--tests/ui/nll/polonius/storagedead-kills-loans.rs5
-rw-r--r--tests/ui/nll/polonius/subset-relations.legacy.stderr (renamed from tests/ui/nll/polonius/subset-relations.stderr)2
-rw-r--r--tests/ui/nll/polonius/subset-relations.polonius.stderr14
-rw-r--r--tests/ui/nll/polonius/subset-relations.rs7
-rw-r--r--tests/ui/panics/issue-47429-short-backtraces.rs2
-rw-r--r--tests/ui/panics/issue-47429-short-backtraces.run.stderr2
-rw-r--r--tests/ui/panics/runtime-switch.rs1
-rw-r--r--tests/ui/panics/runtime-switch.run.stderr2
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames-2.rs1
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr2
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames.rs1
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames.run.stderr2
-rw-r--r--tests/ui/parser/mod_file_not_exist.rs2
-rw-r--r--tests/ui/parser/mod_file_not_exist.stderr4
-rw-r--r--tests/ui/privacy/privacy2.rs4
-rw-r--r--tests/ui/privacy/privacy2.stderr38
-rw-r--r--tests/ui/privacy/privacy3.rs4
-rw-r--r--tests/ui/privacy/privacy3.stderr32
-rw-r--r--tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr6
-rw-r--r--tests/ui/range/issue-54505-no-literals.stderr8
-rw-r--r--tests/ui/range/issue-54505.stderr4
-rw-r--r--tests/ui/range/range-1.stderr2
-rw-r--r--tests/ui/self/dispatch-from-dyn-layout-2.rs16
-rw-r--r--tests/ui/self/dispatch-from-dyn-layout-3.rs19
-rw-r--r--tests/ui/self/dispatch-from-dyn-layout.rs (renamed from tests/crashes/57276.rs)6
-rw-r--r--tests/ui/simd/array-trait.rs10
-rw-r--r--tests/ui/simd/array-type.rs10
-rw-r--r--tests/ui/simd/generics.rs5
-rw-r--r--tests/ui/simd/intrinsic/float-math-pass.rs74
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-2.rs67
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-2.stderr48
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-pass.rs67
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs10
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr4
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs10
-rw-r--r--tests/ui/simd/intrinsic/generic-as.rs6
-rw-r--r--tests/ui/simd/intrinsic/generic-bitmask-pass.rs5
-rw-r--r--tests/ui/simd/intrinsic/generic-bitmask.rs5
-rw-r--r--tests/ui/simd/intrinsic/generic-bitmask.stderr10
-rw-r--r--tests/ui/simd/intrinsic/generic-bswap-byte.rs5
-rw-r--r--tests/ui/simd/intrinsic/generic-cast-pass.rs6
-rw-r--r--tests/ui/simd/intrinsic/generic-cast-pointer-width.rs5
-rw-r--r--tests/ui/simd/intrinsic/generic-cast.rs5
-rw-r--r--tests/ui/simd/intrinsic/generic-cast.stderr8
-rw-r--r--tests/ui/simd/intrinsic/generic-comparison-pass.rs26
-rw-r--r--tests/ui/simd/intrinsic/generic-comparison.rs26
-rw-r--r--tests/ui/simd/intrinsic/generic-comparison.stderr36
-rw-r--r--tests/ui/simd/intrinsic/generic-elements-pass.rs13
-rw-r--r--tests/ui/simd/intrinsic/generic-elements.rs19
-rw-r--r--tests/ui/simd/intrinsic/generic-elements.stderr42
-rw-r--r--tests/ui/simd/intrinsic/generic-gather-pass.rs9
-rw-r--r--tests/ui/simd/intrinsic/generic-reduction-pass.rs45
-rw-r--r--tests/ui/simd/intrinsic/generic-reduction.rs28
-rw-r--r--tests/ui/simd/intrinsic/generic-reduction.stderr20
-rw-r--r--tests/ui/simd/intrinsic/generic-select-pass.rs10
-rw-r--r--tests/ui/simd/intrinsic/generic-select.rs11
-rw-r--r--tests/ui/simd/intrinsic/generic-select.stderr16
-rw-r--r--tests/ui/simd/intrinsic/generic-shuffle.rs6
-rw-r--r--tests/ui/simd/intrinsic/inlining-issue67557-ice.rs5
-rw-r--r--tests/ui/simd/intrinsic/inlining-issue67557.rs5
-rw-r--r--tests/ui/simd/intrinsic/issue-85855.rs21
-rw-r--r--tests/ui/simd/intrinsic/issue-85855.stderr18
-rw-r--r--tests/ui/simd/intrinsic/ptr-cast.rs14
-rw-r--r--tests/ui/simd/issue-105439.rs5
-rw-r--r--tests/ui/simd/issue-39720.rs5
-rw-r--r--tests/ui/simd/issue-85915-simd-ptrs.rs10
-rw-r--r--tests/ui/simd/issue-89193.rs5
-rw-r--r--tests/ui/simd/masked-load-store-build-fail.rs10
-rw-r--r--tests/ui/simd/masked-load-store-build-fail.stderr16
-rw-r--r--tests/ui/simd/masked-load-store-check-fail.rs9
-rw-r--r--tests/ui/simd/masked-load-store-check-fail.stderr20
-rw-r--r--tests/ui/simd/masked-load-store.rs9
-rw-r--r--tests/ui/simd/monomorphize-shuffle-index.generic.stderr2
-rw-r--r--tests/ui/simd/monomorphize-shuffle-index.rs15
-rw-r--r--tests/ui/simd/repr_packed.rs5
-rw-r--r--tests/ui/simd/shuffle.rs5
-rw-r--r--tests/ui/simd/simd-bitmask-notpow2.rs10
-rw-r--r--tests/ui/simd/simd-bitmask.rs10
-rw-r--r--tests/ui/stability-attribute/allowed-through-unstable.rs3
-rw-r--r--tests/ui/stability-attribute/allowed-through-unstable.stderr8
-rw-r--r--tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs6
-rw-r--r--tests/ui/static/issue-24446.rs1
-rw-r--r--tests/ui/static/issue-24446.stderr16
-rw-r--r--tests/ui/statics/unsized_type2.stderr14
-rw-r--r--tests/ui/suggestions/box-future-wrong-output.stderr2
-rw-r--r--tests/ui/suggestions/dont-suggest-boxing-async-closure-body.rs2
-rw-r--r--tests/ui/suggestions/dont-suggest-boxing-async-closure-body.stderr2
-rw-r--r--tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr24
-rw-r--r--tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr2
-rw-r--r--tests/ui/suggestions/issue-107860.stderr2
-rw-r--r--tests/ui/suggestions/missing-lifetime-specifier.rs1
-rw-r--r--tests/ui/suggestions/missing-lifetime-specifier.stderr18
-rw-r--r--tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr2
-rw-r--r--tests/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr2
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs1
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr2
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs14
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs3
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs1
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs2
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs12
-rw-r--r--tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.stderr11
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-attribute.rs7
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-attribute.stderr8
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-cfg.rs9
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-flag-disable.rs8
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-flag-disable.stderr2
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-flag.rs8
-rw-r--r--tests/ui/target-feature/forbidden-target-feature-flag.stderr2
-rw-r--r--tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs20
-rw-r--r--tests/ui/target_modifiers/auxiliary/wrong_regparm.rs20
-rw-r--r--tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs20
-rw-r--r--tests/ui/target_modifiers/defaults_check.error.stderr13
-rw-r--r--tests/ui/target_modifiers/defaults_check.rs27
-rw-r--r--tests/ui/target_modifiers/incompatible_regparm.allow_no_value.stderr2
-rw-r--r--tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr13
-rw-r--r--tests/ui/target_modifiers/incompatible_regparm.rs23
-rw-r--r--tests/ui/target_modifiers/two_flags.rs23
-rw-r--r--tests/ui/target_modifiers/two_flags.unknown_allowed.stderr8
-rw-r--r--tests/ui/test-attrs/test-panic-abort-disabled.rs2
-rw-r--r--tests/ui/test-attrs/test-panic-abort-nocapture.rs2
-rw-r--r--tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr4
-rw-r--r--tests/ui/test-attrs/test-panic-abort.rs2
-rw-r--r--tests/ui/test-attrs/test-panic-abort.run.stdout2
-rw-r--r--tests/ui/threads-sendsync/spawning-with-debug.rs1
-rw-r--r--tests/ui/threads-sendsync/thread-local-extern-static.rs2
-rw-r--r--tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs1
-rw-r--r--tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr15
-rw-r--r--tests/ui/traits/const-traits/span-bug-issue-121418.stderr22
-rw-r--r--tests/ui/traits/ice-with-dyn-pointee-errors.stderr2
-rw-r--r--tests/ui/traits/issue-52893.stderr2
-rw-r--r--tests/ui/traits/issue-77982.rs5
-rw-r--r--tests/ui/traits/issue-77982.stderr14
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs7
-rw-r--r--tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr26
-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.stderr6
-rw-r--r--tests/ui/traits/object/pretty.stderr4
-rw-r--r--tests/ui/traits/on_unimplemented_long_types.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98604.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98604.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98608.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98608.stderr2
-rw-r--r--tests/ui/type/pattern_types/assoc_const.default.stderr36
-rw-r--r--tests/ui/type/pattern_types/assoc_const.rs24
-rw-r--r--tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs10
-rw-r--r--tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr42
-rw-r--r--tests/ui/type/pattern_types/bad_pat.rs2
-rw-r--r--tests/ui/type/pattern_types/bad_pat.stderr2
-rw-r--r--tests/ui/type/pattern_types/chars.rs12
-rw-r--r--tests/ui/type/pattern_types/const_block.rs10
-rw-r--r--tests/ui/type/pattern_types/const_block.stderr72
-rw-r--r--tests/ui/type/pattern_types/free_const.rs13
-rw-r--r--tests/ui/type/pattern_types/nested.rs30
-rw-r--r--tests/ui/type/pattern_types/nested.stderr96
-rw-r--r--tests/ui/type/pattern_types/pattern_type_mismatch.rs16
-rw-r--r--tests/ui/type/pattern_types/pattern_type_mismatch.stderr37
-rw-r--r--tests/ui/type/pattern_types/reverse_range.rs14
-rw-r--r--tests/ui/type/pattern_types/reverse_range.stderr17
-rw-r--r--tests/ui/type/pattern_types/unimplemented_pat.rs8
-rw-r--r--tests/ui/type/pattern_types/unimplemented_pat.stderr21
-rw-r--r--tests/ui/type/pattern_types/validity.rs37
-rw-r--r--tests/ui/type/pattern_types/validity.stderr79
-rw-r--r--tests/ui/typeck/issue-105946.rs1
-rw-r--r--tests/ui/typeck/issue-105946.stderr23
-rw-r--r--tests/ui/typeck/issue-107775.stderr2
-rw-r--r--tests/ui/typeck/issue-43189.rs1
-rw-r--r--tests/ui/typeck/issue-43189.stderr2
-rw-r--r--tests/ui/typeck/issue-46112.rs1
-rw-r--r--tests/ui/typeck/issue-46112.stderr4
-rw-r--r--tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs4
-rw-r--r--tests/ui/typeck/return_type_containing_closure.rs2
-rw-r--r--tests/ui/typeck/return_type_containing_closure.stderr2
-rw-r--r--tests/ui/unsafe-binders/expr.rs4
-rw-r--r--tests/ui/unsafe-binders/expr.stderr16
-rw-r--r--tests/ui/unsafe-binders/mismatch.rs17
-rw-r--r--tests/ui/unsafe-binders/mismatch.stderr47
-rw-r--r--tests/ui/unsafe-binders/moves.rs41
-rw-r--r--tests/ui/unsafe-binders/moves.stderr85
-rw-r--r--tests/ui/unsized/box-instead-of-dyn-fn.rs2
-rw-r--r--tests/ui/unsized/box-instead-of-dyn-fn.stderr2
-rw-r--r--tests/ui/unsized/issue-91801.rs2
-rw-r--r--tests/ui/unsized/issue-91801.stderr2
-rw-r--r--tests/ui/unsized/issue-91803.rs2
-rw-r--r--tests/ui/unsized/issue-91803.stderr2
-rw-r--r--tests/ui/where-clauses/ignore-err-clauses.rs1
-rw-r--r--tests/ui/where-clauses/ignore-err-clauses.stderr13
984 files changed, 12006 insertions, 6781 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 75c6ab37bd1..18d5b66eb73 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -43,7 +43,7 @@ dependencies = [
  "cfg-if",
  "once_cell",
  "version_check",
- "zerocopy",
+ "zerocopy 0.7.35",
 ]
 
 [[package]]
@@ -186,6 +186,9 @@ name = "anyhow"
 version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+dependencies = [
+ "backtrace",
+]
 
 [[package]]
 name = "ar_archive_writer"
@@ -567,7 +570,7 @@ dependencies = [
  "termize",
  "tokio",
  "toml 0.7.8",
- "ui_test",
+ "ui_test 0.26.5",
  "walkdir",
 ]
 
@@ -1196,6 +1199,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
 
 [[package]]
+name = "features-status-dump"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "clap",
+ "serde",
+ "serde_json",
+ "tidy",
+]
+
+[[package]]
 name = "field-offset"
 version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1442,7 +1456,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
 dependencies = [
  "cfg-if",
  "libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.13.3+wasi-0.2.2",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -2342,18 +2368,18 @@ dependencies = [
  "chrono-tz",
  "colored",
  "directories",
- "getrandom",
+ "getrandom 0.3.1",
  "libc",
  "libffi",
  "libloading",
  "measureme",
- "rand",
+ "rand 0.9.0",
  "regex",
  "rustc_version",
  "smallvec",
  "tempfile",
  "tikv-jemalloc-sys",
- "ui_test",
+ "ui_test 0.28.0",
  "windows-sys 0.52.0",
 ]
 
@@ -2782,7 +2808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
 dependencies = [
  "phf_shared 0.10.0",
- "rand",
+ "rand 0.8.5",
 ]
 
 [[package]]
@@ -2792,7 +2818,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
 dependencies = [
  "phf_shared 0.11.3",
- "rand",
+ "rand 0.8.5",
 ]
 
 [[package]]
@@ -2860,7 +2886,7 @@ version = "0.2.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
 dependencies = [
- "zerocopy",
+ "zerocopy 0.7.35",
 ]
 
 [[package]]
@@ -2978,8 +3004,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 dependencies = [
  "libc",
- "rand_chacha",
- "rand_core",
+ "rand_chacha 0.3.1",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
+dependencies = [
+ "rand_chacha 0.9.0",
+ "rand_core 0.9.0",
+ "zerocopy 0.8.14",
 ]
 
 [[package]]
@@ -2989,7 +3026,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
 dependencies = [
  "ppv-lite86",
- "rand_core",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.9.0",
 ]
 
 [[package]]
@@ -2998,7 +3045,17 @@ version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
+dependencies = [
+ "getrandom 0.3.1",
+ "zerocopy 0.8.14",
 ]
 
 [[package]]
@@ -3007,7 +3064,7 @@ version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
 dependencies = [
- "rand_core",
+ "rand_core 0.6.4",
 ]
 
 [[package]]
@@ -3045,7 +3102,7 @@ version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
 dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
  "libredox",
  "thiserror 1.0.69",
 ]
@@ -3283,7 +3340,7 @@ name = "rustc_abi"
 version = "0.0.0"
 dependencies = [
  "bitflags",
- "rand",
+ "rand 0.8.5",
  "rand_xoshiro",
  "rustc_data_structures",
  "rustc_feature",
@@ -3897,7 +3954,7 @@ dependencies = [
 name = "rustc_incremental"
 version = "0.0.0"
 dependencies = [
- "rand",
+ "rand 0.8.5",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_errors",
@@ -5218,7 +5275,7 @@ checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
 dependencies = [
  "cfg-if",
  "fastrand",
- "getrandom",
+ "getrandom 0.2.15",
  "once_cell",
  "rustix",
  "windows-sys 0.59.0",
@@ -5281,8 +5338,8 @@ version = "0.1.0"
 dependencies = [
  "indicatif",
  "num",
- "rand",
- "rand_chacha",
+ "rand 0.8.5",
+ "rand_chacha 0.3.1",
  "rayon",
 ]
 
@@ -5375,6 +5432,7 @@ dependencies = [
  "regex",
  "rustc-hash 2.1.0",
  "semver",
+ "serde",
  "similar",
  "termcolor",
  "walkdir",
@@ -5602,7 +5660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
 dependencies = [
  "cfg-if",
- "rand",
+ "rand 0.8.5",
  "static_assertions",
 ]
 
@@ -5663,6 +5721,32 @@ dependencies = [
 ]
 
 [[package]]
+name = "ui_test"
+version = "0.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7484683d60d50ca1d1b6433c3dbf6c5ad71d20387acdcfb16fe79573f3fba576"
+dependencies = [
+ "annotate-snippets 0.11.5",
+ "anyhow",
+ "bstr",
+ "cargo-platform",
+ "cargo_metadata 0.18.1",
+ "color-eyre",
+ "colored",
+ "comma",
+ "crossbeam-channel",
+ "indicatif",
+ "levenshtein",
+ "prettydiff",
+ "regex",
+ "rustc_version",
+ "rustfix",
+ "serde",
+ "serde_json",
+ "spanned",
+]
+
+[[package]]
 name = "unic-langid"
 version = "0.9.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5843,7 +5927,7 @@ version = "1.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4"
 dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
 ]
 
 [[package]]
@@ -5881,6 +5965,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
+name = "wasi"
+version = "0.13.3+wasi-0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
+[[package]]
 name = "wasi-preview1-component-adapter-provider"
 version = "29.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6476,6 +6569,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3ab703352da6a72f35c39a533526393725640575bb211f61987a2748323ad956"
 
 [[package]]
+name = "wit-bindgen-rt"
+version = "0.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
 name = "wit-component"
 version = "0.223.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6584,7 +6686,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
 dependencies = [
  "byteorder",
- "zerocopy-derive",
+ "zerocopy-derive 0.7.35",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.8.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468"
+dependencies = [
+ "zerocopy-derive 0.8.14",
 ]
 
 [[package]]
@@ -6599,6 +6710,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "zerocopy-derive"
+version = "0.8.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
 name = "zerofrom"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index b773030b4ca..68d142ebe92 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -47,6 +47,7 @@ members = [
   "src/tools/coverage-dump",
   "src/tools/rustc-perf-wrapper",
   "src/tools/wasm-component-ld",
+  "src/tools/features-status-dump",
 ]
 
 exclude = [
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index ad942e9b494..08621c1c56a 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1657,7 +1657,7 @@ impl GenBlockKind {
 }
 
 /// Whether we're unwrapping or wrapping an unsafe binder
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 #[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum UnsafeBinderCastKind {
     // e.g. `&i32` -> `unsafe<'a> &'a i32`
@@ -3348,11 +3348,18 @@ pub struct Impl {
     pub items: ThinVec<P<AssocItem>>,
 }
 
+#[derive(Clone, Encodable, Decodable, Debug, Default)]
+pub struct FnContract {
+    pub requires: Option<P<Expr>>,
+    pub ensures: Option<P<Expr>>,
+}
+
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Fn {
     pub defaultness: Defaultness,
     pub generics: Generics,
     pub sig: FnSig,
+    pub contract: Option<P<FnContract>>,
     pub body: Option<P<Block>>,
 }
 
@@ -3650,7 +3657,7 @@ mod size_asserts {
     static_assert_size!(Block, 32);
     static_assert_size!(Expr, 72);
     static_assert_size!(ExprKind, 40);
-    static_assert_size!(Fn, 160);
+    static_assert_size!(Fn, 168);
     static_assert_size!(ForeignItem, 88);
     static_assert_size!(ForeignItemKind, 16);
     static_assert_size!(GenericArg, 24);
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 7caf7c4c356..70616fe8769 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -143,6 +143,10 @@ pub trait MutVisitor: Sized {
         walk_flat_map_assoc_item(self, i, ctxt)
     }
 
+    fn visit_contract(&mut self, c: &mut P<FnContract>) {
+        walk_contract(self, c);
+    }
+
     fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) {
         walk_fn_decl(self, d);
     }
@@ -958,13 +962,16 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
             _ctxt,
             _ident,
             _vis,
-            Fn { defaultness, generics, body, sig: FnSig { header, decl, span } },
+            Fn { defaultness, generics, contract, body, sig: FnSig { header, decl, span } },
         ) => {
             // Identifier and visibility are visited as a part of the item.
             visit_defaultness(vis, defaultness);
             vis.visit_fn_header(header);
             vis.visit_generics(generics);
             vis.visit_fn_decl(decl);
+            if let Some(contract) = contract {
+                vis.visit_contract(contract);
+            }
             if let Some(body) = body {
                 vis.visit_block(body);
             }
@@ -979,6 +986,16 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
     }
 }
 
+fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut P<FnContract>) {
+    let FnContract { requires, ensures } = contract.deref_mut();
+    if let Some(pred) = requires {
+        vis.visit_expr(pred);
+    }
+    if let Some(pred) = ensures {
+        vis.visit_expr(pred);
+    }
+}
+
 fn walk_fn_decl<T: MutVisitor>(vis: &mut T, decl: &mut P<FnDecl>) {
     let FnDecl { inputs, output } = decl.deref_mut();
     inputs.flat_map_in_place(|param| vis.flat_map_param(param));
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 232fd546de9..714b074f930 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -188,6 +188,9 @@ pub trait Visitor<'ast>: Sized {
     fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) -> Self::Result {
         walk_closure_binder(self, b)
     }
+    fn visit_contract(&mut self, c: &'ast FnContract) -> Self::Result {
+        walk_contract(self, c)
+    }
     fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result {
         walk_where_predicate(self, p)
     }
@@ -800,6 +803,17 @@ pub fn walk_closure_binder<'a, V: Visitor<'a>>(
     V::Result::output()
 }
 
+pub fn walk_contract<'a, V: Visitor<'a>>(visitor: &mut V, c: &'a FnContract) -> V::Result {
+    let FnContract { requires, ensures } = c;
+    if let Some(pred) = requires {
+        visitor.visit_expr(pred);
+    }
+    if let Some(pred) = ensures {
+        visitor.visit_expr(pred);
+    }
+    V::Result::output()
+}
+
 pub fn walk_where_predicate<'a, V: Visitor<'a>>(
     visitor: &mut V,
     predicate: &'a WherePredicate,
@@ -862,12 +876,13 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
             _ctxt,
             _ident,
             _vis,
-            Fn { defaultness: _, sig: FnSig { header, decl, span: _ }, generics, body },
+            Fn { defaultness: _, sig: FnSig { header, decl, span: _ }, generics, contract, body },
         ) => {
             // Identifier and visibility are visited as a part of the item.
             try_visit!(visitor.visit_fn_header(header));
             try_visit!(visitor.visit_generics(generics));
             try_visit!(visitor.visit_fn_decl(decl));
+            visit_opt!(visitor, visit_contract, contract);
             visit_opt!(visitor, visit_block, body);
         }
         FnKind::Closure(binder, coroutine_kind, decl, body) => {
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 1267281f73e..89d5b5a75a2 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -284,9 +284,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ExprKind::Index(el, er, brackets_span) => {
                     hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er), *brackets_span)
                 }
-                ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => {
-                    self.lower_expr_range_closed(e.span, e1, e2)
-                }
                 ExprKind::Range(e1, e2, lims) => {
                     self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), *lims)
                 }
@@ -314,8 +311,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     hir::ExprKind::Continue(self.lower_jump_destination(e.id, *opt_label))
                 }
                 ExprKind::Ret(e) => {
-                    let e = e.as_ref().map(|x| self.lower_expr(x));
-                    hir::ExprKind::Ret(e)
+                    let expr = e.as_ref().map(|x| self.lower_expr(x));
+                    self.checked_return(expr)
                 }
                 ExprKind::Yeet(sub_expr) => self.lower_expr_yeet(e.span, sub_expr.as_deref()),
                 ExprKind::Become(sub_expr) => {
@@ -382,6 +379,32 @@ impl<'hir> LoweringContext<'_, 'hir> {
         })
     }
 
+    /// Create an `ExprKind::Ret` that is preceded by a call to check contract ensures clause.
+    fn checked_return(&mut self, opt_expr: Option<&'hir hir::Expr<'hir>>) -> hir::ExprKind<'hir> {
+        let checked_ret = if let Some(Some((span, fresh_ident))) =
+            self.contract.as_ref().map(|c| c.ensures.as_ref().map(|e| (e.expr.span, e.fresh_ident)))
+        {
+            let expr = opt_expr.unwrap_or_else(|| self.expr_unit(span));
+            Some(self.inject_ensures_check(expr, span, fresh_ident.0, fresh_ident.2))
+        } else {
+            opt_expr
+        };
+        hir::ExprKind::Ret(checked_ret)
+    }
+
+    /// Wraps an expression with a call to the ensures check before it gets returned.
+    pub(crate) fn inject_ensures_check(
+        &mut self,
+        expr: &'hir hir::Expr<'hir>,
+        span: Span,
+        check_ident: Ident,
+        check_hir_id: HirId,
+    ) -> &'hir hir::Expr<'hir> {
+        let checker_fn = self.expr_ident(span, check_ident, check_hir_id);
+        let span = self.mark_span_with_reason(DesugaringKind::Contract, span, None);
+        self.expr_call(span, checker_fn, std::slice::from_ref(expr))
+    }
+
     pub(crate) fn lower_const_block(&mut self, c: &AnonConst) -> hir::ConstBlock {
         self.with_new_scopes(c.value.span, |this| {
             let def_id = this.local_def_id(c.id);
@@ -1512,15 +1535,39 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
         let lang_item = match (e1, e2, lims) {
             (None, None, HalfOpen) => hir::LangItem::RangeFull,
-            (Some(..), None, HalfOpen) => hir::LangItem::RangeFrom,
+            (Some(..), None, HalfOpen) => {
+                if self.tcx.features().new_range() {
+                    hir::LangItem::RangeFromCopy
+                } else {
+                    hir::LangItem::RangeFrom
+                }
+            }
             (None, Some(..), HalfOpen) => hir::LangItem::RangeTo,
-            (Some(..), Some(..), HalfOpen) => hir::LangItem::Range,
+            (Some(..), Some(..), HalfOpen) => {
+                if self.tcx.features().new_range() {
+                    hir::LangItem::RangeCopy
+                } else {
+                    hir::LangItem::Range
+                }
+            }
             (None, Some(..), Closed) => hir::LangItem::RangeToInclusive,
-            (Some(..), Some(..), Closed) => unreachable!(),
+            (Some(e1), Some(e2), Closed) => {
+                if self.tcx.features().new_range() {
+                    hir::LangItem::RangeInclusiveCopy
+                } else {
+                    return self.lower_expr_range_closed(span, e1, e2);
+                }
+            }
             (start, None, Closed) => {
                 self.dcx().emit_err(InclusiveRangeWithNoEnd { span });
                 match start {
-                    Some(..) => hir::LangItem::RangeFrom,
+                    Some(..) => {
+                        if self.tcx.features().new_range() {
+                            hir::LangItem::RangeFromCopy
+                        } else {
+                            hir::LangItem::RangeFrom
+                        }
+                    }
                     None => hir::LangItem::RangeFull,
                 }
             }
@@ -1970,7 +2017,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     ),
                 ))
             } else {
-                self.arena.alloc(self.expr(try_span, hir::ExprKind::Ret(Some(from_residual_expr))))
+                let ret_expr = self.checked_return(Some(from_residual_expr));
+                self.arena.alloc(self.expr(try_span, ret_expr))
             };
             self.lower_attrs(ret_expr.hir_id, &attrs);
 
@@ -2019,7 +2067,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             let target_id = Ok(catch_id);
             hir::ExprKind::Break(hir::Destination { label: None, target_id }, Some(from_yeet_expr))
         } else {
-            hir::ExprKind::Ret(Some(from_yeet_expr))
+            self.checked_return(Some(from_yeet_expr))
         }
     }
 
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index f8fb21d5cd0..d1e23bf2522 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -412,8 +412,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         });
     }
 
-    fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
-        self.visit_pat(p)
+    fn visit_pattern_type_pattern(&mut self, pat: &'hir hir::TyPat<'hir>) {
+        self.insert(pat.span, pat.hir_id, Node::TyPat(pat));
+
+        self.with_parent(pat.hir_id, |this| {
+            intravisit::walk_ty_pat(this, pat);
+        });
     }
 
     fn visit_precise_capturing_arg(
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 74870d74150..c96110fee61 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -207,9 +207,40 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 sig: FnSig { decl, header, span: fn_sig_span },
                 generics,
                 body,
+                contract,
                 ..
             }) => {
                 self.with_new_scopes(*fn_sig_span, |this| {
+                    assert!(this.contract.is_none());
+                    if let Some(contract) = contract {
+                        let requires = contract.requires.clone();
+                        let ensures = contract.ensures.clone();
+                        let ensures = ensures.map(|ens| {
+                            // FIXME: this needs to be a fresh (or illegal) identifier to prevent
+                            // accidental capture of a parameter or global variable.
+                            let checker_ident: Ident =
+                                Ident::from_str_and_span("__ensures_checker", ens.span);
+                            let (checker_pat, checker_hir_id) = this.pat_ident_binding_mode_mut(
+                                ens.span,
+                                checker_ident,
+                                hir::BindingMode::NONE,
+                            );
+
+                            crate::FnContractLoweringEnsures {
+                                expr: ens,
+                                fresh_ident: (checker_ident, checker_pat, checker_hir_id),
+                            }
+                        });
+
+                        // Note: `with_new_scopes` will reinstall the outer
+                        // item's contract (if any) after its callback finishes.
+                        this.contract.replace(crate::FnContractLoweringInfo {
+                            span,
+                            requires,
+                            ensures,
+                        });
+                    }
+
                     // Note: we don't need to change the return type from `T` to
                     // `impl Future<Output = T>` here because lower_body
                     // only cares about the input argument patterns in the function
@@ -1054,10 +1085,64 @@ impl<'hir> LoweringContext<'_, 'hir> {
         body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
     ) -> hir::BodyId {
         self.lower_body(|this| {
-            (
-                this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x))),
-                body(this),
-            )
+            let params =
+                this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x)));
+            let result = body(this);
+
+            let opt_contract = this.contract.take();
+
+            // { body }
+            // ==>
+            // { contract_requires(PRECOND); { body } }
+            let Some(contract) = opt_contract else { return (params, result) };
+            let result_ref = this.arena.alloc(result);
+            let lit_unit = |this: &mut LoweringContext<'_, 'hir>| {
+                this.expr(contract.span, hir::ExprKind::Tup(&[]))
+            };
+
+            let precond: hir::Stmt<'hir> = if let Some(req) = contract.requires {
+                let lowered_req = this.lower_expr_mut(&req);
+                let precond = this.expr_call_lang_item_fn_mut(
+                    req.span,
+                    hir::LangItem::ContractCheckRequires,
+                    &*arena_vec![this; lowered_req],
+                );
+                this.stmt_expr(req.span, precond)
+            } else {
+                let u = lit_unit(this);
+                this.stmt_expr(contract.span, u)
+            };
+
+            let (postcond_checker, result) = if let Some(ens) = contract.ensures {
+                let crate::FnContractLoweringEnsures { expr: ens, fresh_ident } = ens;
+                let lowered_ens: hir::Expr<'hir> = this.lower_expr_mut(&ens);
+                let postcond_checker = this.expr_call_lang_item_fn(
+                    ens.span,
+                    hir::LangItem::ContractBuildCheckEnsures,
+                    &*arena_vec![this; lowered_ens],
+                );
+                let checker_binding_pat = fresh_ident.1;
+                (
+                    this.stmt_let_pat(
+                        None,
+                        ens.span,
+                        Some(postcond_checker),
+                        this.arena.alloc(checker_binding_pat),
+                        hir::LocalSource::Contract,
+                    ),
+                    this.inject_ensures_check(result_ref, ens.span, fresh_ident.0, fresh_ident.2),
+                )
+            } else {
+                let u = lit_unit(this);
+                (this.stmt_expr(contract.span, u), &*result_ref)
+            };
+
+            let block = this.block_all(
+                contract.span,
+                arena_vec![this; precond, postcond_checker],
+                Some(result),
+            );
+            (params, this.expr_block(block))
         })
     }
 
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index b9f1a4220b8..bb7c66f6094 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -86,6 +86,19 @@ mod path;
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
+#[derive(Debug, Clone)]
+struct FnContractLoweringInfo<'hir> {
+    pub span: Span,
+    pub requires: Option<ast::ptr::P<ast::Expr>>,
+    pub ensures: Option<FnContractLoweringEnsures<'hir>>,
+}
+
+#[derive(Debug, Clone)]
+struct FnContractLoweringEnsures<'hir> {
+    expr: ast::ptr::P<ast::Expr>,
+    fresh_ident: (Ident, hir::Pat<'hir>, HirId),
+}
+
 struct LoweringContext<'a, 'hir> {
     tcx: TyCtxt<'hir>,
     resolver: &'a mut ResolverAstLowering,
@@ -100,6 +113,8 @@ struct LoweringContext<'a, 'hir> {
     /// Collect items that were created by lowering the current owner.
     children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>,
 
+    contract: Option<FnContractLoweringInfo<'hir>>,
+
     coroutine_kind: Option<hir::CoroutineKind>,
 
     /// When inside an `async` context, this is the `HirId` of the
@@ -148,6 +163,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             bodies: Vec::new(),
             attrs: SortedMap::default(),
             children: Vec::default(),
+            contract: None,
             current_hir_id_owner: hir::CRATE_OWNER_ID,
             item_local_id_counter: hir::ItemLocalId::ZERO,
             ident_and_label_to_local_id: Default::default(),
@@ -418,10 +434,10 @@ fn compute_hir_hash(
 pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
     let sess = tcx.sess;
     // Queries that borrow `resolver_for_lowering`.
-    tcx.ensure_with_value().output_filenames(());
-    tcx.ensure_with_value().early_lint_checks(());
-    tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE);
-    tcx.ensure_with_value().get_lang_items(());
+    tcx.ensure_done().output_filenames(());
+    tcx.ensure_done().early_lint_checks(());
+    tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);
+    tcx.ensure_done().get_lang_items(());
     let (mut resolver, krate) = tcx.resolver_for_lowering().steal();
 
     let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
@@ -834,12 +850,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = false;
 
+        let old_contract = self.contract.take();
+
         let catch_scope = self.catch_scope.take();
         let loop_scope = self.loop_scope.take();
         let ret = f(self);
         self.catch_scope = catch_scope;
         self.loop_scope = loop_scope;
 
+        self.contract = old_contract;
+
         self.is_in_loop_condition = was_in_loop_condition;
 
         self.current_item = current_item;
@@ -1377,7 +1397,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     }
                 }
             }
-            TyKind::Pat(ty, pat) => hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_pat(pat)),
+            TyKind::Pat(ty, pat) => {
+                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
+            }
             TyKind::MacCall(_) => {
                 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
             }
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index cde8ddbfe03..bb9b2a13185 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -4,10 +4,10 @@ use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir as hir;
-use rustc_hir::def::Res;
+use rustc_hir::def::{DefKind, Res};
 use rustc_middle::span_bug;
 use rustc_span::source_map::{Spanned, respan};
-use rustc_span::{Ident, Span};
+use rustc_span::{Ident, Span, kw};
 
 use super::errors::{
     ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
@@ -429,4 +429,81 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         };
         self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
     }
+
+    pub(crate) fn lower_ty_pat(&mut self, pattern: &Pat) -> &'hir hir::TyPat<'hir> {
+        self.arena.alloc(self.lower_ty_pat_mut(pattern))
+    }
+
+    fn lower_ty_pat_mut(&mut self, mut pattern: &Pat) -> hir::TyPat<'hir> {
+        // loop here to avoid recursion
+        let pat_hir_id = self.lower_node_id(pattern.id);
+        let node = loop {
+            match &pattern.kind {
+                PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
+                    // FIXME(pattern_types): remove this closure and call `lower_const_arg` instead.
+                    // That requires first modifying the AST to have const args here.
+                    let mut lower_expr = |e: &Expr| -> &_ {
+                        if let ExprKind::Path(None, path) = &e.kind
+                            && let Some(res) = self
+                                .resolver
+                                .get_partial_res(e.id)
+                                .and_then(|partial_res| partial_res.full_res())
+                        {
+                            self.lower_const_path_to_const_arg(path, res, e.id, e.span)
+                        } else {
+                            let node_id = self.next_node_id();
+                            let def_id = self.create_def(
+                                self.current_hir_id_owner.def_id,
+                                node_id,
+                                kw::Empty,
+                                DefKind::AnonConst,
+                                e.span,
+                            );
+                            let hir_id = self.lower_node_id(node_id);
+                            let ac = self.arena.alloc(hir::AnonConst {
+                                def_id,
+                                hir_id,
+                                body: self.lower_const_body(pattern.span, Some(e)),
+                                span: self.lower_span(pattern.span),
+                            });
+                            self.arena.alloc(hir::ConstArg {
+                                hir_id: self.next_id(),
+                                kind: hir::ConstArgKind::Anon(ac),
+                            })
+                        }
+                    };
+                    break hir::TyPatKind::Range(
+                        e1.as_deref().map(|e| lower_expr(e)),
+                        e2.as_deref().map(|e| lower_expr(e)),
+                        self.lower_range_end(end, e2.is_some()),
+                    );
+                }
+                // return inner to be processed in next loop
+                PatKind::Paren(inner) => pattern = inner,
+                PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
+                PatKind::Err(guar) => break hir::TyPatKind::Err(*guar),
+                PatKind::Deref(..)
+                | PatKind::Box(..)
+                | PatKind::Or(..)
+                | PatKind::Struct(..)
+                | PatKind::TupleStruct(..)
+                | PatKind::Tuple(..)
+                | PatKind::Ref(..)
+                | PatKind::Expr(..)
+                | PatKind::Guard(..)
+                | PatKind::Slice(_)
+                | PatKind::Ident(..)
+                | PatKind::Path(..)
+                | PatKind::Wild
+                | PatKind::Never
+                | PatKind::Rest => {
+                    break hir::TyPatKind::Err(
+                        self.dcx().span_err(pattern.span, "pattern not supported in pattern types"),
+                    );
+                }
+            }
+        };
+
+        hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
+    }
 }
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index ea1f4a6559a..0049c5b4823 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -917,7 +917,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 walk_list!(self, visit_attribute, &item.attrs);
                 return; // Avoid visiting again.
             }
-            ItemKind::Fn(func @ box Fn { defaultness, generics: _, sig, body }) => {
+            ItemKind::Fn(func @ box Fn { defaultness, generics: _, sig, contract: _, body }) => {
                 self.check_defaultness(item.span, *defaultness);
 
                 let is_intrinsic =
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 80b99f94485..62e451fa876 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -548,6 +548,8 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     gate_all!(pin_ergonomics, "pinned reference syntax is experimental");
     gate_all!(unsafe_fields, "`unsafe` fields are experimental");
     gate_all!(unsafe_binders, "unsafe binder types are experimental");
+    gate_all!(contracts, "contracts are incomplete");
+    gate_all!(contracts_internals, "contract internal machinery is for internal use only");
 
     if !visitor.features.never_patterns() {
         if let Some(spans) = spans.get(&sym::never_patterns) {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 4cfcaa95233..c10b5ad34e1 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -650,13 +650,17 @@ impl<'a> State<'a> {
         attrs: &[ast::Attribute],
         func: &ast::Fn,
     ) {
-        let ast::Fn { defaultness, generics, sig, body } = func;
+        let ast::Fn { defaultness, generics, sig, contract, body } = func;
         if body.is_some() {
             self.head("");
         }
         self.print_visibility(vis);
         self.print_defaultness(*defaultness);
         self.print_fn(&sig.decl, sig.header, Some(name), generics);
+        if let Some(contract) = &contract {
+            self.nbsp();
+            self.print_contract(contract);
+        }
         if let Some(body) = body {
             self.nbsp();
             self.print_block_with_attrs(body, attrs);
@@ -665,6 +669,21 @@ impl<'a> State<'a> {
         }
     }
 
+    fn print_contract(&mut self, contract: &ast::FnContract) {
+        if let Some(pred) = &contract.requires {
+            self.word("rustc_requires");
+            self.popen();
+            self.print_expr(pred, FixupContext::default());
+            self.pclose();
+        }
+        if let Some(pred) = &contract.ensures {
+            self.word("rustc_ensures");
+            self.popen();
+            self.print_expr(pred, FixupContext::default());
+            self.pclose();
+        }
+    }
+
     pub(crate) fn print_fn(
         &mut self,
         decl: &ast::FnDecl,
diff --git a/compiler/rustc_attr_data_structures/src/stability.rs b/compiler/rustc_attr_data_structures/src/stability.rs
index dfda04387ec..c2213fc9ed8 100644
--- a/compiler/rustc_attr_data_structures/src/stability.rs
+++ b/compiler/rustc_attr_data_structures/src/stability.rs
@@ -101,16 +101,6 @@ impl PartialConstStability {
     }
 }
 
-#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
-#[derive(HashStable_Generic)]
-pub enum AllowedThroughUnstableModules {
-    /// This does not get a deprecation warning. We still generally would prefer people to use the
-    /// fully stable path, and a warning will likely be emitted in the future.
-    WithoutDeprecation,
-    /// Emit the given deprecation warning.
-    WithDeprecation(Symbol),
-}
-
 /// The available stability levels.
 #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
 #[derive(HashStable_Generic)]
@@ -147,8 +137,9 @@ pub enum StabilityLevel {
     Stable {
         /// Rust release which stabilized this feature.
         since: StableSince,
-        /// This is `Some` if this item allowed to be referred to on stable via unstable modules.
-        allowed_through_unstable_modules: Option<AllowedThroughUnstableModules>,
+        /// This is `Some` if this item allowed to be referred to on stable via unstable modules;
+        /// the `Symbol` is the deprecation message printed in that case.
+        allowed_through_unstable_modules: Option<Symbol>,
     },
 }
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs
index bfbe51b27d8..454b8b5de82 100644
--- a/compiler/rustc_attr_parsing/src/attributes/stability.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs
@@ -6,12 +6,12 @@ use rustc_ast::MetaItem;
 use rustc_ast::attr::AttributeExt;
 use rustc_ast_pretty::pprust;
 use rustc_attr_data_structures::{
-    AllowedThroughUnstableModules, ConstStability, DefaultBodyStability, Stability, StabilityLevel,
-    StableSince, UnstableReason, VERSION_PLACEHOLDER,
+    ConstStability, DefaultBodyStability, Stability, StabilityLevel, StableSince, UnstableReason,
+    VERSION_PLACEHOLDER,
 };
 use rustc_errors::ErrorGuaranteed;
 use rustc_session::Session;
-use rustc_span::{Span, Symbol, sym};
+use rustc_span::{Span, Symbol, kw, sym};
 
 use crate::attributes::util::UnsupportedLiteralReason;
 use crate::{parse_version, session_diagnostics};
@@ -29,10 +29,14 @@ pub fn find_stability(
     for attr in attrs {
         match attr.name_or_empty() {
             sym::rustc_allowed_through_unstable_modules => {
-                allowed_through_unstable_modules = Some(match attr.value_str() {
-                    Some(msg) => AllowedThroughUnstableModules::WithDeprecation(msg),
-                    None => AllowedThroughUnstableModules::WithoutDeprecation,
-                })
+                // The value is mandatory, but avoid ICEs in case such code reaches this function.
+                allowed_through_unstable_modules = Some(attr.value_str().unwrap_or_else(|| {
+                    sess.dcx().span_delayed_bug(
+                        item_sp,
+                        "`#[rustc_allowed_through_unstable_modules]` without deprecation message",
+                    );
+                    kw::Empty
+                }))
             }
             sym::unstable => {
                 if stab.is_some() {
diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl
index c00e6dde919..ada20e5c614 100644
--- a/compiler/rustc_borrowck/messages.ftl
+++ b/compiler/rustc_borrowck/messages.ftl
@@ -92,9 +92,6 @@ borrowck_lifetime_constraints_error =
 borrowck_limitations_implies_static =
     due to current limitations in the borrow checker, this implies a `'static` lifetime
 
-borrowck_long_type_consider_verbose = consider using `--verbose` to print the full type name to the console
-borrowck_long_type_full_path = the full type name has been written to '{$path}'
-
 borrowck_move_closure_suggestion =
     consider adding 'move' keyword before the nested closure
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 0118b72962d..b3fb2cd938b 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -289,8 +289,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 None => "value".to_owned(),
             };
             if needs_note {
-                let mut path = None;
-                let ty = self.infcx.tcx.short_ty_string(ty, &mut path);
+                let ty = self.infcx.tcx.short_string(ty, err.long_ty_path());
                 if let Some(local) = place.as_local() {
                     let span = self.body.local_decls[local].source_info.span;
                     err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
@@ -306,11 +305,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         place: &note_msg,
                     });
                 };
-                if let Some(path) = path {
-                    err.subdiagnostic(crate::session_diagnostics::LongTypePath {
-                        path: path.display().to_string(),
-                    });
-                }
             }
 
             if let UseSpans::FnSelfUse {
@@ -3118,12 +3112,24 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             drop_span, borrow_span
         );
 
+        // `TerminatorKind::Return`'s span (the `drop_span` here) `lo` can be subtly wrong and point
+        // at a single character after the end of the function. This is somehow relied upon in
+        // existing diagnostics, and changing this in `rustc_mir_build` makes diagnostics worse in
+        // general. We fix these here.
+        let sm = self.infcx.tcx.sess.source_map();
+        let end_of_function = if drop_span.is_empty()
+            && let Ok(adjusted_span) = sm.span_extend_prev_while(drop_span, |c| c == '}')
+        {
+            adjusted_span
+        } else {
+            drop_span
+        };
         self.thread_local_value_does_not_live_long_enough(borrow_span)
             .with_span_label(
                 borrow_span,
                 "thread-local variables cannot be borrowed beyond the end of the function",
             )
-            .with_span_label(drop_span, "end of enclosing function is here")
+            .with_span_label(end_of_function, "end of enclosing function is here")
     }
 
     #[instrument(level = "debug", skip(self))]
@@ -3915,7 +3921,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         ProjectionElem::ConstantIndex { .. }
                         | ProjectionElem::Subslice { .. }
                         | ProjectionElem::Subtype(_)
-                        | ProjectionElem::Index(_) => kind,
+                        | ProjectionElem::Index(_)
+                        | ProjectionElem::UnwrapUnsafeBinder(_) => kind,
                     },
                     place_ty.projection_ty(tcx, elem),
                 )
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 2656e0bb6a4..3e474225afd 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -248,7 +248,98 @@ impl<'tcx> BorrowExplanation<'tcx> {
                         );
                         err.span_label(body.source_info(drop_loc).span, message);
 
-                        if let LocalInfo::BlockTailTemp(info) = local_decl.local_info() {
+                        struct FindLetExpr<'hir> {
+                            span: Span,
+                            result: Option<(Span, &'hir hir::Pat<'hir>, &'hir hir::Expr<'hir>)>,
+                            tcx: TyCtxt<'hir>,
+                        }
+
+                        impl<'hir> rustc_hir::intravisit::Visitor<'hir> for FindLetExpr<'hir> {
+                            type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;
+                            fn nested_visit_map(&mut self) -> Self::Map {
+                                self.tcx.hir()
+                            }
+                            fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
+                                if let hir::ExprKind::If(cond, _conseq, _alt)
+                                | hir::ExprKind::Loop(
+                                    hir::Block {
+                                        expr:
+                                            Some(&hir::Expr {
+                                                kind: hir::ExprKind::If(cond, _conseq, _alt),
+                                                ..
+                                            }),
+                                        ..
+                                    },
+                                    _,
+                                    hir::LoopSource::While,
+                                    _,
+                                ) = expr.kind
+                                    && let hir::ExprKind::Let(hir::LetExpr {
+                                        init: let_expr_init,
+                                        span: let_expr_span,
+                                        pat: let_expr_pat,
+                                        ..
+                                    }) = cond.kind
+                                    && let_expr_init.span.contains(self.span)
+                                {
+                                    self.result =
+                                        Some((*let_expr_span, let_expr_pat, let_expr_init))
+                                } else {
+                                    hir::intravisit::walk_expr(self, expr);
+                                }
+                            }
+                        }
+
+                        if let &LocalInfo::IfThenRescopeTemp { if_then } = local_decl.local_info()
+                            && let hir::Node::Expr(expr) = tcx.hir_node(if_then)
+                            && let hir::ExprKind::If(cond, conseq, alt) = expr.kind
+                            && let hir::ExprKind::Let(&hir::LetExpr {
+                                span: _,
+                                pat,
+                                init,
+                                // FIXME(#101728): enable rewrite when type ascription is
+                                // stabilized again.
+                                ty: None,
+                                recovered: _,
+                            }) = cond.kind
+                            && pat.span.can_be_used_for_suggestions()
+                            && let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
+                        {
+                            suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
+                        } else if let Some((old, new)) = multiple_borrow_span
+                            && let def_id = body.source.def_id()
+                            && let Some(node) = tcx.hir().get_if_local(def_id)
+                            && let Some(body_id) = node.body_id()
+                            && let hir_body = tcx.hir().body(body_id)
+                            && let mut expr_finder = (FindLetExpr { span: old, result: None, tcx })
+                            && let Some((let_expr_span, let_expr_pat, let_expr_init)) = {
+                                expr_finder.visit_expr(hir_body.value);
+                                expr_finder.result
+                            }
+                            && !let_expr_span.contains(new)
+                        {
+                            // #133941: The `old` expression is at the conditional part of an
+                            // if/while let expression. Adding a semicolon won't work.
+                            // Instead, try suggesting the `matches!` macro or a temporary.
+                            if let_expr_pat
+                                .walk_short(|pat| !matches!(pat.kind, hir::PatKind::Binding(..)))
+                            {
+                                if let Ok(pat_snippet) =
+                                    tcx.sess.source_map().span_to_snippet(let_expr_pat.span)
+                                    && let Ok(init_snippet) =
+                                        tcx.sess.source_map().span_to_snippet(let_expr_init.span)
+                                {
+                                    err.span_suggestion_verbose(
+                                        let_expr_span,
+                                        "consider using the `matches!` macro",
+                                        format!("matches!({init_snippet}, {pat_snippet})"),
+                                        Applicability::MaybeIncorrect,
+                                    );
+                                } else {
+                                    err.note("consider using the `matches!` macro");
+                                }
+                            }
+                        } else if let LocalInfo::BlockTailTemp(info) = local_decl.local_info() {
                             if info.tail_result_is_ignored {
                                 // #85581: If the first mutable borrow's scope contains
                                 // the second borrow, this suggestion isn't helpful.
@@ -281,23 +372,6 @@ impl<'tcx> BorrowExplanation<'tcx> {
                                     Applicability::MaybeIncorrect,
                                 );
                             };
-                        } else if let &LocalInfo::IfThenRescopeTemp { if_then } =
-                            local_decl.local_info()
-                            && let hir::Node::Expr(expr) = tcx.hir_node(if_then)
-                            && let hir::ExprKind::If(cond, conseq, alt) = expr.kind
-                            && let hir::ExprKind::Let(&hir::LetExpr {
-                                span: _,
-                                pat,
-                                init,
-                                // FIXME(#101728): enable rewrite when type ascription is
-                                // stabilized again.
-                                ty: None,
-                                recovered: _,
-                            }) = cond.kind
-                            && pat.span.can_be_used_for_suggestions()
-                            && let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
-                        {
-                            suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
                         }
                     }
                 }
@@ -548,8 +622,25 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
             }
         }
 
+        // NLL doesn't consider boring locals for liveness, and wouldn't encounter a
+        // `Cause::LiveVar` for such a local. Polonius can't avoid computing liveness for boring
+        // locals yet, and will encounter them when trying to explain why a borrow contains a given
+        // point.
+        //
+        // We want to focus on relevant live locals in diagnostics, so when polonius is enabled, we
+        // ensure that we don't emit live boring locals as explanations.
+        let is_local_boring = |local| {
+            if let Some(polonius_diagnostics) = self.polonius_diagnostics {
+                polonius_diagnostics.boring_nll_locals.contains(&local)
+            } else {
+                assert!(!tcx.sess.opts.unstable_opts.polonius.is_next_enabled());
+
+                // Boring locals are never the cause of a borrow explanation in NLLs.
+                false
+            }
+        };
         match find_use::find(body, regioncx, tcx, region_sub, use_location) {
-            Some(Cause::LiveVar(local, location)) => {
+            Some(Cause::LiveVar(local, location)) if !is_local_boring(local) => {
                 let span = body.source_info(location).span;
                 let spans = self
                     .move_spans(Place::from(local).as_ref(), location)
@@ -592,7 +683,9 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
                 }
             }
 
-            None => {
+            Some(Cause::LiveVar(..)) | None => {
+                // Here, under NLL: no cause was found. Under polonius: no cause was found, or a
+                // boring local was found, which we ignore like NLLs do to match its diagnostics.
                 if let Some(region) = self.to_error_region_vid(borrow_region_vid) {
                     let (category, from_closure, span, region_name, path) =
                         self.free_region_constraint_info(borrow_region_vid, region);
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 5fe8eef3460..01ed0464c8a 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -4,7 +4,7 @@ use std::collections::BTreeMap;
 
 use rustc_abi::{FieldIdx, VariantIdx};
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_errors::{Applicability, Diag, EmissionGuarantee, MultiSpan};
+use rustc_errors::{Applicability, Diag, EmissionGuarantee, MultiSpan, listify};
 use rustc_hir::def::{CtorKind, Namespace};
 use rustc_hir::{self as hir, CoroutineKind, LangItem};
 use rustc_index::IndexSlice;
@@ -29,7 +29,7 @@ use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::error_reporting::traits::call_kind::{CallDesugaringKind, call_kind};
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::{
-    FulfillmentErrorCode, type_known_to_meet_bound_modulo_regions,
+    FulfillmentError, FulfillmentErrorCode, type_known_to_meet_bound_modulo_regions,
 };
 use tracing::debug;
 
@@ -370,6 +370,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 ProjectionElem::Downcast(..) => (),
                 ProjectionElem::OpaqueCast(..) => (),
                 ProjectionElem::Subtype(..) => (),
+                ProjectionElem::UnwrapUnsafeBinder(_) => (),
                 ProjectionElem::Field(field, _ty) => {
                     // FIXME(project-rfc_2229#36): print capture precisely here.
                     if let Some(field) = self.is_upvar_field_projection(PlaceRef {
@@ -450,9 +451,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                     PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx)
                 }
                 ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx),
-                ProjectionElem::Subtype(ty) | ProjectionElem::OpaqueCast(ty) => {
-                    PlaceTy::from_ty(*ty)
-                }
+                ProjectionElem::Subtype(ty)
+                | ProjectionElem::OpaqueCast(ty)
+                | ProjectionElem::UnwrapUnsafeBinder(ty) => PlaceTy::from_ty(*ty),
                 ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type),
             },
         };
@@ -1433,17 +1434,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                                             error.obligation.predicate,
                                         )
                                     }
-                                    [errors @ .., last] => {
+                                    _ => {
                                         format!(
                                             "you could `clone` the value and consume it, if the \
-                                             following trait bounds could be satisfied: \
-                                             {} and `{}`",
-                                            errors
-                                                .iter()
-                                                .map(|e| format!("`{}`", e.obligation.predicate))
-                                                .collect::<Vec<_>>()
-                                                .join(", "),
-                                            last.obligation.predicate,
+                                             following trait bounds could be satisfied: {}",
+                                            listify(&errors, |e: &FulfillmentError<'tcx>| format!(
+                                                "`{}`",
+                                                e.obligation.predicate
+                                            ))
+                                            .unwrap(),
                                         )
                                     }
                                 };
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 14a900f38e9..58c5c2fd774 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -596,19 +596,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         self.suggest_cloning(err, place_ty, expr, None);
                     }
 
-                    let mut path = None;
-                    let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path);
+                    let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path());
                     err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
                         is_partial_move: false,
                         ty,
                         place: &place_desc,
                         span,
                     });
-                    if let Some(path) = path {
-                        err.subdiagnostic(crate::session_diagnostics::LongTypePath {
-                            path: path.display().to_string(),
-                        });
-                    }
                 } else {
                     binds_to.sort();
                     binds_to.dedup();
@@ -635,19 +629,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                     self.suggest_cloning(err, place_ty, expr, Some(use_spans));
                 }
 
-                let mut path = None;
-                let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path);
+                let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path());
                 err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
                     is_partial_move: false,
                     ty,
                     place: &place_desc,
                     span: use_span,
                 });
-                if let Some(path) = path {
-                    err.subdiagnostic(crate::session_diagnostics::LongTypePath {
-                        path: path.display().to_string(),
-                    });
-                }
 
                 use_spans.args_subdiag(err, |args_span| {
                     crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
@@ -845,19 +833,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                     self.suggest_cloning(err, bind_to.ty, expr, None);
                 }
 
-                let mut path = None;
-                let ty = self.infcx.tcx.short_ty_string(bind_to.ty, &mut path);
+                let ty = self.infcx.tcx.short_string(bind_to.ty, err.long_ty_path());
                 err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
                     is_partial_move: false,
                     ty,
                     place: place_desc,
                     span: binding_span,
                 });
-                if let Some(path) = path {
-                    err.subdiagnostic(crate::session_diagnostics::LongTypePath {
-                        path: path.display().to_string(),
-                    });
-                }
             }
         }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index e841a5e4c94..706dd7135f7 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -167,7 +167,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         | ProjectionElem::ConstantIndex { .. }
                         | ProjectionElem::OpaqueCast { .. }
                         | ProjectionElem::Subslice { .. }
-                        | ProjectionElem::Downcast(..),
+                        | ProjectionElem::Downcast(..)
+                        | ProjectionElem::UnwrapUnsafeBinder(_),
                     ],
             } => bug!("Unexpected immutable place."),
         }
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index decfab502bb..8ddc8add675 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -60,6 +60,7 @@ use crate::diagnostics::{
 use crate::path_utils::*;
 use crate::place_ext::PlaceExt;
 use crate::places_conflict::{PlaceConflictBias, places_conflict};
+use crate::polonius::PoloniusDiagnosticsContext;
 use crate::polonius::legacy::{PoloniusLocationTable, PoloniusOutput};
 use crate::prefixes::PrefixSet;
 use crate::region_infer::RegionInferenceContext;
@@ -198,7 +199,7 @@ fn do_mir_borrowck<'tcx>(
         polonius_output,
         opt_closure_req,
         nll_errors,
-        localized_outlives_constraints,
+        polonius_diagnostics,
     } = nll::compute_regions(
         &infcx,
         free_regions,
@@ -270,6 +271,7 @@ fn do_mir_borrowck<'tcx>(
             polonius_output: None,
             move_errors: Vec::new(),
             diags_buffer,
+            polonius_diagnostics: polonius_diagnostics.as_ref(),
         };
         struct MoveVisitor<'a, 'b, 'infcx, 'tcx> {
             ctxt: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>,
@@ -308,6 +310,7 @@ fn do_mir_borrowck<'tcx>(
         polonius_output,
         move_errors: Vec::new(),
         diags_buffer,
+        polonius_diagnostics: polonius_diagnostics.as_ref(),
     };
 
     // Compute and report region errors, if any.
@@ -329,7 +332,7 @@ fn do_mir_borrowck<'tcx>(
         body,
         &regioncx,
         &borrow_set,
-        localized_outlives_constraints,
+        polonius_diagnostics.as_ref(),
         &opt_closure_req,
     );
 
@@ -579,6 +582,9 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
 
     diags_buffer: &'a mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>,
     move_errors: Vec<MoveError<'tcx>>,
+
+    /// When using `-Zpolonius=next`: the data used to compute errors and diagnostics.
+    polonius_diagnostics: Option<&'a PoloniusDiagnosticsContext>,
 }
 
 // Check that:
@@ -1398,6 +1404,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     self.consume_operand(location, (operand, span), state);
                 }
             }
+
+            Rvalue::WrapUnsafeBinder(op, _) => {
+                self.consume_operand(location, (op, span), state);
+            }
         }
     }
 
@@ -1770,7 +1780,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 // So it's safe to skip these.
                 ProjectionElem::OpaqueCast(_)
                 | ProjectionElem::Subtype(_)
-                | ProjectionElem::Downcast(_, _) => (),
+                | ProjectionElem::Downcast(_, _)
+                | ProjectionElem::UnwrapUnsafeBinder(_) => (),
             }
 
             place_ty = place_ty.projection_ty(tcx, elem);
@@ -2004,6 +2015,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 // FIXME: is this true even if P is an adt with a dtor?
                 { }
 
+                ProjectionElem::UnwrapUnsafeBinder(_) => {
+                    check_parent_of_field(self, location, place_base, span, state);
+                }
+
                 // assigning to (*P) requires P to be initialized
                 ProjectionElem::Deref => {
                     self.check_if_full_path_is_moved(
@@ -2384,7 +2399,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     | ProjectionElem::Subslice { .. }
                     | ProjectionElem::Subtype(..)
                     | ProjectionElem::OpaqueCast { .. }
-                    | ProjectionElem::Downcast(..) => {
+                    | ProjectionElem::Downcast(..)
+                    | ProjectionElem::UnwrapUnsafeBinder(_) => {
                         let upvar_field_projection = self.is_upvar_field_projection(place);
                         if let Some(field) = upvar_field_projection {
                             let upvar = &self.upvars[field.index()];
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 35264bd1a70..2031579dfd5 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -27,7 +27,7 @@ use tracing::{debug, instrument};
 use crate::borrow_set::BorrowSet;
 use crate::consumers::ConsumerOptions;
 use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors};
-use crate::polonius::LocalizedOutlivesConstraintSet;
+use crate::polonius::PoloniusDiagnosticsContext;
 use crate::polonius::legacy::{
     PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput,
 };
@@ -46,8 +46,9 @@ pub(crate) struct NllOutput<'tcx> {
     pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
     pub nll_errors: RegionErrors<'tcx>,
 
-    /// When using `-Zpolonius=next`: the localized typeck and liveness constraints.
-    pub localized_outlives_constraints: Option<LocalizedOutlivesConstraintSet>,
+    /// When using `-Zpolonius=next`: the data used to compute errors and diagnostics, e.g.
+    /// localized typeck and liveness constraints.
+    pub polonius_diagnostics: Option<PoloniusDiagnosticsContext>,
 }
 
 /// Rewrites the regions in the MIR to use NLL variables, also scraping out the set of universal
@@ -144,7 +145,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
 
     // If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives constraints
     // and use them to compute loan liveness.
-    let localized_outlives_constraints = polonius_context.as_ref().map(|polonius_context| {
+    let polonius_diagnostics = polonius_context.map(|polonius_context| {
         polonius_context.compute_loan_liveness(infcx.tcx, &mut regioncx, body, borrow_set)
     });
 
@@ -188,7 +189,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
         polonius_output,
         opt_closure_req: closure_region_requirements,
         nll_errors,
-        localized_outlives_constraints,
+        polonius_diagnostics,
     }
 }
 
diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index 679e111caa9..cf3e82426e8 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -250,7 +250,8 @@ fn place_components_conflict<'tcx>(
                 | (ProjectionElem::Subslice { .. }, _, _)
                 | (ProjectionElem::OpaqueCast { .. }, _, _)
                 | (ProjectionElem::Subtype(_), _, _)
-                | (ProjectionElem::Downcast { .. }, _, _) => {
+                | (ProjectionElem::Downcast { .. }, _, _)
+                | (ProjectionElem::UnwrapUnsafeBinder(_), _, _) => {
                     // Recursive case. This can still be disjoint on a
                     // further iteration if this a shallow access and
                     // there's a deref later on, e.g., a borrow
@@ -519,5 +520,9 @@ fn place_projection_conflict<'tcx>(
             pi1_elem,
             pi2_elem
         ),
+
+        (ProjectionElem::UnwrapUnsafeBinder(_), _) => {
+            todo!()
+        }
     }
 }
diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs
index 6d32ee17f4c..5f9fa3612b8 100644
--- a/compiler/rustc_borrowck/src/polonius/dump.rs
+++ b/compiler/rustc_borrowck/src/polonius/dump.rs
@@ -12,7 +12,9 @@ use rustc_session::config::MirIncludeSpans;
 
 use crate::borrow_set::BorrowSet;
 use crate::constraints::OutlivesConstraint;
-use crate::polonius::{LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet};
+use crate::polonius::{
+    LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet, PoloniusDiagnosticsContext,
+};
 use crate::region_infer::values::LivenessValues;
 use crate::type_check::Locations;
 use crate::{BorrowckInferCtxt, RegionInferenceContext};
@@ -23,7 +25,7 @@ pub(crate) fn dump_polonius_mir<'tcx>(
     body: &Body<'tcx>,
     regioncx: &RegionInferenceContext<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
-    localized_outlives_constraints: Option<LocalizedOutlivesConstraintSet>,
+    polonius_diagnostics: Option<&PoloniusDiagnosticsContext>,
     closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
 ) {
     let tcx = infcx.tcx;
@@ -35,8 +37,8 @@ pub(crate) fn dump_polonius_mir<'tcx>(
         return;
     }
 
-    let localized_outlives_constraints = localized_outlives_constraints
-        .expect("missing localized constraints with `-Zpolonius=next`");
+    let polonius_diagnostics =
+        polonius_diagnostics.expect("missing diagnostics context with `-Zpolonius=next`");
 
     let _: io::Result<()> = try {
         let mut file = create_dump_file(tcx, "html", false, "polonius", &0, body)?;
@@ -45,7 +47,7 @@ pub(crate) fn dump_polonius_mir<'tcx>(
             body,
             regioncx,
             borrow_set,
-            localized_outlives_constraints,
+            &polonius_diagnostics.localized_outlives_constraints,
             closure_region_requirements,
             &mut file,
         )?;
@@ -63,7 +65,7 @@ fn emit_polonius_dump<'tcx>(
     body: &Body<'tcx>,
     regioncx: &RegionInferenceContext<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
-    localized_outlives_constraints: LocalizedOutlivesConstraintSet,
+    localized_outlives_constraints: &LocalizedOutlivesConstraintSet,
     closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
     out: &mut dyn io::Write,
 ) -> io::Result<()> {
diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
index f79bcf5af55..0d1d8642bca 100644
--- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
+++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
@@ -325,6 +325,10 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
                     self.consume_operand(location, operand);
                 }
             }
+
+            Rvalue::WrapUnsafeBinder(op, _) => {
+                self.consume_operand(location, op);
+            }
         }
     }
 
diff --git a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs
index 75ee29c9d0d..6ab09f731c0 100644
--- a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs
+++ b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs
@@ -1,7 +1,6 @@
 use std::collections::BTreeMap;
 
 use rustc_index::bit_set::SparseBitMatrix;
-use rustc_index::interval::SparseIntervalMatrix;
 use rustc_middle::mir::{Body, Location};
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeVisitable};
@@ -9,12 +8,12 @@ use rustc_mir_dataflow::points::PointIndex;
 
 use super::{
     ConstraintDirection, LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet,
-    PoloniusContext,
+    PoloniusLivenessContext,
 };
 use crate::region_infer::values::LivenessValues;
 use crate::universal_regions::UniversalRegions;
 
-impl PoloniusContext {
+impl PoloniusLivenessContext {
     /// Record the variance of each region contained within the given value.
     pub(crate) fn record_live_region_variance<'tcx>(
         &mut self,
@@ -30,25 +29,6 @@ impl PoloniusContext {
         };
         extractor.relate(value, value).expect("Can't have a type error relating to itself");
     }
-
-    /// Unlike NLLs, in polonius we traverse the cfg to look for regions live across an edge, so we
-    /// need to transpose the "points where each region is live" matrix to a "live regions per point"
-    /// matrix.
-    // FIXME: avoid this conversion by always storing liveness data in this shape in the rest of
-    // borrowck.
-    pub(crate) fn record_live_regions_per_point(
-        &mut self,
-        num_regions: usize,
-        points_per_live_region: &SparseIntervalMatrix<RegionVid, PointIndex>,
-    ) {
-        let mut live_regions_per_point = SparseBitMatrix::new(num_regions);
-        for region in points_per_live_region.rows() {
-            for point in points_per_live_region.row(region).unwrap().iter() {
-                live_regions_per_point.insert(point, region);
-            }
-        }
-        self.live_regions = Some(live_regions_per_point);
-    }
 }
 
 /// Propagate loans throughout the CFG: for each statement in the MIR, create localized outlives
diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs
index 502c868194a..142ef8ba28e 100644
--- a/compiler/rustc_borrowck/src/polonius/mod.rs
+++ b/compiler/rustc_borrowck/src/polonius/mod.rs
@@ -32,6 +32,16 @@
 //! - <https://smallcultfollowing.com/babysteps/blog/2023/09/22/polonius-part-1/>
 //! - <https://smallcultfollowing.com/babysteps/blog/2023/09/29/polonius-part-2/>
 //!
+//!
+//! Data flows like this:
+//! 1) during MIR typeck, record liveness data needed later: live region variances, as well as the
+//!    usual NLL liveness data (just computed on more locals). That's the [PoloniusLivenessContext].
+//! 2) once that is done, variance data is transferred, and the NLL region liveness is converted to
+//!    the polonius shape. That's the main [PoloniusContext].
+//! 3) during region inference, that data and the NLL outlives constraints are used to create the
+//!    localized outlives constraints, as described above. That's the [PoloniusDiagnosticsContext].
+//! 4) transfer this back to the main borrowck procedure: it handles computing errors and
+//!    diagnostics, debugging and MIR dumping concerns.
 
 mod constraints;
 mod dump;
@@ -42,8 +52,10 @@ mod typeck_constraints;
 
 use std::collections::BTreeMap;
 
+use rustc_data_structures::fx::FxHashSet;
 use rustc_index::bit_set::SparseBitMatrix;
-use rustc_middle::mir::Body;
+use rustc_index::interval::SparseIntervalMatrix;
+use rustc_middle::mir::{Body, Local};
 use rustc_middle::ty::{RegionVid, TyCtxt};
 use rustc_mir_dataflow::points::PointIndex;
 
@@ -57,15 +69,40 @@ use crate::{BorrowSet, RegionInferenceContext};
 
 pub(crate) type LiveLoans = SparseBitMatrix<PointIndex, BorrowIndex>;
 
-/// This struct holds the data needed to create the Polonius localized constraints.
+/// This struct holds the liveness data created during MIR typeck, and which will be used later in
+/// the process, to compute the polonius localized constraints.
+#[derive(Default)]
+pub(crate) struct PoloniusLivenessContext {
+    /// The expected edge direction per live region: the kind of directed edge we'll create as
+    /// liveness constraints depends on the variance of types with respect to each contained region.
+    live_region_variances: BTreeMap<RegionVid, ConstraintDirection>,
+
+    /// The regions that outlive free regions are used to distinguish relevant live locals from
+    /// boring locals. A boring local is one whose type contains only such regions. Polonius
+    /// currently has more boring locals than NLLs so we record the latter to use in errors and
+    /// diagnostics, to focus on the locals we consider relevant and match NLL diagnostics.
+    pub(crate) boring_nll_locals: FxHashSet<Local>,
+}
+
+/// This struct holds the data needed to create the Polonius localized constraints. Its data is
+/// transferred and converted from the [PoloniusLivenessContext] at the end of MIR typeck.
 pub(crate) struct PoloniusContext {
+    /// The liveness data we recorded during MIR typeck.
+    liveness_context: PoloniusLivenessContext,
+
     /// The set of regions that are live at a given point in the CFG, used to create localized
     /// outlives constraints between regions that are live at connected points in the CFG.
-    live_regions: Option<SparseBitMatrix<PointIndex, RegionVid>>,
+    live_regions: SparseBitMatrix<PointIndex, RegionVid>,
+}
 
-    /// The expected edge direction per live region: the kind of directed edge we'll create as
-    /// liveness constraints depends on the variance of types with respect to each contained region.
-    live_region_variances: BTreeMap<RegionVid, ConstraintDirection>,
+/// This struct holds the data needed by the borrowck error computation and diagnostics. Its data is
+/// computed from the [PoloniusContext] when computing NLL regions.
+pub(crate) struct PoloniusDiagnosticsContext {
+    /// The localized outlives constraints that were computed in the main analysis.
+    localized_outlives_constraints: LocalizedOutlivesConstraintSet,
+
+    /// The liveness data computed during MIR typeck: [PoloniusLivenessContext::boring_nll_locals].
+    pub(crate) boring_nll_locals: FxHashSet<Local>,
 }
 
 /// The direction a constraint can flow into. Used to create liveness constraints according to
@@ -83,8 +120,24 @@ enum ConstraintDirection {
 }
 
 impl PoloniusContext {
-    pub(crate) fn new() -> PoloniusContext {
-        Self { live_region_variances: BTreeMap::new(), live_regions: None }
+    /// Unlike NLLs, in polonius we traverse the cfg to look for regions live across an edge, so we
+    /// need to transpose the "points where each region is live" matrix to a "live regions per point"
+    /// matrix.
+    // FIXME: avoid this conversion by always storing liveness data in this shape in the rest of
+    // borrowck.
+    pub(crate) fn create_from_liveness(
+        liveness_context: PoloniusLivenessContext,
+        num_regions: usize,
+        points_per_live_region: &SparseIntervalMatrix<RegionVid, PointIndex>,
+    ) -> PoloniusContext {
+        let mut live_regions_per_point = SparseBitMatrix::new(num_regions);
+        for region in points_per_live_region.rows() {
+            for point in points_per_live_region.row(region).unwrap().iter() {
+                live_regions_per_point.insert(point, region);
+            }
+        }
+
+        PoloniusContext { live_regions: live_regions_per_point, liveness_context }
     }
 
     /// Computes live loans using the set of loans model for `-Zpolonius=next`.
@@ -95,13 +148,18 @@ impl PoloniusContext {
     ///
     /// Then, this graph is traversed, and combined with kills, reachability is recorded as loan
     /// liveness, to be used by the loan scope and active loans computations.
+    ///
+    /// The constraint data will be used to compute errors and diagnostics.
     pub(crate) fn compute_loan_liveness<'tcx>(
-        &self,
+        self,
         tcx: TyCtxt<'tcx>,
         regioncx: &mut RegionInferenceContext<'tcx>,
         body: &Body<'tcx>,
         borrow_set: &BorrowSet<'tcx>,
-    ) -> LocalizedOutlivesConstraintSet {
+    ) -> PoloniusDiagnosticsContext {
+        let PoloniusLivenessContext { live_region_variances, boring_nll_locals } =
+            self.liveness_context;
+
         let mut localized_outlives_constraints = LocalizedOutlivesConstraintSet::default();
         convert_typeck_constraints(
             tcx,
@@ -112,14 +170,11 @@ impl PoloniusContext {
             &mut localized_outlives_constraints,
         );
 
-        let live_regions = self.live_regions.as_ref().expect(
-            "live regions per-point data should have been created at the end of MIR typeck",
-        );
         create_liveness_constraints(
             body,
             regioncx.liveness_constraints(),
-            live_regions,
-            &self.live_region_variances,
+            &self.live_regions,
+            &live_region_variances,
             regioncx.universal_regions(),
             &mut localized_outlives_constraints,
         );
@@ -136,6 +191,6 @@ impl PoloniusContext {
         );
         regioncx.record_live_loans(live_loans);
 
-        localized_outlives_constraints
+        PoloniusDiagnosticsContext { localized_outlives_constraints, boring_nll_locals }
     }
 }
diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs
index fc7e6e58641..83cca38a5c0 100644
--- a/compiler/rustc_borrowck/src/prefixes.rs
+++ b/compiler/rustc_borrowck/src/prefixes.rs
@@ -66,6 +66,10 @@ impl<'tcx> Iterator for Prefixes<'tcx> {
                             self.next = Some(cursor_base);
                             return Some(cursor);
                         }
+                        ProjectionElem::UnwrapUnsafeBinder(_) => {
+                            self.next = Some(cursor_base);
+                            return Some(cursor);
+                        }
                         ProjectionElem::Downcast(..)
                         | ProjectionElem::Subslice { .. }
                         | ProjectionElem::OpaqueCast { .. }
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index 2c37d2bc123..11b30c145c2 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -459,13 +459,6 @@ pub(crate) enum OnClosureNote<'a> {
 }
 
 #[derive(Subdiagnostic)]
-#[note(borrowck_long_type_full_path)]
-#[note(borrowck_long_type_consider_verbose)]
-pub(crate) struct LongTypePath {
-    pub(crate) path: String,
-}
-
-#[derive(Subdiagnostic)]
 pub(crate) enum TypeNoCopy<'a> {
     #[label(borrowck_ty_no_impl_copy)]
     Label {
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
index 4e0b2a4e296..dcc17903002 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
@@ -14,7 +14,7 @@ use tracing::debug;
 
 use super::TypeChecker;
 use crate::constraints::OutlivesConstraintSet;
-use crate::polonius::PoloniusContext;
+use crate::polonius::PoloniusLivenessContext;
 use crate::region_infer::values::LivenessValues;
 use crate::universal_regions::UniversalRegions;
 
@@ -38,19 +38,24 @@ pub(super) fn generate<'a, 'tcx>(
 ) {
     debug!("liveness::generate");
 
+    let mut free_regions = regions_that_outlive_free_regions(
+        typeck.infcx.num_region_vars(),
+        &typeck.universal_regions,
+        &typeck.constraints.outlives_constraints,
+    );
+
     // NLLs can avoid computing some liveness data here because its constraints are
     // location-insensitive, but that doesn't work in polonius: locals whose type contains a region
     // that outlives a free region are not necessarily live everywhere in a flow-sensitive setting,
     // unlike NLLs.
-    let free_regions = if !typeck.tcx().sess.opts.unstable_opts.polonius.is_next_enabled() {
-        regions_that_outlive_free_regions(
-            typeck.infcx.num_region_vars(),
-            &typeck.universal_regions,
-            &typeck.constraints.outlives_constraints,
-        )
-    } else {
-        typeck.universal_regions.universal_regions_iter().collect()
-    };
+    // We do record these regions in the polonius context, since they're used to differentiate
+    // relevant and boring locals, which is a key distinction used later in diagnostics.
+    if typeck.tcx().sess.opts.unstable_opts.polonius.is_next_enabled() {
+        let (_, boring_locals) = compute_relevant_live_locals(typeck.tcx(), &free_regions, body);
+        typeck.polonius_liveness.as_mut().unwrap().boring_nll_locals =
+            boring_locals.into_iter().collect();
+        free_regions = typeck.universal_regions.universal_regions_iter().collect();
+    }
     let (relevant_live_locals, boring_locals) =
         compute_relevant_live_locals(typeck.tcx(), &free_regions, body);
 
@@ -70,7 +75,7 @@ pub(super) fn generate<'a, 'tcx>(
         typeck.tcx(),
         &mut typeck.constraints.liveness_constraints,
         &typeck.universal_regions,
-        &mut typeck.polonius_context,
+        &mut typeck.polonius_liveness,
         body,
     );
 }
@@ -147,11 +152,11 @@ fn record_regular_live_regions<'tcx>(
     tcx: TyCtxt<'tcx>,
     liveness_constraints: &mut LivenessValues,
     universal_regions: &UniversalRegions<'tcx>,
-    polonius_context: &mut Option<PoloniusContext>,
+    polonius_liveness: &mut Option<PoloniusLivenessContext>,
     body: &Body<'tcx>,
 ) {
     let mut visitor =
-        LiveVariablesVisitor { tcx, liveness_constraints, universal_regions, polonius_context };
+        LiveVariablesVisitor { tcx, liveness_constraints, universal_regions, polonius_liveness };
     for (bb, data) in body.basic_blocks.iter_enumerated() {
         visitor.visit_basic_block_data(bb, data);
     }
@@ -162,7 +167,7 @@ struct LiveVariablesVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     liveness_constraints: &'a mut LivenessValues,
     universal_regions: &'a UniversalRegions<'tcx>,
-    polonius_context: &'a mut Option<PoloniusContext>,
+    polonius_liveness: &'a mut Option<PoloniusLivenessContext>,
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for LiveVariablesVisitor<'a, 'tcx> {
@@ -214,8 +219,8 @@ impl<'a, 'tcx> LiveVariablesVisitor<'a, 'tcx> {
         });
 
         // When using `-Zpolonius=next`, we record the variance of each live region.
-        if let Some(polonius_context) = self.polonius_context {
-            polonius_context.record_live_region_variance(self.tcx, self.universal_regions, value);
+        if let Some(polonius_liveness) = self.polonius_liveness {
+            polonius_liveness.record_live_region_variance(self.tcx, self.universal_regions, value);
         }
     }
 }
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index c564d85616e..62d49a62744 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -580,8 +580,8 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
         });
 
         // When using `-Zpolonius=next`, we record the variance of each live region.
-        if let Some(polonius_context) = typeck.polonius_context {
-            polonius_context.record_live_region_variance(
+        if let Some(polonius_liveness) = typeck.polonius_liveness.as_mut() {
+            polonius_liveness.record_live_region_variance(
                 typeck.infcx.tcx,
                 typeck.universal_regions,
                 value,
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index a2ef5588f48..002f6e36cd8 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -48,8 +48,8 @@ use crate::borrow_set::BorrowSet;
 use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet};
 use crate::diagnostics::UniverseInfo;
 use crate::member_constraints::MemberConstraintSet;
-use crate::polonius::PoloniusContext;
 use crate::polonius::legacy::{PoloniusFacts, PoloniusLocationTable};
+use crate::polonius::{PoloniusContext, PoloniusLivenessContext};
 use crate::region_infer::TypeTest;
 use crate::region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices};
 use crate::renumber::RegionCtxt;
@@ -148,8 +148,8 @@ pub(crate) fn type_check<'a, 'tcx>(
 
     debug!(?normalized_inputs_and_output);
 
-    let mut polonius_context = if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
-        Some(PoloniusContext::new())
+    let polonius_liveness = if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
+        Some(PoloniusLivenessContext::default())
     } else {
         None
     };
@@ -168,7 +168,7 @@ pub(crate) fn type_check<'a, 'tcx>(
         polonius_facts,
         borrow_set,
         constraints: &mut constraints,
-        polonius_context: &mut polonius_context,
+        polonius_liveness,
     };
 
     typeck.check_user_type_annotations();
@@ -185,11 +185,14 @@ pub(crate) fn type_check<'a, 'tcx>(
     let opaque_type_values =
         opaque_types::take_opaques_and_register_member_constraints(&mut typeck);
 
-    if let Some(polonius_context) = typeck.polonius_context.as_mut() {
-        let num_regions = infcx.num_region_vars();
-        let points_per_live_region = typeck.constraints.liveness_constraints.points();
-        polonius_context.record_live_regions_per_point(num_regions, points_per_live_region);
-    }
+    // We're done with typeck, we can finalize the polonius liveness context for region inference.
+    let polonius_context = typeck.polonius_liveness.take().map(|liveness_context| {
+        PoloniusContext::create_from_liveness(
+            liveness_context,
+            infcx.num_region_vars(),
+            typeck.constraints.liveness_constraints.points(),
+        )
+    });
 
     MirTypeckResults {
         constraints,
@@ -302,6 +305,25 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                     )
                     .unwrap();
             }
+            ProjectionElem::UnwrapUnsafeBinder(ty) => {
+                let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else {
+                    unreachable!();
+                };
+                let found_ty = self.typeck.infcx.instantiate_binder_with_fresh_vars(
+                    self.body().source_info(location).span,
+                    BoundRegionConversionTime::HigherRankedType,
+                    binder_ty.into(),
+                );
+                self.typeck
+                    .relate_types(
+                        ty,
+                        context.ambient_variance(),
+                        found_ty,
+                        location.to_locations(),
+                        ConstraintCategory::Boring,
+                    )
+                    .unwrap();
+            }
             ProjectionElem::Subtype(_) => {
                 bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
             }
@@ -564,8 +586,8 @@ struct TypeChecker<'a, 'tcx> {
     polonius_facts: &'a mut Option<PoloniusFacts>,
     borrow_set: &'a BorrowSet<'tcx>,
     constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
-    /// When using `-Zpolonius=next`, the helper data used to create polonius constraints.
-    polonius_context: &'a mut Option<PoloniusContext>,
+    /// When using `-Zpolonius=next`, the liveness helper data used to create polonius constraints.
+    polonius_liveness: Option<PoloniusLivenessContext>,
 }
 
 /// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions
@@ -1631,6 +1653,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     ConstraintCategory::SizedBound,
                 );
             }
+            &Rvalue::NullaryOp(NullOp::ContractChecks, _) => {}
             &Rvalue::NullaryOp(NullOp::UbChecks, _) => {}
 
             Rvalue::ShallowInitBox(operand, ty) => {
@@ -2233,6 +2256,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 self.check_operand(right, location);
             }
 
+            Rvalue::WrapUnsafeBinder(op, ty) => {
+                self.check_operand(op, location);
+                let operand_ty = op.ty(self.body, self.tcx());
+
+                let ty::UnsafeBinder(binder_ty) = *ty.kind() else {
+                    unreachable!();
+                };
+                let expected_ty = self.infcx.instantiate_binder_with_fresh_vars(
+                    self.body().source_info(location).span,
+                    BoundRegionConversionTime::HigherRankedType,
+                    binder_ty.into(),
+                );
+                self.sub_types(
+                    operand_ty,
+                    expected_ty,
+                    location.to_locations(),
+                    ConstraintCategory::Boring,
+                )
+                .unwrap();
+            }
+
             Rvalue::RawPtr(..)
             | Rvalue::ThreadLocalRef(..)
             | Rvalue::Len(..)
@@ -2258,7 +2302,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             | Rvalue::NullaryOp(..)
             | Rvalue::CopyForDeref(..)
             | Rvalue::UnaryOp(..)
-            | Rvalue::Discriminant(..) => None,
+            | Rvalue::Discriminant(..)
+            | Rvalue::WrapUnsafeBinder(..) => None,
 
             Rvalue::Aggregate(aggregate, _) => match **aggregate {
                 AggregateKind::Adt(_, _, _, user_ty, _) => user_ty,
@@ -2450,7 +2495,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 | ProjectionElem::OpaqueCast(..)
                 | ProjectionElem::Index(..)
                 | ProjectionElem::ConstantIndex { .. }
-                | ProjectionElem::Subslice { .. } => {
+                | ProjectionElem::Subslice { .. }
+                | ProjectionElem::UnwrapUnsafeBinder(_) => {
                     // other field access
                 }
                 ProjectionElem::Subtype(_) => {
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index d2b4e1ca824..cffc4978601 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -85,6 +85,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
         defaultness: ast::Defaultness::Final,
         sig,
         generics: Generics::default(),
+        contract: None,
         body,
     }));
 
diff --git a/compiler/rustc_builtin_macros/src/contracts.rs b/compiler/rustc_builtin_macros/src/contracts.rs
new file mode 100644
index 00000000000..85a30f7bdc9
--- /dev/null
+++ b/compiler/rustc_builtin_macros/src/contracts.rs
@@ -0,0 +1,176 @@
+#![allow(unused_imports, unused_variables)]
+
+use rustc_ast::token;
+use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
+use rustc_errors::ErrorGuaranteed;
+use rustc_expand::base::{AttrProcMacro, ExtCtxt};
+use rustc_span::Span;
+use rustc_span::symbol::{Ident, Symbol, kw, sym};
+
+pub(crate) struct ExpandRequires;
+
+pub(crate) struct ExpandEnsures;
+
+impl AttrProcMacro for ExpandRequires {
+    fn expand<'cx>(
+        &self,
+        ecx: &'cx mut ExtCtxt<'_>,
+        span: Span,
+        annotation: TokenStream,
+        annotated: TokenStream,
+    ) -> Result<TokenStream, ErrorGuaranteed> {
+        expand_requires_tts(ecx, span, annotation, annotated)
+    }
+}
+
+impl AttrProcMacro for ExpandEnsures {
+    fn expand<'cx>(
+        &self,
+        ecx: &'cx mut ExtCtxt<'_>,
+        span: Span,
+        annotation: TokenStream,
+        annotated: TokenStream,
+    ) -> Result<TokenStream, ErrorGuaranteed> {
+        expand_ensures_tts(ecx, span, annotation, annotated)
+    }
+}
+
+/// Expand the function signature to include the contract clause.
+///
+/// The contracts clause will be injected before the function body and the optional where clause.
+/// For that, we search for the body / where token, and invoke the `inject` callback to generate the
+/// contract clause in the right place.
+///
+// FIXME: this kind of manual token tree munging does not have significant precedent among
+// rustc builtin macros, probably because most builtin macros use direct AST manipulation to
+// accomplish similar goals. But since our attributes need to take arbitrary expressions, and
+// our attribute infrastructure does not yet support mixing a token-tree annotation with an AST
+// annotated, we end up doing token tree manipulation.
+fn expand_contract_clause(
+    ecx: &mut ExtCtxt<'_>,
+    attr_span: Span,
+    annotated: TokenStream,
+    inject: impl FnOnce(&mut TokenStream) -> Result<(), ErrorGuaranteed>,
+) -> Result<TokenStream, ErrorGuaranteed> {
+    let mut new_tts = TokenStream::default();
+    let mut cursor = annotated.iter();
+
+    let is_kw = |tt: &TokenTree, sym: Symbol| {
+        if let TokenTree::Token(token, _) = tt { token.is_ident_named(sym) } else { false }
+    };
+
+    // Find the `fn` keyword to check if this is a function.
+    if cursor
+        .find(|tt| {
+            new_tts.push_tree((*tt).clone());
+            is_kw(tt, kw::Fn)
+        })
+        .is_none()
+    {
+        return Err(ecx
+            .sess
+            .dcx()
+            .span_err(attr_span, "contract annotations can only be used on functions"));
+    }
+
+    // Found the `fn` keyword, now find either the `where` token or the function body.
+    let next_tt = loop {
+        let Some(tt) = cursor.next() else {
+            return Err(ecx.sess.dcx().span_err(
+                attr_span,
+                "contract annotations is only supported in functions with bodies",
+            ));
+        };
+        // If `tt` is the last element. Check if it is the function body.
+        if cursor.peek().is_none() {
+            if let TokenTree::Delimited(_, _, token::Delimiter::Brace, _) = tt {
+                break tt;
+            } else {
+                return Err(ecx.sess.dcx().span_err(
+                    attr_span,
+                    "contract annotations is only supported in functions with bodies",
+                ));
+            }
+        }
+
+        if is_kw(tt, kw::Where) {
+            break tt;
+        }
+        new_tts.push_tree(tt.clone());
+    };
+
+    // At this point, we've transcribed everything from the `fn` through the formal parameter list
+    // and return type declaration, (if any), but `tt` itself has *not* been transcribed.
+    //
+    // Now inject the AST contract form.
+    //
+    inject(&mut new_tts)?;
+
+    // Above we injected the internal AST requires/ensures construct. Now copy over all the other
+    // token trees.
+    new_tts.push_tree(next_tt.clone());
+    while let Some(tt) = cursor.next() {
+        new_tts.push_tree(tt.clone());
+        if cursor.peek().is_none()
+            && !matches!(tt, TokenTree::Delimited(_, _, token::Delimiter::Brace, _))
+        {
+            return Err(ecx.sess.dcx().span_err(
+                attr_span,
+                "contract annotations is only supported in functions with bodies",
+            ));
+        }
+    }
+
+    // Record the span as a contract attribute expansion.
+    // This is used later to stop users from using the extended syntax directly
+    // which is gated via `contracts_internals`.
+    ecx.psess().contract_attribute_spans.push(attr_span);
+
+    Ok(new_tts)
+}
+
+fn expand_requires_tts(
+    _ecx: &mut ExtCtxt<'_>,
+    attr_span: Span,
+    annotation: TokenStream,
+    annotated: TokenStream,
+) -> Result<TokenStream, ErrorGuaranteed> {
+    expand_contract_clause(_ecx, attr_span, annotated, |new_tts| {
+        new_tts.push_tree(TokenTree::Token(
+            token::Token::from_ast_ident(Ident::new(kw::ContractRequires, attr_span)),
+            Spacing::Joint,
+        ));
+        new_tts.push_tree(TokenTree::Token(
+            token::Token::new(token::TokenKind::OrOr, attr_span),
+            Spacing::Alone,
+        ));
+        new_tts.push_tree(TokenTree::Delimited(
+            DelimSpan::from_single(attr_span),
+            DelimSpacing::new(Spacing::JointHidden, Spacing::JointHidden),
+            token::Delimiter::Parenthesis,
+            annotation,
+        ));
+        Ok(())
+    })
+}
+
+fn expand_ensures_tts(
+    _ecx: &mut ExtCtxt<'_>,
+    attr_span: Span,
+    annotation: TokenStream,
+    annotated: TokenStream,
+) -> Result<TokenStream, ErrorGuaranteed> {
+    expand_contract_clause(_ecx, attr_span, annotated, |new_tts| {
+        new_tts.push_tree(TokenTree::Token(
+            token::Token::from_ast_ident(Ident::new(kw::ContractEnsures, attr_span)),
+            Spacing::Joint,
+        ));
+        new_tts.push_tree(TokenTree::Delimited(
+            DelimSpan::from_single(attr_span),
+            DelimSpacing::new(Spacing::JointHidden, Spacing::JointHidden),
+            token::Delimiter::Parenthesis,
+            annotation,
+        ));
+        Ok(())
+    })
+}
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index eb01ca3941d..8ab21986e68 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -56,7 +56,7 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
 
     let (ident, vdata, fields) = match substr.fields {
         Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
-        EnumMatching(_, v, fields) => (v.ident, &v.data, fields),
+        EnumMatching(v, fields) => (v.ident, &v.data, fields),
         AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, substr),
         EnumDiscr(..) | StaticStruct(..) | StaticEnum(..) => {
             cx.dcx().span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
deleted file mode 100644
index 6348560496e..00000000000
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ /dev/null
@@ -1,215 +0,0 @@
-//! The compiler code necessary for `#[derive(RustcDecodable)]`. See encodable.rs for more.
-
-use rustc_ast::ptr::P;
-use rustc_ast::{self as ast, Expr, MetaItem, Mutability};
-use rustc_expand::base::{Annotatable, ExtCtxt};
-use rustc_span::{Ident, Span, Symbol, sym};
-use thin_vec::{ThinVec, thin_vec};
-
-use crate::deriving::generic::ty::*;
-use crate::deriving::generic::*;
-use crate::deriving::pathvec_std;
-
-pub(crate) fn expand_deriving_rustc_decodable(
-    cx: &ExtCtxt<'_>,
-    span: Span,
-    mitem: &MetaItem,
-    item: &Annotatable,
-    push: &mut dyn FnMut(Annotatable),
-    is_const: bool,
-) {
-    let krate = sym::rustc_serialize;
-    let typaram = sym::__D;
-
-    let trait_def = TraitDef {
-        span,
-        path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global),
-        skip_path_as_bound: false,
-        needs_copy_as_bound_if_packed: true,
-        additional_bounds: Vec::new(),
-        supports_unions: false,
-        methods: vec![MethodDef {
-            name: sym::decode,
-            generics: Bounds {
-                bounds: vec![(typaram, vec![Path::new_(
-                    vec![krate, sym::Decoder],
-                    vec![],
-                    PathKind::Global,
-                )])],
-            },
-            explicit_self: false,
-            nonself_args: vec![(
-                Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut),
-                sym::d,
-            )],
-            ret_ty: Path(Path::new_(
-                pathvec_std!(result::Result),
-                vec![
-                    Box::new(Self_),
-                    Box::new(Path(Path::new_(vec![typaram, sym::Error], vec![], PathKind::Local))),
-                ],
-                PathKind::Std,
-            )),
-            attributes: ast::AttrVec::new(),
-            fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
-            combine_substructure: combine_substructure(Box::new(|a, b, c| {
-                decodable_substructure(a, b, c, krate)
-            })),
-        }],
-        associated_types: Vec::new(),
-        is_const,
-    };
-
-    trait_def.expand(cx, mitem, item, push)
-}
-
-fn decodable_substructure(
-    cx: &ExtCtxt<'_>,
-    trait_span: Span,
-    substr: &Substructure<'_>,
-    krate: Symbol,
-) -> BlockOrExpr {
-    let decoder = substr.nonselflike_args[0].clone();
-    let recurse = vec![
-        Ident::new(krate, trait_span),
-        Ident::new(sym::Decodable, trait_span),
-        Ident::new(sym::decode, trait_span),
-    ];
-    let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse));
-    // throw an underscore in front to suppress unused variable warnings
-    let blkarg = Ident::new(sym::_d, trait_span);
-    let blkdecoder = cx.expr_ident(trait_span, blkarg);
-
-    let expr = match substr.fields {
-        StaticStruct(_, summary) => {
-            let nfields = match summary {
-                Unnamed(fields, _) => fields.len(),
-                Named(fields) => fields.len(),
-            };
-            let fn_read_struct_field_path: Vec<_> =
-                cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct_field]);
-
-            let path = cx.path_ident(trait_span, substr.type_ident);
-            let result =
-                decode_static_fields(cx, trait_span, path, summary, |cx, span, name, field| {
-                    cx.expr_try(
-                        span,
-                        cx.expr_call_global(span, fn_read_struct_field_path.clone(), thin_vec![
-                            blkdecoder.clone(),
-                            cx.expr_str(span, name),
-                            cx.expr_usize(span, field),
-                            exprdecode.clone(),
-                        ]),
-                    )
-                });
-            let result = cx.expr_ok(trait_span, result);
-            let fn_read_struct_path: Vec<_> =
-                cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct]);
-
-            cx.expr_call_global(trait_span, fn_read_struct_path, thin_vec![
-                decoder,
-                cx.expr_str(trait_span, substr.type_ident.name),
-                cx.expr_usize(trait_span, nfields),
-                cx.lambda1(trait_span, result, blkarg),
-            ])
-        }
-        StaticEnum(_, fields) => {
-            let variant = Ident::new(sym::i, trait_span);
-
-            let mut arms = ThinVec::with_capacity(fields.len() + 1);
-            let mut variants = ThinVec::with_capacity(fields.len());
-
-            let fn_read_enum_variant_arg_path: Vec<_> =
-                cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum_variant_arg]);
-
-            for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() {
-                variants.push(cx.expr_str(v_span, ident.name));
-
-                let path = cx.path(trait_span, vec![substr.type_ident, ident]);
-                let decoded =
-                    decode_static_fields(cx, v_span, path, parts, |cx, span, _, field| {
-                        let idx = cx.expr_usize(span, field);
-                        cx.expr_try(
-                            span,
-                            cx.expr_call_global(
-                                span,
-                                fn_read_enum_variant_arg_path.clone(),
-                                thin_vec![blkdecoder.clone(), idx, exprdecode.clone()],
-                            ),
-                        )
-                    });
-
-                arms.push(cx.arm(v_span, cx.pat_lit(v_span, cx.expr_usize(v_span, i)), decoded));
-            }
-
-            arms.push(cx.arm_unreachable(trait_span));
-
-            let result = cx.expr_ok(
-                trait_span,
-                cx.expr_match(trait_span, cx.expr_ident(trait_span, variant), arms),
-            );
-            let lambda = cx.lambda(trait_span, vec![blkarg, variant], result);
-            let variant_array_ref = cx.expr_array_ref(trait_span, variants);
-            let fn_read_enum_variant_path: Vec<_> =
-                cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum_variant]);
-            let result = cx.expr_call_global(trait_span, fn_read_enum_variant_path, thin_vec![
-                blkdecoder,
-                variant_array_ref,
-                lambda
-            ]);
-            let fn_read_enum_path: Vec<_> =
-                cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum]);
-
-            cx.expr_call_global(trait_span, fn_read_enum_path, thin_vec![
-                decoder,
-                cx.expr_str(trait_span, substr.type_ident.name),
-                cx.lambda1(trait_span, result, blkarg),
-            ])
-        }
-        _ => cx.dcx().bug("expected StaticEnum or StaticStruct in derive(Decodable)"),
-    };
-    BlockOrExpr::new_expr(expr)
-}
-
-/// Creates a decoder for a single enum variant/struct:
-/// - `outer_pat_path` is the path to this enum variant/struct
-/// - `getarg` should retrieve the `usize`-th field with name `@str`.
-fn decode_static_fields<F>(
-    cx: &ExtCtxt<'_>,
-    trait_span: Span,
-    outer_pat_path: ast::Path,
-    fields: &StaticFields,
-    mut getarg: F,
-) -> P<Expr>
-where
-    F: FnMut(&ExtCtxt<'_>, Span, Symbol, usize) -> P<Expr>,
-{
-    match fields {
-        Unnamed(fields, is_tuple) => {
-            let path_expr = cx.expr_path(outer_pat_path);
-            if matches!(is_tuple, IsTuple::No) {
-                path_expr
-            } else {
-                let fields = fields
-                    .iter()
-                    .enumerate()
-                    .map(|(i, &span)| getarg(cx, span, Symbol::intern(&format!("_field{i}")), i))
-                    .collect();
-
-                cx.expr_call(trait_span, path_expr, fields)
-            }
-        }
-        Named(fields) => {
-            // use the field's span to get nicer error messages.
-            let fields = fields
-                .iter()
-                .enumerate()
-                .map(|(i, &(ident, span, _))| {
-                    let arg = getarg(cx, span, ident.name, i);
-                    cx.field_imm(span, ident, arg)
-                })
-                .collect();
-            cx.expr_struct(trait_span, outer_pat_path, fields)
-        }
-    }
-}
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 3c7bebd0f19..2388b7dd648 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -42,7 +42,7 @@ pub(crate) fn expand_deriving_default(
                     StaticStruct(_, fields) => {
                         default_struct_substructure(cx, trait_span, substr, fields)
                     }
-                    StaticEnum(enum_def, _) => {
+                    StaticEnum(enum_def) => {
                         default_enum_substructure(cx, trait_span, enum_def, item.span())
                     }
                     _ => cx.dcx().span_bug(trait_span, "method in `derive(Default)`"),
diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
deleted file mode 100644
index 20aacb2caca..00000000000
--- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs
+++ /dev/null
@@ -1,284 +0,0 @@
-//! The compiler code necessary to implement the `#[derive(RustcEncodable)]`
-//! (and `RustcDecodable`, in `decodable.rs`) extension. The idea here is that
-//! type-defining items may be tagged with
-//! `#[derive(RustcEncodable, RustcDecodable)]`.
-//!
-//! For example, a type like:
-//!
-//! ```ignore (old code)
-//! #[derive(RustcEncodable, RustcDecodable)]
-//! struct Node { id: usize }
-//! ```
-//!
-//! would generate two implementations like:
-//!
-//! ```ignore (old code)
-//! # struct Node { id: usize }
-//! impl<S: Encoder<E>, E> Encodable<S, E> for Node {
-//!     fn encode(&self, s: &mut S) -> Result<(), E> {
-//!         s.emit_struct("Node", 1, |this| {
-//!             this.emit_struct_field("id", 0, |this| {
-//!                 Encodable::encode(&self.id, this)
-//!                 /* this.emit_usize(self.id) can also be used */
-//!             })
-//!         })
-//!     }
-//! }
-//!
-//! impl<D: Decoder<E>, E> Decodable<D, E> for Node {
-//!     fn decode(d: &mut D) -> Result<Node, E> {
-//!         d.read_struct("Node", 1, |this| {
-//!             match this.read_struct_field("id", 0, |this| Decodable::decode(this)) {
-//!                 Ok(id) => Ok(Node { id: id }),
-//!                 Err(e) => Err(e),
-//!             }
-//!         })
-//!     }
-//! }
-//! ```
-//!
-//! Other interesting scenarios are when the item has type parameters or
-//! references other non-built-in types. A type definition like:
-//!
-//! ```ignore (old code)
-//! # #[derive(RustcEncodable, RustcDecodable)]
-//! # struct Span;
-//! #[derive(RustcEncodable, RustcDecodable)]
-//! struct Spanned<T> { node: T, span: Span }
-//! ```
-//!
-//! would yield functions like:
-//!
-//! ```ignore (old code)
-//! # #[derive(RustcEncodable, RustcDecodable)]
-//! # struct Span;
-//! # struct Spanned<T> { node: T, span: Span }
-//! impl<
-//!     S: Encoder<E>,
-//!     E,
-//!     T: Encodable<S, E>
-//! > Encodable<S, E> for Spanned<T> {
-//!     fn encode(&self, s: &mut S) -> Result<(), E> {
-//!         s.emit_struct("Spanned", 2, |this| {
-//!             this.emit_struct_field("node", 0, |this| self.node.encode(this))
-//!                 .unwrap();
-//!             this.emit_struct_field("span", 1, |this| self.span.encode(this))
-//!         })
-//!     }
-//! }
-//!
-//! impl<
-//!     D: Decoder<E>,
-//!     E,
-//!     T: Decodable<D, E>
-//! > Decodable<D, E> for Spanned<T> {
-//!     fn decode(d: &mut D) -> Result<Spanned<T>, E> {
-//!         d.read_struct("Spanned", 2, |this| {
-//!             Ok(Spanned {
-//!                 node: this.read_struct_field("node", 0, |this| Decodable::decode(this))
-//!                     .unwrap(),
-//!                 span: this.read_struct_field("span", 1, |this| Decodable::decode(this))
-//!                     .unwrap(),
-//!             })
-//!         })
-//!     }
-//! }
-//! ```
-
-use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability};
-use rustc_expand::base::{Annotatable, ExtCtxt};
-use rustc_span::{Ident, Span, Symbol, sym};
-use thin_vec::{ThinVec, thin_vec};
-
-use crate::deriving::generic::ty::*;
-use crate::deriving::generic::*;
-use crate::deriving::pathvec_std;
-
-pub(crate) fn expand_deriving_rustc_encodable(
-    cx: &ExtCtxt<'_>,
-    span: Span,
-    mitem: &MetaItem,
-    item: &Annotatable,
-    push: &mut dyn FnMut(Annotatable),
-    is_const: bool,
-) {
-    let krate = sym::rustc_serialize;
-    let typaram = sym::__S;
-
-    let trait_def = TraitDef {
-        span,
-        path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global),
-        skip_path_as_bound: false,
-        needs_copy_as_bound_if_packed: true,
-        additional_bounds: Vec::new(),
-        supports_unions: false,
-        methods: vec![MethodDef {
-            name: sym::encode,
-            generics: Bounds {
-                bounds: vec![(typaram, vec![Path::new_(
-                    vec![krate, sym::Encoder],
-                    vec![],
-                    PathKind::Global,
-                )])],
-            },
-            explicit_self: true,
-            nonself_args: vec![(
-                Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut),
-                sym::s,
-            )],
-            ret_ty: Path(Path::new_(
-                pathvec_std!(result::Result),
-                vec![
-                    Box::new(Unit),
-                    Box::new(Path(Path::new_(vec![typaram, sym::Error], vec![], PathKind::Local))),
-                ],
-                PathKind::Std,
-            )),
-            attributes: AttrVec::new(),
-            fieldless_variants_strategy: FieldlessVariantsStrategy::Default,
-            combine_substructure: combine_substructure(Box::new(|a, b, c| {
-                encodable_substructure(a, b, c, krate)
-            })),
-        }],
-        associated_types: Vec::new(),
-        is_const,
-    };
-
-    trait_def.expand(cx, mitem, item, push)
-}
-
-fn encodable_substructure(
-    cx: &ExtCtxt<'_>,
-    trait_span: Span,
-    substr: &Substructure<'_>,
-    krate: Symbol,
-) -> BlockOrExpr {
-    let encoder = substr.nonselflike_args[0].clone();
-    // throw an underscore in front to suppress unused variable warnings
-    let blkarg = Ident::new(sym::_e, trait_span);
-    let blkencoder = cx.expr_ident(trait_span, blkarg);
-    let fn_path = cx.expr_path(cx.path_global(trait_span, vec![
-        Ident::new(krate, trait_span),
-        Ident::new(sym::Encodable, trait_span),
-        Ident::new(sym::encode, trait_span),
-    ]));
-
-    match substr.fields {
-        Struct(_, fields) => {
-            let fn_emit_struct_field_path =
-                cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]);
-            let mut stmts = ThinVec::new();
-            for (i, &FieldInfo { name, ref self_expr, span, .. }) in fields.iter().enumerate() {
-                let name = match name {
-                    Some(id) => id.name,
-                    None => Symbol::intern(&format!("_field{i}")),
-                };
-                let self_ref = cx.expr_addr_of(span, self_expr.clone());
-                let enc =
-                    cx.expr_call(span, fn_path.clone(), thin_vec![self_ref, blkencoder.clone()]);
-                let lambda = cx.lambda1(span, enc, blkarg);
-                let call = cx.expr_call_global(span, fn_emit_struct_field_path.clone(), thin_vec![
-                    blkencoder.clone(),
-                    cx.expr_str(span, name),
-                    cx.expr_usize(span, i),
-                    lambda,
-                ]);
-
-                // last call doesn't need a try!
-                let last = fields.len() - 1;
-                let call = if i != last {
-                    cx.expr_try(span, call)
-                } else {
-                    cx.expr(span, ExprKind::Ret(Some(call)))
-                };
-
-                let stmt = cx.stmt_expr(call);
-                stmts.push(stmt);
-            }
-
-            // unit structs have no fields and need to return Ok()
-            let blk = if stmts.is_empty() {
-                let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, ThinVec::new()));
-                cx.lambda1(trait_span, ok, blkarg)
-            } else {
-                cx.lambda_stmts_1(trait_span, stmts, blkarg)
-            };
-
-            let fn_emit_struct_path =
-                cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct]);
-
-            let expr = cx.expr_call_global(trait_span, fn_emit_struct_path, thin_vec![
-                encoder,
-                cx.expr_str(trait_span, substr.type_ident.name),
-                cx.expr_usize(trait_span, fields.len()),
-                blk,
-            ]);
-            BlockOrExpr::new_expr(expr)
-        }
-
-        EnumMatching(idx, variant, fields) => {
-            // We're not generating an AST that the borrow checker is expecting,
-            // so we need to generate a unique local variable to take the
-            // mutable loan out on, otherwise we get conflicts which don't
-            // actually exist.
-            let me = cx.stmt_let(trait_span, false, blkarg, encoder);
-            let encoder = cx.expr_ident(trait_span, blkarg);
-
-            let fn_emit_enum_variant_arg_path: Vec<_> =
-                cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum_variant_arg]);
-
-            let mut stmts = ThinVec::new();
-            if !fields.is_empty() {
-                let last = fields.len() - 1;
-                for (i, &FieldInfo { ref self_expr, span, .. }) in fields.iter().enumerate() {
-                    let self_ref = cx.expr_addr_of(span, self_expr.clone());
-                    let enc = cx
-                        .expr_call(span, fn_path.clone(), thin_vec![self_ref, blkencoder.clone()]);
-                    let lambda = cx.lambda1(span, enc, blkarg);
-
-                    let call = cx.expr_call_global(
-                        span,
-                        fn_emit_enum_variant_arg_path.clone(),
-                        thin_vec![blkencoder.clone(), cx.expr_usize(span, i), lambda],
-                    );
-                    let call = if i != last {
-                        cx.expr_try(span, call)
-                    } else {
-                        cx.expr(span, ExprKind::Ret(Some(call)))
-                    };
-                    stmts.push(cx.stmt_expr(call));
-                }
-            } else {
-                let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, ThinVec::new()));
-                let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok)));
-                stmts.push(cx.stmt_expr(ret_ok));
-            }
-
-            let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
-            let name = cx.expr_str(trait_span, variant.ident.name);
-
-            let fn_emit_enum_variant_path: Vec<_> =
-                cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum_variant]);
-
-            let call = cx.expr_call_global(trait_span, fn_emit_enum_variant_path, thin_vec![
-                blkencoder,
-                name,
-                cx.expr_usize(trait_span, *idx),
-                cx.expr_usize(trait_span, fields.len()),
-                blk,
-            ]);
-
-            let blk = cx.lambda1(trait_span, call, blkarg);
-            let fn_emit_enum_path: Vec<_> =
-                cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum]);
-            let expr = cx.expr_call_global(trait_span, fn_emit_enum_path, thin_vec![
-                encoder,
-                cx.expr_str(trait_span, substr.type_ident.name),
-                blk
-            ]);
-            BlockOrExpr::new_mixed(thin_vec![me], Some(expr))
-        }
-
-        _ => cx.dcx().bug("expected Struct or EnumMatching in derive(Encodable)"),
-    }
-}
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index f0a5e44e066..0631c5a80fc 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -311,7 +311,7 @@ pub(crate) enum SubstructureFields<'a> {
     /// Matching variants of the enum: variant index, ast::Variant,
     /// fields: the field name is only non-`None` in the case of a struct
     /// variant.
-    EnumMatching(usize, &'a ast::Variant, Vec<FieldInfo>),
+    EnumMatching(&'a ast::Variant, Vec<FieldInfo>),
 
     /// The discriminant of an enum. The first field is a `FieldInfo` for the discriminants, as
     /// if they were fields. The second field is the expression to combine the
@@ -322,7 +322,7 @@ pub(crate) enum SubstructureFields<'a> {
     StaticStruct(&'a ast::VariantData, StaticFields),
 
     /// A static method where `Self` is an enum.
-    StaticEnum(&'a ast::EnumDef, Vec<(Ident, Span, StaticFields)>),
+    StaticEnum(&'a ast::EnumDef),
 }
 
 /// Combine the values of all the fields together. The last argument is
@@ -1034,6 +1034,7 @@ impl<'a> MethodDef<'a> {
                 defaultness,
                 sig,
                 generics: fn_generics,
+                contract: None,
                 body: Some(body_block),
             })),
             tokens: None,
@@ -1270,7 +1271,7 @@ impl<'a> MethodDef<'a> {
                     trait_,
                     type_ident,
                     nonselflike_args,
-                    &EnumMatching(0, variant, Vec::new()),
+                    &EnumMatching(variant, Vec::new()),
                 );
             }
         }
@@ -1282,9 +1283,8 @@ impl<'a> MethodDef<'a> {
         // where each tuple has length = selflike_args.len()
         let mut match_arms: ThinVec<ast::Arm> = variants
             .iter()
-            .enumerate()
-            .filter(|&(_, v)| !(unify_fieldless_variants && v.data.fields().is_empty()))
-            .map(|(index, variant)| {
+            .filter(|&v| !(unify_fieldless_variants && v.data.fields().is_empty()))
+            .map(|variant| {
                 // A single arm has form (&VariantK, &VariantK, ...) => BodyK
                 // (see "Final wrinkle" note below for why.)
 
@@ -1316,7 +1316,7 @@ impl<'a> MethodDef<'a> {
                 // expressions for referencing every field of every
                 // Self arg, assuming all are instances of VariantK.
                 // Build up code associated with such a case.
-                let substructure = EnumMatching(index, variant, fields);
+                let substructure = EnumMatching(variant, fields);
                 let arm_expr = self
                     .call_substructure_method(
                         cx,
@@ -1344,7 +1344,7 @@ impl<'a> MethodDef<'a> {
                         trait_,
                         type_ident,
                         nonselflike_args,
-                        &EnumMatching(0, v, Vec::new()),
+                        &EnumMatching(v, Vec::new()),
                     )
                     .into_expr(cx, span),
                 )
@@ -1407,21 +1407,12 @@ impl<'a> MethodDef<'a> {
         type_ident: Ident,
         nonselflike_args: &[P<Expr>],
     ) -> BlockOrExpr {
-        let summary = enum_def
-            .variants
-            .iter()
-            .map(|v| {
-                let sp = v.span.with_ctxt(trait_.span.ctxt());
-                let summary = trait_.summarise_struct(cx, &v.data);
-                (v.ident, sp, summary)
-            })
-            .collect();
         self.call_substructure_method(
             cx,
             trait_,
             type_ident,
             nonselflike_args,
-            &StaticEnum(enum_def, summary),
+            &StaticEnum(enum_def),
         )
     }
 }
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index af6dc62db7a..f34a6ae1d98 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -21,7 +21,6 @@ pub(crate) struct Path {
 #[derive(Clone)]
 pub(crate) enum PathKind {
     Local,
-    Global,
     Std,
 }
 
@@ -57,7 +56,6 @@ impl Path {
         let params = tys.map(GenericArg::Type).collect();
 
         match self.kind {
-            PathKind::Global => cx.path_all(span, true, idents, params),
             PathKind::Local => cx.path_all(span, false, idents, params),
             PathKind::Std => {
                 let def_site = cx.with_def_site_ctxt(DUMMY_SP);
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index ec058b41313..c112589b131 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -23,9 +23,7 @@ pub(crate) mod bounds;
 pub(crate) mod clone;
 pub(crate) mod coerce_pointee;
 pub(crate) mod debug;
-pub(crate) mod decodable;
 pub(crate) mod default;
-pub(crate) mod encodable;
 pub(crate) mod hash;
 
 #[path = "cmp/eq.rs"]
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 7c746bd719f..90447da6680 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -8,7 +8,9 @@ use rustc_ast::{
     token,
 };
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{Applicability, Diag, MultiSpan, PResult, SingleLabelManySpans};
+use rustc_errors::{
+    Applicability, Diag, MultiSpan, PResult, SingleLabelManySpans, listify, pluralize,
+};
 use rustc_expand::base::*;
 use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
 use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, LintId};
@@ -975,15 +977,11 @@ fn report_invalid_references(
         } else {
             MultiSpan::from_spans(invalid_refs.iter().filter_map(|&(_, span, _, _)| span).collect())
         };
-        let arg_list = if let &[index] = &indexes[..] {
-            format!("argument {index}")
-        } else {
-            let tail = indexes.pop().unwrap();
-            format!(
-                "arguments {head} and {tail}",
-                head = indexes.into_iter().map(|i| i.to_string()).collect::<Vec<_>>().join(", ")
-            )
-        };
+        let arg_list = format!(
+            "argument{} {}",
+            pluralize!(indexes.len()),
+            listify(&indexes, |i: &usize| i.to_string()).unwrap_or_default()
+        );
         e = ecx.dcx().struct_span_err(
             span,
             format!("invalid reference to positional {arg_list} ({num_args_desc})"),
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 8388e9dcafb..8fdbbf8e704 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -81,6 +81,7 @@ impl AllocFnFactory<'_, '_> {
             defaultness: ast::Defaultness::Final,
             sig,
             generics: Generics::default(),
+            contract: None,
             body,
         }));
         let item = self.cx.item(
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 0918403b855..ca16583a45d 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -55,6 +55,7 @@ mod trace_macros;
 
 pub mod asm;
 pub mod cmdline_attrs;
+pub mod contracts;
 pub mod proc_macro_harness;
 pub mod standard_library_imports;
 pub mod test_harness;
@@ -132,11 +133,13 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         Ord: ord::expand_deriving_ord,
         PartialEq: partial_eq::expand_deriving_partial_eq,
         PartialOrd: partial_ord::expand_deriving_partial_ord,
-        RustcDecodable: decodable::expand_deriving_rustc_decodable,
-        RustcEncodable: encodable::expand_deriving_rustc_encodable,
         CoercePointee: coerce_pointee::expand_deriving_coerce_pointee,
     }
 
     let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
     register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })));
+    let requires = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandRequires));
+    register(sym::contracts_requires, requires);
+    let ensures = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandEnsures));
+    register(sym::contracts_ensures, ensures);
 }
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 31b068bd33d..472e16e62d5 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -344,6 +344,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
         defaultness,
         sig,
         generics: ast::Generics::default(),
+        contract: None,
         body: Some(main_body),
     }));
 
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index c7c9c6236d1..a2b9e5712e5 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -868,7 +868,16 @@ fn codegen_stmt<'tcx>(
                         NullOp::UbChecks => {
                             let val = fx.tcx.sess.ub_checks();
                             let val = CValue::by_val(
-                                fx.bcx.ins().iconst(types::I8, i64::try_from(val).unwrap()),
+                                fx.bcx.ins().iconst(types::I8, i64::from(val)),
+                                fx.layout_of(fx.tcx.types.bool),
+                            );
+                            lval.write_cvalue(fx, val);
+                            return;
+                        }
+                        NullOp::ContractChecks => {
+                            let val = fx.tcx.sess.contract_checks();
+                            let val = CValue::by_val(
+                                fx.bcx.ins().iconst(types::I8, i64::from(val)),
                                 fx.layout_of(fx.tcx.types.bool),
                             );
                             lval.write_cvalue(fx, val);
@@ -925,6 +934,10 @@ fn codegen_stmt<'tcx>(
                     }
                     crate::discriminant::codegen_set_discriminant(fx, lval, variant_index);
                 }
+                Rvalue::WrapUnsafeBinder(ref operand, _to_ty) => {
+                    let operand = codegen_operand(fx, operand);
+                    lval.write_cvalue_transmute(fx, operand);
+                }
             }
         }
         StatementKind::StorageLive(_)
@@ -993,7 +1006,9 @@ pub(crate) fn codegen_place<'tcx>(
                 cplace = cplace.place_deref(fx);
             }
             PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"),
-            PlaceElem::Subtype(ty) => cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty)),
+            PlaceElem::Subtype(ty) | PlaceElem::UnwrapUnsafeBinder(ty) => {
+                cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty));
+            }
             PlaceElem::Field(field, _ty) => {
                 cplace = cplace.place_field(fx, field);
             }
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index 27adf6318e2..a52b18573b1 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -692,7 +692,7 @@ pub(crate) fn run_aot(
 
     if tcx.dep_graph.is_fully_enabled() {
         for cgu in cgus {
-            tcx.ensure().codegen_unit(cgu.name());
+            tcx.ensure_ok().codegen_unit(cgu.name());
         }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 2d007416263..264d43c6d46 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -421,6 +421,20 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         unchecked_umul(x, y) => LLVMBuildNUWMul,
     }
 
+    fn or_disjoint(&mut self, a: &'ll Value, b: &'ll Value) -> &'ll Value {
+        unsafe {
+            let or = llvm::LLVMBuildOr(self.llbuilder, a, b, UNNAMED);
+
+            // If a and b are both values, then `or` is a value, rather than
+            // an instruction, so we need to check before setting the flag.
+            // (See also `LLVMBuildNUWNeg` which also needs a check.)
+            if llvm::LLVMIsAInstruction(or).is_some() {
+                llvm::LLVMSetIsDisjoint(or, True);
+            }
+            or
+        }
+    }
+
     set_math_builder_methods! {
         fadd_fast(x, y) => (LLVMBuildFAdd, LLVMRustSetFastMath),
         fsub_fast(x, y) => (LLVMBuildFSub, LLVMRustSetFastMath),
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 771ebf2057f..c6855dd42e5 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -420,8 +420,14 @@ impl<'ll> CodegenCx<'ll, '_> {
             let g = if val_llty == llty {
                 g
             } else {
-                // If we created the global with the wrong type,
-                // correct the type.
+                // codegen_static_initializer creates the global value just from the
+                // `Allocation` data by generating one big struct value that is just
+                // all the bytes and pointers after each other. This will almost never
+                // match the type that the static was declared with. Unfortunately
+                // we can't just LLVMConstBitCast our way out of it because that has very
+                // specific rules on what can be cast. So instead of adding a new way to
+                // generate static initializers that match the static's type, we picked
+                // the easier option and retroactively change the type of the static item itself.
                 let name = llvm::get_value_name(g).to_vec();
                 llvm::set_value_name(g, b"");
 
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
index 11eb9651af6..f52991b3697 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
@@ -127,7 +127,7 @@ fn make_mir_scope<'ll, 'tcx>(
             })
         }
         None => unsafe {
-            llvm::LLVMRustDIBuilderCreateLexicalBlock(
+            llvm::LLVMDIBuilderCreateLexicalBlock(
                 DIB(cx),
                 parent_scope.dbg_scope,
                 file_metadata,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 3a0c7f007bd..f497ba95661 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -931,7 +931,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
 
     unsafe {
         let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(
-            debug_context.builder,
+            debug_context.builder.as_ref(),
             name_in_debuginfo.as_c_char_ptr(),
             name_in_debuginfo.len(),
             work_dir.as_c_char_ptr(),
@@ -944,7 +944,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
         );
 
         let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
-            debug_context.builder,
+            debug_context.builder.as_ref(),
             dwarf_const::DW_LANG_Rust,
             compile_unit_file,
             producer.as_c_char_ptr(),
@@ -1641,7 +1641,14 @@ pub(crate) fn extend_scope_to_file<'ll>(
     file: &SourceFile,
 ) -> &'ll DILexicalBlock {
     let file_metadata = file_metadata(cx, file);
-    unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) }
+    unsafe {
+        llvm::LLVMDIBuilderCreateLexicalBlockFile(
+            DIB(cx),
+            scope_metadata,
+            file_metadata,
+            /* Discriminator (default) */ 0u32,
+        )
+    }
 }
 
 fn tuple_field_name(field_index: usize) -> Cow<'static, str> {
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index b1ce52667bd..496178c6b1d 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -34,7 +34,7 @@ use crate::builder::Builder;
 use crate::common::{AsCCharPtr, CodegenCx};
 use crate::llvm;
 use crate::llvm::debuginfo::{
-    DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType,
+    DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType,
     DIVariable,
 };
 use crate::value::Value;
@@ -61,7 +61,7 @@ const DW_TAG_arg_variable: c_uint = 0x101;
 /// A context object for maintaining all state needed by the debuginfo module.
 pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> {
     llmod: &'ll llvm::Module,
-    builder: &'ll mut DIBuilder<'ll>,
+    builder: DIBuilderBox<'ll>,
     created_files: RefCell<UnordMap<Option<(StableSourceFileId, SourceFileHash)>, &'ll DIFile>>,
 
     type_map: metadata::TypeMap<'ll, 'tcx>,
@@ -69,18 +69,10 @@ pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> {
     recursion_marker_type: OnceCell<&'ll DIType>,
 }
 
-impl Drop for CodegenUnitDebugContext<'_, '_> {
-    fn drop(&mut self) {
-        unsafe {
-            llvm::LLVMRustDIBuilderDispose(&mut *(self.builder as *mut _));
-        }
-    }
-}
-
 impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
     pub(crate) fn new(llmod: &'ll llvm::Module) -> Self {
         debug!("CodegenUnitDebugContext::new");
-        let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) };
+        let builder = DIBuilderBox::new(llmod);
         // DIBuilder inherits context from the module, so we'd better use the same one
         CodegenUnitDebugContext {
             llmod,
@@ -93,7 +85,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
     }
 
     pub(crate) fn finalize(&self, sess: &Session) {
-        unsafe { llvm::LLVMRustDIBuilderFinalize(self.builder) };
+        unsafe { llvm::LLVMDIBuilderFinalize(self.builder.as_ref()) };
 
         match sess.target.debuginfo_kind {
             DebuginfoKind::Dwarf | DebuginfoKind::DwarfDsym => {
@@ -582,7 +574,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             (line, col)
         };
 
-        unsafe { llvm::LLVMRustDIBuilderCreateDebugLocation(line, col, scope, inlined_at) }
+        unsafe { llvm::LLVMDIBuilderCreateDebugLocation(self.llcx, line, col, scope, inlined_at) }
     }
 
     fn create_vtable_debuginfo(
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
index 33d9bc23890..b4d639368b0 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
@@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::ty::{self, Instance};
 
 use super::utils::{DIB, debug_context};
-use crate::common::{AsCCharPtr, CodegenCx};
+use crate::common::CodegenCx;
 use crate::llvm;
 use crate::llvm::debuginfo::DIScope;
 
@@ -33,12 +33,12 @@ pub(crate) fn item_namespace<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'l
     };
 
     let scope = unsafe {
-        llvm::LLVMRustDIBuilderCreateNameSpace(
+        llvm::LLVMDIBuilderCreateNameSpace(
             DIB(cx),
             parent_scope,
-            namespace_name_string.as_c_char_ptr(),
+            namespace_name_string.as_ptr(),
             namespace_name_string.len(),
-            false, // ExportSymbols (only relevant for C++ anonymous namespaces)
+            llvm::False, // ExportSymbols (only relevant for C++ anonymous namespaces)
         )
     };
 
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
index 6e841293477..cc1d504b430 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
@@ -41,7 +41,7 @@ pub(crate) fn debug_context<'a, 'll, 'tcx>(
 #[inline]
 #[allow(non_snake_case)]
 pub(crate) fn DIB<'a, 'll>(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> {
-    cx.dbg_cx.as_ref().unwrap().builder
+    cx.dbg_cx.as_ref().unwrap().builder.as_ref()
 }
 
 pub(crate) fn get_namespace_for_item<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
index ae813fe5ebf..92b0ce8ffe1 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
@@ -4,6 +4,8 @@ use libc::{c_char, c_uint};
 
 use super::ffi::{BasicBlock, Metadata, Module, Type, Value};
 use crate::llvm::Bool;
+
+#[link(name = "llvm-wrapper", kind = "static")]
 extern "C" {
     // Enzyme
     pub fn LLVMRustHasMetadata(I: &Value, KindID: c_uint) -> bool;
@@ -12,10 +14,13 @@ extern "C" {
     pub fn LLVMRustDIGetInstMetadata(I: &Value) -> Option<&Metadata>;
     pub fn LLVMRustEraseInstFromParent(V: &Value);
     pub fn LLVMRustGetTerminator<'a>(B: &BasicBlock) -> &'a Value;
-    pub fn LLVMDumpModule(M: &Module);
-    pub fn LLVMDumpValue(V: &Value);
     pub fn LLVMRustVerifyFunction(V: &Value, action: LLVMRustVerifierFailureAction) -> Bool;
+}
 
+extern "C" {
+    // Enzyme
+    pub fn LLVMDumpModule(M: &Module);
+    pub fn LLVMDumpValue(V: &Value);
     pub fn LLVMGetFunctionCallConv(F: &Value) -> c_uint;
     pub fn LLVMGetReturnType(T: &Type) -> &Type;
     pub fn LLVMGetParams(Fnc: &Value, parms: *mut &Value);
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index cc7c5231aca..0d04f770bc6 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1,3 +1,15 @@
+//! Bindings to the LLVM-C API (`LLVM*`), and to our own `extern "C"` wrapper
+//! functions around the unstable LLVM C++ API (`LLVMRust*`).
+//!
+//! ## Passing pointer/length strings as `*const c_uchar`
+//!
+//! Normally it's a good idea for Rust-side bindings to match the corresponding
+//! C-side function declarations as closely as possible. But when passing `&str`
+//! or `&[u8]` data as a pointer/length pair, it's more convenient to declare
+//! the Rust-side pointer as `*const c_uchar` instead of `*const c_char`.
+//! Both pointer types have the same ABI, and using `*const c_uchar` avoids
+//! the need for an extra cast from `*const u8` on the Rust side.
+
 #![allow(non_camel_case_types)]
 #![allow(non_upper_case_globals)]
 
@@ -5,17 +17,18 @@ use std::fmt::Debug;
 use std::marker::PhantomData;
 use std::ptr;
 
-use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t};
+use bitflags::bitflags;
+use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_void, size_t};
 use rustc_macros::TryFromU32;
 use rustc_target::spec::SymbolVisibility;
 
 use super::RustString;
 use super::debuginfo::{
     DIArray, DIBasicType, DIBuilder, DICompositeType, DIDerivedType, DIDescriptor, DIEnumerator,
-    DIFile, DIFlags, DIGlobalVariableExpression, DILexicalBlock, DILocation, DINameSpace,
-    DISPFlags, DIScope, DISubprogram, DISubrange, DITemplateTypeParameter, DIType, DIVariable,
-    DebugEmissionKind, DebugNameTableKind,
+    DIFile, DIFlags, DIGlobalVariableExpression, DILocation, DISPFlags, DIScope, DISubprogram,
+    DISubrange, DITemplateTypeParameter, DIType, DIVariable, DebugEmissionKind, DebugNameTableKind,
 };
+use crate::llvm;
 
 /// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
 /// which has a different ABI from Rust or C++ `bool`.
@@ -789,12 +802,50 @@ pub type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void
 pub type InlineAsmDiagHandlerTy = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint);
 
 pub mod debuginfo {
+    use std::ptr;
+
     use bitflags::bitflags;
 
     use super::{InvariantOpaque, Metadata};
+    use crate::llvm::{self, Module};
 
+    /// Opaque target type for references to an LLVM debuginfo builder.
+    ///
+    /// `&'_ DIBuilder<'ll>` corresponds to `LLVMDIBuilderRef`, which is the
+    /// LLVM-C wrapper for `DIBuilder *`.
+    ///
+    /// Debuginfo builders are created and destroyed during codegen, so the
+    /// builder reference typically has a shorter lifetime than the LLVM
+    /// session (`'ll`) that it participates in.
     #[repr(C)]
-    pub struct DIBuilder<'a>(InvariantOpaque<'a>);
+    pub struct DIBuilder<'ll>(InvariantOpaque<'ll>);
+
+    /// Owning pointer to a `DIBuilder<'ll>` that will dispose of the builder
+    /// when dropped. Use `.as_ref()` to get the underlying `&DIBuilder`
+    /// needed for debuginfo FFI calls.
+    pub(crate) struct DIBuilderBox<'ll> {
+        raw: ptr::NonNull<DIBuilder<'ll>>,
+    }
+
+    impl<'ll> DIBuilderBox<'ll> {
+        pub(crate) fn new(llmod: &'ll Module) -> Self {
+            let raw = unsafe { llvm::LLVMCreateDIBuilder(llmod) };
+            let raw = ptr::NonNull::new(raw).unwrap();
+            Self { raw }
+        }
+
+        pub(crate) fn as_ref(&self) -> &DIBuilder<'ll> {
+            // SAFETY: This is an owning pointer, so `&DIBuilder` is valid
+            // for as long as `&self` is.
+            unsafe { self.raw.as_ref() }
+        }
+    }
+
+    impl<'ll> Drop for DIBuilderBox<'ll> {
+        fn drop(&mut self) {
+            unsafe { llvm::LLVMDisposeDIBuilder(self.raw) };
+        }
+    }
 
     pub type DIDescriptor = Metadata;
     pub type DILocation = Metadata;
@@ -914,7 +965,6 @@ pub mod debuginfo {
     }
 }
 
-use bitflags::bitflags;
 // These values **must** match with LLVMRustAllocKindFlags
 bitflags! {
     #[repr(transparent)]
@@ -1380,6 +1430,9 @@ unsafe extern "C" {
     pub fn LLVMBuildFNeg<'a>(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value;
     pub fn LLVMBuildNot<'a>(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value;
 
+    // Extra flags on arithmetic
+    pub fn LLVMSetIsDisjoint(Instr: &Value, IsDisjoint: Bool);
+
     // Memory
     pub fn LLVMBuildAlloca<'a>(B: &Builder<'a>, Ty: &'a Type, Name: *const c_char) -> &'a Value;
     pub fn LLVMBuildArrayAlloca<'a>(
@@ -1672,6 +1725,50 @@ unsafe extern "C" {
     ) -> &'a Value;
 }
 
+// FFI bindings for `DIBuilder` functions in the LLVM-C API.
+// Try to keep these in the same order as in `llvm/include/llvm-c/DebugInfo.h`.
+//
+// FIXME(#134001): Audit all `Option` parameters, especially in lists, to check
+// that they really are nullable on the C/C++ side. LLVM doesn't appear to
+// actually document which ones are nullable.
+unsafe extern "C" {
+    pub(crate) fn LLVMCreateDIBuilder<'ll>(M: &'ll Module) -> *mut DIBuilder<'ll>;
+    pub(crate) fn LLVMDisposeDIBuilder<'ll>(Builder: ptr::NonNull<DIBuilder<'ll>>);
+
+    pub(crate) fn LLVMDIBuilderFinalize<'ll>(Builder: &DIBuilder<'ll>);
+
+    pub(crate) fn LLVMDIBuilderCreateNameSpace<'ll>(
+        Builder: &DIBuilder<'ll>,
+        ParentScope: Option<&'ll Metadata>,
+        Name: *const c_uchar,
+        NameLen: size_t,
+        ExportSymbols: llvm::Bool,
+    ) -> &'ll Metadata;
+
+    pub(crate) fn LLVMDIBuilderCreateLexicalBlock<'ll>(
+        Builder: &DIBuilder<'ll>,
+        Scope: &'ll Metadata,
+        File: &'ll Metadata,
+        Line: c_uint,
+        Column: c_uint,
+    ) -> &'ll Metadata;
+
+    pub(crate) fn LLVMDIBuilderCreateLexicalBlockFile<'ll>(
+        Builder: &DIBuilder<'ll>,
+        Scope: &'ll Metadata,
+        File: &'ll Metadata,
+        Discriminator: c_uint, // (optional "DWARF path discriminator"; default is 0)
+    ) -> &'ll Metadata;
+
+    pub(crate) fn LLVMDIBuilderCreateDebugLocation<'ll>(
+        Ctx: &'ll Context,
+        Line: c_uint,
+        Column: c_uint,
+        Scope: &'ll Metadata,
+        InlinedAt: Option<&'ll Metadata>,
+    ) -> &'ll Metadata;
+}
+
 #[link(name = "llvm-wrapper", kind = "static")]
 unsafe extern "C" {
     pub fn LLVMRustInstallErrorHandlers();
@@ -1939,12 +2036,6 @@ unsafe extern "C" {
         ValueLen: size_t,
     );
 
-    pub fn LLVMRustDIBuilderCreate(M: &Module) -> &mut DIBuilder<'_>;
-
-    pub fn LLVMRustDIBuilderDispose<'a>(Builder: &'a mut DIBuilder<'a>);
-
-    pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder<'_>);
-
     pub fn LLVMRustDIBuilderCreateCompileUnit<'a>(
         Builder: &DIBuilder<'a>,
         Lang: c_uint,
@@ -2107,20 +2198,6 @@ unsafe extern "C" {
         Type: &'a DIType,
     ) -> &'a DIDerivedType;
 
-    pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>(
-        Builder: &DIBuilder<'a>,
-        Scope: &'a DIScope,
-        File: &'a DIFile,
-        Line: c_uint,
-        Col: c_uint,
-    ) -> &'a DILexicalBlock;
-
-    pub fn LLVMRustDIBuilderCreateLexicalBlockFile<'a>(
-        Builder: &DIBuilder<'a>,
-        Scope: &'a DIScope,
-        File: &'a DIFile,
-    ) -> &'a DILexicalBlock;
-
     pub fn LLVMRustDIBuilderCreateStaticVariable<'a>(
         Builder: &DIBuilder<'a>,
         Context: Option<&'a DIScope>,
@@ -2245,14 +2322,6 @@ unsafe extern "C" {
         Ty: &'a DIType,
     ) -> &'a DITemplateTypeParameter;
 
-    pub fn LLVMRustDIBuilderCreateNameSpace<'a>(
-        Builder: &DIBuilder<'a>,
-        Scope: Option<&'a DIScope>,
-        Name: *const c_char,
-        NameLen: size_t,
-        ExportSymbols: bool,
-    ) -> &'a DINameSpace;
-
     pub fn LLVMRustDICompositeTypeReplaceArrays<'a>(
         Builder: &DIBuilder<'a>,
         CompositeType: &'a DIType,
@@ -2260,12 +2329,6 @@ unsafe extern "C" {
         Params: Option<&'a DIArray>,
     );
 
-    pub fn LLVMRustDIBuilderCreateDebugLocation<'a>(
-        Line: c_uint,
-        Column: c_uint,
-        Scope: &'a DIScope,
-        InlinedAt: Option<&'a DILocation>,
-    ) -> &'a DILocation;
     pub fn LLVMRustDILocationCloneWithBaseDiscriminator<'a>(
         Location: &'a DILocation,
         BD: c_uint,
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 914f2c21fa7..ce2161a07eb 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -403,7 +403,7 @@ fn generate_lto_work<B: ExtraBackendMethods>(
         assert!(needs_thin_lto.is_empty());
         let mut module =
             B::run_fat_lto(cgcx, needs_fat_lto, import_only_modules).unwrap_or_else(|e| e.raise());
-        if cgcx.lto == Lto::Fat {
+        if cgcx.lto == Lto::Fat && !autodiff.is_empty() {
             let config = cgcx.config(ModuleKind::Regular);
             module = unsafe { module.autodiff(cgcx, autodiff, config).unwrap() };
         }
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 6e0333cf3ce..df945920ee8 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -634,7 +634,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     // unnecessarily.
     if tcx.dep_graph.is_fully_enabled() {
         for cgu in codegen_units {
-            tcx.ensure().codegen_unit(cgu.name());
+            tcx.ensure_ok().codegen_unit(cgu.name());
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 304ac4544ee..6e7fbe62c8d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -225,6 +225,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 args[1].val.unaligned_volatile_store(bx, dst);
                 return Ok(());
             }
+            sym::disjoint_bitor => {
+                let a = args[0].immediate();
+                let b = args[1].immediate();
+                bx.or_disjoint(a, b)
+            }
             sym::exact_div => {
                 let ty = arg_tys[0];
                 match int_type_width_signed(ty, bx.tcx()) {
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index c634f864ffb..73a41676802 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -502,6 +502,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     bug!("encountered OpaqueCast({ty}) in codegen")
                 }
                 mir::ProjectionElem::Subtype(ty) => cg_base.project_type(bx, self.monomorphize(ty)),
+                mir::ProjectionElem::UnwrapUnsafeBinder(ty) => {
+                    cg_base.project_type(bx, self.monomorphize(ty))
+                }
                 mir::ProjectionElem::Index(index) => {
                     let index = &mir::Operand::Copy(mir::Place::from(index));
                     let index = self.codegen_operand(bx, index);
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index d7fc5e8e673..27cb7883b9a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -741,6 +741,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         let val = bx.tcx().sess.ub_checks();
                         bx.cx().const_bool(val)
                     }
+                    mir::NullOp::ContractChecks => {
+                        let val = bx.tcx().sess.contract_checks();
+                        bx.cx().const_bool(val)
+                    }
                 };
                 let tcx = self.cx.tcx();
                 OperandRef {
@@ -823,6 +827,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
                 OperandRef { val: OperandValue::Immediate(val), layout: box_layout }
             }
+            mir::Rvalue::WrapUnsafeBinder(ref operand, binder_ty) => {
+                let operand = self.codegen_operand(bx, operand);
+                let binder_ty = self.monomorphize(binder_ty);
+                let layout = bx.cx().layout_of(binder_ty);
+                OperandRef { val: operand.val, layout }
+            }
         }
     }
 
@@ -1123,7 +1133,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::Rvalue::Discriminant(..) |
             mir::Rvalue::NullaryOp(..) |
             mir::Rvalue::ThreadLocalRef(_) |
-            mir::Rvalue::Use(..) => // (*)
+            mir::Rvalue::Use(..) |
+            mir::Rvalue::WrapUnsafeBinder(..) => // (*)
                 true,
             // Arrays are always aggregates, so it's not worth checking anything here.
             // (If it's really `[(); N]` or `[T; 0]` and we use the place path, fine.)
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index bbf87a59942..b7dcf16fa2b 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -167,6 +167,11 @@ pub trait BuilderMethods<'a, 'tcx>:
     fn unchecked_umul(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
     fn and(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
     fn or(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
+    /// Defaults to [`Self::or`], but guarantees `(lhs & rhs) == 0` so some backends
+    /// can emit something more helpful for optimizations.
+    fn or_disjoint(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value {
+        self.or(lhs, rhs)
+    }
     fn xor(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
     fn neg(&mut self, v: Self::Value) -> Self::Value;
     fn fneg(&mut self, v: Self::Value) -> Self::Value;
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index d600d223bff..eecc6690f51 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -280,7 +280,9 @@ const_eval_nullary_intrinsic_fail =
     could not evaluate nullary intrinsic
 
 const_eval_offset_from_different_allocations =
-    `{$name}` called on pointers into different allocations
+    `{$name}` called on two different pointers that are not both derived from the same allocation
+const_eval_offset_from_out_of_bounds =
+    `{$name}` called on two different pointers where the memory range between them is not in-bounds of an allocation
 const_eval_offset_from_overflow =
     `{$name}` called when first pointer is too far ahead of second
 const_eval_offset_from_test =
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 4834fd3d34c..d0ce027ec2b 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -675,7 +675,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             Rvalue::Cast(_, _, _) => {}
 
             Rvalue::NullaryOp(
-                NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks,
+                NullOp::SizeOf
+                | NullOp::AlignOf
+                | NullOp::OffsetOf(_)
+                | NullOp::UbChecks
+                | NullOp::ContractChecks,
                 _,
             ) => {}
             Rvalue::ShallowInitBox(_, _) => {}
@@ -728,6 +732,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     );
                 }
             }
+
+            Rvalue::WrapUnsafeBinder(..) => {
+                // Unsafe binders are always trivial to create.
+            }
         }
     }
 
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index 5d368b600a0..9c99782d223 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -258,6 +258,8 @@ where
             in_place::<Q, _>(cx, in_local, place.as_ref())
         }
 
+        Rvalue::WrapUnsafeBinder(op, _) => in_operand::<Q, _>(cx, in_local, op),
+
         Rvalue::Aggregate(kind, operands) => {
             // Return early if we know that the struct or enum being constructed is always
             // qualified.
@@ -297,7 +299,8 @@ where
             | ProjectionElem::ConstantIndex { .. }
             | ProjectionElem::Subslice { .. }
             | ProjectionElem::Downcast(_, _)
-            | ProjectionElem::Index(_) => {}
+            | ProjectionElem::Index(_)
+            | ProjectionElem::UnwrapUnsafeBinder(_) => {}
         }
 
         let base_ty = place_base.ty(cx.body, cx.tcx);
diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs
index 79df63a9e84..8cee282311f 100644
--- a/compiler/rustc_const_eval/src/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs
@@ -202,7 +202,8 @@ where
             | mir::Rvalue::NullaryOp(..)
             | mir::Rvalue::UnaryOp(..)
             | mir::Rvalue::Discriminant(..)
-            | mir::Rvalue::Aggregate(..) => {}
+            | mir::Rvalue::Aggregate(..)
+            | mir::Rvalue::WrapUnsafeBinder(..) => {}
         }
     }
 
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index 34f795bda75..c0438fb3ff8 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -1,7 +1,7 @@
 // Not in interpret to make sure we do not use private implementation details
 
 use rustc_abi::VariantIdx;
-use rustc_middle::query::{Key, TyCtxtAt};
+use rustc_middle::query::Key;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::{bug, mir};
@@ -35,16 +35,17 @@ pub(crate) type ValTreeCreationResult<'tcx> = Result<ty::ValTree<'tcx>, ValTreeC
 
 #[instrument(skip(tcx), level = "debug")]
 pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
-    tcx: TyCtxtAt<'tcx>,
+    tcx: TyCtxt<'tcx>,
     val: mir::ConstValue<'tcx>,
     ty: Ty<'tcx>,
 ) -> Option<mir::DestructuredConstant<'tcx>> {
     let typing_env = ty::TypingEnv::fully_monomorphized();
-    let (ecx, op) = mk_eval_cx_for_const_val(tcx, typing_env, val, ty)?;
+    // FIXME: use a proper span here?
+    let (ecx, op) = mk_eval_cx_for_const_val(tcx.at(rustc_span::DUMMY_SP), typing_env, val, ty)?;
 
     // We go to `usize` as we cannot allocate anything bigger anyway.
     let (field_count, variant, down) = match ty.kind() {
-        ty::Array(_, len) => (len.try_to_target_usize(tcx.tcx)? as usize, None, op),
+        ty::Array(_, len) => (len.try_to_target_usize(tcx)? as usize, None, op),
         ty::Adt(def, _) if def.variants().is_empty() => {
             return None;
         }
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 4d625f76aba..c35910a706b 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -273,59 +273,63 @@ pub(crate) fn eval_to_valtree<'tcx>(
 /// Converts a `ValTree` to a `ConstValue`, which is needed after mir
 /// construction has finished.
 // FIXME(valtrees): Merge `valtree_to_const_value` and `valtree_into_mplace` into one function
-// FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately.
 #[instrument(skip(tcx), level = "debug", ret)]
 pub fn valtree_to_const_value<'tcx>(
     tcx: TyCtxt<'tcx>,
     typing_env: ty::TypingEnv<'tcx>,
-    ty: Ty<'tcx>,
-    valtree: ty::ValTree<'tcx>,
+    cv: ty::Value<'tcx>,
 ) -> mir::ConstValue<'tcx> {
     // Basic idea: We directly construct `Scalar` values from trivial `ValTree`s
     // (those for constants with type bool, int, uint, float or char).
     // For all other types we create an `MPlace` and fill that by walking
     // the `ValTree` and using `place_projection` and `place_field` to
     // create inner `MPlace`s which are filled recursively.
-    // FIXME Does this need an example?
-    match *ty.kind() {
+    // FIXME: Does this need an example?
+    match *cv.ty.kind() {
         ty::FnDef(..) => {
-            assert!(valtree.unwrap_branch().is_empty());
+            assert!(cv.valtree.unwrap_branch().is_empty());
             mir::ConstValue::ZeroSized
         }
         ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(_, _) => {
-            match valtree {
+            match cv.valtree {
                 ty::ValTree::Leaf(scalar_int) => mir::ConstValue::Scalar(Scalar::Int(scalar_int)),
                 ty::ValTree::Branch(_) => bug!(
                     "ValTrees for Bool, Int, Uint, Float, Char or RawPtr should have the form ValTree::Leaf"
                 ),
             }
         }
-        ty::Pat(ty, _) => valtree_to_const_value(tcx, typing_env, ty, valtree),
+        ty::Pat(ty, _) => {
+            let cv = ty::Value { valtree: cv.valtree, ty };
+            valtree_to_const_value(tcx, typing_env, cv)
+        }
         ty::Ref(_, inner_ty, _) => {
             let mut ecx =
                 mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, typing_env, CanAccessMutGlobal::No);
-            let imm = valtree_to_ref(&mut ecx, valtree, inner_ty);
-            let imm =
-                ImmTy::from_immediate(imm, tcx.layout_of(typing_env.as_query_input(ty)).unwrap());
+            let imm = valtree_to_ref(&mut ecx, cv.valtree, inner_ty);
+            let imm = ImmTy::from_immediate(
+                imm,
+                tcx.layout_of(typing_env.as_query_input(cv.ty)).unwrap(),
+            );
             op_to_const(&ecx, &imm.into(), /* for diagnostics */ false)
         }
         ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => {
-            let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap();
+            let layout = tcx.layout_of(typing_env.as_query_input(cv.ty)).unwrap();
             if layout.is_zst() {
                 // Fast path to avoid some allocations.
                 return mir::ConstValue::ZeroSized;
             }
             if layout.backend_repr.is_scalar()
-                && (matches!(ty.kind(), ty::Tuple(_))
-                    || matches!(ty.kind(), ty::Adt(def, _) if def.is_struct()))
+                && (matches!(cv.ty.kind(), ty::Tuple(_))
+                    || matches!(cv.ty.kind(), ty::Adt(def, _) if def.is_struct()))
             {
                 // A Scalar tuple/struct; we can avoid creating an allocation.
-                let branches = valtree.unwrap_branch();
+                let branches = cv.valtree.unwrap_branch();
                 // Find the non-ZST field. (There can be aligned ZST!)
                 for (i, &inner_valtree) in branches.iter().enumerate() {
                     let field = layout.field(&LayoutCx::new(tcx, typing_env), i);
                     if !field.is_zst() {
-                        return valtree_to_const_value(tcx, typing_env, field.ty, inner_valtree);
+                        let cv = ty::Value { valtree: inner_valtree, ty: field.ty };
+                        return valtree_to_const_value(tcx, typing_env, cv);
                     }
                 }
                 bug!("could not find non-ZST field during in {layout:#?}");
@@ -335,9 +339,9 @@ pub fn valtree_to_const_value<'tcx>(
                 mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, typing_env, CanAccessMutGlobal::No);
 
             // Need to create a place for this valtree.
-            let place = create_valtree_place(&mut ecx, layout, valtree);
+            let place = create_valtree_place(&mut ecx, layout, cv.valtree);
 
-            valtree_into_mplace(&mut ecx, &place, valtree);
+            valtree_into_mplace(&mut ecx, &place, cv.valtree);
             dump_place(&ecx, &place);
             intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap();
 
@@ -362,7 +366,7 @@ pub fn valtree_to_const_value<'tcx>(
         | ty::Slice(_)
         | ty::Dynamic(..)
         | ty::UnsafeBinder(_) => {
-            bug!("no ValTree should have been created for type {:?}", ty.kind())
+            bug!("no ValTree should have been created for type {:?}", cv.ty.kind())
         }
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 9f5f2533e08..4ca317e3a1e 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -319,7 +319,25 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
                 // Check that the memory between them is dereferenceable at all, starting from the
                 // origin pointer: `dist` is `a - b`, so it is based on `b`.
-                self.check_ptr_access_signed(b, dist, CheckInAllocMsg::OffsetFromTest)?;
+                self.check_ptr_access_signed(b, dist, CheckInAllocMsg::OffsetFromTest)
+                    .map_err_kind(|_| {
+                        // This could mean they point to different allocations, or they point to the same allocation
+                        // but not the entire range between the pointers is in-bounds.
+                        if let Ok((a_alloc_id, ..)) = self.ptr_try_get_alloc_id(a, 0)
+                            && let Ok((b_alloc_id, ..)) = self.ptr_try_get_alloc_id(b, 0)
+                            && a_alloc_id == b_alloc_id
+                        {
+                            err_ub_custom!(
+                                fluent::const_eval_offset_from_out_of_bounds,
+                                name = intrinsic_name,
+                            )
+                        } else {
+                            err_ub_custom!(
+                                fluent::const_eval_offset_from_different_allocations,
+                                name = intrinsic_name,
+                            )
+                        }
+                    })?;
                 // Then check that this is also dereferenceable from `a`. This ensures that they are
                 // derived from the same allocation.
                 self.check_ptr_access_signed(
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 8f6b15b8df0..1a799f5dea5 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -293,6 +293,9 @@ pub trait Machine<'tcx>: Sized {
     /// Determines the result of a `NullaryOp::UbChecks` invocation.
     fn ub_checks(_ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool>;
 
+    /// Determines the result of a `NullaryOp::ContractChecks` invocation.
+    fn contract_checks(_ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool>;
+
     /// Called when the interpreter encounters a `StatementKind::ConstEvalCounter` instruction.
     /// You can use this to detect long or endlessly running programs.
     #[inline]
@@ -680,6 +683,13 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
     }
 
     #[inline(always)]
+    fn contract_checks(_ecx: &InterpCx<$tcx, Self>) -> InterpResult<$tcx, bool> {
+        // We can't look at `tcx.sess` here as that can differ across crates, which can lead to
+        // unsound differences in evaluating the same constant at different instantiation sites.
+        interp_ok(true)
+    }
+
+    #[inline(always)]
     fn adjust_global_allocation<'b>(
         _ecx: &InterpCx<$tcx, Self>,
         _id: AllocId,
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index 5fa632fc57a..899670aeb62 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -537,6 +537,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 ImmTy::from_uint(val, usize_layout())
             }
             UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx),
+            ContractChecks => ImmTy::from_bool(M::contract_checks(self)?, *self.tcx),
         })
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index 996142d7b03..8ecb3e13d5c 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -381,6 +381,7 @@ where
             OpaqueCast(ty) => {
                 span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck")
             }
+            UnwrapUnsafeBinder(target) => base.transmute(self.layout_of(target)?, self)?,
             // We don't want anything happening here, this is here as a dummy.
             Subtype(_) => base.transmute(base.layout(), self)?,
             Field(field, _) => self.project_field(base, field.index())?,
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index d9c0ff5acd1..abe73c43d8a 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -277,6 +277,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let discr = self.discriminant_for_variant(op.layout.ty, variant)?;
                 self.write_immediate(*discr, &dest)?;
             }
+
+            WrapUnsafeBinder(ref op, _ty) => {
+                // Constructing an unsafe binder acts like a transmute
+                // since the operand's layout does not change.
+                let op = self.eval_operand(op, None)?;
+                self.copy_op_allow_transmute(&op, &dest)?;
+            }
         }
 
         trace!("{:?}", self.dump_place(&dest));
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index d75df1ad442..8e544798742 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -1240,6 +1240,17 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
                     self.visit_field(val, 0, &self.ecx.project_index(val, 0)?)?;
                 }
             }
+            ty::Pat(base, pat) => {
+                // First check that the base type is valid
+                self.visit_value(&val.transmute(self.ecx.layout_of(*base)?, self.ecx)?)?;
+                // When you extend this match, make sure to also add tests to
+                // tests/ui/type/pattern_types/validity.rs((
+                match **pat {
+                    // Range patterns are precisely reflected into `valid_range` and thus
+                    // handled fully by `visit_scalar` (called below).
+                    ty::PatternKind::Range { .. } => {},
+                }
+            }
             _ => {
                 // default handler
                 try_validation!(
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index ecf9745b779..b44d2a01d57 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -46,14 +46,8 @@ pub fn provide(providers: &mut Providers) {
     };
     providers.hooks.try_destructure_mir_constant_for_user_output =
         const_eval::try_destructure_mir_constant_for_user_output;
-    providers.valtree_to_const_val = |tcx, cv| {
-        const_eval::valtree_to_const_value(
-            tcx,
-            ty::TypingEnv::fully_monomorphized(),
-            cv.ty,
-            cv.valtree,
-        )
-    };
+    providers.valtree_to_const_val =
+        |tcx, cv| const_eval::valtree_to_const_value(tcx, ty::TypingEnv::fully_monomorphized(), cv);
     providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
         util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
     };
diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs
index 6dd9447cf5a..e926040e9ba 100644
--- a/compiler/rustc_const_eval/src/util/caller_location.rs
+++ b/compiler/rustc_const_eval/src/util/caller_location.rs
@@ -1,7 +1,6 @@
 use rustc_hir::LangItem;
-use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::ty::{self};
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_middle::{bug, mir};
 use rustc_span::Symbol;
 use tracing::trace;
@@ -48,15 +47,15 @@ fn alloc_caller_location<'tcx>(
 }
 
 pub(crate) fn const_caller_location_provider(
-    tcx: TyCtxtAt<'_>,
+    tcx: TyCtxt<'_>,
     file: Symbol,
     line: u32,
     col: u32,
 ) -> mir::ConstValue<'_> {
     trace!("const_caller_location: {}:{}:{}", file, line, col);
     let mut ecx = mk_eval_cx_to_read_const_val(
-        tcx.tcx,
-        tcx.span,
+        tcx,
+        rustc_span::DUMMY_SP, // FIXME: use a proper span here?
         ty::TypingEnv::fully_monomorphized(),
         CanAccessMutGlobal::No,
     );
diff --git a/compiler/rustc_data_structures/src/vec_cache.rs b/compiler/rustc_data_structures/src/vec_cache.rs
index eb251b587c8..2ff60ab7f36 100644
--- a/compiler/rustc_data_structures/src/vec_cache.rs
+++ b/compiler/rustc_data_structures/src/vec_cache.rs
@@ -206,6 +206,19 @@ impl SlotIndex {
     }
 }
 
+/// In-memory cache for queries whose keys are densely-numbered IDs
+/// (e.g `CrateNum`, `LocalDefId`), and can therefore be used as indices
+/// into a dense vector of cached values.
+///
+/// (As of [#124780] the underlying storage is not an actual `Vec`, but rather
+/// a series of increasingly-large buckets, for improved performance when the
+/// parallel frontend is using multiple threads.)
+///
+/// Each entry in the cache stores the query's return value (`V`), and also
+/// an associated index (`I`), which in practice is a `DepNodeIndex` used for
+/// query dependency tracking.
+///
+/// [#124780]: https://github.com/rust-lang/rust/pull/124780
 pub struct VecCache<K: Idx, V, I> {
     // Entries per bucket:
     // Bucket  0:       4096 2^12
diff --git a/compiler/rustc_driver_impl/src/args.rs b/compiler/rustc_driver_impl/src/args.rs
index 2fc767b3750..b0970144c42 100644
--- a/compiler/rustc_driver_impl/src/args.rs
+++ b/compiler/rustc_driver_impl/src/args.rs
@@ -1,7 +1,6 @@
 use std::{env, error, fmt, fs, io};
 
 use rustc_session::EarlyDiagCtxt;
-use rustc_span::ErrorGuaranteed;
 
 /// Expands argfiles in command line arguments.
 #[derive(Default)]
@@ -118,22 +117,22 @@ pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec<Stri
 ///
 /// This function is identical to [`env::args()`] except that it emits an error when it encounters
 /// non-Unicode arguments instead of panicking.
-pub fn raw_args(early_dcx: &EarlyDiagCtxt) -> Result<Vec<String>, ErrorGuaranteed> {
-    let mut res = Ok(Vec::new());
+pub fn raw_args(early_dcx: &EarlyDiagCtxt) -> Vec<String> {
+    let mut args = Vec::new();
+    let mut guar = Ok(());
     for (i, arg) in env::args_os().enumerate() {
         match arg.into_string() {
-            Ok(arg) => {
-                if let Ok(args) = &mut res {
-                    args.push(arg);
-                }
-            }
+            Ok(arg) => args.push(arg),
             Err(arg) => {
-                res =
+                guar =
                     Err(early_dcx.early_err(format!("argument {i} is not valid Unicode: {arg:?}")))
             }
         }
     }
-    res
+    if let Err(guar) = guar {
+        guar.raise_fatal();
+    }
+    args
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index c9d38a0f932..6ea14d15c14 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -317,7 +317,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
         if let Some(pp_mode) = sess.opts.pretty {
             if pp_mode.needs_ast_map() {
                 create_and_enter_global_ctxt(compiler, krate, |tcx| {
-                    tcx.ensure().early_lint_checks(());
+                    tcx.ensure_ok().early_lint_checks(());
                     pretty::print(sess, pp_mode, pretty::PrintExtra::NeedsAstMap { tcx });
                     passes::write_dep_info(tcx);
                 });
@@ -365,7 +365,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
                 return early_exit();
             }
 
-            tcx.ensure().analysis(());
+            tcx.ensure_ok().analysis(());
 
             if callbacks.after_analysis(compiler, tcx) == Compilation::Stop {
                 return early_exit();
@@ -1212,9 +1212,9 @@ pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, FatalError> {
 
 /// Variant of `catch_fatal_errors` for the `interface::Result` return type
 /// that also computes the exit code.
-pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 {
+pub fn catch_with_exit_code(f: impl FnOnce()) -> i32 {
     match catch_fatal_errors(f) {
-        Ok(Ok(())) => EXIT_SUCCESS,
+        Ok(()) => EXIT_SUCCESS,
         _ => EXIT_FAILURE,
     }
 }
@@ -1499,10 +1499,8 @@ pub fn main() -> ! {
     install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
     install_ctrlc_handler();
 
-    let exit_code = catch_with_exit_code(|| {
-        run_compiler(&args::raw_args(&early_dcx)?, &mut callbacks);
-        Ok(())
-    });
+    let exit_code =
+        catch_with_exit_code(|| run_compiler(&args::raw_args(&early_dcx), &mut callbacks));
 
     if let Some(format) = callbacks.time_passes {
         let end_rss = get_resident_set_size();
diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs
index 699742aa0ea..576b1c76823 100644
--- a/compiler/rustc_driver_impl/src/pretty.rs
+++ b/compiler/rustc_driver_impl/src/pretty.rs
@@ -101,6 +101,10 @@ impl<'tcx> pprust_hir::PpAnn for HirIdentifiedAnn<'tcx> {
                 s.s.space();
                 s.synth_comment(format!("pat hir_id: {}", pat.hir_id));
             }
+            pprust_hir::AnnNode::TyPat(pat) => {
+                s.s.space();
+                s.synth_comment(format!("ty pat hir_id: {}", pat.hir_id));
+            }
             pprust_hir::AnnNode::Arm(arm) => {
                 s.s.space();
                 s.synth_comment(format!("arm hir_id: {}", arm.hir_id));
@@ -222,7 +226,7 @@ impl<'tcx> PrintExtra<'tcx> {
 
 pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
     if ppm.needs_analysis() {
-        ex.tcx().ensure().analysis(());
+        ex.tcx().ensure_ok().analysis(());
     }
 
     let (src, src_name) = get_source(sess);
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 797dcd7b4d1..29a74ed3f4e 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -4,6 +4,7 @@ use std::hash::{Hash, Hasher};
 use std::marker::PhantomData;
 use std::ops::{Deref, DerefMut};
 use std::panic;
+use std::path::PathBuf;
 use std::thread::panicking;
 
 use rustc_data_structures::fx::FxIndexMap;
@@ -301,6 +302,7 @@ pub struct DiagInner {
 
     pub is_lint: Option<IsLint>,
 
+    pub long_ty_path: Option<PathBuf>,
     /// With `-Ztrack_diagnostics` enabled,
     /// we print where in rustc this error was emitted.
     pub(crate) emitted_at: DiagLocation,
@@ -324,6 +326,7 @@ impl DiagInner {
             args: Default::default(),
             sort_span: DUMMY_SP,
             is_lint: None,
+            long_ty_path: None,
             emitted_at: DiagLocation::caller(),
         }
     }
@@ -641,7 +644,14 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
         found_label: &dyn fmt::Display,
         found: DiagStyledString,
     ) -> &mut Self {
-        self.note_expected_found_extra(expected_label, expected, found_label, found, &"", &"")
+        self.note_expected_found_extra(
+            expected_label,
+            expected,
+            found_label,
+            found,
+            DiagStyledString::normal(""),
+            DiagStyledString::normal(""),
+        )
     }
 
     #[rustc_lint_diagnostics]
@@ -651,8 +661,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
         expected: DiagStyledString,
         found_label: &dyn fmt::Display,
         found: DiagStyledString,
-        expected_extra: &dyn fmt::Display,
-        found_extra: &dyn fmt::Display,
+        expected_extra: DiagStyledString,
+        found_extra: DiagStyledString,
     ) -> &mut Self {
         let expected_label = expected_label.to_string();
         let expected_label = if expected_label.is_empty() {
@@ -677,10 +687,13 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
             expected_label
         ))];
         msg.extend(expected.0);
-        msg.push(StringPart::normal(format!("`{expected_extra}\n")));
+        msg.push(StringPart::normal(format!("`")));
+        msg.extend(expected_extra.0);
+        msg.push(StringPart::normal(format!("\n")));
         msg.push(StringPart::normal(format!("{}{} `", " ".repeat(found_padding), found_label)));
         msg.extend(found.0);
-        msg.push(StringPart::normal(format!("`{found_extra}")));
+        msg.push(StringPart::normal(format!("`")));
+        msg.extend(found_extra.0);
 
         // For now, just attach these as notes.
         self.highlighted_note(msg);
@@ -1293,9 +1306,37 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
     /// `cancel`, etc. Afterwards, `drop` is the only code that will be run on
     /// `self`.
     fn take_diag(&mut self) -> DiagInner {
+        if let Some(path) = &self.long_ty_path {
+            self.note(format!(
+                "the full name for the type has been written to '{}'",
+                path.display()
+            ));
+            self.note("consider using `--verbose` to print the full type name to the console");
+        }
         Box::into_inner(self.diag.take().unwrap())
     }
 
+    /// This method allows us to access the path of the file where "long types" are written to.
+    ///
+    /// When calling `Diag::emit`, as part of that we will check if a `long_ty_path` has been set,
+    /// and if it has been then we add a note mentioning the file where the "long types" were
+    /// written to.
+    ///
+    /// When calling `tcx.short_string()` after a `Diag` is constructed, the preferred way of doing
+    /// so is `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that
+    /// keeps the existence of a "long type" anywhere in the diagnostic, so the note telling the
+    /// user where we wrote the file to is only printed once at most, *and* it makes it much harder
+    /// to forget to set it.
+    ///
+    /// If the diagnostic hasn't been created before a "short ty string" is created, then you should
+    /// ensure that this method is called to set it `*diag.long_ty_path() = path`.
+    ///
+    /// As a rule of thumb, if you see or add at least one `tcx.short_string()` call anywhere, in a
+    /// scope, `diag.long_ty_path()` should be called once somewhere close by.
+    pub fn long_ty_path(&mut self) -> &mut Option<PathBuf> {
+        &mut self.long_ty_path
+    }
+
     /// Most `emit_producing_guarantee` functions use this as a starting point.
     fn emit_producing_nothing(mut self) {
         let diag = self.take_diag();
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 991dfa1821a..d0b4211c351 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -35,8 +35,8 @@ use crate::snippet::{
 use crate::styled_buffer::StyledBuffer;
 use crate::translation::{Translate, to_fluent_args};
 use crate::{
-    CodeSuggestion, DiagCtxt, DiagInner, DiagMessage, ErrCode, FluentBundle, LazyFallbackBundle,
-    Level, MultiSpan, Subdiag, SubstitutionHighlight, SuggestionStyle, TerminalUrl,
+    CodeSuggestion, DiagInner, DiagMessage, ErrCode, FluentBundle, LazyFallbackBundle, Level,
+    MultiSpan, Subdiag, SubstitutionHighlight, SuggestionStyle, TerminalUrl,
 };
 
 /// Default column width, used in tests and when terminal dimensions cannot be determined.
@@ -537,11 +537,10 @@ impl Emitter for HumanEmitter {
 }
 
 /// An emitter that does nothing when emitting a non-fatal diagnostic.
-/// Fatal diagnostics are forwarded to `fatal_dcx` to avoid silent
+/// Fatal diagnostics are forwarded to `fatal_emitter` to avoid silent
 /// failures of rustc, as witnessed e.g. in issue #89358.
 pub struct SilentEmitter {
-    pub fallback_bundle: LazyFallbackBundle,
-    pub fatal_dcx: DiagCtxt,
+    pub fatal_emitter: Box<dyn Emitter + DynSend>,
     pub fatal_note: Option<String>,
     pub emit_fatal_diagnostic: bool,
 }
@@ -552,9 +551,7 @@ impl Translate for SilentEmitter {
     }
 
     fn fallback_fluent_bundle(&self) -> &FluentBundle {
-        // Ideally this field wouldn't be necessary and the fallback bundle in `fatal_dcx` would be
-        // used but the lock prevents this.
-        &self.fallback_bundle
+        self.fatal_emitter.fallback_fluent_bundle()
     }
 }
 
@@ -563,12 +560,12 @@ impl Emitter for SilentEmitter {
         None
     }
 
-    fn emit_diagnostic(&mut self, mut diag: DiagInner, _registry: &Registry) {
+    fn emit_diagnostic(&mut self, mut diag: DiagInner, registry: &Registry) {
         if self.emit_fatal_diagnostic && diag.level == Level::Fatal {
             if let Some(fatal_note) = &self.fatal_note {
                 diag.sub(Level::Note, fatal_note.clone(), MultiSpan::new());
             }
-            self.fatal_dcx.handle().emit_diagnostic(diag);
+            self.fatal_emitter.emit_diagnostic(diag, registry);
         }
     }
 }
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 549729548f5..7a02e0dd2f0 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -59,13 +59,13 @@ use emitter::{DynEmitter, Emitter, is_case_difference, is_different};
 use rustc_data_structures::AtomicRef;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
-use rustc_data_structures::sync::Lock;
+use rustc_data_structures::sync::{DynSend, Lock};
 pub use rustc_error_messages::{
     DiagMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel,
     SubdiagMessage, fallback_fluent_bundle, fluent_bundle,
 };
 use rustc_lint_defs::LintExpectationId;
-pub use rustc_lint_defs::{Applicability, pluralize};
+pub use rustc_lint_defs::{Applicability, listify, pluralize};
 use rustc_macros::{Decodable, Encodable};
 pub use rustc_span::ErrorGuaranteed;
 pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
@@ -676,57 +676,44 @@ impl DiagCtxt {
         Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
     }
 
-    pub fn make_silent(
-        &self,
-        fallback_bundle: LazyFallbackBundle,
-        fatal_note: Option<String>,
-        emit_fatal_diagnostic: bool,
-    ) {
-        self.wrap_emitter(|old_dcx| {
-            Box::new(emitter::SilentEmitter {
-                fallback_bundle,
-                fatal_dcx: DiagCtxt { inner: Lock::new(old_dcx) },
-                fatal_note,
-                emit_fatal_diagnostic,
-            })
-        });
-    }
-
-    fn wrap_emitter<F>(&self, f: F)
-    where
-        F: FnOnce(DiagCtxtInner) -> Box<DynEmitter>,
-    {
-        // A empty type that implements `Emitter` so that a `DiagCtxtInner` can be constructed
-        // to temporarily swap in place of the real one, which will be used in constructing
-        // its replacement.
+    pub fn make_silent(&self, fatal_note: Option<String>, emit_fatal_diagnostic: bool) {
+        // An empty type that implements `Emitter` to temporarily swap in place of the real one,
+        // which will be used in constructing its replacement.
         struct FalseEmitter;
 
         impl Emitter for FalseEmitter {
             fn emit_diagnostic(&mut self, _: DiagInner, _: &Registry) {
-                unimplemented!("false emitter must only used during `wrap_emitter`")
+                unimplemented!("false emitter must only used during `make_silent`")
             }
 
             fn source_map(&self) -> Option<&SourceMap> {
-                unimplemented!("false emitter must only used during `wrap_emitter`")
+                unimplemented!("false emitter must only used during `make_silent`")
             }
         }
 
         impl translation::Translate for FalseEmitter {
             fn fluent_bundle(&self) -> Option<&FluentBundle> {
-                unimplemented!("false emitter must only used during `wrap_emitter`")
+                unimplemented!("false emitter must only used during `make_silent`")
             }
 
             fn fallback_fluent_bundle(&self) -> &FluentBundle {
-                unimplemented!("false emitter must only used during `wrap_emitter`")
+                unimplemented!("false emitter must only used during `make_silent`")
             }
         }
 
         let mut inner = self.inner.borrow_mut();
-        let mut prev_dcx = DiagCtxtInner::new(Box::new(FalseEmitter));
-        std::mem::swap(&mut *inner, &mut prev_dcx);
-        let new_emitter = f(prev_dcx);
-        let mut new_dcx = DiagCtxtInner::new(new_emitter);
-        std::mem::swap(&mut *inner, &mut new_dcx);
+        let mut prev_emitter = Box::new(FalseEmitter) as Box<dyn Emitter + DynSend>;
+        std::mem::swap(&mut inner.emitter, &mut prev_emitter);
+        let new_emitter = Box::new(emitter::SilentEmitter {
+            fatal_emitter: prev_emitter,
+            fatal_note,
+            emit_fatal_diagnostic,
+        });
+        inner.emitter = new_emitter;
+    }
+
+    pub fn set_emitter(&self, emitter: Box<dyn Emitter + DynSend>) {
+        self.inner.borrow_mut().emitter = emitter;
     }
 
     /// Translate `message` eagerly with `args` to `SubdiagMessage::Eager`.
@@ -1999,18 +1986,6 @@ pub fn a_or_an(s: &str) -> &'static str {
     }
 }
 
-/// Grammatical tool for displaying messages to end users in a nice form.
-///
-/// Take a list ["a", "b", "c"] and output a display friendly version "a, b and c"
-pub fn display_list_with_comma_and<T: std::fmt::Display>(v: &[T]) -> String {
-    match v {
-        [] => "".to_string(),
-        [a] => a.to_string(),
-        [a, b] => format!("{a} and {b}"),
-        [a, v @ ..] => format!("{a}, {}", display_list_with_comma_and(v)),
-    }
-}
-
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum TerminalUrl {
     No,
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 684fc5e37e0..67eb96e4d56 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -19,6 +19,7 @@ const GATED_CFGS: &[GatedCfg] = &[
     // (name in cfg, feature, function to check if the feature is enabled)
     (sym::overflow_checks, sym::cfg_overflow_checks, Features::cfg_overflow_checks),
     (sym::ub_checks, sym::cfg_ub_checks, Features::cfg_ub_checks),
+    (sym::contract_checks, sym::cfg_contract_checks, Features::cfg_contract_checks),
     (sym::target_thread_local, sym::cfg_target_thread_local, Features::cfg_target_thread_local),
     (
         sym::target_has_atomic_equal_alignment,
@@ -616,7 +617,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint",
     ),
     rustc_attr!(
-        rustc_allowed_through_unstable_modules, Normal, template!(Word, NameValueStr: "deprecation message"),
+        rustc_allowed_through_unstable_modules, Normal, template!(NameValueStr: "deprecation message"),
         WarnFollowing, EncodeCrossCrate::No,
         "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
         through unstable paths"
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 1a216ebf117..115b3eabbaa 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -403,6 +403,8 @@ declare_features! (
     (unstable, c_variadic, "1.34.0", Some(44930)),
     /// Allows the use of `#[cfg(<true/false>)]`.
     (unstable, cfg_boolean_literals, "1.83.0", Some(131204)),
+    /// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled.
+    (unstable, cfg_contract_checks, "CURRENT_RUSTC_VERSION", Some(128044)),
     /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour.
     (unstable, cfg_overflow_checks, "1.71.0", Some(111466)),
     /// Provides the relocation model information as cfg entry
@@ -445,6 +447,10 @@ declare_features! (
     (unstable, const_trait_impl, "1.42.0", Some(67792)),
     /// Allows the `?` operator in const contexts.
     (unstable, const_try, "1.56.0", Some(74935)),
+    /// Allows use of contracts attributes.
+    (incomplete, contracts, "CURRENT_RUSTC_VERSION", Some(128044)),
+    /// Allows access to internal machinery used to implement contracts.
+    (internal, contracts_internals, "CURRENT_RUSTC_VERSION", Some(128044)),
     /// Allows coroutines to be cloned.
     (unstable, coroutine_clone, "1.65.0", Some(95360)),
     /// Allows defining coroutines.
@@ -529,6 +535,8 @@ declare_features! (
     (unstable, inline_const_pat, "1.58.0", Some(76001)),
     /// Allows using `pointer` and `reference` in intra-doc links
     (unstable, intra_doc_pointers, "1.51.0", Some(80896)),
+    // Allows using the `kl` and `widekl` target features and the associated intrinsics
+    (unstable, keylocker_x86, "CURRENT_RUSTC_VERSION", Some(134813)),
     // Allows setting the threshold for the `large_assignments` lint.
     (unstable, large_assignments, "1.52.0", Some(83518)),
     /// Allow to have type alias types for inter-crate use.
@@ -568,6 +576,8 @@ declare_features! (
     (unstable, never_type, "1.13.0", Some(35121)),
     /// Allows diverging expressions to fall back to `!` rather than `()`.
     (unstable, never_type_fallback, "1.41.0", Some(65992)),
+    /// Switch `..` syntax to use the new (`Copy + IntoIterator`) range types.
+    (unstable, new_range, "CURRENT_RUSTC_VERSION", Some(123741)),
     /// Allows `#![no_core]`.
     (unstable, no_core, "1.3.0", Some(29639)),
     /// Allows the use of `no_sanitize` attribute.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index af2f86b67e0..1c87a0eb1a7 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1419,6 +1419,14 @@ impl<'hir> Block<'hir> {
 }
 
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
+pub struct TyPat<'hir> {
+    #[stable_hasher(ignore)]
+    pub hir_id: HirId,
+    pub kind: TyPatKind<'hir>,
+    pub span: Span,
+}
+
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct Pat<'hir> {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -1592,6 +1600,15 @@ pub enum PatExprKind<'hir> {
 }
 
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
+pub enum TyPatKind<'hir> {
+    /// A range pattern (e.g., `1..=2` or `1..2`).
+    Range(Option<&'hir ConstArg<'hir>>, Option<&'hir ConstArg<'hir>>, RangeEnd),
+
+    /// A placeholder for a pattern that wasn't well formed in some way.
+    Err(ErrorGuaranteed),
+}
+
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum PatKind<'hir> {
     /// Represents a wildcard pattern (i.e., `_`).
     Wild,
@@ -2313,6 +2330,18 @@ impl Expr<'_> {
                     [val2],
                     StructTailExpr::None,
                 ),
+            )
+            | (
+                ExprKind::Struct(
+                    QPath::LangItem(LangItem::RangeFromCopy, _),
+                    [val1],
+                    StructTailExpr::None,
+                ),
+                ExprKind::Struct(
+                    QPath::LangItem(LangItem::RangeFromCopy, _),
+                    [val2],
+                    StructTailExpr::None,
+                ),
             ) => val1.expr.equivalent_for_indexing(val2.expr),
             (
                 ExprKind::Struct(
@@ -2325,6 +2354,30 @@ impl Expr<'_> {
                     [val2, val4],
                     StructTailExpr::None,
                 ),
+            )
+            | (
+                ExprKind::Struct(
+                    QPath::LangItem(LangItem::RangeCopy, _),
+                    [val1, val3],
+                    StructTailExpr::None,
+                ),
+                ExprKind::Struct(
+                    QPath::LangItem(LangItem::RangeCopy, _),
+                    [val2, val4],
+                    StructTailExpr::None,
+                ),
+            )
+            | (
+                ExprKind::Struct(
+                    QPath::LangItem(LangItem::RangeInclusiveCopy, _),
+                    [val1, val3],
+                    StructTailExpr::None,
+                ),
+                ExprKind::Struct(
+                    QPath::LangItem(LangItem::RangeInclusiveCopy, _),
+                    [val2, val4],
+                    StructTailExpr::None,
+                ),
             ) => {
                 val1.expr.equivalent_for_indexing(val2.expr)
                     && val3.expr.equivalent_for_indexing(val4.expr)
@@ -2354,7 +2407,10 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
                     | LangItem::RangeTo
                     | LangItem::RangeFrom
                     | LangItem::RangeFull
-                    | LangItem::RangeToInclusive,
+                    | LangItem::RangeToInclusive
+                    | LangItem::RangeCopy
+                    | LangItem::RangeFromCopy
+                    | LangItem::RangeInclusiveCopy,
                 ..
             )
         ),
@@ -2598,6 +2654,8 @@ pub enum LocalSource {
     /// A desugared `expr = expr`, where the LHS is a tuple, struct, array or underscore expression.
     /// The span is that of the `=` sign.
     AssignDesugar(Span),
+    /// A contract `#[ensures(..)]` attribute injects a let binding for the check that runs at point of return.
+    Contract,
 }
 
 /// Hints at the original code for a `match _ { .. }`.
@@ -3345,7 +3403,7 @@ pub enum TyKind<'hir, Unambig = ()> {
     /// Placeholder for a type that has failed to be defined.
     Err(rustc_span::ErrorGuaranteed),
     /// Pattern types (`pattern_type!(u32 is 1..)`)
-    Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
+    Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
     /// `TyKind::Infer` means the type should be inferred instead of it having been
     /// specified. This can appear anywhere in a type.
     ///
@@ -4331,6 +4389,7 @@ pub enum Node<'hir> {
     AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
     TraitRef(&'hir TraitRef<'hir>),
     OpaqueTy(&'hir OpaqueTy<'hir>),
+    TyPat(&'hir TyPat<'hir>),
     Pat(&'hir Pat<'hir>),
     PatField(&'hir PatField<'hir>),
     /// Needed as its own node with its own HirId for tracking
@@ -4393,6 +4452,7 @@ impl<'hir> Node<'hir> {
             | Node::Block(..)
             | Node::Ctor(..)
             | Node::Pat(..)
+            | Node::TyPat(..)
             | Node::PatExpr(..)
             | Node::Arm(..)
             | Node::LetStmt(..)
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 31764ab1209..6519552d604 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -393,10 +393,8 @@ pub trait Visitor<'v>: Sized {
     fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result {
         walk_expr_field(self, field)
     }
-    fn visit_pattern_type_pattern(&mut self, _p: &'v Pat<'v>) {
-        // Do nothing. Only a few visitors need to know the details of the pattern type,
-        // and they opt into it. All other visitors will just choke on our fake patterns
-        // because they aren't in a body.
+    fn visit_pattern_type_pattern(&mut self, p: &'v TyPat<'v>) -> Self::Result {
+        walk_ty_pat(self, p)
     }
     fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) -> Self::Result {
         walk_generic_param(self, p)
@@ -702,6 +700,18 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) -> V::Res
     visitor.visit_expr(arm.body)
 }
 
+pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>) -> V::Result {
+    try_visit!(visitor.visit_id(pattern.hir_id));
+    match pattern.kind {
+        TyPatKind::Range(lower_bound, upper_bound, _) => {
+            visit_opt!(visitor, visit_const_arg_unambig, lower_bound);
+            visit_opt!(visitor, visit_const_arg_unambig, upper_bound);
+        }
+        TyPatKind::Err(_) => (),
+    }
+    V::Result::output()
+}
+
 pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V::Result {
     try_visit!(visitor.visit_id(pattern.hir_id));
     match pattern.kind {
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index d9759580e8f..b6689c95c4b 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -416,8 +416,17 @@ language_item_table! {
     RangeToInclusive,        sym::RangeToInclusive,    range_to_inclusive_struct,  Target::Struct,         GenericRequirement::None;
     RangeTo,                 sym::RangeTo,             range_to_struct,            Target::Struct,         GenericRequirement::None;
 
+    // `new_range` types that are `Copy + IntoIterator`
+    RangeFromCopy,           sym::RangeFromCopy,       range_from_copy_struct,     Target::Struct,         GenericRequirement::None;
+    RangeCopy,               sym::RangeCopy,           range_copy_struct,          Target::Struct,         GenericRequirement::None;
+    RangeInclusiveCopy,      sym::RangeInclusiveCopy,  range_inclusive_copy_struct, Target::Struct,         GenericRequirement::None;
+
     String,                  sym::String,              string,                     Target::Struct,         GenericRequirement::None;
     CStr,                    sym::CStr,                c_str,                      Target::Struct,         GenericRequirement::None;
+
+    // Experimental lang items for implementing contract pre- and post-condition checking.
+    ContractBuildCheckEnsures, sym::contract_build_check_ensures, contract_build_check_ensures_fn, Target::Fn, GenericRequirement::None;
+    ContractCheckRequires,     sym::contract_check_requires,      contract_check_requires_fn,      Target::Fn, GenericRequirement::None;
 }
 
 pub enum GenericRequirement {
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index be4004f5904..c28c1afcfe6 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -234,6 +234,9 @@ hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a
     .help = consider moving this inherent impl into the crate defining the type if possible
     .span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
 
+hir_analysis_invalid_base_type = `{$ty}` is not a valid base type for range patterns
+    .note = range patterns only support integers
+
 hir_analysis_invalid_generic_receiver_ty = invalid generic `self` parameter type: `{$receiver_ty}`
     .note = type of `self` must not be a method generic parameter type
 
@@ -433,12 +436,8 @@ hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a t
 hir_analysis_parenthesized_fn_trait_expansion =
     parenthesized trait syntax expands to `{$expanded_type}`
 
-hir_analysis_pattern_type_non_const_range = range patterns must have constant range start and end
-hir_analysis_pattern_type_wild_pat = wildcard patterns are not permitted for pattern types
-    .label = this type is the same as the inner type without a pattern
 hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
     .label = not allowed in type signatures
-
 hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
     .label = `Self` is not a generic argument, but an alias to the type of the {$what}
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 40049f96de4..6c534d58a7d 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -778,13 +778,13 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     match tcx.def_kind(def_id) {
         DefKind::Static { .. } => {
-            tcx.ensure().typeck(def_id);
+            tcx.ensure_ok().typeck(def_id);
             maybe_check_static_with_link_section(tcx, def_id);
             check_static_inhabited(tcx, def_id);
             check_static_linkage(tcx, def_id);
         }
         DefKind::Const => {
-            tcx.ensure().typeck(def_id);
+            tcx.ensure_ok().typeck(def_id);
         }
         DefKind::Enum => {
             check_enum(tcx, def_id);
@@ -804,7 +804,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
         DefKind::Impl { of_trait } => {
             if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
                 if tcx
-                    .ensure()
+                    .ensure_ok()
                     .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)
                     .is_ok()
                 {
@@ -1042,7 +1042,7 @@ fn check_impl_items_against_trait<'tcx>(
             continue;
         };
 
-        let res = tcx.ensure().compare_impl_item(impl_item.expect_local());
+        let res = tcx.ensure_ok().compare_impl_item(impl_item.expect_local());
 
         if res.is_ok() {
             match ty_impl_item.kind {
@@ -1488,7 +1488,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
     for v in def.variants() {
         if let ty::VariantDiscr::Explicit(discr_def_id) = v.discr {
-            tcx.ensure().typeck(discr_def_id.expect_local());
+            tcx.ensure_ok().typeck(discr_def_id.expect_local());
         }
     }
 
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 3bff5fe02c0..a91d72e9225 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -2034,7 +2034,7 @@ pub(super) fn check_type_bounds<'tcx>(
 ) -> Result<(), ErrorGuaranteed> {
     // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
     // other `Foo` impls are incoherent.
-    tcx.ensure().coherent_trait(impl_trait_ref.def_id)?;
+    tcx.ensure_ok().coherent_trait(impl_trait_ref.def_id)?;
 
     let param_env = tcx.param_env(impl_ty.def_id);
     debug!(?param_env);
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index cf3d4897304..40769ef7536 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -132,6 +132,9 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
         | sym::aggregate_raw_ptr
         | sym::ptr_metadata
         | sym::ub_checks
+        | sym::contract_checks
+        | sym::contract_check_requires
+        | sym::contract_check_ensures
         | sym::fadd_algebraic
         | sym::fsub_algebraic
         | sym::fmul_algebraic
@@ -219,6 +222,16 @@ pub fn check_intrinsic_type(
             }
         };
         (n_tps, 0, 0, inputs, output, hir::Safety::Unsafe)
+    } else if intrinsic_name == sym::contract_check_ensures {
+        // contract_check_ensures::<'a, Ret, C>(&'a Ret, C)
+        // where C: impl Fn(&'a Ret) -> bool,
+        //
+        // so: two type params, one lifetime param, 0 const params, two inputs, no return
+
+        let p = generics.param_at(0, tcx);
+        let r = ty::Region::new_early_param(tcx, p.to_early_bound_region_data());
+        let ref_ret = Ty::new_imm_ref(tcx, r, param(1));
+        (2, 1, 0, vec![ref_ret, param(2)], tcx.types.unit, hir::Safety::Safe)
     } else {
         let safety = intrinsic_operation_unsafety(tcx, intrinsic_id);
         let (n_tps, n_cts, inputs, output) = match intrinsic_name {
@@ -472,7 +485,7 @@ pub fn check_intrinsic_type(
                 vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
                 tcx.types.usize,
             ),
-            sym::unchecked_div | sym::unchecked_rem | sym::exact_div => {
+            sym::unchecked_div | sym::unchecked_rem | sym::exact_div | sym::disjoint_bitor => {
                 (1, 0, vec![param(0), param(0)], param(0))
             }
             sym::unchecked_shl | sym::unchecked_shr => (2, 0, vec![param(0), param(1)], param(0)),
@@ -610,6 +623,11 @@ pub fn check_intrinsic_type(
 
             sym::box_new => (1, 0, vec![param(0)], Ty::new_box(tcx, param(0))),
 
+            // contract_checks() -> bool
+            sym::contract_checks => (0, 0, Vec::new(), tcx.types.bool),
+            // contract_check_requires::<C>(C) -> bool, where C: impl Fn() -> bool
+            sym::contract_check_requires => (1, 0, vec![param(0)], tcx.types.unit),
+
             sym::simd_eq
             | sym::simd_ne
             | sym::simd_lt
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index c9837ca3716..20eb96f3ab1 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -328,16 +328,20 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
         hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
         // `ForeignItem`s are handled separately.
         hir::ItemKind::ForeignMod { .. } => Ok(()),
-        hir::ItemKind::TyAlias(hir_ty, hir_generics) => {
-            if tcx.type_alias_is_lazy(item.owner_id) {
-                // Bounds of lazy type aliases and of eager ones that contain opaque types are respected.
-                // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`.
-                let res = check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
-                check_variances_for_type_defn(tcx, item, hir_generics);
-                res
-            } else {
+        hir::ItemKind::TyAlias(hir_ty, hir_generics) if tcx.type_alias_is_lazy(item.owner_id) => {
+            let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
+                let ty = tcx.type_of(def_id).instantiate_identity();
+                let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
+                wfcx.register_wf_obligation(
+                    hir_ty.span,
+                    Some(WellFormedLoc::Ty(def_id)),
+                    item_ty.into(),
+                );
+                check_where_clauses(wfcx, item.span, def_id);
                 Ok(())
-            }
+            });
+            check_variances_for_type_defn(tcx, item, hir_generics);
+            res
         }
         _ => Ok(()),
     };
@@ -1046,7 +1050,7 @@ fn check_associated_item(
 
         // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
         // other `Foo` impls are incoherent.
-        tcx.ensure()
+        tcx.ensure_ok()
             .coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?;
 
         let self_ty = match item.container {
@@ -1061,6 +1065,7 @@ fn check_associated_item(
                 let ty = tcx.type_of(item.def_id).instantiate_identity();
                 let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
                 wfcx.register_wf_obligation(span, loc, ty.into());
+                check_sized_if_body(wfcx, item.def_id.expect_local(), ty, Some(span));
                 Ok(())
             }
             ty::AssocKind::Fn => {
@@ -1185,7 +1190,7 @@ fn check_type_defn<'tcx>(
                     ),
                     wfcx.param_env,
                     ty,
-                    tcx.require_lang_item(LangItem::Sized, None),
+                    tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)),
                 );
             }
 
@@ -1276,7 +1281,6 @@ fn check_item_fn(
 
 enum UnsizedHandling {
     Forbid,
-    Allow,
     AllowIfForeignTail,
 }
 
@@ -1294,7 +1298,6 @@ fn check_item_type(
 
         let forbid_unsized = match unsized_handling {
             UnsizedHandling::Forbid => true,
-            UnsizedHandling::Allow => false,
             UnsizedHandling::AllowIfForeignTail => {
                 let tail =
                     tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
@@ -1312,7 +1315,7 @@ fn check_item_type(
                 ),
                 wfcx.param_env,
                 item_ty,
-                tcx.require_lang_item(LangItem::Sized, None),
+                tcx.require_lang_item(LangItem::Sized, Some(ty_span)),
             );
         }
 
@@ -1354,7 +1357,7 @@ fn check_impl<'tcx>(
                 let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity();
                 // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
                 // other `Foo` impls are incoherent.
-                tcx.ensure().coherent_trait(trait_ref.def_id)?;
+                tcx.ensure_ok().coherent_trait(trait_ref.def_id)?;
                 let trait_span = hir_trait_ref.path.span;
                 let trait_ref = wfcx.normalize(
                     trait_span,
@@ -1642,6 +1645,31 @@ fn check_fn_or_method<'tcx>(
             );
         }
     }
+
+    // If the function has a body, additionally require that the return type is sized.
+    check_sized_if_body(wfcx, def_id, sig.output(), match hir_decl.output {
+        hir::FnRetTy::Return(ty) => Some(ty.span),
+        hir::FnRetTy::DefaultReturn(_) => None,
+    });
+}
+
+fn check_sized_if_body<'tcx>(
+    wfcx: &WfCheckingCtxt<'_, 'tcx>,
+    def_id: LocalDefId,
+    ty: Ty<'tcx>,
+    maybe_span: Option<Span>,
+) {
+    let tcx = wfcx.tcx();
+    if let Some(body) = tcx.hir().maybe_body_owned_by(def_id) {
+        let span = maybe_span.unwrap_or(body.value.span);
+
+        wfcx.register_bound(
+            ObligationCause::new(span, def_id, traits::ObligationCauseCode::SizedReturnType),
+            wfcx.param_env,
+            ty,
+            tcx.require_lang_item(LangItem::Sized, Some(span)),
+        );
+    }
 }
 
 /// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`.
@@ -2268,11 +2296,13 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
 fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> {
     let items = tcx.hir_module_items(module);
     let res = items
-        .par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))
-        .and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
-        .and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
-        .and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
-        .and(items.par_opaques(|item| tcx.ensure().check_well_formed(item)));
+        .par_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))
+        .and(items.par_impl_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)))
+        .and(items.par_trait_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)))
+        .and(
+            items.par_foreign_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)),
+        )
+        .and(items.par_opaques(|item| tcx.ensure_ok().check_well_formed(item)));
     if module == LocalModDefId::CRATE_DEF_ID {
         super::entry::check_for_entry_fn(tcx);
     }
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 30f51fe1724..3511dbc6252 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -192,7 +192,7 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E
     // errors; other parts of the code may demand it for the info of
     // course.
     let span = tcx.def_span(impl_did);
-    tcx.at(span).ensure().coerce_unsized_info(impl_did)
+    tcx.at(span).ensure_ok().coerce_unsized_info(impl_did)
 }
 
 fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index b9ef166fc3f..1bc60087ab5 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -151,7 +151,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
     let Some(impls) = tcx.all_local_trait_impls(()).get(&def_id) else { return Ok(()) };
     // Trigger building the specialization graph for the trait. This will detect and report any
     // overlap errors.
-    let mut res = tcx.ensure().specialization_graph_of(def_id);
+    let mut res = tcx.ensure_ok().specialization_graph_of(def_id);
 
     for &impl_def_id in impls {
         let trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
@@ -162,7 +162,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
             .and(check_impl(tcx, impl_def_id, trait_ref, trait_def))
             .and(check_object_overlap(tcx, impl_def_id, trait_ref))
             .and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def))
-            .and(tcx.ensure().orphan_check_impl(impl_def_id))
+            .and(tcx.ensure_ok().orphan_check_impl(impl_def_id))
             .and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header));
     }
 
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 226370fccad..ce7319f6561 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -292,16 +292,16 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
             match param.kind {
                 hir::GenericParamKind::Lifetime { .. } => {}
                 hir::GenericParamKind::Type { default: Some(_), .. } => {
-                    self.tcx.ensure().type_of(param.def_id);
+                    self.tcx.ensure_ok().type_of(param.def_id);
                 }
                 hir::GenericParamKind::Type { .. } => {}
                 hir::GenericParamKind::Const { default, .. } => {
-                    self.tcx.ensure().type_of(param.def_id);
+                    self.tcx.ensure_ok().type_of(param.def_id);
                     if let Some(default) = default {
                         // need to store default and type of default
-                        self.tcx.ensure().const_param_default(param.def_id);
+                        self.tcx.ensure_ok().const_param_default(param.def_id);
                         if let hir::ConstArgKind::Anon(ac) = default.kind {
-                            self.tcx.ensure().type_of(ac.def_id);
+                            self.tcx.ensure_ok().type_of(ac.def_id);
                         }
                     }
                 }
@@ -312,8 +312,8 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         if let hir::ExprKind::Closure(closure) = expr.kind {
-            self.tcx.ensure().generics_of(closure.def_id);
-            self.tcx.ensure().codegen_fn_attrs(closure.def_id);
+            self.tcx.ensure_ok().generics_of(closure.def_id);
+            self.tcx.ensure_ok().codegen_fn_attrs(closure.def_id);
             // We do not call `type_of` for closures here as that
             // depends on typecheck and would therefore hide
             // any further errors in case one typeck fails.
@@ -325,15 +325,15 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
     /// `check_item_type` ensures that it's called instead.
     fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) {
         let def_id = opaque.def_id;
-        self.tcx.ensure().generics_of(def_id);
-        self.tcx.ensure().predicates_of(def_id);
-        self.tcx.ensure().explicit_item_bounds(def_id);
-        self.tcx.ensure().explicit_item_self_bounds(def_id);
-        self.tcx.ensure().item_bounds(def_id);
-        self.tcx.ensure().item_self_bounds(def_id);
+        self.tcx.ensure_ok().generics_of(def_id);
+        self.tcx.ensure_ok().predicates_of(def_id);
+        self.tcx.ensure_ok().explicit_item_bounds(def_id);
+        self.tcx.ensure_ok().explicit_item_self_bounds(def_id);
+        self.tcx.ensure_ok().item_bounds(def_id);
+        self.tcx.ensure_ok().item_self_bounds(def_id);
         if self.tcx.is_conditionally_const(def_id) {
-            self.tcx.ensure().explicit_implied_const_bounds(def_id);
-            self.tcx.ensure().const_conditions(def_id);
+            self.tcx.ensure_ok().explicit_implied_const_bounds(def_id);
+            self.tcx.ensure_ok().const_conditions(def_id);
         }
         intravisit::walk_opaque_ty(self, opaque);
     }
@@ -683,20 +683,20 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
         hir::ItemKind::ForeignMod { items, .. } => {
             for item in *items {
                 let item = tcx.hir().foreign_item(item.id);
-                tcx.ensure().generics_of(item.owner_id);
-                tcx.ensure().type_of(item.owner_id);
-                tcx.ensure().predicates_of(item.owner_id);
+                tcx.ensure_ok().generics_of(item.owner_id);
+                tcx.ensure_ok().type_of(item.owner_id);
+                tcx.ensure_ok().predicates_of(item.owner_id);
                 if tcx.is_conditionally_const(def_id) {
-                    tcx.ensure().explicit_implied_const_bounds(def_id);
-                    tcx.ensure().const_conditions(def_id);
+                    tcx.ensure_ok().explicit_implied_const_bounds(def_id);
+                    tcx.ensure_ok().const_conditions(def_id);
                 }
                 match item.kind {
                     hir::ForeignItemKind::Fn(..) => {
-                        tcx.ensure().codegen_fn_attrs(item.owner_id);
-                        tcx.ensure().fn_sig(item.owner_id)
+                        tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
+                        tcx.ensure_ok().fn_sig(item.owner_id)
                     }
                     hir::ForeignItemKind::Static(..) => {
-                        tcx.ensure().codegen_fn_attrs(item.owner_id);
+                        tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
                         let mut visitor = HirPlaceholderCollector::default();
                         visitor.visit_foreign_item(item);
                         placeholder_type_error(
@@ -713,40 +713,40 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
             }
         }
         hir::ItemKind::Enum(..) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().predicates_of(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
             lower_enum_variant_types(tcx, def_id.to_def_id());
         }
         hir::ItemKind::Impl { .. } => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().impl_trait_header(def_id);
-            tcx.ensure().predicates_of(def_id);
-            tcx.ensure().associated_items(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().impl_trait_header(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
+            tcx.ensure_ok().associated_items(def_id);
         }
         hir::ItemKind::Trait(..) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().trait_def(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().trait_def(def_id);
             tcx.at(it.span).explicit_super_predicates_of(def_id);
-            tcx.ensure().predicates_of(def_id);
-            tcx.ensure().associated_items(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
+            tcx.ensure_ok().associated_items(def_id);
         }
         hir::ItemKind::TraitAlias(..) => {
-            tcx.ensure().generics_of(def_id);
+            tcx.ensure_ok().generics_of(def_id);
             tcx.at(it.span).explicit_implied_predicates_of(def_id);
             tcx.at(it.span).explicit_super_predicates_of(def_id);
-            tcx.ensure().predicates_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
         }
         hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().predicates_of(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
 
             for f in struct_def.fields() {
-                tcx.ensure().generics_of(f.def_id);
-                tcx.ensure().type_of(f.def_id);
-                tcx.ensure().predicates_of(f.def_id);
+                tcx.ensure_ok().generics_of(f.def_id);
+                tcx.ensure_ok().type_of(f.def_id);
+                tcx.ensure_ok().predicates_of(f.def_id);
             }
 
             if let Some(ctor_def_id) = struct_def.ctor_def_id() {
@@ -755,15 +755,15 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
         }
 
         hir::ItemKind::TyAlias(..) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().predicates_of(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
         }
 
         hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().predicates_of(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
             if !ty.is_suggestable_infer_ty() {
                 let mut visitor = HirPlaceholderCollector::default();
                 visitor.visit_item(it);
@@ -779,11 +779,11 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
         }
 
         hir::ItemKind::Fn { .. } => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().predicates_of(def_id);
-            tcx.ensure().fn_sig(def_id);
-            tcx.ensure().codegen_fn_attrs(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
+            tcx.ensure_ok().fn_sig(def_id);
+            tcx.ensure_ok().codegen_fn_attrs(def_id);
         }
     }
 }
@@ -791,18 +791,18 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
 fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
     let trait_item = tcx.hir().trait_item(trait_item_id);
     let def_id = trait_item_id.owner_id;
-    tcx.ensure().generics_of(def_id);
+    tcx.ensure_ok().generics_of(def_id);
     let icx = ItemCtxt::new(tcx, def_id.def_id);
 
     match trait_item.kind {
         hir::TraitItemKind::Fn(..) => {
-            tcx.ensure().codegen_fn_attrs(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().fn_sig(def_id);
+            tcx.ensure_ok().codegen_fn_attrs(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().fn_sig(def_id);
         }
 
         hir::TraitItemKind::Const(ty, body_id) => {
-            tcx.ensure().type_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
             if !tcx.dcx().has_stashed_diagnostic(ty.span, StashKey::ItemNoType)
                 && !(ty.is_suggestable_infer_ty() && body_id.is_some())
             {
@@ -821,9 +821,9 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
         }
 
         hir::TraitItemKind::Type(_, Some(_)) => {
-            tcx.ensure().item_bounds(def_id);
-            tcx.ensure().item_self_bounds(def_id);
-            tcx.ensure().type_of(def_id);
+            tcx.ensure_ok().item_bounds(def_id);
+            tcx.ensure_ok().item_self_bounds(def_id);
+            tcx.ensure_ok().type_of(def_id);
             // Account for `type T = _;`.
             let mut visitor = HirPlaceholderCollector::default();
             visitor.visit_trait_item(trait_item);
@@ -838,8 +838,8 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
         }
 
         hir::TraitItemKind::Type(_, None) => {
-            tcx.ensure().item_bounds(def_id);
-            tcx.ensure().item_self_bounds(def_id);
+            tcx.ensure_ok().item_bounds(def_id);
+            tcx.ensure_ok().item_self_bounds(def_id);
             // #74612: Visit and try to find bad placeholders
             // even if there is no concrete type.
             let mut visitor = HirPlaceholderCollector::default();
@@ -856,20 +856,20 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
         }
     };
 
-    tcx.ensure().predicates_of(def_id);
+    tcx.ensure_ok().predicates_of(def_id);
 }
 
 fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
     let def_id = impl_item_id.owner_id;
-    tcx.ensure().generics_of(def_id);
-    tcx.ensure().type_of(def_id);
-    tcx.ensure().predicates_of(def_id);
+    tcx.ensure_ok().generics_of(def_id);
+    tcx.ensure_ok().type_of(def_id);
+    tcx.ensure_ok().predicates_of(def_id);
     let impl_item = tcx.hir().impl_item(impl_item_id);
     let icx = ItemCtxt::new(tcx, def_id.def_id);
     match impl_item.kind {
         hir::ImplItemKind::Fn(..) => {
-            tcx.ensure().codegen_fn_attrs(def_id);
-            tcx.ensure().fn_sig(def_id);
+            tcx.ensure_ok().codegen_fn_attrs(def_id);
+            tcx.ensure_ok().fn_sig(def_id);
         }
         hir::ImplItemKind::Type(_) => {
             // Account for `type T = _;`
@@ -904,9 +904,9 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
 }
 
 fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) {
-    tcx.ensure().generics_of(def_id);
-    tcx.ensure().type_of(def_id);
-    tcx.ensure().predicates_of(def_id);
+    tcx.ensure_ok().generics_of(def_id);
+    tcx.ensure_ok().type_of(def_id);
+    tcx.ensure_ok().predicates_of(def_id);
 }
 
 fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
@@ -937,9 +937,9 @@ fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
         );
 
         for f in &variant.fields {
-            tcx.ensure().generics_of(f.did);
-            tcx.ensure().type_of(f.did);
-            tcx.ensure().predicates_of(f.did);
+            tcx.ensure_ok().generics_of(f.did);
+            tcx.ensure_ok().type_of(f.did);
+            tcx.ensure_ok().predicates_of(f.did);
         }
 
         // Lower the ctor, if any. This also registers the variant as an item.
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 2ac8acbd3a4..c0902398a54 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -198,6 +198,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                     {
                         Some(parent_did)
                     }
+                    Node::TyPat(_) => Some(parent_did),
                     _ => None,
                 }
             }
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 d67b9d33596..76006354717 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -831,8 +831,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::Pat<'tcx>) {
-        intravisit::walk_pat(self, p)
+    fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::TyPat<'tcx>) {
+        intravisit::walk_ty_pat(self, p)
     }
 
     #[instrument(level = "debug", skip(self))]
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 348d4d708b5..4e12db190fd 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -18,9 +18,10 @@ use crate::hir_ty_lowering::HirTyLowerer;
 
 mod opaque;
 
-fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
+fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
     use hir::*;
     use rustc_middle::ty::Ty;
+    let tcx = icx.tcx;
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
 
     let node = tcx.hir_node(hir_id);
@@ -54,7 +55,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
             hir_id: arg_hir_id,
             kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
             ..
-        }) if anon_hir_id == hir_id => const_arg_anon_type_of(tcx, arg_hir_id, span),
+        }) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),
 
         // Anon consts outside the type system.
         Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
@@ -138,10 +139,12 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
     }
 }
 
-fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
+fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
     use hir::*;
     use rustc_middle::ty::Ty;
 
+    let tcx = icx.tcx;
+
     match tcx.parent_hir_node(arg_hir_id) {
         // Array length const arguments do not have `type_of` fed as there is never a corresponding
         // generic parameter definition.
@@ -149,7 +152,15 @@ fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span
         | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
             if constant.hir_id == arg_hir_id =>
         {
-            return tcx.types.usize;
+            tcx.types.usize
+        }
+
+        Node::TyPat(pat) => {
+            let hir::TyKind::Pat(ty, p) = tcx.parent_hir_node(pat.hir_id).expect_ty().kind else {
+                bug!()
+            };
+            assert_eq!(p.hir_id, pat.hir_id);
+            icx.lower_ty(ty)
         }
 
         // This is not a `bug!` as const arguments in path segments that did not resolve to anything
@@ -344,7 +355,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
             tcx.typeck(def_id).node_type(hir_id)
         }
 
-        Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
+        Node::AnonConst(_) => anon_const_type_of(&icx, def_id),
 
         Node::ConstBlock(_) => {
             let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 1dcea5d0335..9769be30226 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1605,13 +1605,6 @@ pub(crate) struct OpaqueCapturesHigherRankedLifetime {
     pub bad_place: &'static str,
 }
 
-#[derive(Diagnostic)]
-#[diag(hir_analysis_pattern_type_non_const_range)]
-pub(crate) struct NonConstRange {
-    #[primary_span]
-    pub span: Span,
-}
-
 #[derive(Subdiagnostic)]
 pub(crate) enum InvalidReceiverTyHint {
     #[note(hir_analysis_invalid_receiver_ty_help_weak_note)]
diff --git a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs
index bb771d6ea17..ec7b3aaa1c1 100644
--- a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs
+++ b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs
@@ -1,9 +1,14 @@
 use rustc_macros::Diagnostic;
+use rustc_middle::ty::Ty;
 use rustc_span::Span;
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_pattern_type_wild_pat)]
-pub(crate) struct WildPatTy {
+#[diag(hir_analysis_invalid_base_type)]
+pub(crate) struct InvalidBaseType<'tcx> {
+    pub ty: Ty<'tcx>,
     #[primary_span]
-    pub span: Span,
+    pub ty_span: Span,
+    pub pat: &'static str,
+    #[note]
+    pub pat_span: Span,
 }
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 36b214b6ae7..79aa2f4b8cc 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -3,7 +3,7 @@ use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::unord::UnordMap;
 use rustc_errors::codes::*;
 use rustc_errors::{
-    Applicability, Diag, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err,
+    Applicability, Diag, ErrorGuaranteed, MultiSpan, listify, pluralize, struct_span_code_err,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -808,14 +808,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             .map(|(trait_, mut assocs)| {
                 assocs.sort();
                 let trait_ = trait_.print_trait_sugared();
-                format!("{} in `{trait_}`", match &assocs[..] {
-                    [] => String::new(),
-                    [only] => format!("`{only}`"),
-                    [assocs @ .., last] => format!(
-                        "{} and `{last}`",
-                        assocs.iter().map(|a| format!("`{a}`")).collect::<Vec<_>>().join(", ")
-                    ),
-                })
+                format!(
+                    "{} in `{trait_}`",
+                    listify(&assocs[..], |a| format!("`{a}`")).unwrap_or_default()
+                )
             })
             .collect::<Vec<String>>();
         names.sort();
@@ -1075,18 +1071,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 }
             })
             .collect();
-        let this_type = match &types_and_spans[..] {
-            [.., _, (last, _)] => format!(
-                "{} and {last}",
-                types_and_spans[..types_and_spans.len() - 1]
-                    .iter()
-                    .map(|(x, _)| x.as_str())
-                    .intersperse(", ")
-                    .collect::<String>()
-            ),
-            [(only, _)] => only.to_string(),
-            [] => bug!("expected one segment to deny"),
-        };
+        let this_type = listify(&types_and_spans, |(t, _)| t.to_string())
+            .expect("expected one segment to deny");
 
         let arg_spans: Vec<Span> = segments
             .clone()
@@ -1102,21 +1088,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             ProhibitGenericsArg::Infer => kinds.push("generic"),
         });
 
-        let (kind, s) = match kinds[..] {
-            [.., _, last] => (
-                format!(
-                    "{} and {last}",
-                    kinds[..kinds.len() - 1]
-                        .iter()
-                        .map(|&x| x)
-                        .intersperse(", ")
-                        .collect::<String>()
-                ),
-                "s",
-            ),
-            [only] => (only.to_string(), ""),
-            [] => bug!("expected at least one generic to prohibit"),
-        };
+        let s = pluralize!(kinds.len());
+        let kind =
+            listify(&kinds, |k| k.to_string()).expect("expected at least one generic to prohibit");
         let last_span = *arg_spans.last().unwrap();
         let span: MultiSpan = arg_spans.into();
         let mut err = struct_span_code_err!(
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index b4cab3330af..079e8921627 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -53,7 +53,7 @@ use tracing::{debug, instrument};
 
 use crate::bounds::Bounds;
 use crate::check::check_abi_fn_ptr;
-use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, WildPatTy};
+use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType};
 use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
 use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
 use crate::middle::resolve_bound_vars as rbv;
@@ -2432,61 +2432,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 self.ty_infer(None, hir_ty.span)
             }
             hir::TyKind::Pat(ty, pat) => {
+                let ty_span = ty.span;
                 let ty = self.lower_ty(ty);
                 let pat_ty = match pat.kind {
-                    hir::PatKind::Wild => {
-                        let err = self.dcx().emit_err(WildPatTy { span: pat.span });
-                        Ty::new_error(tcx, err)
-                    }
-                    hir::PatKind::Range(start, end, include_end) => {
-                        let expr_to_const = |expr: &'tcx hir::PatExpr<'tcx>| -> ty::Const<'tcx> {
-                            let (c, c_ty) = match expr.kind {
-                                hir::PatExprKind::Lit { lit, negated } => {
-                                    let lit_input =
-                                        LitToConstInput { lit: &lit.node, ty, neg: negated };
-                                    let ct = tcx.lit_to_const(lit_input);
-                                    (ct, ty)
-                                }
-
-                                hir::PatExprKind::Path(hir::QPath::Resolved(
-                                    _,
-                                    path @ &hir::Path {
-                                        res: Res::Def(DefKind::ConstParam, def_id),
-                                        ..
-                                    },
-                                )) => {
-                                    match self.prohibit_generic_args(
-                                        path.segments.iter(),
-                                        GenericsArgsErrExtend::Param(def_id),
-                                    ) {
-                                        Ok(()) => {
-                                            let ty = tcx
-                                                .type_of(def_id)
-                                                .no_bound_vars()
-                                                .expect("const parameter types cannot be generic");
-                                            let ct = self.lower_const_param(def_id, expr.hir_id);
-                                            (ct, ty)
-                                        }
-                                        Err(guar) => (
-                                            ty::Const::new_error(tcx, guar),
-                                            Ty::new_error(tcx, guar),
-                                        ),
-                                    }
-                                }
-
-                                _ => {
-                                    let err = tcx
-                                        .dcx()
-                                        .emit_err(crate::errors::NonConstRange { span: expr.span });
-                                    (ty::Const::new_error(tcx, err), Ty::new_error(tcx, err))
-                                }
-                            };
-                            self.record_ty(expr.hir_id, c_ty, expr.span);
-                            c
+                    hir::TyPatKind::Range(start, end, include_end) => {
+                        let ty = match ty.kind() {
+                            ty::Int(_) | ty::Uint(_) | ty::Char => ty,
+                            _ => Ty::new_error(
+                                tcx,
+                                self.dcx().emit_err(InvalidBaseType {
+                                    ty,
+                                    pat: "range",
+                                    ty_span,
+                                    pat_span: pat.span,
+                                }),
+                            ),
                         };
-
-                        let start = start.map(expr_to_const);
-                        let end = end.map(expr_to_const);
+                        let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
+                        let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
 
                         let include_end = match include_end {
                             hir::RangeEnd::Included => true,
@@ -2496,12 +2459,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
                         Ty::new_pat(tcx, ty, pat)
                     }
-                    hir::PatKind::Err(e) => Ty::new_error(tcx, e),
-                    _ => Ty::new_error_with_message(
-                        tcx,
-                        pat.span,
-                        format!("unsupported pattern for pattern type: {pat:#?}"),
-                    ),
+                    hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
                 };
                 self.record_ty(pat.hir_id, ty, pat.span);
                 pat_ty
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index fd5a7089b4c..c30b39dfe76 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -62,7 +62,7 @@ pub(crate) fn check_impl_wf(
     // Check that the args are constrained. We queryfied the check for ty/const params
     // since unconstrained type/const params cause ICEs in projection, so we want to
     // detect those specifically and project those to `TyKind::Error`.
-    let mut res = tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id);
+    let mut res = tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id);
     res = res.and(enforce_impl_lifetime_params_are_constrained(tcx, impl_def_id));
 
     if tcx.features().min_specialization() {
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index ae054a9eaeb..3af4318544e 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -100,7 +100,7 @@ use rustc_middle::middle;
 use rustc_middle::mir::interpret::GlobalId;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt};
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::traits;
 
 pub use crate::collect::suggest_impl_trait;
@@ -139,16 +139,20 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     let _prof_timer = tcx.sess.timer("type_check_crate");
 
     tcx.sess.time("coherence_checking", || {
+        // When discarding query call results, use an explicit type to indicate
+        // what we are intending to discard, to help future type-based refactoring.
+        type R = Result<(), ErrorGuaranteed>;
+
         tcx.hir().par_for_each_module(|module| {
-            let _ = tcx.ensure().check_mod_type_wf(module);
+            let _: R = tcx.ensure_ok().check_mod_type_wf(module);
         });
 
         for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
-            let _ = tcx.ensure().coherent_trait(trait_def_id);
+            let _: R = tcx.ensure_ok().coherent_trait(trait_def_id);
         }
         // these queries are executed for side-effects (error reporting):
-        let _ = tcx.ensure().crate_inherent_impls_validity_check(());
-        let _ = tcx.ensure().crate_inherent_impls_overlap_check(());
+        let _: R = tcx.ensure_ok().crate_inherent_impls_validity_check(());
+        let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(());
     });
 
     if tcx.features().rustc_attrs() {
@@ -167,12 +171,12 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     tcx.hir().par_body_owners(|item_def_id| {
         let def_kind = tcx.def_kind(item_def_id);
         match def_kind {
-            DefKind::Static { .. } => tcx.ensure().eval_static_initializer(item_def_id),
+            DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id),
             DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
                 let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty());
                 let cid = GlobalId { instance, promoted: None };
                 let typing_env = ty::TypingEnv::fully_monomorphized();
-                tcx.ensure().eval_to_const_value_raw(typing_env.as_query_input(cid));
+                tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid));
             }
             _ => (),
         }
@@ -185,11 +189,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     tcx.hir().par_body_owners(|item_def_id| {
         let def_kind = tcx.def_kind(item_def_id);
         if !matches!(def_kind, DefKind::AnonConst) {
-            tcx.ensure().typeck(item_def_id);
+            tcx.ensure_ok().typeck(item_def_id);
         }
     });
 
-    tcx.ensure().check_unused_traits(());
+    tcx.ensure_ok().check_unused_traits(());
 }
 
 /// Lower a [`hir::Ty`] to a [`Ty`].
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index a91afa51230..3b163d0bc20 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -18,7 +18,7 @@ use rustc_ast_pretty::pprust::state::MacHeader;
 use rustc_ast_pretty::pprust::{Comments, PrintState};
 use rustc_hir::{
     BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind,
-    HirId, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term,
+    HirId, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term, TyPatKind,
 };
 use rustc_span::source_map::SourceMap;
 use rustc_span::{FileName, Ident, Span, Symbol, kw};
@@ -35,6 +35,7 @@ pub enum AnnNode<'a> {
     SubItem(HirId),
     Expr(&'a hir::Expr<'a>),
     Pat(&'a hir::Pat<'a>),
+    TyPat(&'a hir::TyPat<'a>),
     Arm(&'a hir::Arm<'a>),
 }
 
@@ -198,6 +199,7 @@ impl<'a> State<'a> {
             Node::TraitRef(a) => self.print_trait_ref(a),
             Node::OpaqueTy(o) => self.print_opaque_ty(o),
             Node::Pat(a) => self.print_pat(a),
+            Node::TyPat(a) => self.print_ty_pat(a),
             Node::PatField(a) => self.print_patfield(a),
             Node::PatExpr(a) => self.print_pat_expr(a),
             Node::Arm(a) => self.print_arm(a),
@@ -224,6 +226,16 @@ impl<'a> State<'a> {
             Node::Err(_) => self.word("/*ERROR*/"),
         }
     }
+
+    fn print_generic_arg(&mut self, generic_arg: &GenericArg<'_>, elide_lifetimes: bool) {
+        match generic_arg {
+            GenericArg::Lifetime(lt) if !elide_lifetimes => self.print_lifetime(lt),
+            GenericArg::Lifetime(_) => {}
+            GenericArg::Type(ty) => self.print_type(ty.as_unambig_ty()),
+            GenericArg::Const(ct) => self.print_const_arg(ct.as_unambig_ct()),
+            GenericArg::Infer(_inf) => self.word("_"),
+        }
+    }
 }
 
 impl std::ops::Deref for State<'_> {
@@ -448,7 +460,7 @@ impl<'a> State<'a> {
             hir::TyKind::Pat(ty, pat) => {
                 self.print_type(ty);
                 self.word(" is ");
-                self.print_pat(pat);
+                self.print_ty_pat(pat);
             }
         }
         self.end()
@@ -1797,13 +1809,7 @@ impl<'a> State<'a> {
                 if nonelided_generic_args {
                     start_or_comma(self);
                     self.commasep(Inconsistent, generic_args.args, |s, generic_arg| {
-                        match generic_arg {
-                            GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt),
-                            GenericArg::Lifetime(_) => {}
-                            GenericArg::Type(ty) => s.print_type(ty.as_unambig_ty()),
-                            GenericArg::Const(ct) => s.print_const_arg(ct.as_unambig_ct()),
-                            GenericArg::Infer(_inf) => s.word("_"),
-                        }
+                        s.print_generic_arg(generic_arg, elide_lifetimes)
                     });
                 }
 
@@ -1864,6 +1870,33 @@ impl<'a> State<'a> {
         }
     }
 
+    fn print_ty_pat(&mut self, pat: &hir::TyPat<'_>) {
+        self.maybe_print_comment(pat.span.lo());
+        self.ann.pre(self, AnnNode::TyPat(pat));
+        // Pat isn't normalized, but the beauty of it
+        // is that it doesn't matter
+        match pat.kind {
+            TyPatKind::Range(begin, end, end_kind) => {
+                if let Some(expr) = begin {
+                    self.print_const_arg(expr);
+                }
+                match end_kind {
+                    RangeEnd::Included => self.word("..."),
+                    RangeEnd::Excluded => self.word(".."),
+                }
+                if let Some(expr) = end {
+                    self.print_const_arg(expr);
+                }
+            }
+            TyPatKind::Err(_) => {
+                self.popen();
+                self.word("/*ERROR*/");
+                self.pclose();
+            }
+        }
+        self.ann.post(self, AnnNode::TyPat(pat))
+    }
+
     fn print_pat(&mut self, pat: &hir::Pat<'_>) {
         self.maybe_print_comment(pat.span.lo());
         self.ann.pre(self, AnnNode::Pat(pat));
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 28b1a823dae..edc3702d90b 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -49,7 +49,7 @@ pub(crate) fn check_legal_trait_for_method_call(
         };
         return Err(tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg }));
     }
-    tcx.ensure().coherent_trait(trait_id)
+    tcx.ensure_ok().coherent_trait(trait_id)
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index b0698183b57..9fdc5a0ae4e 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -117,22 +117,17 @@ pub(super) fn check_fn<'a, 'tcx>(
 
     fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
 
-    let return_or_body_span = match decl.output {
-        hir::FnRetTy::DefaultReturn(_) => body.value.span,
-        hir::FnRetTy::Return(ty) => ty.span,
-    };
-
-    fcx.require_type_is_sized(
-        declared_ret_ty,
-        return_or_body_span,
-        ObligationCauseCode::SizedReturnType,
-    );
-    // We checked the root's signature during wfcheck, but not the child.
+    // We checked the root's ret ty during wfcheck, but not the child.
     if fcx.tcx.is_typeck_child(fn_def_id.to_def_id()) {
+        let return_or_body_span = match decl.output {
+            hir::FnRetTy::DefaultReturn(_) => body.value.span,
+            hir::FnRetTy::Return(ty) => ty.span,
+        };
+
         fcx.require_type_is_sized(
             declared_ret_ty,
             return_or_body_span,
-            ObligationCauseCode::WellFormed(None),
+            ObligationCauseCode::SizedReturnType,
         );
     }
 
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 153fd6001bb..83acc7dd6af 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -50,7 +50,6 @@ use rustc_infer::traits::{
     IfExpressionCause, MatchExpressionArmCause, Obligation, PredicateObligation,
     PredicateObligations,
 };
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::span_bug;
 use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::ty::adjustment::{
@@ -1937,7 +1936,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                     cond_expr.span.desugaring_kind(),
                     None | Some(DesugaringKind::WhileLoop)
                 )
-                && !in_external_macro(fcx.tcx.sess, cond_expr.span)
+                && !cond_expr.span.in_external_macro(fcx.tcx.sess.source_map())
                 && !matches!(
                     cond_expr.kind,
                     hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_))
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index bc076670585..85e949952f8 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -1,4 +1,4 @@
-use rustc_errors::{Applicability, Diag, MultiSpan};
+use rustc_errors::{Applicability, Diag, MultiSpan, listify};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::intravisit::Visitor;
@@ -1016,18 +1016,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 },
                 self.tcx.def_path_str(candidate.item.container_id(self.tcx))
             ),
-            [.., last] if other_methods_in_scope.len() < 5 => {
+            _ if other_methods_in_scope.len() < 5 => {
                 format!(
-                    "the methods of the same name on {} and `{}`",
-                    other_methods_in_scope[..other_methods_in_scope.len() - 1]
-                        .iter()
-                        .map(|c| format!(
-                            "`{}`",
-                            self.tcx.def_path_str(c.item.container_id(self.tcx))
-                        ))
-                        .collect::<Vec<String>>()
-                        .join(", "),
-                    self.tcx.def_path_str(last.item.container_id(self.tcx))
+                    "the methods of the same name on {}",
+                    listify(
+                        &other_methods_in_scope[..other_methods_in_scope.len() - 1],
+                        |c| format!("`{}`", self.tcx.def_path_str(c.item.container_id(self.tcx)))
+                    )
+                    .unwrap_or_default(),
                 )
             }
             _ => format!(
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index f79667e59ba..49f712090f0 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -11,7 +11,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::unord::UnordMap;
 use rustc_errors::codes::*;
 use rustc_errors::{
-    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, Subdiagnostic, pluralize,
+    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, Subdiagnostic, listify, pluralize,
     struct_span_code_err,
 };
 use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -269,6 +269,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // diverging expression (e.g. it arose from desugaring of `try { return }`),
             // we skip issuing a warning because it is autogenerated code.
             ExprKind::Call(..) if expr.span.is_desugaring(DesugaringKind::TryBlock) => {}
+            // Likewise, do not lint unreachable code injected via contracts desugaring.
+            ExprKind::Call(..) if expr.span.is_desugaring(DesugaringKind::Contract) => {}
             ExprKind::Call(callee, _) => self.warn_if_unreachable(expr.hir_id, callee.span, "call"),
             ExprKind::MethodCall(segment, ..) => {
                 self.warn_if_unreachable(expr.hir_id, segment.ident.span, "call")
@@ -412,7 +414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             })
             | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => true,
 
-            hir::Node::Pat(_) => {
+            hir::Node::TyPat(_) | hir::Node::Pat(_) => {
                 self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
                 true
             }
@@ -1658,8 +1660,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         hir_ty: Option<&'tcx hir::Ty<'tcx>>,
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
-        self.dcx().span_err(inner_expr.span, "unsafe binder casts are not fully implemented");
-
         match kind {
             hir::UnsafeBinderCastKind::Wrap => {
                 let ascribed_ty =
@@ -2190,13 +2190,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             if !missing_mandatory_fields.is_empty() {
                 let s = pluralize!(missing_mandatory_fields.len());
-                let fields: Vec<_> =
-                    missing_mandatory_fields.iter().map(|f| format!("`{f}`")).collect();
-                let fields = match &fields[..] {
-                    [] => unreachable!(),
-                    [only] => only.to_string(),
-                    [start @ .., last] => format!("{} and {last}", start.join(", ")),
-                };
+                let fields = listify(&missing_mandatory_fields, |f| format!("`{f}`")).unwrap();
                 self.dcx()
                     .struct_span_err(
                         span.shrink_to_hi(),
@@ -2553,25 +2547,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .partition(|field| field.2);
         err.span_labels(used_private_fields.iter().map(|(_, span, _)| *span), "private field");
         if !remaining_private_fields.is_empty() {
-            let remaining_private_fields_len = remaining_private_fields.len();
-            let names = match &remaining_private_fields
-                .iter()
-                .map(|(name, _, _)| name)
-                .collect::<Vec<_>>()[..]
-            {
-                _ if remaining_private_fields_len > 6 => String::new(),
-                [name] => format!("`{name}` "),
-                [names @ .., last] => {
-                    let names = names.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
-                    format!("{} and `{last}` ", names.join(", "))
-                }
-                [] => bug!("expected at least one private field to report"),
+            let names = if remaining_private_fields.len() > 6 {
+                String::new()
+            } else {
+                format!(
+                    "{} ",
+                    listify(&remaining_private_fields, |(name, _, _)| format!("`{name}`"))
+                        .expect("expected at least one private field to report")
+                )
             };
             err.note(format!(
                 "{}private field{s} {names}that {were} not provided",
                 if used_fields.is_empty() { "" } else { "...and other " },
-                s = pluralize!(remaining_private_fields_len),
-                were = pluralize!("was", remaining_private_fields_len),
+                s = pluralize!(remaining_private_fields.len()),
+                were = pluralize!("was", remaining_private_fields.len()),
             ));
         }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index fb5fc109ce4..e90474cabb4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -4,8 +4,7 @@ use itertools::Itertools;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::codes::*;
 use rustc_errors::{
-    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, a_or_an,
-    display_list_with_comma_and, pluralize,
+    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, a_or_an, listify, pluralize,
 };
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
@@ -14,7 +13,7 @@ use rustc_hir::{ExprKind, HirId, Node, QPath};
 use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
 use rustc_hir_analysis::check::potentially_plural_count;
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
-use rustc_index::IndexVec;
+use rustc_index::{Idx, IndexVec};
 use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TypeTrace};
 use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::error::TypeError;
@@ -22,7 +21,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::Session;
-use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
+use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
 use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext};
@@ -127,7 +126,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             Err(guar) => Err(guar),
         };
         if let Err(guar) = has_error {
-            let err_inputs = self.err_args(args_no_rcvr.len(), guar);
+            let err_inputs = self.err_args(
+                method.map_or(args_no_rcvr.len(), |method| method.sig.inputs().len() - 1),
+                guar,
+            );
             let err_output = Ty::new_error(self.tcx, guar);
 
             let err_inputs = match tuple_arguments {
@@ -2375,11 +2377,11 @@ 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.1.is_some())
+                        && params_with_generics.iter().any(|(x, _)| x.is_some())
                     {
-                        for &(idx, generic, _) in &params_with_generics {
+                        for (idx, (generic, _)) in params_with_generics.iter_enumerated() {
                             // Param has to have a generic and be matched to be relevant
-                            if matched_inputs[idx.into()].is_none() {
+                            if matched_inputs[idx].is_none() {
                                 continue;
                             }
 
@@ -2387,10 +2389,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 continue;
                             };
 
-                            for unmatching_idx in idx + 1..params_with_generics.len() {
-                                if matched_inputs[unmatching_idx.into()].is_none()
+                            for unmatching_idx in
+                                idx.plus(1)..ExpectedIdx::from_usize(params_with_generics.len())
+                            {
+                                if matched_inputs[unmatching_idx].is_none()
                                     && let Some(unmatched_idx_param_generic) =
-                                        params_with_generics[unmatching_idx].1
+                                        params_with_generics[unmatching_idx].0
                                     && unmatched_idx_param_generic.name.ident()
                                         == generic.name.ident()
                                 {
@@ -2405,64 +2409,66 @@ 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().filter(|&(idx, _, _)| {
+                for (idx, &(generic_param, param)) in
+                    params_with_generics.iter_enumerated().filter(|&(idx, _)| {
                         check_for_matched_generics
-                            || expected_idx.is_none_or(|expected_idx| expected_idx == *idx)
+                            || expected_idx
+                                .is_none_or(|expected_idx| expected_idx == idx.as_usize())
                     })
                 {
                     let Some(generic_param) = generic_param else {
-                        spans.push_span_label(param.span, "");
+                        spans.push_span_label(param.span(), "");
                         continue;
                     };
 
-                    let other_params_matched: Vec<(usize, &hir::Param<'_>)> = 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[idx.into()].is_none()
-                                && matched_inputs[(*other_idx).into()].is_none()
-                            {
-                                return false;
-                            }
-                            if matched_inputs[idx.into()].is_some()
-                                && matched_inputs[(*other_idx).into()].is_some()
-                            {
-                                return false;
-                            }
-                            other_generic_param.name.ident() == generic_param.name.ident()
-                        })
-                        .map(|&(other_idx, _, other_param)| (other_idx, other_param))
-                        .collect();
+                    let other_params_matched: Vec<(ExpectedIdx, FnParam<'_>)> =
+                        params_with_generics
+                            .iter_enumerated()
+                            .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[idx].is_none()
+                                    && matched_inputs[other_idx].is_none()
+                                {
+                                    return false;
+                                }
+                                if matched_inputs[idx].is_some()
+                                    && matched_inputs[other_idx].is_some()
+                                {
+                                    return false;
+                                }
+                                other_generic_param.name.ident() == generic_param.name.ident()
+                            })
+                            .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(|(idx, other_param)| {
-                                if let hir::PatKind::Binding(_, _, ident, _) = other_param.pat.kind
-                                {
-                                    format!("`{ident}`")
+                                if let Some(name) = other_param.name() {
+                                    format!("`{name}`")
                                 } else {
-                                    format!("parameter #{}", idx + 1)
+                                    format!("parameter #{}", idx.as_u32() + 1)
                                 }
                             })
                             .collect();
 
                         let matched_ty = self
-                            .resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
+                            .resolve_vars_if_possible(formal_and_expected_inputs[idx].1)
                             .sort_string(self.tcx);
 
-                        if matched_inputs[idx.into()].is_some() {
+                        if matched_inputs[idx].is_some() {
                             spans.push_span_label(
-                                param.span,
+                                param.span(),
                                 format!(
                                     "{} need{} to match the {} type of this parameter",
-                                    display_list_with_comma_and(&other_param_matched_names),
+                                    listify(&other_param_matched_names, |n| n.to_string())
+                                        .unwrap_or_default(),
                                     pluralize!(if other_param_matched_names.len() == 1 {
                                         0
                                     } else {
@@ -2473,17 +2479,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             );
                         } else {
                             spans.push_span_label(
-                                param.span,
+                                param.span(),
                                 format!(
                                     "this parameter needs to match the {} type of {}",
                                     matched_ty,
-                                    display_list_with_comma_and(&other_param_matched_names),
+                                    listify(&other_param_matched_names, |n| n.to_string())
+                                        .unwrap_or_default(),
                                 ),
                             );
                         }
                         generics_with_unmatched_params.push(generic_param);
                     } else {
-                        spans.push_span_label(param.span, "");
+                        spans.push_span_label(param.span(), "");
                     }
                 }
 
@@ -2501,19 +2508,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     })
                 {
                     let param_idents_matching: Vec<String> = params_with_generics
-                        .iter()
-                        .filter(|(_, generic, _)| {
+                        .iter_enumerated()
+                        .filter(|&(_, &(generic, _))| {
                             if let Some(generic) = generic {
                                 generic.name.ident() == generic_param.name.ident()
                             } else {
                                 false
                             }
                         })
-                        .map(|(idx, _, param)| {
-                            if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind {
-                                format!("`{ident}`")
+                        .map(|(idx, &(_, param))| {
+                            if let Some(name) = param.name() {
+                                format!("`{name}`")
                             } else {
-                                format!("parameter #{}", idx + 1)
+                                format!("parameter #{}", idx.as_u32() + 1)
                             }
                         })
                         .collect();
@@ -2523,7 +2530,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             generic_param.span,
                             format!(
                                 "{} {} reference this parameter `{}`",
-                                display_list_with_comma_and(&param_idents_matching),
+                                listify(&param_idents_matching, |n| n.to_string())
+                                    .unwrap_or_default(),
                                 if param_idents_matching.len() == 2 { "both" } else { "all" },
                                 generic_param.name.ident().name,
                             ),
@@ -2605,12 +2613,13 @@ 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 {
-                if matched_inputs[idx.into()].is_none() {
+            for (idx, (generic_param, _)) in params_with_generics.iter_enumerated() {
+                if matched_inputs[idx].is_none() {
                     continue;
                 }
 
-                let Some((_, matched_arg_span)) = provided_arg_tys.get(idx.into()) else {
+                let Some((_, matched_arg_span)) = provided_arg_tys.get(idx.to_provided_idx())
+                else {
                     continue;
                 };
 
@@ -2618,32 +2627,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     continue;
                 };
 
-                let mut idxs_matched: Vec<usize> = vec![];
-                for &(other_idx, _, _) in
-                    params_with_generics.iter().filter(|&&(other_idx, other_generic_param, _)| {
+                let idxs_matched = params_with_generics
+                    .iter_enumerated()
+                    .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].is_some() {
                             return false;
                         }
                         other_generic_param.name.ident() == generic_param.name.ident()
                     })
-                {
-                    idxs_matched.push(other_idx);
-                }
+                    .count();
 
-                if idxs_matched.is_empty() {
+                if idxs_matched == 0 {
                     continue;
                 }
 
                 let expected_display_type = self
                     .resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
                     .sort_string(self.tcx);
-                let label = if idxs_matched.len() == params_with_generics.len() - 1 {
+                let label = if idxs_matched == params_with_generics.len() - 1 {
                     format!(
                         "expected all arguments to be this {} type because they need to match the type of this parameter",
                         expected_display_type
@@ -2662,62 +2669,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Returns the parameters of a function, with their generic parameters if those are the full
-    /// type of that parameter. Returns `None` if the function body is unavailable (eg is an instrinsic).
+    /// type of that parameter. Returns `None` if the function has no generics or the body is
+    /// unavailable (eg is an instrinsic).
     fn get_hir_params_with_generics(
         &self,
         def_id: DefId,
         is_method: bool,
-    ) -> 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()?;
-
-        let generic_params: Vec<Option<&hir::GenericParam<'_>>> = fn_decl
-            .inputs
-            .into_iter()
-            .skip(if is_method { 1 } else { 0 })
-            .map(|param| {
-                if let hir::TyKind::Path(QPath::Resolved(
-                    _,
-                    hir::Path { res: Res::Def(_, res_def_id), .. },
-                )) = param.kind
-                {
-                    fn_node
-                        .generics()
-                        .into_iter()
-                        .flat_map(|generics| generics.params)
-                        .find(|param| &param.def_id.to_def_id() == res_def_id)
-                } else {
-                    None
-                }
+    ) -> Option<IndexVec<ExpectedIdx, (Option<&hir::GenericParam<'_>>, FnParam<'_>)>> {
+        let (sig, generics, body_id, param_names) = match self.tcx.hir().get_if_local(def_id)? {
+            hir::Node::TraitItem(&hir::TraitItem {
+                generics,
+                kind: hir::TraitItemKind::Fn(sig, trait_fn),
+                ..
+            }) => match trait_fn {
+                hir::TraitFn::Required(params) => (sig, generics, None, Some(params)),
+                hir::TraitFn::Provided(body) => (sig, generics, Some(body), None),
+            },
+            hir::Node::ImplItem(&hir::ImplItem {
+                generics,
+                kind: hir::ImplItemKind::Fn(sig, body),
+                ..
             })
-            .collect();
-
-        let mut params: Vec<&hir::Param<'_>> = self
-            .tcx
-            .hir()
-            .body(fn_node.body_id()?)
-            .params
-            .into_iter()
-            .skip(if is_method { 1 } else { 0 })
-            .collect();
-
-        // The surrounding code expects variadic functions to not have a parameter representing
-        // the "..." parameter. This is already true of the FnDecl but not of the body params, so
-        // we drop it if it exists.
+            | hir::Node::Item(&hir::Item {
+                kind: hir::ItemKind::Fn { sig, generics, body, .. },
+                ..
+            }) => (sig, generics, Some(body), None),
+            _ => return None,
+        };
 
-        if fn_decl.c_variadic {
-            params.pop();
+        // Make sure to remove both the receiver and variadic argument. Both are removed
+        // when matching parameter types.
+        let fn_inputs = sig.decl.inputs.get(is_method as usize..)?.iter().map(|param| {
+            if let hir::TyKind::Path(QPath::Resolved(
+                _,
+                &hir::Path { res: Res::Def(_, res_def_id), .. },
+            )) = param.kind
+            {
+                generics.params.iter().find(|param| param.def_id.to_def_id() == res_def_id)
+            } else {
+                None
+            }
+        });
+        match (body_id, param_names) {
+            (Some(_), Some(_)) | (None, None) => unreachable!(),
+            (Some(body), None) => {
+                let params = self.tcx.hir().body(body).params;
+                let params =
+                    params.get(is_method as usize..params.len() - sig.decl.c_variadic as usize)?;
+                debug_assert_eq!(params.len(), fn_inputs.len());
+                Some(fn_inputs.zip(params.iter().map(|param| FnParam::Param(param))).collect())
+            }
+            (None, Some(params)) => {
+                let params = params.get(is_method as usize..)?;
+                debug_assert_eq!(params.len(), fn_inputs.len());
+                Some(fn_inputs.zip(params.iter().map(|param| FnParam::Name(param))).collect())
+            }
         }
-
-        debug_assert_eq!(params.len(), generic_params.len());
-        Some(
-            generic_params
-                .into_iter()
-                .zip(params)
-                .enumerate()
-                .map(|(a, (b, c))| (a, b, c))
-                .collect(),
-        )
     }
 }
 
@@ -2740,3 +2747,27 @@ impl<'tcx> Visitor<'tcx> for FindClosureArg<'tcx> {
         hir::intravisit::walk_expr(self, ex);
     }
 }
+
+#[derive(Clone, Copy)]
+enum FnParam<'hir> {
+    Param(&'hir hir::Param<'hir>),
+    Name(&'hir Ident),
+}
+impl FnParam<'_> {
+    fn span(&self) -> Span {
+        match self {
+            Self::Param(x) => x.span,
+            Self::Name(x) => x.span,
+        }
+    }
+
+    fn name(&self) -> Option<Symbol> {
+        match self {
+            Self::Param(x) if let hir::PatKind::Binding(_, _, ident, _) = x.pat.kind => {
+                Some(ident.name)
+            }
+            Self::Name(x) if x.name != kw::Empty => Some(x.name),
+            _ => None,
+        }
+    }
+}
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 60f9265bfcc..217ebd9cd2b 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -4,7 +4,7 @@ use core::iter;
 use hir::def_id::LocalDefId;
 use rustc_ast::util::parser::ExprPrecedence;
 use rustc_data_structures::packed::Pu128;
-use rustc_errors::{Applicability, Diag, MultiSpan};
+use rustc_errors::{Applicability, Diag, MultiSpan, listify};
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{
@@ -14,7 +14,6 @@ use rustc_hir::{
 };
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
 use rustc_hir_analysis::suggest_impl_trait;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::middle::stability::EvalResult;
 use rustc_middle::span_bug;
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -770,7 +769,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // If the expression is from an external macro, then do not suggest
                         // adding a semicolon, because there's nowhere to put it.
                         // See issue #81943.
-                        && !in_external_macro(self.tcx.sess, expression.span) =>
+                        && !expression.span.in_external_macro(self.tcx.sess.source_map()) =>
                 {
                     if needs_block {
                         err.multipart_suggestion(
@@ -1836,16 +1835,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 error.obligation.predicate,
                             ));
                         }
-                        [errors @ .., last] => {
+                        _ => {
                             diag.help(format!(
                                 "`Clone` is not implemented because the following trait bounds \
-                                 could not be satisfied: {} and `{}`",
-                                errors
-                                    .iter()
-                                    .map(|e| format!("`{}`", e.obligation.predicate))
-                                    .collect::<Vec<_>>()
-                                    .join(", "),
-                                last.obligation.predicate,
+                                 could not be satisfied: {}",
+                                listify(&errors, |e| format!("`{}`", e.obligation.predicate))
+                                    .unwrap(),
                             ));
                         }
                     }
@@ -2265,7 +2260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Ty<'tcx>,
         expr_ty: Ty<'tcx>,
     ) -> bool {
-        if in_external_macro(self.tcx.sess, expr.span) {
+        if expr.span.in_external_macro(self.tcx.sess.source_map()) {
             return false;
         }
         if let ty::Adt(expected_adt, args) = expected.kind() {
@@ -2593,14 +2588,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     )> {
         let sess = self.sess();
         let sp = expr.span;
+        let sm = sess.source_map();
 
         // If the span is from an external macro, there's no suggestion we can make.
-        if in_external_macro(sess, sp) {
+        if sp.in_external_macro(sm) {
             return None;
         }
 
-        let sm = sess.source_map();
-
         let replace_prefix = |s: &str, old: &str, new: &str| {
             s.strip_prefix(old).map(|stripped| new.to_string() + stripped)
         };
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 07e013e4afa..02fbd46173c 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -186,8 +186,6 @@ fn typeck_with_inspect<'tcx>(
         let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
         fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code);
 
-        fcx.require_type_is_sized(expected_type, body.value.span, ObligationCauseCode::ConstSized);
-
         // Gather locals in statics (because of block expressions).
         GatherLocalsVisitor::new(&fcx).visit_body(body);
 
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index e4a6a0fedc5..cbbda0b6cbc 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -5,6 +5,7 @@
 
 use core::ops::ControlFlow;
 use std::borrow::Cow;
+use std::path::PathBuf;
 
 use hir::Expr;
 use rustc_ast::ast::Mutability;
@@ -362,14 +363,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn suggest_missing_writer(&self, rcvr_ty: Ty<'tcx>, rcvr_expr: &hir::Expr<'tcx>) -> Diag<'_> {
         let mut file = None;
-        let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file);
         let mut err = struct_span_code_err!(
             self.dcx(),
             rcvr_expr.span,
             E0599,
             "cannot write into `{}`",
-            ty_str
+            self.tcx.short_string(rcvr_ty, &mut file),
         );
+        *err.long_ty_path() = file;
         err.span_note(
             rcvr_expr.span,
             "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method",
@@ -380,11 +381,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 "a writer is needed before this format string",
             );
         };
-        if let Some(file) = file {
-            err.note(format!("the full type name has been written to '{}'", file.display()));
-            err.note("consider using `--verbose` to print the full type name to the console");
-        }
-
         err
     }
 
@@ -595,7 +591,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 (predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string()))
             } else {
                 (
-                    tcx.short_ty_string(rcvr_ty, &mut ty_file),
+                    tcx.short_string(rcvr_ty, &mut ty_file),
                     with_forced_trimmed_paths!(rcvr_ty.to_string()),
                 )
             };
@@ -624,6 +620,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             span,
             item_name,
             &short_ty_str,
+            &mut ty_file,
         ) {
             return guar;
         }
@@ -635,6 +632,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             item_kind,
             item_name,
             &short_ty_str,
+            &mut ty_file,
         ) {
             return guar;
         }
@@ -728,10 +726,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ty_str = short_ty_str;
         }
 
-        if let Some(file) = ty_file {
-            err.note(format!("the full type name has been written to '{}'", file.display(),));
-            err.note("consider using `--verbose` to print the full type name to the console");
-        }
         if rcvr_ty.references_error() {
             err.downgrade_to_delayed_bug();
         }
@@ -1314,7 +1308,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     bound_list.into_iter().map(|(_, path)| path).collect::<Vec<_>>().join("\n");
                 let actual_prefix = rcvr_ty.prefix_string(self.tcx);
                 info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
-                let mut long_ty_file = None;
                 let (primary_message, label, notes) = if unimplemented_traits.len() == 1
                     && unimplemented_traits_only
                 {
@@ -1329,7 +1322,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             }
                             let OnUnimplementedNote { message, label, notes, .. } = self
                                 .err_ctxt()
-                                .on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file);
+                                .on_unimplemented_note(trait_ref, &obligation, &mut ty_file);
                             (message, label, notes)
                         })
                         .unwrap()
@@ -1343,15 +1336,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     )
                 });
                 err.primary_message(primary_message);
-                if let Some(file) = long_ty_file {
-                    err.note(format!(
-                        "the full name for the type has been written to '{}'",
-                        file.display(),
-                    ));
-                    err.note(
-                        "consider using `--verbose` to print the full type name to the console",
-                    );
-                }
                 if let Some(label) = label {
                     custom_span_label = true;
                     err.span_label(span, label);
@@ -2403,6 +2387,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         item_name: Ident,
         ty_str: &str,
+        long_ty_path: &mut Option<PathBuf>,
     ) -> Result<(), ErrorGuaranteed> {
         if let SelfSource::MethodCall(expr) = source {
             for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) {
@@ -2410,6 +2395,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let lang_item = match parent_expr.kind {
                         ExprKind::Struct(qpath, _, _) => match *qpath {
                             QPath::LangItem(LangItem::Range, ..) => Some(LangItem::Range),
+                            QPath::LangItem(LangItem::RangeCopy, ..) => Some(LangItem::RangeCopy),
+                            QPath::LangItem(LangItem::RangeInclusiveCopy, ..) => {
+                                Some(LangItem::RangeInclusiveCopy)
+                            }
                             QPath::LangItem(LangItem::RangeTo, ..) => Some(LangItem::RangeTo),
                             QPath::LangItem(LangItem::RangeToInclusive, ..) => {
                                 Some(LangItem::RangeToInclusive)
@@ -2460,7 +2449,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
                     if pick.is_ok() {
                         let range_span = parent_expr.span.with_hi(expr.span.hi());
-                        return Err(self.dcx().emit_err(errors::MissingParenthesesInRange {
+                        let mut err = self.dcx().create_err(errors::MissingParenthesesInRange {
                             span,
                             ty_str: ty_str.to_string(),
                             method_name: item_name.as_str().to_string(),
@@ -2469,7 +2458,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 left: range_span.shrink_to_lo(),
                                 right: range_span.shrink_to_hi(),
                             }),
-                        }));
+                        });
+                        *err.long_ty_path() = long_ty_path.take();
+                        return Err(err.emit());
                     }
                 }
             }
@@ -2486,6 +2477,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         item_kind: &str,
         item_name: Ident,
         ty_str: &str,
+        long_ty_path: &mut Option<PathBuf>,
     ) -> Result<(), ErrorGuaranteed> {
         let found_candidate = all_traits(self.tcx)
             .into_iter()
@@ -2526,6 +2518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 item_name,
                 ty_str
             );
+            *err.long_ty_path() = long_ty_path.take();
             let concrete_type = if actual.is_integral() { "i32" } else { "f32" };
             match expr.kind {
                 ExprKind::Lit(lit) => {
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index 6dab6468870..563ed7614c6 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -24,7 +24,7 @@ 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));
+        |tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx));
 }
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 515c9c34098..c2513a1af19 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -26,7 +26,6 @@ use rustc_macros::extension;
 pub use rustc_macros::{TypeFoldable, TypeVisitable};
 use rustc_middle::bug;
 use rustc_middle::infer::canonical::{CanonicalQueryInput, CanonicalVarValues};
-use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey};
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::select;
 pub use rustc_middle::ty::IntVarValue;
@@ -46,6 +45,7 @@ use tracing::{debug, instrument};
 use type_variable::TypeVariableOrigin;
 
 use crate::infer::region_constraints::UndoLog;
+use crate::infer::unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey};
 use crate::traits::{
     self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine,
 };
@@ -64,6 +64,7 @@ pub mod relate;
 pub mod resolve;
 pub(crate) mod snapshot;
 mod type_variable;
+mod unify_key;
 
 /// `InferOk<'tcx, ()>` is used a lot. It may seem like a useless wrapper
 /// around `PredicateObligations<'tcx>`, but it has one important property:
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 6496f38269a..57555db37ab 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -8,7 +8,6 @@ use rustc_data_structures::undo_log::UndoLogs;
 use rustc_data_structures::unify as ut;
 use rustc_index::IndexVec;
 use rustc_macros::{TypeFoldable, TypeVisitable};
-use rustc_middle::infer::unify_key::{RegionVariableValue, RegionVidKey};
 use rustc_middle::ty::{self, ReBound, ReStatic, ReVar, Region, RegionVid, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use tracing::{debug, instrument};
@@ -17,6 +16,7 @@ use self::CombineMapType::*;
 use self::UndoLog::*;
 use super::{MiscVariable, RegionVariableOrigin, Rollback, SubregionOrigin};
 use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, Snapshot};
+use crate::infer::unify_key::{RegionVariableValue, RegionVidKey};
 
 mod leak_check;
 
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 21c47967ead..ce2d07f4af9 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -4,7 +4,6 @@ use rustc_data_structures::sso::SsoHashMap;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir::def_id::DefId;
 use rustc_middle::bug;
-use rustc_middle::infer::unify_key::ConstVariableValue;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::visit::MaxUniverse;
 use rustc_middle::ty::{
@@ -18,6 +17,7 @@ use super::{
     PredicateEmittingRelation, Relate, RelateResult, StructurallyRelateAliases, TypeRelation,
 };
 use crate::infer::type_variable::TypeVariableValue;
+use crate::infer::unify_key::ConstVariableValue;
 use crate::infer::{InferCtxt, RegionVariableOrigin, relate};
 
 impl<'tcx> InferCtxt<'tcx> {
diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
index 394e07a81e7..3a47b13665d 100644
--- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
@@ -1,7 +1,6 @@
 use std::ops::Range;
 
 use rustc_data_structures::{snapshot_vec as sv, unify as ut};
-use rustc_middle::infer::unify_key::{ConstVariableValue, ConstVidKey};
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid};
 use rustc_type_ir::visit::TypeVisitableExt;
@@ -10,6 +9,7 @@ use ut::UnifyKey;
 
 use super::VariableLengths;
 use crate::infer::type_variable::TypeVariableOrigin;
+use crate::infer::unify_key::{ConstVariableValue, ConstVidKey};
 use crate::infer::{ConstVariableOrigin, InferCtxt, RegionVariableOrigin, UnificationTable};
 
 fn vars_since_snapshot<'tcx, T>(
diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
index 713389f4618..ba7d8f588e6 100644
--- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
@@ -2,10 +2,10 @@ use std::marker::PhantomData;
 
 use rustc_data_structures::undo_log::{Rollback, UndoLogs};
 use rustc_data_structures::{snapshot_vec as sv, unify as ut};
-use rustc_middle::infer::unify_key::{ConstVidKey, RegionVidKey};
 use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey};
 use tracing::debug;
 
+use crate::infer::unify_key::{ConstVidKey, RegionVidKey};
 use crate::infer::{InferCtxtInner, region_constraints, type_variable};
 use crate::traits;
 
diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_infer/src/infer/unify_key.rs
index 7f9211043d6..3ba8aea1d3a 100644
--- a/compiler/rustc_middle/src/infer/unify_key.rs
+++ b/compiler/rustc_infer/src/infer/unify_key.rs
@@ -2,23 +2,18 @@ use std::cmp;
 use std::marker::PhantomData;
 
 use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue};
+use rustc_middle::{bug, ty};
 use rustc_span::Span;
 use rustc_span::def_id::DefId;
 
-use crate::ty::{self, Ty, TyCtxt};
-
-pub trait ToType {
-    fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
-}
-
 #[derive(Copy, Clone, Debug)]
-pub enum RegionVariableValue<'tcx> {
+pub(crate) enum RegionVariableValue<'tcx> {
     Known { value: ty::Region<'tcx> },
     Unknown { universe: ty::UniverseIndex },
 }
 
 #[derive(PartialEq, Copy, Clone, Debug)]
-pub struct RegionVidKey<'tcx> {
+pub(crate) struct RegionVidKey<'tcx> {
     pub vid: ty::RegionVid,
     pub phantom: PhantomData<RegionVariableValue<'tcx>>,
 }
@@ -44,7 +39,8 @@ impl<'tcx> UnifyKey for RegionVidKey<'tcx> {
     }
 }
 
-pub struct RegionUnificationError;
+pub(crate) struct RegionUnificationError;
+
 impl<'tcx> UnifyValue for RegionVariableValue<'tcx> {
     type Error = RegionUnificationError;
 
@@ -100,7 +96,7 @@ pub struct ConstVariableOrigin {
 }
 
 #[derive(Copy, Clone, Debug)]
-pub enum ConstVariableValue<'tcx> {
+pub(crate) enum ConstVariableValue<'tcx> {
     Known { value: ty::Const<'tcx> },
     Unknown { origin: ConstVariableOrigin, universe: ty::UniverseIndex },
 }
@@ -108,7 +104,7 @@ pub enum ConstVariableValue<'tcx> {
 impl<'tcx> ConstVariableValue<'tcx> {
     /// If this value is known, returns the const it is known to be.
     /// Otherwise, `None`.
-    pub fn known(&self) -> Option<ty::Const<'tcx>> {
+    pub(crate) fn known(&self) -> Option<ty::Const<'tcx>> {
         match *self {
             ConstVariableValue::Unknown { .. } => None,
             ConstVariableValue::Known { value } => Some(value),
@@ -117,7 +113,7 @@ impl<'tcx> ConstVariableValue<'tcx> {
 }
 
 #[derive(PartialEq, Copy, Clone, Debug)]
-pub struct ConstVidKey<'tcx> {
+pub(crate) struct ConstVidKey<'tcx> {
     pub vid: ty::ConstVid,
     pub phantom: PhantomData<ty::Const<'tcx>>,
 }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 0b91c023cfc..8a121c5a865 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -268,6 +268,7 @@ fn configure_and_expand(
 
     resolver.resolve_crate(&krate);
 
+    CStore::from_tcx(tcx).report_incompatible_target_modifiers(tcx, &krate);
     krate
 }
 
@@ -832,20 +833,20 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
     sess.time("misc_checking_1", || {
         parallel!(
             {
-                sess.time("looking_for_entry_point", || tcx.ensure().entry_fn(()));
+                sess.time("looking_for_entry_point", || tcx.ensure_ok().entry_fn(()));
 
                 sess.time("looking_for_derive_registrar", || {
-                    tcx.ensure().proc_macro_decls_static(())
+                    tcx.ensure_ok().proc_macro_decls_static(())
                 });
 
                 CStore::from_tcx(tcx).report_unused_deps(tcx);
             },
             {
                 tcx.hir().par_for_each_module(|module| {
-                    tcx.ensure().check_mod_loops(module);
-                    tcx.ensure().check_mod_attrs(module);
-                    tcx.ensure().check_mod_naked_functions(module);
-                    tcx.ensure().check_mod_unstable_api_usage(module);
+                    tcx.ensure_ok().check_mod_loops(module);
+                    tcx.ensure_ok().check_mod_attrs(module);
+                    tcx.ensure_ok().check_mod_naked_functions(module);
+                    tcx.ensure_ok().check_mod_unstable_api_usage(module);
                 });
             },
             {
@@ -858,8 +859,8 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
                 // since they might not otherwise get called.
                 // This marks the corresponding crate-level attributes
                 // as used, and ensures that their values are valid.
-                tcx.ensure().limits(());
-                tcx.ensure().stability_index(());
+                tcx.ensure_ok().limits(());
+                tcx.ensure_ok().stability_index(());
             }
         );
     });
@@ -868,7 +869,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
     sess.time("MIR_coroutine_by_move_body", || {
         tcx.hir().par_body_owners(|def_id| {
             if tcx.needs_coroutine_by_move_body_def_id(def_id.to_def_id()) {
-                tcx.ensure_with_value().coroutine_by_move_body_def_id(def_id);
+                tcx.ensure_done().coroutine_by_move_body_def_id(def_id);
             }
         });
     });
@@ -883,13 +884,13 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
         tcx.hir().par_body_owners(|def_id| {
             // Run unsafety check because it's responsible for stealing and
             // deallocating THIR.
-            tcx.ensure().check_unsafety(def_id);
-            tcx.ensure().mir_borrowck(def_id)
+            tcx.ensure_ok().check_unsafety(def_id);
+            tcx.ensure_ok().mir_borrowck(def_id)
         });
     });
     sess.time("MIR_effect_checking", || {
         tcx.hir().par_body_owners(|def_id| {
-            tcx.ensure().has_ffi_unwind_calls(def_id);
+            tcx.ensure_ok().has_ffi_unwind_calls(def_id);
 
             // If we need to codegen, ensure that we emit all errors from
             // `mir_drops_elaborated_and_const_checked` now, to avoid discovering
@@ -897,15 +898,15 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
             if tcx.sess.opts.output_types.should_codegen()
                 || tcx.hir().body_const_context(def_id).is_some()
             {
-                tcx.ensure().mir_drops_elaborated_and_const_checked(def_id);
+                tcx.ensure_ok().mir_drops_elaborated_and_const_checked(def_id);
             }
         });
     });
     sess.time("coroutine_obligations", || {
         tcx.hir().par_body_owners(|def_id| {
             if tcx.is_coroutine(def_id.to_def_id()) {
-                tcx.ensure().mir_coroutine_witnesses(def_id);
-                tcx.ensure().check_coroutine_obligations(
+                tcx.ensure_ok().mir_coroutine_witnesses(def_id);
+                tcx.ensure_ok().check_coroutine_obligations(
                     tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(),
                 );
             }
@@ -950,15 +951,16 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
     sess.time("misc_checking_3", || {
         parallel!(
             {
-                tcx.ensure().effective_visibilities(());
+                tcx.ensure_ok().effective_visibilities(());
 
                 parallel!(
                     {
-                        tcx.ensure().check_private_in_public(());
+                        tcx.ensure_ok().check_private_in_public(());
                     },
                     {
-                        tcx.hir()
-                            .par_for_each_module(|module| tcx.ensure().check_mod_deathness(module));
+                        tcx.hir().par_for_each_module(|module| {
+                            tcx.ensure_ok().check_mod_deathness(module)
+                        });
                     },
                     {
                         sess.time("lint_checking", || {
@@ -966,14 +968,14 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
                         });
                     },
                     {
-                        tcx.ensure().clashing_extern_declarations(());
+                        tcx.ensure_ok().clashing_extern_declarations(());
                     }
                 );
             },
             {
                 sess.time("privacy_checking_modules", || {
                     tcx.hir().par_for_each_module(|module| {
-                        tcx.ensure().check_mod_privacy(module);
+                        tcx.ensure_ok().check_mod_privacy(module);
                     });
                 });
             }
@@ -981,7 +983,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
 
         // This check has to be run after all lints are done processing. We don't
         // define a lint filter, as all lint checks should have finished at this point.
-        sess.time("check_lint_expectations", || tcx.ensure().check_expectations(None));
+        sess.time("check_lint_expectations", || tcx.ensure_ok().check_expectations(None));
 
         // This query is only invoked normally if a diagnostic is emitted that needs any
         // diagnostic item. If the crate compiles without checking any diagnostic items,
@@ -1006,7 +1008,7 @@ fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
                     )
                 }) =>
             {
-                tcx.ensure().trigger_delayed_bug(def_id);
+                tcx.ensure_ok().trigger_delayed_bug(def_id);
             }
 
             // Bare `#[rustc_error]`.
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index e8a4e9a84c4..e2bafbed6e1 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -29,7 +29,6 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
 use rustc_hir::intravisit::FnKind as HirFnKind;
 use rustc_hir::{Body, FnDecl, GenericParamKind, PatKind, PredicateOrigin};
 use rustc_middle::bug;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef};
@@ -2029,7 +2028,7 @@ impl ExplicitOutlivesRequirements {
                 }
 
                 let span = bound.span().find_ancestor_inside(predicate_span)?;
-                if in_external_macro(tcx.sess, span) {
+                if span.in_external_macro(tcx.sess.source_map()) {
                     return None;
                 }
 
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 50bb1fb942e..e0863aa035c 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -4,7 +4,7 @@
 //! overview of how lints are implemented.
 
 use std::cell::Cell;
-use std::{iter, slice};
+use std::slice;
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync;
@@ -718,30 +718,6 @@ impl<'tcx> LateContext<'tcx> {
         }
     }
 
-    /// Check if a `DefId`'s path matches the given absolute type path usage.
-    ///
-    /// Anonymous scopes such as `extern` imports are matched with `kw::Empty`;
-    /// inherent `impl` blocks are matched with the name of the type.
-    ///
-    /// Instead of using this method, it is often preferable to instead use
-    /// `rustc_diagnostic_item` or a `lang_item`. This is less prone to errors
-    /// as paths get invalidated if the target definition moves.
-    ///
-    /// # Examples
-    ///
-    /// ```rust,ignore (no context or def id available)
-    /// if cx.match_def_path(def_id, &[sym::core, sym::option, sym::Option]) {
-    ///     // The given `def_id` is that of an `Option` type
-    /// }
-    /// ```
-    ///
-    /// Used by clippy, but should be replaced by diagnostic items eventually.
-    pub fn match_def_path(&self, def_id: DefId, path: &[Symbol]) -> bool {
-        let names = self.get_def_path(def_id);
-
-        names.len() == path.len() && iter::zip(names, path).all(|(a, &b)| a == b)
-    }
-
     /// Gets the absolute path of `def_id` as a vector of `Symbol`.
     ///
     /// # Examples
diff --git a/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs
index da6dd8161ee..946dbc34f71 100644
--- a/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs
+++ b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs
@@ -135,7 +135,7 @@ pub(super) fn unexpected_cfg_name(
     };
 
     let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
-    let is_from_external_macro = rustc_middle::lint::in_external_macro(sess, name_span);
+    let is_from_external_macro = name_span.in_external_macro(sess.source_map());
     let mut is_feature_cfg = name == sym::feature;
 
     let code_sugg = if is_feature_cfg && is_from_cargo {
@@ -281,7 +281,7 @@ pub(super) fn unexpected_cfg_value(
         .collect();
 
     let is_from_cargo = rustc_session::utils::was_invoked_from_cargo();
-    let is_from_external_macro = rustc_middle::lint::in_external_macro(sess, name_span);
+    let is_from_external_macro = name_span.in_external_macro(sess.source_map());
 
     // Show the full list if all possible values for a given name, but don't do it
     // for names as the possibilities could be very long
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index c6d7b839e19..826ecc22c24 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -458,7 +458,7 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) {
         || {
             tcx.sess.time("module_lints", || {
                 // Run per-module lints
-                tcx.hir().par_for_each_module(|module| tcx.ensure().lint_mod(module));
+                tcx.hir().par_for_each_module(|module| tcx.ensure_ok().lint_mod(module));
             });
         },
     );
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index 6f047b4da49..648d0675627 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -2,7 +2,6 @@ use rustc_ast as ast;
 use rustc_errors::Applicability;
 use rustc_hir::{self as hir, LangItem};
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::{bug, ty};
 use rustc_parse_format::{ParseMode, Parser, Piece};
 use rustc_session::lint::FutureIncompatibilityReason;
@@ -100,7 +99,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
 
     let (span, panic, symbol) = panic_call(cx, f);
 
-    if in_external_macro(cx.sess(), span) {
+    if span.in_external_macro(cx.sess().source_map()) {
         // Nothing that can be done about it in the current crate.
         return;
     }
@@ -229,14 +228,15 @@ fn check_panic_str<'tcx>(
 
     let (span, _, _) = panic_call(cx, f);
 
-    if in_external_macro(cx.sess(), span) && in_external_macro(cx.sess(), arg.span) {
+    let sm = cx.sess().source_map();
+    if span.in_external_macro(sm) && arg.span.in_external_macro(sm) {
         // Nothing that can be done about it in the current crate.
         return;
     }
 
     let fmt_span = arg.span.source_callsite();
 
-    let (snippet, style) = match cx.sess().psess.source_map().span_to_snippet(fmt_span) {
+    let (snippet, style) = match sm.span_to_snippet(fmt_span) {
         Ok(snippet) => {
             // Count the number of `#`s between the `r` and `"`.
             let style = snippet.strip_prefix('r').and_then(|s| s.find('"'));
@@ -283,7 +283,7 @@ fn check_panic_str<'tcx>(
 /// Given the span of `some_macro!(args);`, gives the span of `(` and `)`,
 /// and the type of (opening) delimiter used.
 fn find_delimiters(cx: &LateContext<'_>, span: Span) -> Option<(Span, Span, char)> {
-    let snippet = cx.sess().psess.source_map().span_to_snippet(span).ok()?;
+    let snippet = cx.sess().source_map().span_to_snippet(span).ok()?;
     let (open, open_ch) = snippet.char_indices().find(|&(_, c)| "([{".contains(c))?;
     let close = snippet.rfind(|c| ")]}".contains(c))?;
     Some((
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 3f1e98556ef..7ffe4e4e490 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -42,6 +42,23 @@ macro_rules! pluralize {
     };
 }
 
+/// Grammatical tool for displaying messages to end users in a nice form.
+///
+/// Take a list of items and a function to turn those items into a `String`, and output a display
+/// friendly comma separated list of those items.
+// FIXME(estebank): this needs to be changed to go through the translation machinery.
+pub fn listify<T>(list: &[T], fmt: impl Fn(&T) -> String) -> Option<String> {
+    Some(match list {
+        [only] => fmt(&only),
+        [others @ .., last] => format!(
+            "{} and {}",
+            others.iter().map(|i| fmt(i)).collect::<Vec<_>>().join(", "),
+            fmt(&last),
+        ),
+        [] => return None,
+    })
+}
+
 /// Indicates the confidence in the correctness of a suggestion.
 ///
 /// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 7ff316ba83a..76ad7fc8909 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1003,10 +1003,6 @@ extern "C" void LLVMRustDIBuilderDispose(LLVMDIBuilderRef Builder) {
   delete unwrap(Builder);
 }
 
-extern "C" void LLVMRustDIBuilderFinalize(LLVMDIBuilderRef Builder) {
-  unwrap(Builder)->finalize();
-}
-
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
     LLVMDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
     const char *Producer, size_t ProducerLen, bool isOptimized,
@@ -1183,20 +1179,6 @@ LLVMRustDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag,
       unwrap(Builder)->createQualifiedType(Tag, unwrapDI<DIType>(Type)));
 }
 
-extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Builder,
-                                    LLVMMetadataRef Scope, LLVMMetadataRef File,
-                                    unsigned Line, unsigned Col) {
-  return wrap(unwrap(Builder)->createLexicalBlock(
-      unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Line, Col));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlockFile(
-    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef File) {
-  return wrap(unwrap(Builder)->createLexicalBlockFile(
-      unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File)));
-}
-
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
     LLVMDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name,
     size_t NameLen, const char *LinkageName, size_t LinkageNameLen,
@@ -1325,14 +1307,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
       unwrapDI<DIType>(Ty), IsDefault));
 }
 
-extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateNameSpace(LLVMDIBuilderRef Builder,
-                                 LLVMMetadataRef Scope, const char *Name,
-                                 size_t NameLen, bool ExportSymbols) {
-  return wrap(unwrap(Builder)->createNameSpace(
-      unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols));
-}
-
 extern "C" void LLVMRustDICompositeTypeReplaceArrays(
     LLVMDIBuilderRef Builder, LLVMMetadataRef CompositeTy,
     LLVMMetadataRef Elements, LLVMMetadataRef Params) {
@@ -1342,16 +1316,6 @@ extern "C" void LLVMRustDICompositeTypeReplaceArrays(
 }
 
 extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
-                                     LLVMMetadataRef ScopeRef,
-                                     LLVMMetadataRef InlinedAt) {
-  MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
-  DILocation *Loc = DILocation::get(Scope->getContext(), Line, Column, Scope,
-                                    unwrapDIPtr<MDNode>(InlinedAt));
-  return wrap(Loc);
-}
-
-extern "C" LLVMMetadataRef
 LLVMRustDILocationCloneWithBaseDiscriminator(LLVMMetadataRef Location,
                                              unsigned BD) {
   DILocation *Loc = unwrapDIPtr<DILocation>(Location);
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index 88ea6e07d6e..62bf34ad5ad 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -118,11 +118,17 @@ struct QueryModifiers {
     /// Generate a `feed` method to set the query's value from another query.
     feedable: Option<Ident>,
 
-    /// Forward the result on ensure if the query gets recomputed, and
-    /// return `Ok(())` otherwise. Only applicable to queries returning
-    /// `Result<T, ErrorGuaranteed>`. The `T` is not returned from `ensure`
-    /// invocations.
-    ensure_forwards_result_if_red: Option<Ident>,
+    /// When this query is called via `tcx.ensure_ok()`, it returns
+    /// `Result<(), ErrorGuaranteed>` instead of `()`. If the query needs to
+    /// be executed, and that execution returns an error, the error result is
+    /// returned to the caller.
+    ///
+    /// If execution is skipped, a synthetic `Ok(())` is returned, on the
+    /// assumption that a query with all-green inputs must have succeeded.
+    ///
+    /// Can only be applied to queries with a return value of
+    /// `Result<_, ErrorGuaranteed>`.
+    return_result_from_ensure_ok: Option<Ident>,
 }
 
 fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
@@ -138,7 +144,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
     let mut depth_limit = None;
     let mut separate_provide_extern = None;
     let mut feedable = None;
-    let mut ensure_forwards_result_if_red = None;
+    let mut return_result_from_ensure_ok = None;
 
     while !input.is_empty() {
         let modifier: Ident = input.parse()?;
@@ -200,8 +206,8 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
             try_insert!(separate_provide_extern = modifier);
         } else if modifier == "feedable" {
             try_insert!(feedable = modifier);
-        } else if modifier == "ensure_forwards_result_if_red" {
-            try_insert!(ensure_forwards_result_if_red = modifier);
+        } else if modifier == "return_result_from_ensure_ok" {
+            try_insert!(return_result_from_ensure_ok = modifier);
         } else {
             return Err(Error::new(modifier.span(), "unknown query modifier"));
         }
@@ -222,7 +228,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
         depth_limit,
         separate_provide_extern,
         feedable,
-        ensure_forwards_result_if_red,
+        return_result_from_ensure_ok,
     })
 }
 
@@ -354,7 +360,7 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
             eval_always,
             depth_limit,
             separate_provide_extern,
-            ensure_forwards_result_if_red,
+            return_result_from_ensure_ok,
         );
 
         if modifiers.cache.is_some() {
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index d2b5ae53185..6fc84b06647 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -113,6 +113,14 @@ metadata_incompatible_rustc =
     found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info}
     .help = please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first)
 
+metadata_incompatible_target_modifiers =
+    mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`
+    .note = `{$flag_name_prefixed}={$flag_local_value}` in this crate is incompatible with `{$flag_name_prefixed}={$flag_extern_value}` in dependency `{$extern_crate}`
+    .help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+
+metadata_incompatible_target_modifiers_help_allow = if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error
+metadata_incompatible_target_modifiers_help_fix = set `{$flag_name_prefixed}={$flag_extern_value}` in this crate or `{$flag_name_prefixed}={$flag_local_value}` in `{$extern_crate}`
+
 metadata_incompatible_wasm_link =
     `wasm_import_module` is incompatible with other arguments in `#[link]` attributes
 
@@ -284,6 +292,8 @@ metadata_unknown_link_kind =
 metadata_unknown_link_modifier =
     unknown linking modifier `{$modifier}`, expected one of: bundle, verbatim, whole-archive, as-needed
 
+metadata_unknown_target_modifier_unsafe_allowed = unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}`
+
 metadata_unsupported_abi =
     ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
 
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index a6cd0ecafd0..6bad8312790 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -23,7 +23,10 @@ use rustc_hir::definitions::Definitions;
 use rustc_index::IndexVec;
 use rustc_middle::bug;
 use rustc_middle::ty::{TyCtxt, TyCtxtFeed};
-use rustc_session::config::{self, CrateType, ExternLocation};
+use rustc_session::config::{
+    self, CrateType, ExtendedTargetModifierInfo, ExternLocation, OptionsTargetModifiers,
+    TargetModifier,
+};
 use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource};
 use rustc_session::lint::{self, BuiltinLintDiag};
 use rustc_session::output::validate_crate_name;
@@ -35,7 +38,9 @@ use tracing::{debug, info, trace};
 
 use crate::errors;
 use crate::locator::{CrateError, CrateLocator, CratePaths};
-use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
+use crate::rmeta::{
+    CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob, TargetModifiers,
+};
 
 /// The backend's way to give the crate store access to the metadata in a library.
 /// Note that it returns the raw metadata bytes stored in the library file, whether
@@ -296,6 +301,94 @@ impl CStore {
         }
     }
 
+    fn report_target_modifiers_extended(
+        tcx: TyCtxt<'_>,
+        krate: &Crate,
+        mods: &TargetModifiers,
+        dep_mods: &TargetModifiers,
+        data: &CrateMetadata,
+    ) {
+        let span = krate.spans.inner_span.shrink_to_lo();
+        let allowed_flag_mismatches = &tcx.sess.opts.cg.unsafe_allow_abi_mismatch;
+        let name = tcx.crate_name(LOCAL_CRATE);
+        let tmod_extender = |tmod: &TargetModifier| (tmod.extend(), tmod.clone());
+        let report_diff = |prefix: &String,
+                           opt_name: &String,
+                           flag_local_value: &String,
+                           flag_extern_value: &String| {
+            if allowed_flag_mismatches.contains(&opt_name) {
+                return;
+            }
+            tcx.dcx().emit_err(errors::IncompatibleTargetModifiers {
+                span,
+                extern_crate: data.name(),
+                local_crate: name,
+                flag_name: opt_name.clone(),
+                flag_name_prefixed: format!("-{}{}", prefix, opt_name),
+                flag_local_value: flag_local_value.to_string(),
+                flag_extern_value: flag_extern_value.to_string(),
+            });
+        };
+        let mut it1 = mods.iter().map(tmod_extender);
+        let mut it2 = dep_mods.iter().map(tmod_extender);
+        let mut left_name_val: Option<(ExtendedTargetModifierInfo, TargetModifier)> = None;
+        let mut right_name_val: Option<(ExtendedTargetModifierInfo, TargetModifier)> = None;
+        let no_val = "*".to_string();
+        loop {
+            left_name_val = left_name_val.or_else(|| it1.next());
+            right_name_val = right_name_val.or_else(|| it2.next());
+            match (&left_name_val, &right_name_val) {
+                (Some(l), Some(r)) => match l.1.opt.cmp(&r.1.opt) {
+                    cmp::Ordering::Equal => {
+                        if l.0.tech_value != r.0.tech_value {
+                            report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &r.1.value_name);
+                        }
+                        left_name_val = None;
+                        right_name_val = None;
+                    }
+                    cmp::Ordering::Greater => {
+                        report_diff(&r.0.prefix, &r.0.name, &no_val, &r.1.value_name);
+                        right_name_val = None;
+                    }
+                    cmp::Ordering::Less => {
+                        report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &no_val);
+                        left_name_val = None;
+                    }
+                },
+                (Some(l), None) => {
+                    report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &no_val);
+                    left_name_val = None;
+                }
+                (None, Some(r)) => {
+                    report_diff(&r.0.prefix, &r.0.name, &no_val, &r.1.value_name);
+                    right_name_val = None;
+                }
+                (None, None) => break,
+            }
+        }
+    }
+
+    pub fn report_incompatible_target_modifiers(&self, tcx: TyCtxt<'_>, krate: &Crate) {
+        for flag_name in &tcx.sess.opts.cg.unsafe_allow_abi_mismatch {
+            if !OptionsTargetModifiers::is_target_modifier(flag_name) {
+                tcx.dcx().emit_err(errors::UnknownTargetModifierUnsafeAllowed {
+                    span: krate.spans.inner_span.shrink_to_lo(),
+                    flag_name: flag_name.clone(),
+                });
+            }
+        }
+        let mods = tcx.sess.opts.gather_target_modifiers();
+        for (_cnum, data) in self.iter_crate_data() {
+            if data.is_proc_macro_crate() {
+                continue;
+            }
+            let dep_mods = data.target_modifiers();
+            if mods != dep_mods {
+                Self::report_target_modifiers_extended(tcx, krate, &mods, &dep_mods, data);
+            }
+        }
+    }
+
     pub fn new(metadata_loader: Box<MetadataLoaderDyn>) -> CStore {
         CStore {
             metadata_loader,
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index cefc6498f68..a77f9bc623b 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -739,3 +739,28 @@ pub(crate) struct WasmCAbi {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(metadata_incompatible_target_modifiers)]
+#[help]
+#[note]
+#[help(metadata_incompatible_target_modifiers_help_fix)]
+#[help(metadata_incompatible_target_modifiers_help_allow)]
+pub struct IncompatibleTargetModifiers {
+    #[primary_span]
+    pub span: Span,
+    pub extern_crate: Symbol,
+    pub local_crate: Symbol,
+    pub flag_name: String,
+    pub flag_name_prefixed: String,
+    pub flag_local_value: String,
+    pub flag_extern_value: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(metadata_unknown_target_modifier_unsafe_allowed)]
+pub struct UnknownTargetModifierUnsafeAllowed {
+    #[primary_span]
+    pub span: Span,
+    pub flag_name: String,
+}
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index e02c4871f35..2ae4a6a6066 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -29,6 +29,7 @@ use rustc_middle::{bug, implement_ty_decoder};
 use rustc_serialize::opaque::MemDecoder;
 use rustc_serialize::{Decodable, Decoder};
 use rustc_session::Session;
+use rustc_session::config::TargetModifier;
 use rustc_session::cstore::{CrateSource, ExternCrate};
 use rustc_span::hygiene::HygieneDecodeContext;
 use rustc_span::{BytePos, DUMMY_SP, Pos, SpanData, SpanDecoder, SyntaxContext, kw};
@@ -73,6 +74,9 @@ impl MetadataBlob {
 /// own crate numbers.
 pub(crate) type CrateNumMap = IndexVec<CrateNum, CrateNum>;
 
+/// Target modifiers - abi or exploit mitigations flags
+pub(crate) type TargetModifiers = Vec<TargetModifier>;
+
 pub(crate) struct CrateMetadata {
     /// The primary crate data - binary metadata blob.
     blob: MetadataBlob,
@@ -961,6 +965,13 @@ impl CrateRoot {
     ) -> impl ExactSizeIterator<Item = CrateDep> + Captures<'a> {
         self.crate_deps.decode(metadata)
     }
+
+    pub(crate) fn decode_target_modifiers<'a>(
+        &self,
+        metadata: &'a MetadataBlob,
+    ) -> impl ExactSizeIterator<Item = TargetModifier> + Captures<'a> {
+        self.target_modifiers.decode(metadata)
+    }
 }
 
 impl<'a> CrateMetadataRef<'a> {
@@ -1883,6 +1894,10 @@ impl CrateMetadata {
         self.dependencies.push(cnum);
     }
 
+    pub(crate) fn target_modifiers(&self) -> TargetModifiers {
+        self.root.decode_target_modifiers(&self.blob).collect()
+    }
+
     pub(crate) fn update_extern_crate(&mut self, new_extern_crate: ExternCrate) -> bool {
         let update =
             Some(new_extern_crate.rank()) > self.extern_crate.as_ref().map(ExternCrate::rank);
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index da07ad8f6c0..028ff56155f 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -165,7 +165,7 @@ macro_rules! provide_one {
             // doesn't need to do this (and can't, as it would cause a query cycle).
             use rustc_middle::dep_graph::dep_kinds;
             if dep_kinds::$name != dep_kinds::crate_hash && $tcx.dep_graph.is_fully_enabled() {
-                $tcx.ensure().crate_hash($def_id.krate);
+                $tcx.ensure_ok().crate_hash($def_id.krate);
             }
 
             let cdata = rustc_data_structures::sync::FreezeReadGuard::map(CStore::from_tcx($tcx), |c| {
@@ -689,7 +689,7 @@ fn provide_cstore_hooks(providers: &mut Providers) {
     providers.hooks.def_path_hash_to_def_id_extern = |tcx, hash, stable_crate_id| {
         // If this is a DefPathHash from an upstream crate, let the CrateStore map
         // it to a DefId.
-        let cstore = CStore::from_tcx(tcx.tcx);
+        let cstore = CStore::from_tcx(tcx);
         let cnum = *tcx
             .untracked()
             .stable_crate_ids
@@ -702,11 +702,11 @@ fn provide_cstore_hooks(providers: &mut Providers) {
     };
 
     providers.hooks.expn_hash_to_expn_id = |tcx, cnum, index_guess, hash| {
-        let cstore = CStore::from_tcx(tcx.tcx);
+        let cstore = CStore::from_tcx(tcx);
         cstore.get_crate_data(cnum).expn_hash_to_expn_id(tcx.sess, index_guess, hash)
     };
     providers.hooks.import_source_files = |tcx, cnum| {
-        let cstore = CStore::from_tcx(tcx.tcx);
+        let cstore = CStore::from_tcx(tcx);
         let cdata = cstore.get_crate_data(cnum);
         for file_index in 0..cdata.root.source_map.size() {
             cdata.imported_source_file(file_index as u32, tcx.sess);
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 43372154b2c..db41a33dcc5 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -25,7 +25,7 @@ use rustc_middle::ty::fast_reject::{self, TreatParams};
 use rustc_middle::ty::{AssocItemContainer, SymbolName};
 use rustc_middle::{bug, span_bug};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque};
-use rustc_session::config::{CrateType, OptLevel};
+use rustc_session::config::{CrateType, OptLevel, TargetModifier};
 use rustc_span::hygiene::HygieneEncodeContext;
 use rustc_span::{
     ExternalSource, FileName, SourceFile, SpanData, SpanEncoder, StableSourceFileId, SyntaxContext,
@@ -692,6 +692,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         // Encode source_map. This needs to be done last, because encoding `Span`s tells us which
         // `SourceFiles` we actually need to encode.
         let source_map = stat!("source-map", || self.encode_source_map());
+        let target_modifiers = stat!("target-modifiers", || self.encode_target_modifiers());
 
         let root = stat!("final", || {
             let attrs = tcx.hir().krate_attrs();
@@ -735,6 +736,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 native_libraries,
                 foreign_modules,
                 source_map,
+                target_modifiers,
                 traits,
                 impls,
                 incoherent_impls,
@@ -2009,6 +2011,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         self.lazy_array(deps.iter().map(|(_, dep)| dep))
     }
 
+    fn encode_target_modifiers(&mut self) -> LazyArray<TargetModifier> {
+        empty_proc_macro!(self);
+        let tcx = self.tcx;
+        self.lazy_array(tcx.sess.opts.gather_target_modifiers())
+    }
+
     fn encode_lib_features(&mut self) -> LazyArray<(Symbol, FeatureStability)> {
         empty_proc_macro!(self);
         let tcx = self.tcx;
@@ -2191,13 +2199,13 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
         let (encode_const, encode_opt) = should_encode_mir(tcx, reachable_set, def_id);
 
         if encode_const {
-            tcx.ensure_with_value().mir_for_ctfe(def_id);
+            tcx.ensure_done().mir_for_ctfe(def_id);
         }
         if encode_opt {
-            tcx.ensure_with_value().optimized_mir(def_id);
+            tcx.ensure_done().optimized_mir(def_id);
         }
         if encode_opt || encode_const {
-            tcx.ensure_with_value().promoted_mir(def_id);
+            tcx.ensure_done().promoted_mir(def_id);
         }
     })
 }
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index d1d356c5220..7b34e605c53 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -1,7 +1,7 @@
 use std::marker::PhantomData;
 use std::num::NonZero;
 
-pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
+pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob, TargetModifiers};
 use decoder::{DecodeContext, Metadata};
 use def_path_hash_map::DefPathHashMapRef;
 use encoder::EncodeContext;
@@ -32,7 +32,7 @@ use rustc_middle::ty::{
 use rustc_middle::util::Providers;
 use rustc_middle::{mir, trivially_parameterized_over_tcx};
 use rustc_serialize::opaque::FileEncoder;
-use rustc_session::config::SymbolManglingVersion;
+use rustc_session::config::{SymbolManglingVersion, TargetModifier};
 use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::{ExpnIndex, MacroKind, SyntaxContextData};
@@ -282,6 +282,7 @@ pub(crate) struct CrateRoot {
     def_path_hash_map: LazyValue<DefPathHashMapRef<'static>>,
 
     source_map: LazyTable<u32, Option<LazyValue<rustc_span::SourceFile>>>,
+    target_modifiers: LazyArray<TargetModifier>,
 
     compiler_builtins: bool,
     needs_allocator: bool,
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index fcfc31575f8..7525aeb9227 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -1,61 +1,3 @@
-//! Nodes in the dependency graph.
-//!
-//! A node in the [dependency graph] is represented by a [`DepNode`].
-//! A `DepNode` consists of a [`DepKind`] (which
-//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
-//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which
-//! depends on the node's `DepKind`. Together, the kind and the fingerprint
-//! fully identify a dependency node, even across multiple compilation sessions.
-//! In other words, the value of the fingerprint does not depend on anything
-//! that is specific to a given compilation session, like an unpredictable
-//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a
-//! pointer. The concept behind this could be compared to how git commit hashes
-//! uniquely identify a given commit. The fingerprinting approach has
-//! a few advantages:
-//!
-//! * A `DepNode` can simply be serialized to disk and loaded in another session
-//!   without the need to do any "rebasing" (like we have to do for Spans and
-//!   NodeIds) or "retracing" (like we had to do for `DefId` in earlier
-//!   implementations of the dependency graph).
-//! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
-//!   implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
-//! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
-//!   memory without any post-processing (e.g., "abomination-style" pointer
-//!   reconstruction).
-//! * Because a `DepNode` is self-contained, we can instantiate `DepNodes` that
-//!   refer to things that do not exist anymore. In previous implementations
-//!   `DepNode` contained a `DefId`. A `DepNode` referring to something that
-//!   had been removed between the previous and the current compilation session
-//!   could not be instantiated because the current compilation session
-//!   contained no `DefId` for thing that had been removed.
-//!
-//! `DepNode` definition happens in the `define_dep_nodes!()` macro. This macro
-//! defines the `DepKind` enum. Each `DepKind` has its own parameters that are
-//! needed at runtime in order to construct a valid `DepNode` fingerprint.
-//! However, only `CompileCodegenUnit` and `CompileMonoItem` are constructed
-//! explicitly (with `make_compile_codegen_unit` cq `make_compile_mono_item`).
-//!
-//! Because the macro sees what parameters a given `DepKind` requires, it can
-//! "infer" some properties for each kind of `DepNode`:
-//!
-//! * Whether a `DepNode` of a given kind has any parameters at all. Some
-//!   `DepNode`s could represent global concepts with only one value.
-//! * Whether it is possible, in principle, to reconstruct a query key from a
-//!   given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
-//!   in which case it is possible to map the node's fingerprint back to the
-//!   `DefId` it was computed from. In other cases, too much information gets
-//!   lost during fingerprint computation.
-//!
-//! `make_compile_codegen_unit` and `make_compile_mono_items`, together with
-//! `DepNode::new()`, ensures that only valid `DepNode` instances can be
-//! constructed. For example, the API does not allow for constructing
-//! parameterless `DepNode`s with anything other than a zeroed out fingerprint.
-//! More generally speaking, it relieves the user of the `DepNode` API of
-//! having to know how to compute the expected fingerprint for a given set of
-//! node parameters.
-//!
-//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
-
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
 use rustc_hir::definitions::DefPathHash;
@@ -158,26 +100,14 @@ pub(crate) fn make_compile_mono_item<'tcx>(
 }
 
 pub trait DepNodeExt: Sized {
-    /// Extracts the DefId corresponding to this DepNode. This will work
-    /// if two conditions are met:
-    ///
-    /// 1. The Fingerprint of the DepNode actually is a DefPathHash, and
-    /// 2. the item that the DefPath refers to exists in the current tcx.
-    ///
-    /// Condition (1) is determined by the DepKind variant of the
-    /// DepNode. Condition (2) might not be fulfilled if a DepNode
-    /// refers to something from the previous compilation session that
-    /// has been removed.
     fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId>;
 
-    /// Used in testing
     fn from_label_string(
         tcx: TyCtxt<'_>,
         label: &str,
         def_path_hash: DefPathHash,
     ) -> Result<Self, ()>;
 
-    /// Used in testing
     fn has_label_string(label: &str) -> bool;
 }
 
@@ -399,52 +329,46 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
     }
 }
 
-macro_rules! impl_for_typed_def_id {
-    ($Name:ident, $LocalName:ident) => {
-        impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for $Name {
-            #[inline(always)]
-            fn fingerprint_style() -> FingerprintStyle {
-                FingerprintStyle::DefPathHash
-            }
+impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for ModDefId {
+    #[inline(always)]
+    fn fingerprint_style() -> FingerprintStyle {
+        FingerprintStyle::DefPathHash
+    }
 
-            #[inline(always)]
-            fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
-                self.to_def_id().to_fingerprint(tcx)
-            }
+    #[inline(always)]
+    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
+        self.to_def_id().to_fingerprint(tcx)
+    }
 
-            #[inline(always)]
-            fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
-                self.to_def_id().to_debug_str(tcx)
-            }
+    #[inline(always)]
+    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
+        self.to_def_id().to_debug_str(tcx)
+    }
 
-            #[inline(always)]
-            fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
-                DefId::recover(tcx, dep_node).map($Name::new_unchecked)
-            }
-        }
+    #[inline(always)]
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
+        DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked)
+    }
+}
 
-        impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for $LocalName {
-            #[inline(always)]
-            fn fingerprint_style() -> FingerprintStyle {
-                FingerprintStyle::DefPathHash
-            }
+impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for LocalModDefId {
+    #[inline(always)]
+    fn fingerprint_style() -> FingerprintStyle {
+        FingerprintStyle::DefPathHash
+    }
 
-            #[inline(always)]
-            fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
-                self.to_def_id().to_fingerprint(tcx)
-            }
+    #[inline(always)]
+    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
+        self.to_def_id().to_fingerprint(tcx)
+    }
 
-            #[inline(always)]
-            fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
-                self.to_def_id().to_debug_str(tcx)
-            }
+    #[inline(always)]
+    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
+        self.to_def_id().to_debug_str(tcx)
+    }
 
-            #[inline(always)]
-            fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
-                LocalDefId::recover(tcx, dep_node).map($LocalName::new_unchecked)
-            }
-        }
-    };
+    #[inline(always)]
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
+        LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked)
+    }
 }
-
-impl_for_typed_def_id! { ModDefId, LocalModDefId }
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 926760b84aa..4df4624971d 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -937,6 +937,7 @@ impl<'hir> Map<'hir> {
             Node::TraitRef(tr) => tr.path.span,
             Node::OpaqueTy(op) => op.span,
             Node::Pat(pat) => pat.span,
+            Node::TyPat(pat) => pat.span,
             Node::PatField(field) => field.span,
             Node::PatExpr(lit) => lit.span,
             Node::Arm(arm) => arm.span,
@@ -1212,6 +1213,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
         Node::TraitRef(_) => node_str("trait ref"),
         Node::OpaqueTy(_) => node_str("opaque type"),
         Node::Pat(_) => node_str("pat"),
+        Node::TyPat(_) => node_str("pat ty"),
         Node::PatField(_) => node_str("pattern field"),
         Node::PatExpr(_) => node_str("pattern literal"),
         Node::Param(_) => node_str("param"),
diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs
index 2be242364c1..276a02b4e0f 100644
--- a/compiler/rustc_middle/src/hooks/mod.rs
+++ b/compiler/rustc_middle/src/hooks/mod.rs
@@ -6,11 +6,9 @@
 use rustc_hir::def_id::{DefId, DefPathHash};
 use rustc_session::StableCrateId;
 use rustc_span::def_id::{CrateNum, LocalDefId};
-use rustc_span::{DUMMY_SP, ExpnHash, ExpnId};
-use tracing::instrument;
+use rustc_span::{ExpnHash, ExpnId};
 
 use crate::mir;
-use crate::query::TyCtxtAt;
 use crate::ty::{Ty, TyCtxt};
 
 macro_rules! declare_hooks {
@@ -22,26 +20,14 @@ macro_rules! declare_hooks {
             #[inline(always)]
             pub fn $name(self, $($arg: $K,)*) -> $V
             {
-                self.at(DUMMY_SP).$name($($arg,)*)
-            }
-            )*
-        }
-
-        impl<'tcx> TyCtxtAt<'tcx> {
-            $(
-            $(#[$attr])*
-            #[inline(always)]
-            #[instrument(level = "debug", skip(self), ret)]
-            pub fn $name(self, $($arg: $K,)*) -> $V
-            {
-                (self.tcx.hooks.$name)(self, $($arg,)*)
+                (self.hooks.$name)(self, $($arg,)*)
             }
             )*
         }
 
         pub struct Providers {
             $(pub $name: for<'tcx> fn(
-                TyCtxtAt<'tcx>,
+                TyCtxt<'tcx>,
                 $($arg: $K,)*
             ) -> $V,)*
         }
diff --git a/compiler/rustc_middle/src/infer/mod.rs b/compiler/rustc_middle/src/infer/mod.rs
index 3dfcf90cb93..73e8971c3bd 100644
--- a/compiler/rustc_middle/src/infer/mod.rs
+++ b/compiler/rustc_middle/src/infer/mod.rs
@@ -1,2 +1 @@
 pub mod canonical;
-pub mod unify_key;
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index bbe23d8abe8..7a6d329fd47 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -1,10 +1,11 @@
 //! The "main crate" of the Rust compiler. This crate contains common
 //! type definitions that are used by the other crates in the rustc
-//! "family". Some prominent examples (note that each of these modules
-//! has their own README with further details).
+//! "family". The following are some prominent examples.
 //!
 //! - **HIR.** The "high-level (H) intermediate representation (IR)" is
 //!   defined in the [`hir`] module.
+//! - **THIR.** The "typed high-level (H) intermediate representation (IR)"
+//!   is defined in the [`thir`] module.
 //! - **MIR.** The "mid-level (M) intermediate representation (IR)" is
 //!   defined in the [`mir`] module. This module contains only the
 //!   *definition* of the MIR; the passes that transform and operate
@@ -37,7 +38,6 @@
 #![feature(box_as_ptr)]
 #![feature(box_patterns)]
 #![feature(closure_track_caller)]
-#![feature(const_type_name)]
 #![feature(core_intrinsics)]
 #![feature(coroutines)]
 #![feature(debug_closure_helpers)]
@@ -50,7 +50,6 @@
 #![feature(intra_doc_pointers)]
 #![feature(iter_from_coroutine)]
 #![feature(let_chains)]
-#![feature(macro_metavar_expr)]
 #![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(never_type)]
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index cae980cde61..ab711aca573 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -8,8 +8,7 @@ use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_session::Session;
 use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS};
 use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId};
-use rustc_span::hygiene::{ExpnKind, MacroKind};
-use rustc_span::{DUMMY_SP, DesugaringKind, Span, Symbol, kw};
+use rustc_span::{DUMMY_SP, Span, Symbol, kw};
 use tracing::instrument;
 
 use crate::ty::TyCtxt;
@@ -201,7 +200,7 @@ impl LintExpectation {
     }
 }
 
-pub fn explain_lint_level_source(
+fn explain_lint_level_source(
     lint: &'static Lint,
     level: Level,
     src: LintLevelSource,
@@ -325,7 +324,7 @@ pub fn lint_level(
         // If this code originates in a foreign macro, aka something that this crate
         // did not itself author, then it's likely that there's nothing this crate
         // can do about it. We probably want to skip the lint entirely.
-        if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
+        if err.span.primary_spans().iter().any(|s| s.in_external_macro(sess.source_map())) {
             // Any suggestions made here are likely to be incorrect, so anything we
             // emit shouldn't be automatically fixed by rustfix.
             err.disable_suggestions();
@@ -422,36 +421,3 @@ pub fn lint_level(
     }
     lint_level_impl(sess, lint, level, src, span, Box::new(decorate))
 }
-
-/// Returns whether `span` originates in a foreign crate's external macro.
-///
-/// This is used to test whether a lint should not even begin to figure out whether it should
-/// be reported on the current node.
-pub fn in_external_macro(sess: &Session, span: Span) -> bool {
-    let expn_data = span.ctxt().outer_expn_data();
-    match expn_data.kind {
-        ExpnKind::Root
-        | ExpnKind::Desugaring(
-            DesugaringKind::ForLoop
-            | DesugaringKind::WhileLoop
-            | DesugaringKind::OpaqueTy
-            | DesugaringKind::Async
-            | DesugaringKind::Await,
-        ) => false,
-        ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
-        ExpnKind::Macro(MacroKind::Bang, _) => {
-            // Dummy span for the `def_site` means it's an external macro.
-            expn_data.def_site.is_dummy() || sess.source_map().is_imported(expn_data.def_site)
-        }
-        ExpnKind::Macro { .. } => true, // definitely a plugin
-    }
-}
-
-/// Return whether `span` is generated by `async` or `await`.
-pub fn is_from_async_await(span: Span) -> bool {
-    let expn_data = span.ctxt().outer_expn_data();
-    match expn_data.kind {
-        ExpnKind::Desugaring(DesugaringKind::Async | DesugaringKind::Await) => true,
-        _ => false,
-    }
-}
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index f4f9f221a75..45c862e0d34 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -15,7 +15,8 @@ use std::{fmt, io};
 use rustc_abi::{AddressSpace, Align, Endian, HasDataLayout, Size};
 use rustc_ast::{LitKind, Mutability};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lock;
+use rustc_data_structures::sharded::ShardedHashMap;
+use rustc_data_structures::sync::{AtomicU64, Lock};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
@@ -389,35 +390,39 @@ pub const CTFE_ALLOC_SALT: usize = 0;
 
 pub(crate) struct AllocMap<'tcx> {
     /// Maps `AllocId`s to their corresponding allocations.
-    alloc_map: FxHashMap<AllocId, GlobalAlloc<'tcx>>,
+    // Note that this map on rustc workloads seems to be rather dense, but in miri workloads should
+    // be pretty sparse. In #136105 we considered replacing it with a (dense) Vec-based map, but
+    // since there are workloads where it can be sparse we decided to go with sharding for now. At
+    // least up to 32 cores the one workload tested didn't exhibit much difference between the two.
+    //
+    // Should be locked *after* locking dedup if locking both to avoid deadlocks.
+    to_alloc: ShardedHashMap<AllocId, GlobalAlloc<'tcx>>,
 
     /// Used to deduplicate global allocations: functions, vtables, string literals, ...
     ///
     /// The `usize` is a "salt" used by Miri to make deduplication imperfect, thus better emulating
     /// the actual guarantees.
-    dedup: FxHashMap<(GlobalAlloc<'tcx>, usize), AllocId>,
+    dedup: Lock<FxHashMap<(GlobalAlloc<'tcx>, usize), AllocId>>,
 
     /// The `AllocId` to assign to the next requested ID.
     /// Always incremented; never gets smaller.
-    next_id: AllocId,
+    next_id: AtomicU64,
 }
 
 impl<'tcx> AllocMap<'tcx> {
     pub(crate) fn new() -> Self {
         AllocMap {
-            alloc_map: Default::default(),
+            to_alloc: Default::default(),
             dedup: Default::default(),
-            next_id: AllocId(NonZero::new(1).unwrap()),
+            next_id: AtomicU64::new(1),
         }
     }
-    fn reserve(&mut self) -> AllocId {
-        let next = self.next_id;
-        self.next_id.0 = self.next_id.0.checked_add(1).expect(
-            "You overflowed a u64 by incrementing by 1... \
-             You've just earned yourself a free drink if we ever meet. \
-             Seriously, how did you do that?!",
-        );
-        next
+    fn reserve(&self) -> AllocId {
+        // Technically there is a window here where we overflow and then another thread
+        // increments `next_id` *again* and uses it before we panic and tear down the entire session.
+        // We consider this fine since such overflows cannot realistically occur.
+        let next_id = self.next_id.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
+        AllocId(NonZero::new(next_id).unwrap())
     }
 }
 
@@ -428,26 +433,34 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such
     /// an `AllocId` from a query.
     pub fn reserve_alloc_id(self) -> AllocId {
-        self.alloc_map.lock().reserve()
+        self.alloc_map.reserve()
     }
 
     /// Reserves a new ID *if* this allocation has not been dedup-reserved before.
     /// Should not be used for mutable memory.
     fn reserve_and_set_dedup(self, alloc: GlobalAlloc<'tcx>, salt: usize) -> AllocId {
-        let mut alloc_map = self.alloc_map.lock();
         if let GlobalAlloc::Memory(mem) = alloc {
             if mem.inner().mutability.is_mut() {
                 bug!("trying to dedup-reserve mutable memory");
             }
         }
         let alloc_salt = (alloc, salt);
-        if let Some(&alloc_id) = alloc_map.dedup.get(&alloc_salt) {
+        // Locking this *before* `to_alloc` also to ensure correct lock order.
+        let mut dedup = self.alloc_map.dedup.lock();
+        if let Some(&alloc_id) = dedup.get(&alloc_salt) {
             return alloc_id;
         }
-        let id = alloc_map.reserve();
+        let id = self.alloc_map.reserve();
         debug!("creating alloc {:?} with id {id:?}", alloc_salt.0);
-        alloc_map.alloc_map.insert(id, alloc_salt.0.clone());
-        alloc_map.dedup.insert(alloc_salt, id);
+        let had_previous = self
+            .alloc_map
+            .to_alloc
+            .lock_shard_by_value(&id)
+            .insert(id, alloc_salt.0.clone())
+            .is_some();
+        // We just reserved, so should always be unique.
+        assert!(!had_previous);
+        dedup.insert(alloc_salt, id);
         id
     }
 
@@ -497,7 +510,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// local dangling pointers and allocations in constants/statics.
     #[inline]
     pub fn try_get_global_alloc(self, id: AllocId) -> Option<GlobalAlloc<'tcx>> {
-        self.alloc_map.lock().alloc_map.get(&id).cloned()
+        self.alloc_map.to_alloc.lock_shard_by_value(&id).get(&id).cloned()
     }
 
     #[inline]
@@ -516,7 +529,9 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
     /// call this function twice, even with the same `Allocation` will ICE the compiler.
     pub fn set_alloc_id_memory(self, id: AllocId, mem: ConstAllocation<'tcx>) {
-        if let Some(old) = self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Memory(mem)) {
+        if let Some(old) =
+            self.alloc_map.to_alloc.lock_shard_by_value(&id).insert(id, GlobalAlloc::Memory(mem))
+        {
             bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}");
         }
     }
@@ -524,8 +539,11 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Freezes an `AllocId` created with `reserve` by pointing it at a static item. Trying to
     /// call this function twice, even with the same `DefId` will ICE the compiler.
     pub fn set_nested_alloc_id_static(self, id: AllocId, def_id: LocalDefId) {
-        if let Some(old) =
-            self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Static(def_id.to_def_id()))
+        if let Some(old) = self
+            .alloc_map
+            .to_alloc
+            .lock_shard_by_value(&id)
+            .insert(id, GlobalAlloc::Static(def_id.to_def_id()))
         {
             bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}");
         }
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 4c47d9636d3..78749428c6d 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -9,7 +9,7 @@ use super::{
     ReportedErrorInfo,
 };
 use crate::mir;
-use crate::query::TyCtxtEnsure;
+use crate::query::TyCtxtEnsureOk;
 use crate::ty::visit::TypeVisitableExt;
 use crate::ty::{self, GenericArgs, TyCtxt};
 
@@ -198,7 +198,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 }
 
-impl<'tcx> TyCtxtEnsure<'tcx> {
+impl<'tcx> TyCtxtEnsureOk<'tcx> {
     /// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
     /// that can't take any generic arguments like const items or enum discriminants. If a
     /// generic parameter is used within the constant `ErrorHandled::TooGeneric` will be returned.
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index e49fc376a13..75931956310 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -92,51 +92,88 @@ impl<'tcx> MonoItem<'tcx> {
     }
 
     pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
-        let generate_cgu_internal_copies =
-            (tcx.sess.opts.optimize != OptLevel::No) && !tcx.sess.link_dead_code();
+        // The case handling here is written in the same style as cross_crate_inlinable, we first
+        // handle the cases where we must use a particular instantiation mode, then cascade down
+        // through a sequence of heuristics.
 
-        match *self {
-            MonoItem::Fn(ref instance) => {
-                let entry_def_id = tcx.entry_fn(()).map(|(id, _)| id);
-                // If this function isn't inlined or otherwise has an extern
-                // indicator, then we'll be creating a globally shared version.
-                let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id());
-                if codegen_fn_attrs.contains_extern_indicator()
-                    || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED)
-                    || !instance.def.generates_cgu_internal_copy(tcx)
-                    || Some(instance.def_id()) == entry_def_id
-                {
-                    return InstantiationMode::GloballyShared { may_conflict: false };
-                }
-
-                if let InlineAttr::Never = tcx.codegen_fn_attrs(instance.def_id()).inline
-                    && self.is_generic_fn()
-                {
-                    // Upgrade inline(never) to a globally shared instance.
-                    return InstantiationMode::GloballyShared { may_conflict: true };
-                }
-
-                // At this point we don't have explicit linkage and we're an
-                // inlined function. If this crate's build settings permit,
-                // we'll be creating a local copy per CGU.
-                if generate_cgu_internal_copies {
-                    return InstantiationMode::LocalCopy;
-                }
-
-                // Finally, if this is `#[inline(always)]` we're sure to respect
-                // that with an inline copy per CGU, but otherwise we'll be
-                // creating one copy of this `#[inline]` function which may
-                // conflict with upstream crates as it could be an exported
-                // symbol.
-                if tcx.codegen_fn_attrs(instance.def_id()).inline.always() {
-                    InstantiationMode::LocalCopy
-                } else {
-                    InstantiationMode::GloballyShared { may_conflict: true }
-                }
-            }
+        // The first thing we do is detect MonoItems which we must instantiate exactly once in the
+        // whole program.
+
+        // Statics and global_asm! must be instantiated exactly once.
+        let instance = match *self {
+            MonoItem::Fn(instance) => instance,
             MonoItem::Static(..) | MonoItem::GlobalAsm(..) => {
-                InstantiationMode::GloballyShared { may_conflict: false }
+                return InstantiationMode::GloballyShared { may_conflict: false };
             }
+        };
+
+        // Similarly, the executable entrypoint must be instantiated exactly once.
+        if let Some((entry_def_id, _)) = tcx.entry_fn(()) {
+            if instance.def_id() == entry_def_id {
+                return InstantiationMode::GloballyShared { may_conflict: false };
+            }
+        }
+
+        // If the function is #[naked] or contains any other attribute that requires exactly-once
+        // instantiation:
+        let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id());
+        if codegen_fn_attrs.contains_extern_indicator()
+            || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED)
+        {
+            return InstantiationMode::GloballyShared { may_conflict: false };
+        }
+
+        // FIXME: The logic for which functions are permitted to get LocalCopy is actually spread
+        // across 4 functions:
+        // * cross_crate_inlinable(def_id)
+        // * InstanceKind::requires_inline
+        // * InstanceKind::generate_cgu_internal_copy
+        // * MonoItem::instantiation_mode
+        // Since reachable_non_generics calls InstanceKind::generates_cgu_internal_copy to decide
+        // which symbols this crate exports, we are obligated to only generate LocalCopy when
+        // generates_cgu_internal_copy returns true.
+        if !instance.def.generates_cgu_internal_copy(tcx) {
+            return InstantiationMode::GloballyShared { may_conflict: false };
+        }
+
+        // Beginning of heuristics. The handling of link-dead-code and inline(always) are QoL only,
+        // the compiler should not crash and linkage should work, but codegen may be undesirable.
+
+        // -Clink-dead-code was given an unfortunate name; the point of the flag is to assist
+        // coverage tools which rely on having every function in the program appear in the
+        // generated code. If we select LocalCopy, functions which are not used because they are
+        // missing test coverage will disappear from such coverage reports, defeating the point.
+        // Note that -Cinstrument-coverage does not require such assistance from us, only coverage
+        // tools implemented without compiler support ironically require a special compiler flag.
+        if tcx.sess.link_dead_code() {
+            return InstantiationMode::GloballyShared { may_conflict: true };
+        }
+
+        // To ensure that #[inline(always)] can be inlined as much as possible, especially in unoptimized
+        // builds, we always select LocalCopy.
+        if codegen_fn_attrs.inline.always() {
+            return InstantiationMode::LocalCopy;
+        }
+
+        // #[inline(never)] functions in general are poor candidates for inlining and thus since
+        // LocalCopy generally increases code size for the benefit of optimizations from inlining,
+        // we want to give them GloballyShared codegen.
+        // The slight problem is that generic functions need to always support cross-crate
+        // compilation, so all previous stages of the compiler are obligated to treat generic
+        // functions the same as those that unconditionally get LocalCopy codegen. It's only when
+        // we get here that we can at least not codegen a #[inline(never)] generic function in all
+        // of our CGUs.
+        if let InlineAttr::Never = tcx.codegen_fn_attrs(instance.def_id()).inline
+            && self.is_generic_fn()
+        {
+            return InstantiationMode::GloballyShared { may_conflict: true };
+        }
+
+        // The fallthrough case is to generate LocalCopy for all optimized builds, and
+        // GloballyShared with conflict prevention when optimizations are disabled.
+        match tcx.sess.opts.optimize {
+            OptLevel::No => InstantiationMode::GloballyShared { may_conflict: true },
+            _ => InstantiationMode::LocalCopy,
         }
     }
 
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index a318bacb866..3007b787496 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -12,6 +12,7 @@ use rustc_middle::mir::interpret::{
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
 use tracing::trace;
+use ty::print::PrettyPrinter;
 
 use super::graphviz::write_mir_fn_graphviz;
 use crate::mir::interpret::ConstAllocation;
@@ -1103,6 +1104,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                     NullOp::AlignOf => write!(fmt, "AlignOf({t})"),
                     NullOp::OffsetOf(fields) => write!(fmt, "OffsetOf({t}, {fields:?})"),
                     NullOp::UbChecks => write!(fmt, "UbChecks()"),
+                    NullOp::ContractChecks => write!(fmt, "ContractChecks()"),
                 }
             }
             ThreadLocalRef(did) => ty::tls::with(|tcx| {
@@ -1248,6 +1250,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
             ShallowInitBox(ref place, ref ty) => {
                 with_no_trimmed_paths!(write!(fmt, "ShallowInitBox({place:?}, {ty})"))
             }
+
+            WrapUnsafeBinder(ref op, ty) => {
+                with_no_trimmed_paths!(write!(fmt, "wrap_binder!({op:?}; {ty})"))
+            }
         }
     }
 }
@@ -1308,6 +1314,9 @@ fn pre_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
             ProjectionElem::Index(_)
             | ProjectionElem::ConstantIndex { .. }
             | ProjectionElem::Subslice { .. } => {}
+            ProjectionElem::UnwrapUnsafeBinder(_) => {
+                write!(fmt, "unwrap_binder!(")?;
+            }
         }
     }
 
@@ -1356,6 +1365,9 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
             ProjectionElem::Subslice { from, to, from_end: false } => {
                 write!(fmt, "[{from:?}..{to:?}]")?;
             }
+            ProjectionElem::UnwrapUnsafeBinder(ty) => {
+                write!(fmt, "; {ty})")?;
+            }
         }
     }
 
@@ -1429,10 +1441,10 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
                 })
             };
 
-            // FIXME: call pretty_print_const_valtree?
-            let fmt_valtree = |valtree: &ty::ValTree<'tcx>| match valtree {
-                ty::ValTree::Leaf(leaf) => format!("Leaf({leaf:?})"),
-                ty::ValTree::Branch(_) => "Branch(..)".to_string(),
+            let fmt_valtree = |cv: &ty::Value<'tcx>| {
+                let mut cx = FmtPrinter::new(self.tcx, Namespace::ValueNS);
+                cx.pretty_print_const_valtree(*cv, /*print_ty*/ true).unwrap();
+                cx.into_buffer()
             };
 
             let val = match const_ {
@@ -1442,7 +1454,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
                         format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,)
                     }
                     ty::ConstKind::Value(cv) => {
-                        format!("ty::Valtree({})", fmt_valtree(&cv.valtree))
+                        format!("ty::Valtree({})", fmt_valtree(&cv))
                     }
                     // No `ty::` prefix since we also use this to represent errors from `mir::Unevaluated`.
                     ty::ConstKind::Error(_) => "Error".to_string(),
diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
index 609d5647d04..d345c99f902 100644
--- a/compiler/rustc_middle/src/mir/statement.rs
+++ b/compiler/rustc_middle/src/mir/statement.rs
@@ -62,7 +62,8 @@ impl<V, T> ProjectionElem<V, T> {
             | Self::Subtype(_)
             | Self::ConstantIndex { .. }
             | Self::Subslice { .. }
-            | Self::Downcast(_, _) => false,
+            | Self::Downcast(_, _)
+            | Self::UnwrapUnsafeBinder(..) => false,
         }
     }
 
@@ -76,7 +77,8 @@ impl<V, T> ProjectionElem<V, T> {
             | Self::Subtype(_)
             | Self::ConstantIndex { .. }
             | Self::Subslice { .. }
-            | Self::Downcast(_, _) => true,
+            | Self::Downcast(_, _)
+            | Self::UnwrapUnsafeBinder(..) => true,
         }
     }
 
@@ -102,6 +104,9 @@ impl<V, T> ProjectionElem<V, T> {
             | Self::Subtype(_)
             | Self::OpaqueCast(_)
             | Self::Subslice { .. } => false,
+
+            // FIXME(unsafe_binders): Figure this out.
+            Self::UnwrapUnsafeBinder(..) => false,
         }
     }
 }
@@ -443,7 +448,8 @@ impl<'tcx> Rvalue<'tcx> {
             | Rvalue::UnaryOp(_, _)
             | Rvalue::Discriminant(_)
             | Rvalue::Aggregate(_, _)
-            | Rvalue::ShallowInitBox(_, _) => true,
+            | Rvalue::ShallowInitBox(_, _)
+            | Rvalue::WrapUnsafeBinder(_, _) => true,
         }
     }
 }
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 90a2f175bc9..9cec8d832dd 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1276,6 +1276,10 @@ pub enum ProjectionElem<V, T> {
     /// requiring an intermediate variable.
     OpaqueCast(T),
 
+    /// A transmute from an unsafe binder to the type that it wraps. This is a projection
+    /// of a place, so it doesn't necessarily constitute a move out of the binder.
+    UnwrapUnsafeBinder(T),
+
     /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where
     /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping
     /// explicit during optimizations and codegen.
@@ -1493,6 +1497,9 @@ pub enum Rvalue<'tcx> {
     /// optimizations and codegen backends that previously had to handle deref operations anywhere
     /// in a place.
     CopyForDeref(Place<'tcx>),
+
+    /// Wraps a value in an unsafe binder.
+    WrapUnsafeBinder(Operand<'tcx>, Ty<'tcx>),
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
@@ -1584,6 +1591,9 @@ pub enum NullOp<'tcx> {
     /// Returns whether we should perform some UB-checking at runtime.
     /// See the `ub_checks` intrinsic docs for details.
     UbChecks,
+    /// Returns whether we should perform contract-checking at runtime.
+    /// See the `contract_checks` intrinsic docs for details.
+    ContractChecks,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 4d11492e94d..af23c8b2ea7 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -146,6 +146,11 @@ impl<'tcx> PlaceTy<'tcx> {
             ProjectionElem::Subtype(ty) => {
                 PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty))
             }
+
+            // FIXME(unsafe_binders): Rename `handle_opaque_cast_and_subtype` to be more general.
+            ProjectionElem::UnwrapUnsafeBinder(ty) => {
+                PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty))
+            }
         };
         debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
         answer
@@ -225,7 +230,8 @@ impl<'tcx> Rvalue<'tcx> {
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
                 tcx.types.usize
             }
-            Rvalue::NullaryOp(NullOp::UbChecks, _) => tcx.types.bool,
+            Rvalue::NullaryOp(NullOp::ContractChecks, _)
+            | Rvalue::NullaryOp(NullOp::UbChecks, _) => tcx.types.bool,
             Rvalue::Aggregate(ref ak, ref ops) => match **ak {
                 AggregateKind::Array(ty) => Ty::new_array(tcx, ty, ops.len() as u64),
                 AggregateKind::Tuple => {
@@ -241,6 +247,7 @@ impl<'tcx> Rvalue<'tcx> {
             },
             Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),
             Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty,
+            Rvalue::WrapUnsafeBinder(_, ty) => ty,
         }
     }
 
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index b59b9e55fe8..9893dd0484c 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -1,6 +1,7 @@
 //! `TypeFoldable` implementations for MIR types
 
 use rustc_ast::InlineAsmTemplatePiece;
+use rustc_hir::UnsafeBinderCastKind;
 use rustc_hir::def_id::LocalDefId;
 
 use super::*;
@@ -21,6 +22,7 @@ TrivialTypeTraversalImpls! {
     SwitchTargets,
     CoroutineKind,
     CoroutineSavedLocal,
+    UnsafeBinderCastKind,
 }
 
 TrivialTypeTraversalImpls! {
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 6319a7e65b9..8d04bbb95bd 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -781,6 +781,11 @@ macro_rules! make_mir_visitor {
                         self.visit_operand(operand, location);
                         self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
                     }
+
+                    Rvalue::WrapUnsafeBinder(op, ty) => {
+                        self.visit_operand(op, location);
+                        self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
+                    }
                 }
             }
 
@@ -1151,6 +1156,11 @@ macro_rules! visit_place_fns {
                     self.visit_ty(&mut new_ty, TyContext::Location(location));
                     if ty != new_ty { Some(PlaceElem::Subtype(new_ty)) } else { None }
                 }
+                PlaceElem::UnwrapUnsafeBinder(ty) => {
+                    let mut new_ty = ty;
+                    self.visit_ty(&mut new_ty, TyContext::Location(location));
+                    if ty != new_ty { Some(PlaceElem::UnwrapUnsafeBinder(new_ty)) } else { None }
+                }
                 PlaceElem::Deref
                 | PlaceElem::ConstantIndex { .. }
                 | PlaceElem::Subslice { .. }
@@ -1219,7 +1229,8 @@ macro_rules! visit_place_fns {
             match elem {
                 ProjectionElem::OpaqueCast(ty)
                 | ProjectionElem::Subtype(ty)
-                | ProjectionElem::Field(_, ty) => {
+                | ProjectionElem::Field(_, ty)
+                | ProjectionElem::UnwrapUnsafeBinder(ty) => {
                     self.visit_ty(ty, TyContext::Location(location));
                 }
                 ProjectionElem::Index(local) => {
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index 949d8303385..1489d57aba6 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -20,6 +20,12 @@ pub struct LocalCrate;
 /// The `Key` trait controls what types can legally be used as the key
 /// for a query.
 pub trait Key: Sized {
+    /// The type of in-memory cache to use for queries with this key type.
+    ///
+    /// In practice the cache type must implement [`QueryCache`], though that
+    /// constraint is not enforced here.
+    ///
+    /// [`QueryCache`]: rustc_query_system::query::QueryCache
     // N.B. Most of the keys down below have `type Cache<V> = DefaultCache<Self, V>;`,
     //      it would be reasonable to use associated type defaults, to remove the duplication...
     //
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 41e9858030c..6c442fc1047 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -91,7 +91,7 @@ pub use keys::{AsLocalKey, Key, LocalCrate};
 pub mod on_disk_cache;
 #[macro_use]
 pub mod plumbing;
-pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue};
+pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk};
 
 // Each of these queries corresponds to a function pointer field in the
 // `Providers` struct for requesting a value of that type, and a method
@@ -1087,7 +1087,7 @@ rustc_queries! {
 
     query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     /// Caches `CoerceUnsized` kinds for impls on custom types.
@@ -1095,7 +1095,7 @@ rustc_queries! {
         desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
@@ -1110,7 +1110,7 @@ rustc_queries! {
 
     query coherent_trait(def_id: DefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "coherence checking all impls of trait `{}`", tcx.def_path_str(def_id) }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     /// Borrow-checks the function body. If this is a closure, returns
@@ -1140,7 +1140,7 @@ rustc_queries! {
     /// </div>
     query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> {
         desc { "check for inherent impls that should not be defined in crate" }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     /// Checks all types in the crate for overlap in their inherent impls. Reports errors.
@@ -1152,7 +1152,7 @@ rustc_queries! {
     /// </div>
     query crate_inherent_impls_overlap_check(_: ()) -> Result<(), ErrorGuaranteed> {
         desc { "check for overlap between inherent impls defined in this crate" }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     /// Checks whether all impls in the crate pass the overlap check, returning
@@ -1162,7 +1162,7 @@ rustc_queries! {
             "checking whether impl `{}` follows the orphan rules",
             tcx.def_path_str(key),
         }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     /// Check whether the function has any recursion that could cause the inliner to trigger
@@ -1479,7 +1479,7 @@ rustc_queries! {
     query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> {
         desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) }
         cache_on_disk_if { true }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
     query dyn_compatibility_violations(trait_id: DefId) -> &'tcx [DynCompatibilityViolation] {
         desc { |tcx| "determining dyn-compatibility of trait `{}`", tcx.def_path_str(trait_id) }
@@ -1715,12 +1715,12 @@ rustc_queries! {
 
     query check_well_formed(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     query enforce_impl_non_lifetime_params_are_constrained(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "checking that `{}`'s generics are constrained by the impl header", tcx.def_path_str(key) }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     // The `DefId`s of all non-generic functions and statics in the given crate
@@ -2442,7 +2442,7 @@ rustc_queries! {
     /// Any other def id will ICE.
     query compare_impl_item(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key) }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     query deduced_param_attrs(def_id: DefId) -> &'tcx [ty::DeducedParamAttrs] {
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 1c157f33a81..6c019b427db 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -88,30 +88,68 @@ impl<'tcx> Deref for TyCtxtAt<'tcx> {
 }
 
 #[derive(Copy, Clone)]
-pub struct TyCtxtEnsure<'tcx> {
+#[must_use]
+pub struct TyCtxtEnsureOk<'tcx> {
     pub tcx: TyCtxt<'tcx>,
 }
 
 #[derive(Copy, Clone)]
-pub struct TyCtxtEnsureWithValue<'tcx> {
+#[must_use]
+pub struct TyCtxtEnsureDone<'tcx> {
     pub tcx: TyCtxt<'tcx>,
 }
 
 impl<'tcx> TyCtxt<'tcx> {
-    /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
-    /// are executed instead of just returning their results.
+    /// Wrapper that calls queries in a special "ensure OK" mode, for callers
+    /// that don't need the return value and just want to invoke a query for
+    /// its potential side-effect of emitting fatal errors.
+    ///
+    /// This can be more efficient than a normal query call, because if the
+    /// query's inputs are all green, the call can return immediately without
+    /// needing to obtain a value (by decoding one from disk or by executing
+    /// the query).
+    ///
+    /// (As with all query calls, execution is also skipped if the query result
+    /// is already cached in memory.)
+    ///
+    /// ## WARNING
+    /// A subsequent normal call to the same query might still cause it to be
+    /// executed! This can occur when the inputs are all green, but the query's
+    /// result is not cached on disk, so the query must be executed to obtain a
+    /// return value.
+    ///
+    /// Therefore, this call mode is not appropriate for callers that want to
+    /// ensure that the query is _never_ executed in the future.
+    ///
+    /// ## `return_result_from_ensure_ok`
+    /// If a query has the `return_result_from_ensure_ok` modifier, calls via
+    /// `ensure_ok` will instead return `Result<(), ErrorGuaranteed>`. If the
+    /// query needs to be executed, and execution returns an error, that error
+    /// is returned to the caller.
     #[inline(always)]
-    pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
-        TyCtxtEnsure { tcx: self }
+    pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> {
+        TyCtxtEnsureOk { tcx: self }
     }
 
-    /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
-    /// are executed instead of just returning their results.
+    /// Wrapper that calls queries in a special "ensure done" mode, for callers
+    /// that don't need the return value and just want to guarantee that the
+    /// query won't be executed in the future, by executing it now if necessary.
     ///
-    /// This version verifies that the computed result exists in the cache before returning.
+    /// This is useful for queries that read from a [`Steal`] value, to ensure
+    /// that they are executed before the query that will steal the value.
+    ///
+    /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be
+    /// skipped if its return value is stored in the disk-cache. This is still
+    /// more efficient than a regular query, because in that situation the
+    /// return value doesn't necessarily need to be decoded.
+    ///
+    /// (As with all query calls, execution is also skipped if the query result
+    /// is already cached in memory.)
+    ///
+    /// [`Steal`]: rustc_data_structures::steal::Steal
     #[inline(always)]
-    pub fn ensure_with_value(self) -> TyCtxtEnsureWithValue<'tcx> {
-        TyCtxtEnsureWithValue { tcx: self }
+    pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
+        TyCtxtEnsureDone { tcx: self }
     }
 
     /// Returns a transparent wrapper for `TyCtxt` which uses
@@ -193,7 +231,7 @@ macro_rules! query_ensure {
     ([]$($args:tt)*) => {
         query_ensure($($args)*)
     };
-    ([(ensure_forwards_result_if_red) $($rest:tt)*]$($args:tt)*) => {
+    ([(return_result_from_ensure_ok) $($rest:tt)*]$($args:tt)*) => {
         query_ensure_error_guaranteed($($args)*).map(|_| ())
     };
     ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
@@ -248,15 +286,15 @@ macro_rules! separate_provide_extern_decl {
     };
 }
 
-macro_rules! ensure_result {
-    ([][$ty:ty]) => {
+macro_rules! ensure_ok_result {
+    ( [] ) => {
         ()
     };
-    ([(ensure_forwards_result_if_red) $($rest:tt)*][$ty:ty]) => {
+    ( [(return_result_from_ensure_ok) $($rest:tt)*] ) => {
         Result<(), ErrorGuaranteed>
     };
-    ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
-        ensure_result!([$($modifiers)*][$($args)*])
+    ( [$other:tt $($modifiers:tt)*] ) => {
+        ensure_ok_result!( [$($modifiers)*] )
     };
 }
 
@@ -383,10 +421,13 @@ macro_rules! define_callbacks {
             $($(#[$attr])* pub $name: queries::$name::Storage<'tcx>,)*
         }
 
-        impl<'tcx> TyCtxtEnsure<'tcx> {
+        impl<'tcx> TyCtxtEnsureOk<'tcx> {
             $($(#[$attr])*
             #[inline(always)]
-            pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> ensure_result!([$($modifiers)*][$V]) {
+            pub fn $name(
+                self,
+                key: query_helper_param_ty!($($K)*),
+            ) -> ensure_ok_result!([$($modifiers)*]) {
                 query_ensure!(
                     [$($modifiers)*]
                     self.tcx,
@@ -398,7 +439,7 @@ macro_rules! define_callbacks {
             })*
         }
 
-        impl<'tcx> TyCtxtEnsureWithValue<'tcx> {
+        impl<'tcx> TyCtxtEnsureDone<'tcx> {
             $($(#[$attr])*
             #[inline(always)]
             pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 86014c34b45..e2e2029a362 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -18,7 +18,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
 use rustc_index::{IndexVec, newtype_index};
-use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable};
+use rustc_macros::{HashStable, TypeVisitable};
 use rustc_middle::middle::region;
 use rustc_middle::mir::interpret::AllocId;
 use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp};
@@ -37,9 +37,6 @@ pub mod visit;
 
 macro_rules! thir_with_elements {
     (
-        $($field_name:ident: $field_ty:ty,)*
-
-    @elements:
         $($name:ident: $id:ty => $value:ty => $format:literal,)*
     ) => {
         $(
@@ -53,22 +50,18 @@ macro_rules! thir_with_elements {
         /// A container for a THIR body.
         ///
         /// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
-        #[derive(Debug, HashStable, Clone)]
+        #[derive(Debug, HashStable)]
         pub struct Thir<'tcx> {
-            $(
-                pub $field_name: $field_ty,
-            )*
+            pub body_type: BodyTy<'tcx>,
             $(
                 pub $name: IndexVec<$id, $value>,
             )*
         }
 
         impl<'tcx> Thir<'tcx> {
-            pub fn new($($field_name: $field_ty,)*) -> Thir<'tcx> {
+            pub fn new(body_type: BodyTy<'tcx>) -> Thir<'tcx> {
                 Thir {
-                    $(
-                        $field_name,
-                    )*
+                    body_type,
                     $(
                         $name: IndexVec::new(),
                     )*
@@ -88,9 +81,6 @@ macro_rules! thir_with_elements {
 }
 
 thir_with_elements! {
-    body_type: BodyTy<'tcx>,
-
-@elements:
     arms: ArmId => Arm<'tcx> => "a{}",
     blocks: BlockId => Block => "b{}",
     exprs: ExprId => Expr<'tcx> => "e{}",
@@ -98,14 +88,14 @@ thir_with_elements! {
     params: ParamId => Param<'tcx> => "p{}",
 }
 
-#[derive(Debug, HashStable, Clone)]
+#[derive(Debug, HashStable)]
 pub enum BodyTy<'tcx> {
     Const(Ty<'tcx>),
     Fn(FnSig<'tcx>),
 }
 
 /// Description of a type-checked function parameter.
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub struct Param<'tcx> {
     /// The pattern that appears in the parameter list, or None for implicit parameters.
     pub pat: Option<Box<Pat<'tcx>>>,
@@ -125,7 +115,7 @@ pub enum LintLevel {
     Explicit(HirId),
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub struct Block {
     /// Whether the block itself has a label. Used by `label: {}`
     /// and `try` blocks.
@@ -145,7 +135,7 @@ pub struct Block {
 
 type UserTy<'tcx> = Option<Box<CanonicalUserType<'tcx>>>;
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub struct AdtExpr<'tcx> {
     /// The ADT we're constructing.
     pub adt_def: AdtDef<'tcx>,
@@ -162,7 +152,7 @@ pub struct AdtExpr<'tcx> {
     pub base: AdtExprBase<'tcx>,
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub enum AdtExprBase<'tcx> {
     /// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`.
     None,
@@ -175,7 +165,7 @@ pub enum AdtExprBase<'tcx> {
     DefaultFields(Box<[Ty<'tcx>]>),
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub struct ClosureExpr<'tcx> {
     pub closure_id: LocalDefId,
     pub args: UpvarArgs<'tcx>,
@@ -184,7 +174,7 @@ pub struct ClosureExpr<'tcx> {
     pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>,
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub struct InlineAsmExpr<'tcx> {
     pub asm_macro: AsmMacro,
     pub template: &'tcx [InlineAsmTemplatePiece],
@@ -202,12 +192,12 @@ pub enum BlockSafety {
     ExplicitUnsafe(HirId),
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub struct Stmt<'tcx> {
     pub kind: StmtKind<'tcx>,
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub enum StmtKind<'tcx> {
     /// An expression with a trailing semicolon.
     Expr {
@@ -247,11 +237,11 @@ pub enum StmtKind<'tcx> {
     },
 }
 
-#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, HashStable)]
 pub struct LocalVarId(pub HirId);
 
 /// A THIR expression.
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub struct Expr<'tcx> {
     /// kind of expression
     pub kind: ExprKind<'tcx>,
@@ -278,7 +268,7 @@ pub struct TempLifetime {
     pub backwards_incompatible: Option<region::Scope>,
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub enum ExprKind<'tcx> {
     /// `Scope`s are used to explicitly mark destruction scopes,
     /// and to track the `HirId` of the expressions within the scope.
@@ -489,6 +479,19 @@ pub enum ExprKind<'tcx> {
         user_ty: UserTy<'tcx>,
         user_ty_span: Span,
     },
+    /// An unsafe binder cast on a place, e.g. `unwrap_binder!(*ptr)`.
+    PlaceUnwrapUnsafeBinder {
+        source: ExprId,
+    },
+    /// An unsafe binder cast on a value, e.g. `unwrap_binder!(rvalue())`,
+    /// which makes a temporary.
+    ValueUnwrapUnsafeBinder {
+        source: ExprId,
+    },
+    /// Construct an unsafe binder, e.g. `wrap_binder(&ref)`.
+    WrapUnsafeBinder {
+        source: ExprId,
+    },
     /// A closure definition.
     Closure(Box<ClosureExpr<'tcx>>),
     /// A literal.
@@ -543,20 +546,20 @@ pub enum ExprKind<'tcx> {
 /// Represents the association of a field identifier and an expression.
 ///
 /// This is used in struct constructors.
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub struct FieldExpr {
     pub name: FieldIdx,
     pub expr: ExprId,
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub struct FruInfo<'tcx> {
     pub base: ExprId,
     pub field_types: Box<[Ty<'tcx>]>,
 }
 
 /// A `match` arm.
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub struct Arm<'tcx> {
     pub pattern: Box<Pat<'tcx>>,
     pub guard: Option<ExprId>,
@@ -574,7 +577,7 @@ pub enum LogicalOp {
     Or,
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Debug, HashStable)]
 pub enum InlineAsmOperand<'tcx> {
     In {
         reg: InlineAsmRegOrRegClass,
@@ -612,13 +615,13 @@ pub enum InlineAsmOperand<'tcx> {
     },
 }
 
-#[derive(Clone, Debug, HashStable, TypeVisitable)]
+#[derive(Debug, HashStable, TypeVisitable)]
 pub struct FieldPat<'tcx> {
     pub field: FieldIdx,
     pub pattern: Box<Pat<'tcx>>,
 }
 
-#[derive(Clone, Debug, HashStable, TypeVisitable)]
+#[derive(Debug, HashStable, TypeVisitable)]
 pub struct Pat<'tcx> {
     pub ty: Ty<'tcx>,
     pub span: Span,
@@ -726,7 +729,7 @@ impl<'tcx> Pat<'tcx> {
     }
 }
 
-#[derive(Clone, Debug, HashStable, TypeVisitable)]
+#[derive(Debug, HashStable, TypeVisitable)]
 pub struct Ascription<'tcx> {
     pub annotation: CanonicalUserTypeAnnotation<'tcx>,
     /// Variance to use when relating the `user_ty` to the **type of the value being
@@ -750,7 +753,7 @@ pub struct Ascription<'tcx> {
     pub variance: ty::Variance,
 }
 
-#[derive(Clone, Debug, HashStable, TypeVisitable)]
+#[derive(Debug, HashStable, TypeVisitable)]
 pub enum PatKind<'tcx> {
     /// A wildcard pattern: `_`.
     Wild,
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 64bac12b266..13b8af55e51 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -1,8 +1,7 @@
 use super::{
-    AdtExpr, Arm, Block, ClosureExpr, Expr, ExprKind, InlineAsmExpr, InlineAsmOperand, Pat,
-    PatKind, Stmt, StmtKind, Thir,
+    AdtExpr, AdtExprBase, Arm, Block, ClosureExpr, Expr, ExprKind, InlineAsmExpr, InlineAsmOperand,
+    Pat, PatKind, Stmt, StmtKind, Thir,
 };
-use crate::thir::AdtExprBase;
 
 pub trait Visitor<'thir, 'tcx: 'thir>: Sized {
     fn thir(&self) -> &'thir Thir<'tcx>;
@@ -136,6 +135,9 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
         | ValueTypeAscription { source, user_ty: _, user_ty_span: _ } => {
             visitor.visit_expr(&visitor.thir()[source])
         }
+        PlaceUnwrapUnsafeBinder { source }
+        | ValueUnwrapUnsafeBinder { source }
+        | WrapUnsafeBinder { source } => visitor.visit_expr(&visitor.thir()[source]),
         Closure(box ClosureExpr {
             closure_id: _,
             args: _,
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 28a6eba75aa..d0ce4e6242e 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -21,13 +21,12 @@ use rustc_macros::{
 };
 use rustc_span::def_id::{CRATE_DEF_ID, LocalDefId};
 use rustc_span::{DUMMY_SP, Span, Symbol};
-// FIXME: Remove this import and import via `solve::`
-pub use rustc_type_ir::solve::BuiltinImplSource;
 use smallvec::{SmallVec, smallvec};
 use thin_vec::ThinVec;
 
 pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
 use crate::mir::ConstraintCategory;
+pub use crate::traits::solve::BuiltinImplSource;
 use crate::ty::abstract_const::NotConstEvaluatable;
 use crate::ty::{self, AdtKind, GenericArgsRef, Ty};
 
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index f049da95f29..8cd04a6f5e4 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -7,11 +7,10 @@
 
 use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
 use rustc_span::Span;
-// FIXME: Remove this import and import via `traits::solve`.
-pub use rustc_type_ir::solve::NoSolution;
 
 use crate::error::DropCheckOverflow;
 use crate::infer::canonical::{Canonical, CanonicalQueryInput, QueryResponse};
+pub use crate::traits::solve::NoSolution;
 use crate::ty::{self, GenericArg, Ty, TyCtxt};
 
 pub mod type_op {
diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs
index d914b7576dc..5905076c4d0 100644
--- a/compiler/rustc_middle/src/ty/consts/valtree.rs
+++ b/compiler/rustc_middle/src/ty/consts/valtree.rs
@@ -78,30 +78,6 @@ impl<'tcx> ValTree<'tcx> {
             Self::Branch(_) => None,
         }
     }
-
-    /// Get the values inside the ValTree as a slice of bytes. This only works for
-    /// constants with types &str, &[u8], or [u8; _].
-    pub fn try_to_raw_bytes(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx [u8]> {
-        match ty.kind() {
-            ty::Ref(_, inner_ty, _) => match inner_ty.kind() {
-                // `&str` can be interpreted as raw bytes
-                ty::Str => {}
-                // `&[u8]` can be interpreted as raw bytes
-                ty::Slice(slice_ty) if *slice_ty == tcx.types.u8 => {}
-                // other `&_` can't be interpreted as raw bytes
-                _ => return None,
-            },
-            // `[u8; N]` can be interpreted as raw bytes
-            ty::Array(array_ty, _) if *array_ty == tcx.types.u8 => {}
-            // Otherwise, type cannot be interpreted as raw bytes
-            _ => return None,
-        }
-
-        Some(
-            tcx.arena
-                .alloc_from_iter(self.unwrap_branch().into_iter().map(|v| v.unwrap_leaf().to_u8())),
-        )
-    }
 }
 
 /// A type-level constant value.
@@ -143,6 +119,29 @@ impl<'tcx> Value<'tcx> {
         }
         self.valtree.try_to_scalar_int().map(|s| s.to_target_usize(tcx))
     }
+
+    /// Get the values inside the ValTree as a slice of bytes. This only works for
+    /// constants with types &str, &[u8], or [u8; _].
+    pub fn try_to_raw_bytes(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx [u8]> {
+        match self.ty.kind() {
+            ty::Ref(_, inner_ty, _) => match inner_ty.kind() {
+                // `&str` can be interpreted as raw bytes
+                ty::Str => {}
+                // `&[u8]` can be interpreted as raw bytes
+                ty::Slice(slice_ty) if *slice_ty == tcx.types.u8 => {}
+                // other `&_` can't be interpreted as raw bytes
+                _ => return None,
+            },
+            // `[u8; N]` can be interpreted as raw bytes
+            ty::Array(array_ty, _) if *array_ty == tcx.types.u8 => {}
+            // Otherwise, type cannot be interpreted as raw bytes
+            _ => return None,
+        }
+
+        Some(tcx.arena.alloc_from_iter(
+            self.valtree.unwrap_branch().into_iter().map(|v| v.unwrap_leaf().to_u8()),
+        ))
+    }
 }
 
 impl<'tcx> rustc_type_ir::inherent::ValueConst<TyCtxt<'tcx>> for Value<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 69f6fc0ad8a..86248b495cd 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1366,7 +1366,7 @@ pub struct GlobalCtxt<'tcx> {
     pub data_layout: TargetDataLayout,
 
     /// Stores memory for globals (statics/consts).
-    pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
+    pub(crate) alloc_map: interpret::AllocMap<'tcx>,
 
     current_gcx: CurrentGcx,
 }
@@ -1583,7 +1583,7 @@ impl<'tcx> TyCtxt<'tcx> {
             new_solver_evaluation_cache: Default::default(),
             canonical_param_env_cache: Default::default(),
             data_layout,
-            alloc_map: Lock::new(interpret::AllocMap::new()),
+            alloc_map: interpret::AllocMap::new(),
             current_gcx,
         });
 
@@ -1957,7 +1957,7 @@ impl<'tcx> TyCtxt<'tcx> {
     ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
         // Create a dependency to the crate to be sure we re-execute this when the amount of
         // definitions change.
-        self.ensure().hir_crate(());
+        self.ensure_ok().hir_crate(());
         // Freeze definitions once we start iterating on them, to prevent adding new ones
         // while iterating. If some query needs to add definitions, it should be `ensure`d above.
         self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index b4b66a8133a..cb218a27e62 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -5,7 +5,7 @@ use std::ops::ControlFlow;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{
-    Applicability, Diag, DiagArgValue, IntoDiagArg, into_diag_arg_using_display, pluralize,
+    Applicability, Diag, DiagArgValue, IntoDiagArg, into_diag_arg_using_display, listify, pluralize,
 };
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
@@ -362,11 +362,8 @@ pub fn suggest_constraining_type_params<'a>(
             let n = trait_names.len();
             let stable = if all_stable { "" } else { "unstable " };
             let trait_ = if all_known { format!("trait{}", pluralize!(n)) } else { String::new() };
-            format!("{stable}{trait_}{}", match &trait_names[..] {
-                [t] => format!(" {t}"),
-                [ts @ .., last] => format!(" {} and {last}", ts.join(", ")),
-                [] => return false,
-            },)
+            let Some(trait_names) = listify(&trait_names, |n| n.to_string()) else { return false };
+            format!("{stable}{trait_} {trait_names}")
         } else {
             // We're more explicit when there's a mix of stable and unstable traits.
             let mut trait_names = constraints
@@ -378,10 +375,9 @@ pub fn suggest_constraining_type_params<'a>(
                 .collect::<Vec<_>>();
             trait_names.sort();
             trait_names.dedup();
-            match &trait_names[..] {
-                [t] => t.to_string(),
-                [ts @ .., last] => format!("{} and {last}", ts.join(", ")),
-                [] => return false,
+            match listify(&trait_names, |t| t.to_string()) {
+                Some(names) => names,
+                None => return false,
             }
         };
         let constraint = constraint.join(" + ");
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 35fbaa99569..8c1991ddb36 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -10,8 +10,8 @@ use rustc_hir::def::{CtorOf, DefKind};
 use rustc_macros::extension;
 pub use rustc_type_ir::error::ExpectedFound;
 
-use crate::ty::print::{FmtPrinter, PrettyPrinter, with_forced_trimmed_paths};
-use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::print::{FmtPrinter, Print, with_forced_trimmed_paths};
+use crate::ty::{self, Lift, Ty, TyCtxt};
 
 pub type TypeError<'tcx> = rustc_type_ir::error::TypeError<TyCtxt<'tcx>>;
 
@@ -159,8 +159,8 @@ impl<'tcx> Ty<'tcx> {
             ty::Error(_) => "type error".into(),
             _ => {
                 let width = tcx.sess.diagnostic_width();
-                let length_limit = std::cmp::max(width / 4, 15);
-                format!("`{}`", tcx.ty_string_with_limit(self, length_limit)).into()
+                let length_limit = std::cmp::max(width / 4, 40);
+                format!("`{}`", tcx.string_with_limit(self, length_limit)).into()
             }
         }
     }
@@ -213,10 +213,14 @@ impl<'tcx> Ty<'tcx> {
 }
 
 impl<'tcx> TyCtxt<'tcx> {
-    pub fn ty_string_with_limit(self, ty: Ty<'tcx>, length_limit: usize) -> String {
+    pub fn string_with_limit<'a, T>(self, p: T, length_limit: usize) -> String
+    where
+        T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift<TyCtxt<'tcx>> + Copy,
+        <T as Lift<TyCtxt<'tcx>>>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>,
+    {
         let mut type_limit = 50;
         let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
-            cx.pretty_print_type(ty)
+            self.lift(p).expect("could not lift for printing").print(cx)
         })
         .expect("could not write to `String`");
         if regular.len() <= length_limit {
@@ -231,7 +235,10 @@ impl<'tcx> TyCtxt<'tcx> {
                     hir::def::Namespace::TypeNS,
                     rustc_session::Limit(type_limit),
                 );
-                cx.pretty_print_type(ty).expect("could not write to `String`");
+                self.lift(p)
+                    .expect("could not lift for printing")
+                    .print(&mut cx)
+                    .expect("could not print type");
                 cx.into_buffer()
             });
             if short.len() <= length_limit || type_limit == 0 {
@@ -242,9 +249,17 @@ impl<'tcx> TyCtxt<'tcx> {
         short
     }
 
-    pub fn short_ty_string(self, ty: Ty<'tcx>, path: &mut Option<PathBuf>) -> String {
+    /// When calling this after a `Diag` is constructed, the preferred way of doing so is
+    /// `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that keeps
+    /// the existence of a "long type" anywhere in the diagnostic, so the note telling the user
+    /// where we wrote the file to is only printed once.
+    pub fn short_string<'a, T>(self, p: T, path: &mut Option<PathBuf>) -> String
+    where
+        T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift<TyCtxt<'tcx>> + Copy + Hash,
+        <T as Lift<TyCtxt<'tcx>>>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>,
+    {
         let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
-            cx.pretty_print_type(ty)
+            self.lift(p).expect("could not lift for printing").print(cx)
         })
         .expect("could not write to `String`");
 
@@ -257,13 +272,13 @@ impl<'tcx> TyCtxt<'tcx> {
         if regular.len() <= width * 2 / 3 {
             return regular;
         }
-        let short = self.ty_string_with_limit(ty, length_limit);
+        let short = self.string_with_limit(p, length_limit);
         if regular == short {
             return regular;
         }
         // Ensure we create an unique file for the type passed in when we create a file.
         let mut s = DefaultHasher::new();
-        ty.hash(&mut s);
+        p.hash(&mut s);
         let hash = s.finish();
         *path = Some(path.take().unwrap_or_else(|| {
             self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None)
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 6b6c6f3c72f..8eaf0a58f70 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -101,6 +101,7 @@ trivially_parameterized_over_tcx! {
     rustc_session::cstore::ForeignModule,
     rustc_session::cstore::LinkagePreference,
     rustc_session::cstore::NativeLib,
+    rustc_session::config::TargetModifier,
     rustc_span::ExpnData,
     rustc_span::ExpnHash,
     rustc_span::ExpnId,
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 72f353f06ff..dc2040aa5cf 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -105,6 +105,10 @@ pub trait Printer<'tcx>: Sized {
         args: &[GenericArg<'tcx>],
     ) -> Result<(), PrintError>;
 
+    fn should_truncate(&mut self) -> bool {
+        false
+    }
+
     // Defaults (should not be overridden):
 
     #[instrument(skip(self), level = "debug")]
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 018fcc66aee..3431081b189 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -865,7 +865,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 p!(write("{{"));
                 if !self.tcx().sess.verbose_internals() {
                     p!("coroutine witness");
-                    // FIXME(eddyb) should use `def_span`.
                     if let Some(did) = did.as_local() {
                         let span = self.tcx().def_span(did);
                         p!(write(
@@ -887,26 +886,30 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 p!(write("{{"));
                 if !self.should_print_verbose() {
                     p!(write("closure"));
-                    // FIXME(eddyb) should use `def_span`.
-                    if let Some(did) = did.as_local() {
-                        if self.tcx().sess.opts.unstable_opts.span_free_formats {
-                            p!("@", print_def_path(did.to_def_id(), args));
-                        } else {
-                            let span = self.tcx().def_span(did);
-                            let preference = if with_forced_trimmed_paths() {
-                                FileNameDisplayPreference::Short
+                    if self.should_truncate() {
+                        write!(self, "@...}}")?;
+                        return Ok(());
+                    } else {
+                        if let Some(did) = did.as_local() {
+                            if self.tcx().sess.opts.unstable_opts.span_free_formats {
+                                p!("@", print_def_path(did.to_def_id(), args));
                             } else {
-                                FileNameDisplayPreference::Remapped
-                            };
-                            p!(write(
-                                "@{}",
-                                // This may end up in stderr diagnostics but it may also be emitted
-                                // into MIR. Hence we use the remapped path if available
-                                self.tcx().sess.source_map().span_to_string(span, preference)
-                            ));
+                                let span = self.tcx().def_span(did);
+                                let preference = if with_forced_trimmed_paths() {
+                                    FileNameDisplayPreference::Short
+                                } else {
+                                    FileNameDisplayPreference::Remapped
+                                };
+                                p!(write(
+                                    "@{}",
+                                    // This may end up in stderr diagnostics but it may also be emitted
+                                    // into MIR. Hence we use the remapped path if available
+                                    self.tcx().sess.source_map().span_to_string(span, preference)
+                                ));
+                            }
+                        } else {
+                            p!(write("@"), print_def_path(did, args));
                         }
-                    } else {
-                        p!(write("@"), print_def_path(did, args));
                     }
                 } else {
                     p!(print_def_path(did, args));
@@ -942,7 +945,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                             "coroutine from coroutine-closure should have CoroutineSource::Closure"
                         ),
                     }
-                    // FIXME(eddyb) should use `def_span`.
                     if let Some(did) = did.as_local() {
                         if self.tcx().sess.opts.unstable_opts.span_free_formats {
                             p!("@", print_def_path(did.to_def_id(), args));
@@ -1485,7 +1487,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             },
             ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
             ty::ConstKind::Value(cv) => {
-                return self.pretty_print_const_valtree(cv.valtree, cv.ty, print_ty);
+                return self.pretty_print_const_valtree(cv, print_ty);
             }
 
             ty::ConstKind::Bound(debruijn, bound_var) => {
@@ -1785,48 +1787,47 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         Ok(())
     }
 
-    // FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately.
     fn pretty_print_const_valtree(
         &mut self,
-        valtree: ty::ValTree<'tcx>,
-        ty: Ty<'tcx>,
+        cv: ty::Value<'tcx>,
         print_ty: bool,
     ) -> Result<(), PrintError> {
         define_scoped_cx!(self);
 
         if self.should_print_verbose() {
-            p!(write("ValTree({:?}: ", valtree), print(ty), ")");
+            p!(write("ValTree({:?}: ", cv.valtree), print(cv.ty), ")");
             return Ok(());
         }
 
         let u8_type = self.tcx().types.u8;
-        match (valtree, ty.kind()) {
+        match (cv.valtree, cv.ty.kind()) {
             (ty::ValTree::Branch(_), ty::Ref(_, inner_ty, _)) => match inner_ty.kind() {
                 ty::Slice(t) if *t == u8_type => {
-                    let bytes = valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
+                    let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| {
                         bug!(
                             "expected to convert valtree {:?} to raw bytes for type {:?}",
-                            valtree,
+                            cv.valtree,
                             t
                         )
                     });
                     return self.pretty_print_byte_str(bytes);
                 }
                 ty::Str => {
-                    let bytes = valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
-                        bug!("expected to convert valtree to raw bytes for type {:?}", ty)
+                    let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| {
+                        bug!("expected to convert valtree to raw bytes for type {:?}", cv.ty)
                     });
                     p!(write("{:?}", String::from_utf8_lossy(bytes)));
                     return Ok(());
                 }
                 _ => {
+                    let cv = ty::Value { valtree: cv.valtree, ty: *inner_ty };
                     p!("&");
-                    p!(pretty_print_const_valtree(valtree, *inner_ty, print_ty));
+                    p!(pretty_print_const_valtree(cv, print_ty));
                     return Ok(());
                 }
             },
             (ty::ValTree::Branch(_), ty::Array(t, _)) if *t == u8_type => {
-                let bytes = valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
+                let bytes = cv.try_to_raw_bytes(self.tcx()).unwrap_or_else(|| {
                     bug!("expected to convert valtree to raw bytes for type {:?}", t)
                 });
                 p!("*");
@@ -1835,10 +1836,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             }
             // Aggregates, printed as array/tuple/struct/variant construction syntax.
             (ty::ValTree::Branch(_), ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) => {
-                let contents =
-                    self.tcx().destructure_const(ty::Const::new_value(self.tcx(), valtree, ty));
+                let contents = self.tcx().destructure_const(ty::Const::new_value(
+                    self.tcx(),
+                    cv.valtree,
+                    cv.ty,
+                ));
                 let fields = contents.fields.iter().copied();
-                match *ty.kind() {
+                match *cv.ty.kind() {
                     ty::Array(..) => {
                         p!("[", comma_sep(fields), "]");
                     }
@@ -1855,7 +1859,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                                 write!(this, "unreachable()")?;
                                 Ok(())
                             },
-                            |this| this.print_type(ty),
+                            |this| this.print_type(cv.ty),
                             ": ",
                         )?;
                     }
@@ -1892,7 +1896,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 return self.pretty_print_const_scalar_int(leaf, *inner_ty, print_ty);
             }
             (ty::ValTree::Leaf(leaf), _) => {
-                return self.pretty_print_const_scalar_int(leaf, ty, print_ty);
+                return self.pretty_print_const_scalar_int(leaf, cv.ty, print_ty);
             }
             // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
             // their fields instead of just dumping the memory.
@@ -1900,13 +1904,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         }
 
         // fallback
-        if valtree == ty::ValTree::zst() {
+        if cv.valtree == ty::ValTree::zst() {
             p!(write("<ZST>"));
         } else {
-            p!(write("{:?}", valtree));
+            p!(write("{:?}", cv.valtree));
         }
         if print_ty {
-            p!(": ", print(ty));
+            p!(": ", print(cv.ty));
         }
         Ok(())
     }
@@ -1994,7 +1998,6 @@ pub struct FmtPrinterData<'a, 'tcx> {
     binder_depth: usize,
     printed_type_count: usize,
     type_length_limit: Limit,
-    truncated: bool,
 
     pub region_highlight_mode: RegionHighlightMode<'tcx>,
 
@@ -2046,7 +2049,6 @@ impl<'a, 'tcx> FmtPrinter<'a, 'tcx> {
             binder_depth: 0,
             printed_type_count: 0,
             type_length_limit,
-            truncated: false,
             region_highlight_mode: RegionHighlightMode::default(),
             ty_infer_name_resolver: None,
             const_infer_name_resolver: None,
@@ -2183,16 +2185,49 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
     }
 
     fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
-        if self.type_length_limit.value_within_limit(self.printed_type_count) {
-            self.printed_type_count += 1;
-            self.pretty_print_type(ty)
-        } else {
-            self.truncated = true;
-            write!(self, "...")?;
-            Ok(())
+        match ty.kind() {
+            ty::Tuple(tys) if tys.len() == 0 && self.should_truncate() => {
+                // Don't truncate `()`.
+                self.printed_type_count += 1;
+                self.pretty_print_type(ty)
+            }
+            ty::Adt(..)
+            | ty::Foreign(_)
+            | ty::Pat(..)
+            | ty::RawPtr(..)
+            | ty::Ref(..)
+            | ty::FnDef(..)
+            | ty::FnPtr(..)
+            | ty::UnsafeBinder(..)
+            | ty::Dynamic(..)
+            | ty::Closure(..)
+            | ty::CoroutineClosure(..)
+            | ty::Coroutine(..)
+            | ty::CoroutineWitness(..)
+            | ty::Tuple(_)
+            | ty::Alias(..)
+            | ty::Param(_)
+            | ty::Bound(..)
+            | ty::Placeholder(_)
+            | ty::Error(_)
+                if self.should_truncate() =>
+            {
+                // We only truncate types that we know are likely to be much longer than 3 chars.
+                // There's no point in replacing `i32` or `!`.
+                write!(self, "...")?;
+                Ok(())
+            }
+            _ => {
+                self.printed_type_count += 1;
+                self.pretty_print_type(ty)
+            }
         }
     }
 
+    fn should_truncate(&mut self) -> bool {
+        !self.type_length_limit.value_within_limit(self.printed_type_count)
+    }
+
     fn print_dyn_existential(
         &mut self,
         predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
@@ -2942,7 +2977,7 @@ impl<'tcx> ty::TraitPredicate<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
+#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)]
 pub struct TraitPredPrintWithBoundConstness<'tcx>(
     ty::TraitPredicate<'tcx>,
     Option<ty::BoundConstness>,
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 9e9de4fb064..03b26b44538 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -170,7 +170,7 @@ impl<'tcx> fmt::Debug for ty::Const<'tcx> {
                     bug!("we checked that this is a valtree")
                 };
                 let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-                cx.pretty_print_const_valtree(cv.valtree, cv.ty, /*print_ty*/ true)?;
+                cx.pretty_print_const_valtree(cv, /*print_ty*/ true)?;
                 f.write_str(&cx.into_buffer())
             });
         }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 7d5e5c2e823..318bd0c7ec0 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -367,7 +367,7 @@ impl<'tcx> TyCtxt<'tcx> {
         validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>,
     ) -> Option<ty::Destructor> {
         let drop_trait = self.lang_items().drop_trait()?;
-        self.ensure().coherent_trait(drop_trait).ok()?;
+        self.ensure_ok().coherent_trait(drop_trait).ok()?;
 
         let ty = self.type_of(adt_did).instantiate_identity();
         let mut dtor_candidate = None;
@@ -404,7 +404,7 @@ impl<'tcx> TyCtxt<'tcx> {
         validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>,
     ) -> Option<ty::AsyncDestructor> {
         let async_drop_trait = self.lang_items().async_drop_trait()?;
-        self.ensure().coherent_trait(async_drop_trait).ok()?;
+        self.ensure_ok().coherent_trait(async_drop_trait).ok()?;
 
         let ty = self.type_of(adt_did).instantiate_identity();
         let mut dtor_candidate = None;
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 053775b4937..3cf3c332893 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -25,8 +25,6 @@ mir_build_borrow_of_moved_value = borrow of moved value
     .occurs_because_label = move occurs because `{$name}` has type `{$ty}`, which does not implement the `Copy` trait
     .value_borrowed_label = value borrowed here after move
     .suggestion = borrow this binding in the pattern to avoid moving the value
-    .full_type_name = the full type name has been written to '{$path}'
-    .consider_verbose = consider using `--verbose` to print the full type name to the console
 
 mir_build_call_to_deprecated_safe_fn_requires_unsafe =
     call to deprecated safe function `{$function}` is unsafe and requires unsafe block
@@ -361,6 +359,18 @@ mir_build_unreachable_pattern = unreachable pattern
     .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_binder_cast_requires_unsafe =
+    unsafe binder cast is unsafe and requires unsafe block
+    .label = unsafe binder cast
+    .note = casting to or from an `unsafe<...>` binder type is unsafe since it erases lifetime
+        information that may be required to uphold safety guarantees of a type
+
+mir_build_unsafe_binder_cast_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
+    unsafe binder cast is unsafe and requires unsafe block or unsafe fn
+    .label = unsafe binder cast
+    .note = casting to or from an `unsafe<...>` binder type is unsafe since it erases lifetime
+        information that may be required to uphold safety guarantees of a type
+
 mir_build_unsafe_field_requires_unsafe =
     use of unsafe field is unsafe and requires unsafe block
     .note = unsafe fields may carry library invariants
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
index 0086775e9f4..482f1e3840b 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
@@ -105,7 +105,8 @@ fn convert_to_hir_projections_and_truncate_for_capture(
             ProjectionElem::OpaqueCast(_) | ProjectionElem::Subtype(..) => continue,
             ProjectionElem::Index(..)
             | ProjectionElem::ConstantIndex { .. }
-            | ProjectionElem::Subslice { .. } => {
+            | ProjectionElem::Subslice { .. }
+            | ProjectionElem::UnwrapUnsafeBinder(_) => {
                 // We don't capture array-access projections.
                 // We can stop here as arrays are captured completely.
                 break;
@@ -523,6 +524,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 block.and(PlaceBuilder::from(temp))
             }
 
+            ExprKind::PlaceUnwrapUnsafeBinder { source } => {
+                let place_builder = unpack!(
+                    block = this.expr_as_place(block, source, mutability, fake_borrow_temps,)
+                );
+                block.and(place_builder.project(PlaceElem::UnwrapUnsafeBinder(expr.ty)))
+            }
+            ExprKind::ValueUnwrapUnsafeBinder { source } => {
+                let source_expr = &this.thir[source];
+                let temp = unpack!(
+                    block = this.as_temp(block, source_expr.temp_lifetime, source, mutability)
+                );
+                block.and(PlaceBuilder::from(temp).project(PlaceElem::UnwrapUnsafeBinder(expr.ty)))
+            }
+
             ExprKind::Array { .. }
             | ExprKind::Tuple { .. }
             | ExprKind::Adt { .. }
@@ -560,7 +575,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::OffsetOf { .. }
             | ExprKind::Yield { .. }
             | ExprKind::ThreadLocalRef(_)
-            | ExprKind::Call { .. } => {
+            | ExprKind::Call { .. }
+            | ExprKind::WrapUnsafeBinder { .. } => {
                 // these are not places, so we need to make a temporary.
                 debug_assert!(!matches!(Category::of(&expr.kind), Some(Category::Place)));
                 let temp =
@@ -776,7 +792,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     | ProjectionElem::OpaqueCast(..)
                     | ProjectionElem::Subtype(..)
                     | ProjectionElem::ConstantIndex { .. }
-                    | ProjectionElem::Subslice { .. } => (),
+                    | ProjectionElem::Subslice { .. }
+                    | ProjectionElem::UnwrapUnsafeBinder(_) => (),
                 }
             }
         }
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
index 9961c2488ef..e7713f0a1d6 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
@@ -508,6 +508,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 block.and(Rvalue::Use(Operand::Constant(Box::new(constant))))
             }
 
+            ExprKind::WrapUnsafeBinder { source } => {
+                let source = unpack!(
+                    block = this.as_operand(
+                        block,
+                        scope,
+                        source,
+                        LocalInfo::Boring,
+                        NeedsTemporary::Maybe
+                    )
+                );
+                block.and(Rvalue::WrapUnsafeBinder(source, expr.ty))
+            }
+
             ExprKind::Yield { .. }
             | ExprKind::Block { .. }
             | ExprKind::Match { .. }
@@ -532,7 +545,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::Become { .. }
             | ExprKind::InlineAsm { .. }
             | ExprKind::PlaceTypeAscription { .. }
-            | ExprKind::ValueTypeAscription { .. } => {
+            | ExprKind::ValueTypeAscription { .. }
+            | ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | ExprKind::ValueUnwrapUnsafeBinder { .. } => {
                 // these do not have corresponding `Rvalue` variants,
                 // so make an operand and then return that
                 debug_assert!(!matches!(
diff --git a/compiler/rustc_mir_build/src/builder/expr/category.rs b/compiler/rustc_mir_build/src/builder/expr/category.rs
index e0349e3e3f6..ca55d36bfc6 100644
--- a/compiler/rustc_mir_build/src/builder/expr/category.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/category.rs
@@ -41,7 +41,9 @@ impl Category {
             | ExprKind::UpvarRef { .. }
             | ExprKind::VarRef { .. }
             | ExprKind::PlaceTypeAscription { .. }
-            | ExprKind::ValueTypeAscription { .. } => Some(Category::Place),
+            | ExprKind::ValueTypeAscription { .. }
+            | ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | ExprKind::ValueUnwrapUnsafeBinder { .. } => Some(Category::Place),
 
             ExprKind::LogicalOp { .. }
             | ExprKind::Match { .. }
@@ -68,7 +70,8 @@ impl Category {
             | ExprKind::Assign { .. }
             | ExprKind::AssignOp { .. }
             | ExprKind::ThreadLocalRef(_)
-            | ExprKind::OffsetOf { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
+            | ExprKind::OffsetOf { .. }
+            | ExprKind::WrapUnsafeBinder { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
 
             ExprKind::ConstBlock { .. }
             | ExprKind::Literal { .. }
diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs
index 928156572d5..b25cd0f4426 100644
--- a/compiler/rustc_mir_build/src/builder/expr/into.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/into.rs
@@ -554,7 +554,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             ExprKind::VarRef { .. }
             | ExprKind::UpvarRef { .. }
             | ExprKind::PlaceTypeAscription { .. }
-            | ExprKind::ValueTypeAscription { .. } => {
+            | ExprKind::ValueTypeAscription { .. }
+            | ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | ExprKind::ValueUnwrapUnsafeBinder { .. } => {
                 debug_assert!(Category::of(&expr.kind) == Some(Category::Place));
 
                 let place = unpack!(block = this.as_place(block, expr_id));
@@ -613,7 +615,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::ConstParam { .. }
             | ExprKind::ThreadLocalRef(_)
             | ExprKind::StaticRef { .. }
-            | ExprKind::OffsetOf { .. } => {
+            | ExprKind::OffsetOf { .. }
+            | ExprKind::WrapUnsafeBinder { .. } => {
                 debug_assert!(match Category::of(&expr.kind).unwrap() {
                     // should be handled above
                     Category::Rvalue(RvalueFunc::Into) => false,
diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs
index 93fb9873e80..e04c70b5883 100644
--- a/compiler/rustc_mir_build/src/builder/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/mod.rs
@@ -47,7 +47,7 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>(
 /// Create the MIR for a given `DefId`, including unreachable code. Do not call
 /// this directly; instead use the cached version via `mir_built`.
 pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
-    tcx.ensure_with_value().thir_abstract_const(def);
+    tcx.ensure_done().thir_abstract_const(def);
     if let Err(e) = tcx.check_match(def) {
         return construct_error(tcx, def, e);
     }
@@ -68,7 +68,7 @@ pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
             // "not all control paths return a value" is reported here.
             //
             // maybe move the check to a MIR pass?
-            tcx.ensure().check_liveness(def);
+            tcx.ensure_ok().check_liveness(def);
 
             // Don't steal here, instead steal in unsafeck. This is so that
             // pattern inline constants can be evaluated as part of building the
diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs
index 0659e3ea314..921205428db 100644
--- a/compiler/rustc_mir_build/src/check_tail_calls.rs
+++ b/compiler/rustc_mir_build/src/check_tail_calls.rs
@@ -1,4 +1,5 @@
 use rustc_abi::ExternAbi;
+use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::Applicability;
 use rustc_hir::LangItem;
 use rustc_hir::def::DefKind;
@@ -344,12 +345,14 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for TailCallCkVisitor<'a, 'tcx> {
     }
 
     fn visit_expr(&mut self, expr: &'a Expr<'tcx>) {
-        if let ExprKind::Become { value } = expr.kind {
-            let call = &self.thir[value];
-            self.check_tail_call(call, expr);
-        }
+        ensure_sufficient_stack(|| {
+            if let ExprKind::Become { value } = expr.kind {
+                let call = &self.thir[value];
+                self.check_tail_call(call, expr);
+            }
 
-        visit::walk_expr(self, expr);
+            visit::walk_expr(self, expr);
+        });
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 995bc311b7c..b6494173b0f 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -2,6 +2,7 @@ use std::borrow::Cow;
 use std::mem;
 use std::ops::Bound;
 
+use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::DiagArgValue;
 use rustc_hir::def::DefKind;
 use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
@@ -200,7 +201,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
     fn visit_inner_body(&mut self, def: LocalDefId) {
         if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) {
             // Runs all other queries that depend on THIR.
-            self.tcx.ensure_with_value().mir_built(def);
+            self.tcx.ensure_done().mir_built(def);
             let inner_thir = &inner_thir.steal();
             let hir_context = self.tcx.local_def_id_to_hir_id(def);
             let safety_context = mem::replace(&mut self.safety_context, SafetyContext::Safe);
@@ -439,6 +440,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             | ExprKind::NeverToAny { .. }
             | ExprKind::PlaceTypeAscription { .. }
             | ExprKind::ValueTypeAscription { .. }
+            | ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | ExprKind::ValueUnwrapUnsafeBinder { .. }
+            | ExprKind::WrapUnsafeBinder { .. }
             | ExprKind::PointerCoercion { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::StaticRef { .. }
@@ -473,7 +477,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             ExprKind::Scope { value, lint_level: LintLevel::Explicit(hir_id), region_scope: _ } => {
                 let prev_id = self.hir_context;
                 self.hir_context = hir_id;
-                self.visit_expr(&self.thir[value]);
+                ensure_sufficient_stack(|| {
+                    self.visit_expr(&self.thir[value]);
+                });
                 self.hir_context = prev_id;
                 return; // don't visit the whole expression
             }
@@ -680,6 +686,11 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     }
                 }
             }
+            ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | ExprKind::ValueUnwrapUnsafeBinder { .. }
+            | ExprKind::WrapUnsafeBinder { .. } => {
+                self.requires_unsafe(expr.span, UnsafeBinderCast);
+            }
             _ => {}
         }
         visit::walk_expr(self, expr);
@@ -728,6 +739,7 @@ enum UnsafeOpKind {
         /// (e.g., with `-C target-feature`).
         build_enabled: Vec<Symbol>,
     },
+    UnsafeBinderCast,
 }
 
 use UnsafeOpKind::*;
@@ -891,6 +903,15 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 },
             ),
+            UnsafeBinderCast => tcx.emit_node_span_lint(
+                UNSAFE_OP_IN_UNSAFE_FN,
+                hir_id,
+                span,
+                UnsafeOpInUnsafeFnUnsafeBinderCastRequiresUnsafe {
+                    span,
+                    unsafe_not_inherited_note,
+                },
+            ),
         }
     }
 
@@ -1099,6 +1120,15 @@ impl UnsafeOpKind {
                     function: tcx.def_path_str(*function),
                 });
             }
+            UnsafeBinderCast if unsafe_op_in_unsafe_fn_allowed => {
+                dcx.emit_err(UnsafeBinderCastRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+                    span,
+                    unsafe_not_inherited_note,
+                });
+            }
+            UnsafeBinderCast => {
+                dcx.emit_err(UnsafeBinderCastRequiresUnsafe { span, unsafe_not_inherited_note });
+            }
         }
     }
 }
@@ -1112,7 +1142,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
 
     let Ok((thir, expr)) = tcx.thir_body(def) else { return };
     // Runs all other queries that depend on THIR.
-    tcx.ensure_with_value().mir_built(def);
+    tcx.ensure_done().mir_built(def);
     let thir = &thir.steal();
 
     let hir_id = tcx.local_def_id_to_hir_id(def);
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 1f87bf0dbbb..af6f33d9cdd 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -161,6 +161,18 @@ pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe
 }
 
 #[derive(LintDiagnostic)]
+#[diag(
+    mir_build_unsafe_binder_cast_requires_unsafe,
+    code = E0133,
+)]
+pub(crate) struct UnsafeOpInUnsafeFnUnsafeBinderCastRequiresUnsafe {
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe, code = E0133)]
 #[help]
 pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
@@ -494,6 +506,32 @@ pub(crate) struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
 }
 
+#[derive(Diagnostic)]
+#[diag(
+    mir_build_unsafe_binder_cast_requires_unsafe,
+    code = E0133,
+)]
+pub(crate) struct UnsafeBinderCastRequiresUnsafe {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
+#[derive(Diagnostic)]
+#[diag(
+    mir_build_unsafe_binder_cast_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
+    code = E0133,
+)]
+pub(crate) struct UnsafeBinderCastRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
 #[derive(Subdiagnostic)]
 #[label(mir_build_unsafe_not_inherited)]
 pub(crate) struct UnsafeNotInheritedNote {
@@ -801,10 +839,6 @@ pub(crate) struct BorrowOfMovedValue {
     pub(crate) ty: String,
     #[suggestion(code = "ref ", applicability = "machine-applicable")]
     pub(crate) suggest_borrowing: Option<Span>,
-    #[note(mir_build_full_type_name)]
-    #[note(mir_build_consider_verbose)]
-    pub(crate) has_path: bool,
-    pub(crate) path: String,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs
index c9df027687a..e858b629ab1 100644
--- a/compiler/rustc_mir_build/src/thir/cx/block.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/block.rs
@@ -6,9 +6,9 @@ use rustc_middle::ty;
 use rustc_middle::ty::CanonicalUserTypeAnnotation;
 use tracing::debug;
 
-use crate::thir::cx::Cx;
+use crate::thir::cx::ThirBuildCx;
 
-impl<'tcx> Cx<'tcx> {
+impl<'tcx> ThirBuildCx<'tcx> {
     pub(crate) fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> BlockId {
         // We have to eagerly lower the "spine" of the statements
         // in order to get the lexical scoping correctly.
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 9cdf08d749b..54da6924db4 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -1,5 +1,6 @@
 use itertools::Itertools;
 use rustc_abi::{FIRST_VARIANT, FieldIdx};
+use rustc_ast::UnsafeBinderCastKind;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@@ -20,10 +21,9 @@ use rustc_middle::{bug, span_bug};
 use rustc_span::{Span, sym};
 use tracing::{debug, info, instrument, trace};
 
-use crate::thir::cx::Cx;
-use crate::thir::util::UserAnnotatedTyHelpers;
+use crate::thir::cx::ThirBuildCx;
 
-impl<'tcx> Cx<'tcx> {
+impl<'tcx> ThirBuildCx<'tcx> {
     /// Create a THIR expression for the given HIR expression. This expands all
     /// adjustments and directly adds the type information from the
     /// `typeck_results`. See the [dev-guide] for more details.
@@ -141,9 +141,9 @@ impl<'tcx> Cx<'tcx> {
             Adjust::Deref(Some(deref)) => {
                 // We don't need to do call adjust_span here since
                 // deref coercions always start with a built-in deref.
-                let call_def_id = deref.method_call(self.tcx());
+                let call_def_id = deref.method_call(self.tcx);
                 let overloaded_callee =
-                    Ty::new_fn_def(self.tcx(), call_def_id, self.tcx().mk_args(&[expr.ty.into()]));
+                    Ty::new_fn_def(self.tcx, call_def_id, self.tcx.mk_args(&[expr.ty.into()]));
 
                 expr = Expr {
                     temp_lifetime,
@@ -252,10 +252,10 @@ impl<'tcx> Cx<'tcx> {
 
         // Check to see if this cast is a "coercion cast", where the cast is actually done
         // using a coercion (or is a no-op).
-        if self.typeck_results().is_coercion_cast(source.hir_id) {
+        if self.typeck_results.is_coercion_cast(source.hir_id) {
             // Convert the lexpr to a vexpr.
             ExprKind::Use { source: self.mirror_expr(source) }
-        } else if self.typeck_results().expr_ty(source).is_ref() {
+        } else if self.typeck_results.expr_ty(source).is_ref() {
             // Special cased so that we can type check that the element
             // type of the source matches the pointed to type of the
             // destination.
@@ -265,8 +265,8 @@ impl<'tcx> Cx<'tcx> {
                 is_from_as_cast: true,
             }
         } else if let hir::ExprKind::Path(ref qpath) = source.kind
-            && let res = self.typeck_results().qpath_res(qpath, source.hir_id)
-            && let ty = self.typeck_results().node_type(source.hir_id)
+            && let res = self.typeck_results.qpath_res(qpath, source.hir_id)
+            && let ty = self.typeck_results.node_type(source.hir_id)
             && let ty::Adt(adt_def, args) = ty.kind()
             && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
         {
@@ -329,7 +329,7 @@ impl<'tcx> Cx<'tcx> {
     #[instrument(level = "debug", skip(self), ret)]
     fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
         let tcx = self.tcx;
-        let expr_ty = self.typeck_results().expr_ty(expr);
+        let expr_ty = self.typeck_results.expr_ty(expr);
         let (temp_lifetime, backwards_incompatible) =
             self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id);
 
@@ -353,7 +353,7 @@ impl<'tcx> Cx<'tcx> {
             }
 
             hir::ExprKind::Call(fun, ref args) => {
-                if self.typeck_results().is_method_call(expr) {
+                if self.typeck_results.is_method_call(expr) {
                     // The callee is something implementing Fn, FnMut, or FnOnce.
                     // Find the actual method implementation being called and
                     // build the appropriate UFCS call expression with the
@@ -363,7 +363,7 @@ impl<'tcx> Cx<'tcx> {
 
                     let method = self.method_callee(expr, fun.span, None);
 
-                    let arg_tys = args.iter().map(|e| self.typeck_results().expr_ty_adjusted(e));
+                    let arg_tys = args.iter().map(|e| self.typeck_results.expr_ty_adjusted(e));
                     let tupled_args = Expr {
                         ty: Ty::new_tup_from_iter(tcx, arg_tys),
                         temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
@@ -379,7 +379,7 @@ impl<'tcx> Cx<'tcx> {
                         from_hir_call: true,
                         fn_span: expr.span,
                     }
-                } else if let ty::FnDef(def_id, _) = self.typeck_results().expr_ty(fun).kind()
+                } else if let ty::FnDef(def_id, _) = self.typeck_results.expr_ty(fun).kind()
                     && let Some(intrinsic) = self.tcx.intrinsic(def_id)
                     && intrinsic.name == sym::box_new
                 {
@@ -412,7 +412,7 @@ impl<'tcx> Cx<'tcx> {
                             },
                             hir::QPath::TypeRelative(_ty, _) => {
                                 if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
-                                    self.typeck_results().type_dependent_def(fun.hir_id)
+                                    self.typeck_results.type_dependent_def(fun.hir_id)
                                 {
                                     Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
                                 } else {
@@ -425,8 +425,8 @@ impl<'tcx> Cx<'tcx> {
                         None
                     };
                     if let Some((adt_def, index)) = adt_data {
-                        let node_args = self.typeck_results().node_args(fun.hir_id);
-                        let user_provided_types = self.typeck_results().user_provided_types();
+                        let node_args = self.typeck_results.node_args(fun.hir_id);
+                        let user_provided_types = self.typeck_results.user_provided_types();
                         let user_ty =
                             user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
                                 if let ty::UserTypeKind::TypeOf(ref mut did, _) =
@@ -456,7 +456,7 @@ impl<'tcx> Cx<'tcx> {
                         }))
                     } else {
                         ExprKind::Call {
-                            ty: self.typeck_results().node_type(fun.hir_id),
+                            ty: self.typeck_results.node_type(fun.hir_id),
                             fun: self.mirror_expr(fun),
                             args: self.mirror_exprs(args),
                             from_hir_call: true,
@@ -481,7 +481,7 @@ impl<'tcx> Cx<'tcx> {
             }
 
             hir::ExprKind::AssignOp(op, lhs, rhs) => {
-                if self.typeck_results().is_method_call(expr) {
+                if self.typeck_results.is_method_call(expr) {
                     let lhs = self.mirror_expr(lhs);
                     let rhs = self.mirror_expr(rhs);
                     self.overloaded_operator(expr, Box::new([lhs, rhs]))
@@ -497,7 +497,7 @@ impl<'tcx> Cx<'tcx> {
             hir::ExprKind::Lit(lit) => ExprKind::Literal { lit, neg: false },
 
             hir::ExprKind::Binary(op, lhs, rhs) => {
-                if self.typeck_results().is_method_call(expr) {
+                if self.typeck_results.is_method_call(expr) {
                     let lhs = self.mirror_expr(lhs);
                     let rhs = self.mirror_expr(rhs);
                     self.overloaded_operator(expr, Box::new([lhs, rhs]))
@@ -526,7 +526,7 @@ impl<'tcx> Cx<'tcx> {
             }
 
             hir::ExprKind::Index(lhs, index, brackets_span) => {
-                if self.typeck_results().is_method_call(expr) {
+                if self.typeck_results.is_method_call(expr) {
                     let lhs = self.mirror_expr(lhs);
                     let index = self.mirror_expr(index);
                     self.overloaded_place(
@@ -542,7 +542,7 @@ impl<'tcx> Cx<'tcx> {
             }
 
             hir::ExprKind::Unary(hir::UnOp::Deref, arg) => {
-                if self.typeck_results().is_method_call(expr) {
+                if self.typeck_results.is_method_call(expr) {
                     let arg = self.mirror_expr(arg);
                     self.overloaded_place(expr, expr_ty, None, Box::new([arg]), expr.span)
                 } else {
@@ -551,7 +551,7 @@ impl<'tcx> Cx<'tcx> {
             }
 
             hir::ExprKind::Unary(hir::UnOp::Not, arg) => {
-                if self.typeck_results().is_method_call(expr) {
+                if self.typeck_results.is_method_call(expr) {
                     let arg = self.mirror_expr(arg);
                     self.overloaded_operator(expr, Box::new([arg]))
                 } else {
@@ -560,7 +560,7 @@ impl<'tcx> Cx<'tcx> {
             }
 
             hir::ExprKind::Unary(hir::UnOp::Neg, arg) => {
-                if self.typeck_results().is_method_call(expr) {
+                if self.typeck_results.is_method_call(expr) {
                     let arg = self.mirror_expr(arg);
                     self.overloaded_operator(expr, Box::new([arg]))
                 } else if let hir::ExprKind::Lit(lit) = arg.kind {
@@ -573,7 +573,7 @@ impl<'tcx> Cx<'tcx> {
             hir::ExprKind::Struct(qpath, fields, ref base) => match expr_ty.kind() {
                 ty::Adt(adt, args) => match adt.adt_kind() {
                     AdtKind::Struct | AdtKind::Union => {
-                        let user_provided_types = self.typeck_results().user_provided_types();
+                        let user_provided_types = self.typeck_results.user_provided_types();
                         let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
                         debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
                         ExprKind::Adt(Box::new(AdtExpr {
@@ -585,15 +585,14 @@ impl<'tcx> Cx<'tcx> {
                             base: match base {
                                 hir::StructTailExpr::Base(base) => AdtExprBase::Base(FruInfo {
                                     base: self.mirror_expr(base),
-                                    field_types: self.typeck_results().fru_field_types()
-                                        [expr.hir_id]
+                                    field_types: self.typeck_results.fru_field_types()[expr.hir_id]
                                         .iter()
                                         .copied()
                                         .collect(),
                                 }),
                                 hir::StructTailExpr::DefaultFields(_) => {
                                     AdtExprBase::DefaultFields(
-                                        self.typeck_results().fru_field_types()[expr.hir_id]
+                                        self.typeck_results.fru_field_types()[expr.hir_id]
                                             .iter()
                                             .copied()
                                             .collect(),
@@ -604,7 +603,7 @@ impl<'tcx> Cx<'tcx> {
                         }))
                     }
                     AdtKind::Enum => {
-                        let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
+                        let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
                         match res {
                             Res::Def(DefKind::Variant, variant_id) => {
                                 assert!(matches!(
@@ -614,8 +613,7 @@ impl<'tcx> Cx<'tcx> {
                                 ));
 
                                 let index = adt.variant_index_with_id(variant_id);
-                                let user_provided_types =
-                                    self.typeck_results().user_provided_types();
+                                let user_provided_types = self.typeck_results.user_provided_types();
                                 let user_ty =
                                     user_provided_types.get(expr.hir_id).copied().map(Box::new);
                                 debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
@@ -628,8 +626,7 @@ impl<'tcx> Cx<'tcx> {
                                     base: match base {
                                         hir::StructTailExpr::DefaultFields(_) => {
                                             AdtExprBase::DefaultFields(
-                                                self.typeck_results().fru_field_types()
-                                                    [expr.hir_id]
+                                                self.typeck_results.fru_field_types()[expr.hir_id]
                                                     .iter()
                                                     .copied()
                                                     .collect(),
@@ -654,7 +651,7 @@ impl<'tcx> Cx<'tcx> {
             },
 
             hir::ExprKind::Closure { .. } => {
-                let closure_ty = self.typeck_results().expr_ty(expr);
+                let closure_ty = self.typeck_results.expr_ty(expr);
                 let (def_id, args, movability) = match *closure_ty.kind() {
                     ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args), None),
                     ty::Coroutine(def_id, args) => {
@@ -702,7 +699,7 @@ impl<'tcx> Cx<'tcx> {
             }
 
             hir::ExprKind::Path(ref qpath) => {
-                let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
+                let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
                 self.convert_path_expr(expr, res)
             }
 
@@ -771,7 +768,7 @@ impl<'tcx> Cx<'tcx> {
             }
 
             hir::ExprKind::ConstBlock(ref anon_const) => {
-                let ty = self.typeck_results().node_type(anon_const.hir_id);
+                let ty = self.typeck_results.node_type(anon_const.hir_id);
                 let did = anon_const.def_id.to_def_id();
                 let typeck_root_def_id = tcx.typeck_root_def_id(did);
                 let parent_args =
@@ -782,7 +779,7 @@ impl<'tcx> Cx<'tcx> {
             }
             // Now comes the rote stuff:
             hir::ExprKind::Repeat(v, _) => {
-                let ty = self.typeck_results().expr_ty(expr);
+                let ty = self.typeck_results.expr_ty(expr);
                 let ty::Array(_, count) = ty.kind() else {
                     span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty);
                 };
@@ -836,7 +833,7 @@ impl<'tcx> Cx<'tcx> {
                 match_source,
             },
             hir::ExprKind::Loop(body, ..) => {
-                let block_ty = self.typeck_results().node_type(body.hir_id);
+                let block_ty = self.typeck_results.node_type(body.hir_id);
                 let (temp_lifetime, backwards_incompatible) = self
                     .rvalue_scopes
                     .temporary_scope(self.region_scope_tree, body.hir_id.local_id);
@@ -910,8 +907,19 @@ impl<'tcx> Cx<'tcx> {
                 }
             }
 
-            hir::ExprKind::UnsafeBinderCast(_kind, _source, _ty) => {
-                unreachable!("unsafe binders are not yet implemented")
+            hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Unwrap, source, _ty) => {
+                // FIXME(unsafe_binders): Take into account the ascribed type, too.
+                let mirrored = self.mirror_expr(source);
+                if source.is_syntactic_place_expr() {
+                    ExprKind::PlaceUnwrapUnsafeBinder { source: mirrored }
+                } else {
+                    ExprKind::ValueUnwrapUnsafeBinder { source: mirrored }
+                }
+            }
+            hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Wrap, source, _ty) => {
+                // FIXME(unsafe_binders): Take into account the ascribed type, too.
+                let mirrored = self.mirror_expr(source);
+                ExprKind::WrapUnsafeBinder { source: mirrored }
             }
 
             hir::ExprKind::DropTemps(source) => ExprKind::Use { source: self.mirror_expr(source) },
@@ -945,7 +953,7 @@ impl<'tcx> Cx<'tcx> {
             | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
             | Res::Def(DefKind::Const, _)
             | Res::Def(DefKind::AssocConst, _) => {
-                self.typeck_results().user_provided_types().get(hir_id).copied().map(Box::new)
+                self.typeck_results.user_provided_types().get(hir_id).copied().map(Box::new)
             }
 
             // A unit struct/variant which is used as a value (e.g.,
@@ -977,17 +985,13 @@ impl<'tcx> Cx<'tcx> {
             Some(fn_def) => (fn_def, None),
             None => {
                 let (kind, def_id) =
-                    self.typeck_results().type_dependent_def(expr.hir_id).unwrap_or_else(|| {
+                    self.typeck_results.type_dependent_def(expr.hir_id).unwrap_or_else(|| {
                         span_bug!(expr.span, "no type-dependent def for method callee")
                     });
                 let user_ty = self.user_args_applied_to_res(expr.hir_id, Res::Def(kind, def_id));
                 debug!("method_callee: user_ty={:?}", user_ty);
                 (
-                    Ty::new_fn_def(
-                        self.tcx(),
-                        def_id,
-                        self.typeck_results().node_args(expr.hir_id),
-                    ),
+                    Ty::new_fn_def(self.tcx, def_id, self.typeck_results.node_args(expr.hir_id)),
                     user_ty,
                 )
             }
@@ -1013,7 +1017,7 @@ impl<'tcx> Cx<'tcx> {
     }
 
     fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKind<'tcx> {
-        let args = self.typeck_results().node_args(expr.hir_id);
+        let args = self.typeck_results.node_args(expr.hir_id);
         match res {
             // A regular function, constructor function or a constant.
             Res::Def(DefKind::Fn, _)
@@ -1048,7 +1052,7 @@ impl<'tcx> Cx<'tcx> {
                 let user_provided_types = self.typeck_results.user_provided_types();
                 let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
                 debug!("convert_path_expr: user_ty={:?}", user_ty);
-                let ty = self.typeck_results().node_type(expr.hir_id);
+                let ty = self.typeck_results.node_type(expr.hir_id);
                 match ty.kind() {
                     // A unit struct/variant which is used as a value.
                     // We return a completely different ExprKind here to account for this special case.
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index a98c2bb61f6..9d114e67559 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -16,15 +16,15 @@ use rustc_middle::ty::{self, RvalueScopes, TyCtxt};
 use tracing::instrument;
 
 use crate::thir::pattern::pat_from_hir;
-use crate::thir::util::UserAnnotatedTyHelpers;
 
+/// Query implementation for [`TyCtxt::thir_body`].
 pub(crate) fn thir_body(
     tcx: TyCtxt<'_>,
     owner_def: LocalDefId,
 ) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> {
     let hir = tcx.hir();
     let body = hir.body_owned_by(owner_def);
-    let mut cx = Cx::new(tcx, owner_def);
+    let mut cx = ThirBuildCx::new(tcx, owner_def);
     if let Some(reported) = cx.typeck_results.tainted_by_errors {
         return Err(reported);
     }
@@ -52,8 +52,10 @@ pub(crate) fn thir_body(
     Ok((tcx.alloc_steal_thir(cx.thir), expr))
 }
 
-struct Cx<'tcx> {
+/// Context for lowering HIR to THIR for a single function body (or other kind of body).
+struct ThirBuildCx<'tcx> {
     tcx: TyCtxt<'tcx>,
+    /// The THIR data that this context is building.
     thir: Thir<'tcx>,
 
     typing_env: ty::TypingEnv<'tcx>,
@@ -69,8 +71,8 @@ struct Cx<'tcx> {
     body_owner: DefId,
 }
 
-impl<'tcx> Cx<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Cx<'tcx> {
+impl<'tcx> ThirBuildCx<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
         let typeck_results = tcx.typeck(def);
         let hir = tcx.hir();
         let hir_id = tcx.local_def_id_to_hir_id(def);
@@ -94,7 +96,7 @@ impl<'tcx> Cx<'tcx> {
             BodyTy::Const(typeck_results.node_type(hir_id))
         };
 
-        Cx {
+        Self {
             tcx,
             thir: Thir::new(body_type),
             // FIXME(#132279): We're in a body, we should use a typing
@@ -113,7 +115,7 @@ impl<'tcx> Cx<'tcx> {
 
     #[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>> {
@@ -197,15 +199,12 @@ impl<'tcx> Cx<'tcx> {
             Param { pat: Some(pat), ty, ty_span, self_kind, hir_id: Some(param.hir_id) }
         })
     }
-}
-
-impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
 
-    fn typeck_results(&self) -> &ty::TypeckResults<'tcx> {
-        self.typeck_results
+    fn user_args_applied_to_ty_of_hir_id(
+        &self,
+        hir_id: HirId,
+    ) -> Option<ty::CanonicalUserType<'tcx>> {
+        crate::thir::util::user_args_applied_to_ty_of_hir_id(self.typeck_results, hir_id)
     }
 }
 
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 e0a1117f905..8247a6c6a32 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -326,9 +326,10 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
             | Use { source }
             | PointerCoercion { source, .. }
             | PlaceTypeAscription { source, .. }
-            | ValueTypeAscription { source, .. } => {
-                self.is_known_valid_scrutinee(&self.thir()[*source])
-            }
+            | ValueTypeAscription { source, .. }
+            | PlaceUnwrapUnsafeBinder { source }
+            | ValueUnwrapUnsafeBinder { source }
+            | WrapUnsafeBinder { source } => self.is_known_valid_scrutinee(&self.thir()[*source]),
 
             // These diverge.
             Become { .. } | Break { .. } | Continue { .. } | Return { .. } => true,
@@ -796,16 +797,16 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat:
             });
             if !conflicts_ref.is_empty() {
                 let mut path = None;
-                let ty = cx.tcx.short_ty_string(ty, &mut path);
-                sess.dcx().emit_err(BorrowOfMovedValue {
+                let ty = cx.tcx.short_string(ty, &mut path);
+                let mut err = sess.dcx().create_err(BorrowOfMovedValue {
                     binding_span: pat.span,
                     conflicts_ref,
                     name: Ident::new(name, pat.span),
                     ty,
                     suggest_borrowing: Some(pat.span.shrink_to_lo()),
-                    has_path: path.is_some(),
-                    path: path.map(|p| p.display().to_string()).unwrap_or_default(),
                 });
+                *err.long_ty_path() = path;
+                err.emit();
             }
             return;
         }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 20a728d6d5b..8ecdbecf165 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -27,7 +27,6 @@ use tracing::{debug, instrument};
 pub(crate) use self::check_match::check_match;
 use crate::errors::*;
 use crate::fluent_generated as fluent;
-use crate::thir::util::UserAnnotatedTyHelpers;
 
 struct PatCtxt<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -155,42 +154,41 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
     fn lower_pattern_range_endpoint(
         &mut self,
         expr: Option<&'tcx hir::PatExpr<'tcx>>,
-    ) -> Result<
-        (Option<PatRangeBoundary<'tcx>>, Option<Ascription<'tcx>>, Option<LocalDefId>),
-        ErrorGuaranteed,
-    > {
-        match expr {
-            None => Ok((None, None, None)),
-            Some(expr) => {
-                let (kind, ascr, inline_const) = match self.lower_lit(expr) {
-                    PatKind::ExpandedConstant { subpattern, def_id, is_inline: true } => {
-                        (subpattern.kind, None, def_id.as_local())
-                    }
-                    PatKind::ExpandedConstant { subpattern, is_inline: false, .. } => {
-                        (subpattern.kind, None, None)
-                    }
-                    PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
-                        (kind, Some(ascription), None)
-                    }
-                    kind => (kind, None, None),
-                };
-                let value = match kind {
-                    PatKind::Constant { value } => value,
-                    PatKind::ExpandedConstant { subpattern, .. }
-                        if let PatKind::Constant { value } = subpattern.kind =>
-                    {
-                        value
-                    }
-                    _ => {
-                        let msg = format!(
-                            "found bad range pattern endpoint `{expr:?}` outside of error recovery"
-                        );
-                        return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
+        // Out-parameters collecting extra data to be reapplied by the caller
+        ascriptions: &mut Vec<Ascription<'tcx>>,
+        inline_consts: &mut Vec<LocalDefId>,
+    ) -> Result<Option<PatRangeBoundary<'tcx>>, ErrorGuaranteed> {
+        let Some(expr) = expr else { return Ok(None) };
+
+        // Lower the endpoint into a temporary `PatKind` that will then be
+        // deconstructed to obtain the constant value and other data.
+        let mut kind: PatKind<'tcx> = self.lower_lit(expr);
+
+        // Unpeel any ascription or inline-const wrapper nodes.
+        loop {
+            match kind {
+                PatKind::AscribeUserType { ascription, subpattern } => {
+                    ascriptions.push(ascription);
+                    kind = subpattern.kind;
+                }
+                PatKind::ExpandedConstant { is_inline, def_id, subpattern } => {
+                    if is_inline {
+                        inline_consts.extend(def_id.as_local());
                     }
-                };
-                Ok((Some(PatRangeBoundary::Finite(value)), ascr, inline_const))
+                    kind = subpattern.kind;
+                }
+                _ => break,
             }
         }
+
+        // The unpeeled kind should now be a constant, giving us the endpoint value.
+        let PatKind::Constant { value } = kind else {
+            let msg =
+                format!("found bad range pattern endpoint `{expr:?}` outside of error recovery");
+            return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
+        };
+
+        Ok(Some(PatRangeBoundary::Finite(value)))
     }
 
     /// Overflowing literals are linted against in a late pass. This is mostly fine, except when we
@@ -253,11 +251,15 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             self.tcx.dcx().span_bug(span, msg);
         }
 
-        let (lo, lo_ascr, lo_inline) = self.lower_pattern_range_endpoint(lo_expr)?;
-        let (hi, hi_ascr, hi_inline) = self.lower_pattern_range_endpoint(hi_expr)?;
+        // Collect extra data while lowering the endpoints, to be reapplied later.
+        let mut ascriptions = vec![];
+        let mut inline_consts = vec![];
+
+        let mut lower_endpoint =
+            |expr| self.lower_pattern_range_endpoint(expr, &mut ascriptions, &mut inline_consts);
 
-        let lo = lo.unwrap_or(PatRangeBoundary::NegInfinity);
-        let hi = hi.unwrap_or(PatRangeBoundary::PosInfinity);
+        let lo = lower_endpoint(lo_expr)?.unwrap_or(PatRangeBoundary::NegInfinity);
+        let hi = lower_endpoint(hi_expr)?.unwrap_or(PatRangeBoundary::PosInfinity);
 
         let cmp = lo.compare_with(hi, ty, self.tcx, self.typing_env);
         let mut kind = PatKind::Range(Box::new(PatRange { lo, hi, end, ty }));
@@ -298,13 +300,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         // If we are handling a range with associated constants (e.g.
         // `Foo::<'a>::A..=Foo::B`), we need to put the ascriptions for the associated
         // constants somewhere. Have them on the range pattern.
-        for ascription in [lo_ascr, hi_ascr].into_iter().flatten() {
+        for ascription in ascriptions {
             kind = PatKind::AscribeUserType {
                 ascription,
                 subpattern: Box::new(Pat { span, ty, kind }),
             };
         }
-        for def in [lo_inline, hi_inline].into_iter().flatten() {
+        for def in inline_consts {
             kind = PatKind::ExpandedConstant {
                 def_id: def.to_def_id(),
                 is_inline: true,
@@ -537,16 +539,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             _ => {
                 let e = match res {
                     Res::Def(DefKind::ConstParam, def_id) => {
-                        self.tcx.dcx().emit_err(ConstParamInPattern {
-                            span,
-                            const_span: self.tcx().def_span(def_id),
-                        })
+                        let const_span = self.tcx.def_span(def_id);
+                        self.tcx.dcx().emit_err(ConstParamInPattern { span, const_span })
                     }
                     Res::Def(DefKind::Static { .. }, def_id) => {
-                        self.tcx.dcx().emit_err(StaticInPattern {
-                            span,
-                            static_span: self.tcx().def_span(def_id),
-                        })
+                        let static_span = self.tcx.def_span(def_id);
+                        self.tcx.dcx().emit_err(StaticInPattern { span, static_span })
                     }
                     _ => self.tcx.dcx().emit_err(NonConstPath { span }),
                 };
@@ -570,6 +568,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         kind
     }
 
+    fn user_args_applied_to_ty_of_hir_id(
+        &self,
+        hir_id: hir::HirId,
+    ) -> Option<ty::CanonicalUserType<'tcx>> {
+        crate::thir::util::user_args_applied_to_ty_of_hir_id(self.typeck_results, hir_id)
+    }
+
     /// Takes a HIR Path. If the path is a constant, evaluates it and feeds
     /// it to `const_to_pat`. Any other path (like enum variants without fields)
     /// is converted to the corresponding pattern via `lower_variant_or_leaf`.
@@ -600,12 +605,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             return pattern;
         }
 
-        let user_provided_types = self.typeck_results().user_provided_types();
+        let user_provided_types = self.typeck_results.user_provided_types();
         if let Some(&user_ty) = user_provided_types.get(id) {
             let annotation = CanonicalUserTypeAnnotation {
                 user_ty: Box::new(user_ty),
                 span,
-                inferred_ty: self.typeck_results().node_type(id),
+                inferred_ty: self.typeck_results.node_type(id),
             };
             Box::new(Pat {
                 span,
@@ -669,13 +674,3 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind
     }
 }
-
-impl<'tcx> UserAnnotatedTyHelpers<'tcx> for PatCtxt<'_, 'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn typeck_results(&self) -> &ty::TypeckResults<'tcx> {
-        self.typeck_results
-    }
-}
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index 228a64c2c70..729c8f784ba 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -477,6 +477,24 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
                 self.print_expr(*source, depth_lvl + 2);
                 print_indented!(self, "}", depth_lvl);
             }
+            PlaceUnwrapUnsafeBinder { source } => {
+                print_indented!(self, "PlaceUnwrapUnsafeBinder {", depth_lvl);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            ValueUnwrapUnsafeBinder { source } => {
+                print_indented!(self, "ValueUnwrapUnsafeBinder {", depth_lvl);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            WrapUnsafeBinder { source } => {
+                print_indented!(self, "WrapUnsafeBinder {", depth_lvl);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
             Closure(closure_expr) => {
                 print_indented!(self, "Closure {", depth_lvl);
                 print_indented!(self, "closure_expr:", depth_lvl + 1);
diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs
index ed7c7e40993..4dff093afd0 100644
--- a/compiler/rustc_mir_build/src/thir/util.rs
+++ b/compiler/rustc_mir_build/src/thir/util.rs
@@ -1,33 +1,27 @@
 use rustc_hir as hir;
 use rustc_middle::bug;
-use rustc_middle::ty::{self, CanonicalUserType, TyCtxt};
+use rustc_middle::ty::{self, CanonicalUserType};
 use tracing::debug;
 
-pub(crate) trait UserAnnotatedTyHelpers<'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx>;
-
-    fn typeck_results(&self) -> &ty::TypeckResults<'tcx>;
-
-    /// Looks up the type associated with this hir-id and applies the
-    /// user-given generic parameters; the hir-id must map to a suitable
-    /// type.
-    fn user_args_applied_to_ty_of_hir_id(
-        &self,
-        hir_id: hir::HirId,
-    ) -> Option<CanonicalUserType<'tcx>> {
-        let user_provided_types = self.typeck_results().user_provided_types();
-        let mut user_ty = *user_provided_types.get(hir_id)?;
-        debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty);
-        let ty = self.typeck_results().node_type(hir_id);
-        match ty.kind() {
-            ty::Adt(adt_def, ..) => {
-                if let ty::UserTypeKind::TypeOf(ref mut did, _) = &mut user_ty.value.kind {
-                    *did = adt_def.did();
-                }
-                Some(user_ty)
+/// Looks up the type associated with this hir-id and applies the
+/// user-given generic parameters; the hir-id must map to a suitable
+/// type.
+pub(crate) fn user_args_applied_to_ty_of_hir_id<'tcx>(
+    typeck_results: &ty::TypeckResults<'tcx>,
+    hir_id: hir::HirId,
+) -> Option<CanonicalUserType<'tcx>> {
+    let user_provided_types = typeck_results.user_provided_types();
+    let mut user_ty = *user_provided_types.get(hir_id)?;
+    debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty);
+    let ty = typeck_results.node_type(hir_id);
+    match ty.kind() {
+        ty::Adt(adt_def, ..) => {
+            if let ty::UserTypeKind::TypeOf(ref mut did, _) = &mut user_ty.value.kind {
+                *did = adt_def.did();
             }
-            ty::FnDef(..) => Some(user_ty),
-            _ => bug!("ty: {:?} should not have user provided type {:?} recorded ", ty, user_ty),
+            Some(user_ty)
         }
+        ty::FnDef(..) => Some(user_ty),
+        _ => bug!("ty: {:?} should not have user provided type {:?} recorded ", ty, user_ty),
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index df4b1a53417..9abb8343432 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -97,7 +97,8 @@ where
             | Rvalue::UnaryOp(..)
             | Rvalue::Discriminant(..)
             | Rvalue::Aggregate(..)
-            | Rvalue::CopyForDeref(..) => {}
+            | Rvalue::CopyForDeref(..)
+            | Rvalue::WrapUnsafeBinder(..) => {}
         }
     }
 
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
index d79d2c316ee..d056ad3d4b4 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
@@ -32,6 +32,7 @@ impl<'tcx> Lift for PlaceElem<'tcx> {
             }
             ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u),
             ProjectionElem::Subtype(_ty) => ProjectionElem::Subtype(()),
+            ProjectionElem::UnwrapUnsafeBinder(_ty) => ProjectionElem::UnwrapUnsafeBinder(()),
         }
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index d1b3a389e9e..b6c259aa4e0 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -208,7 +208,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
                     | ty::Infer(_)
                     | ty::Error(_)
                     | ty::Placeholder(_) => bug!(
-                        "When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}"
+                        "When Place contains ProjectionElem::Field its type shouldn't be {place_ty:#?}"
                     ),
                 },
                 ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
@@ -226,6 +226,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
                     }
                     _ => bug!("Unexpected type {place_ty:#?}"),
                 },
+                ProjectionElem::UnwrapUnsafeBinder(_) => {}
                 // `OpaqueCast`:Only transmutes the type, so no moves there.
                 // `Downcast`  :Only changes information about a `Place` without moving.
                 // `Subtype`   :Only transmutes the type, so moves.
@@ -399,7 +400,8 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
             | Rvalue::Repeat(ref operand, _)
             | Rvalue::Cast(_, ref operand, _)
             | Rvalue::ShallowInitBox(ref operand, _)
-            | Rvalue::UnaryOp(_, ref operand) => self.gather_operand(operand),
+            | Rvalue::UnaryOp(_, ref operand)
+            | Rvalue::WrapUnsafeBinder(ref operand, _) => self.gather_operand(operand),
             Rvalue::BinaryOp(ref _binop, box (ref lhs, ref rhs)) => {
                 self.gather_operand(lhs);
                 self.gather_operand(rhs);
@@ -415,7 +417,11 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
             | Rvalue::Discriminant(..)
             | Rvalue::Len(..)
             | Rvalue::NullaryOp(
-                NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..) | NullOp::UbChecks,
+                NullOp::SizeOf
+                | NullOp::AlignOf
+                | NullOp::OffsetOf(..)
+                | NullOp::UbChecks
+                | NullOp::ContractChecks,
                 _,
             ) => {}
         }
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index 5e7b46182dc..a849ed4c3e2 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -6,7 +6,6 @@ use rustc_middle::mir::coverage::{
     FunctionCoverageInfo, MappingKind, Op,
 };
 use rustc_middle::mir::{Body, Statement, StatementKind};
-use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_middle::util::Providers;
 use rustc_span::def_id::LocalDefId;
@@ -15,8 +14,7 @@ use tracing::trace;
 
 /// Registers query/hook implementations related to coverage.
 pub(crate) fn provide(providers: &mut Providers) {
-    providers.hooks.is_eligible_for_coverage =
-        |TyCtxtAt { tcx, .. }, def_id| is_eligible_for_coverage(tcx, def_id);
+    providers.hooks.is_eligible_for_coverage = is_eligible_for_coverage;
     providers.queries.coverage_attr_on = coverage_attr_on;
     providers.queries.coverage_ids_info = coverage_ids_info;
 }
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 8879e029346..90173da17f0 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -504,7 +504,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
             | Rvalue::Cast(..)
             | Rvalue::BinaryOp(..)
             | Rvalue::Aggregate(..)
-            | Rvalue::ShallowInitBox(..) => {
+            | Rvalue::ShallowInitBox(..)
+            | Rvalue::WrapUnsafeBinder(..) => {
                 // No modification is possible through these r-values.
                 return ValueOrPlace::TOP;
             }
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 41de1b58b91..7395ad496db 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -575,6 +575,9 @@ impl WriteInfo {
                             self.add_operand(op);
                         }
                     }
+                    Rvalue::WrapUnsafeBinder(op, _) => {
+                        self.add_operand(op);
+                    }
                     Rvalue::ThreadLocalRef(_)
                     | Rvalue::NullaryOp(_, _)
                     | Rvalue::Ref(_, _, _)
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 16e15fa12e0..d2ffd26f0a0 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -476,6 +476,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                     }
                     ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty),
                     ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty),
+                    ProjectionElem::UnwrapUnsafeBinder(ty) => {
+                        ProjectionElem::UnwrapUnsafeBinder(ty)
+                    }
                     // This should have been replaced by a `ConstantIndex` earlier.
                     ProjectionElem::Index(_) => return None,
                 };
@@ -542,6 +545,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                         .offset_of_subfield(self.typing_env(), layout, fields.iter())
                         .bytes(),
                     NullOp::UbChecks => return None,
+                    NullOp::ContractChecks => return None,
                 };
                 let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap();
                 let imm = ImmTy::from_uint(val, usize_layout);
@@ -713,6 +717,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
             ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty),
             ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty),
+            ProjectionElem::UnwrapUnsafeBinder(ty) => ProjectionElem::UnwrapUnsafeBinder(ty),
         };
 
         Some(self.insert(Value::Projection(value, proj)))
@@ -867,6 +872,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 self.simplify_place_projection(place, location);
                 return self.new_pointer(*place, AddressKind::Address(mutbl));
             }
+            Rvalue::WrapUnsafeBinder(ref mut op, _) => {
+                return self.simplify_operand(op, location);
+            }
 
             // Operations.
             Rvalue::Len(ref mut place) => return self.simplify_len(place, location),
@@ -931,6 +939,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             ProjectionElem::Downcast(symbol, idx) => ProjectionElem::Downcast(symbol, idx),
             ProjectionElem::OpaqueCast(idx) => ProjectionElem::OpaqueCast(idx),
             ProjectionElem::Subtype(idx) => ProjectionElem::Subtype(idx),
+            ProjectionElem::UnwrapUnsafeBinder(ty) => ProjectionElem::UnwrapUnsafeBinder(ty),
         })
     }
 
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 95aeccfdda6..f8b0688dfdc 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -4,7 +4,7 @@ use std::iter;
 use std::ops::{Range, RangeFrom};
 
 use rustc_abi::{ExternAbi, FieldIdx};
-use rustc_attr_parsing::InlineAttr;
+use rustc_attr_parsing::{InlineAttr, OptimizeAttr};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_index::Idx;
@@ -770,6 +770,10 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>(
         return Err("never inline attribute");
     }
 
+    if let OptimizeAttr::DoNotOptimize = callee_attrs.optimize {
+        return Err("has DoNotOptimize attribute");
+    }
+
     // Reachability pass defines which functions are eligible for inlining. Generally inlining
     // other functions is incorrect because they could reference symbols that aren't exported.
     let is_generic = callsite.callee.args.non_erasable_generics().next().is_some();
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index f4ac5c6aa80..e43254ba089 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -444,7 +444,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             | Rvalue::Cast(..)
             | Rvalue::ShallowInitBox(..)
             | Rvalue::Discriminant(..)
-            | Rvalue::NullaryOp(..) => {}
+            | Rvalue::NullaryOp(..)
+            | Rvalue::WrapUnsafeBinder(..) => {}
         }
 
         // FIXME we need to revisit this for #67176
@@ -546,7 +547,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         let val: Value<'_> = match *rvalue {
             ThreadLocalRef(_) => return None,
 
-            Use(ref operand) => self.eval_operand(operand)?.into(),
+            Use(ref operand) | WrapUnsafeBinder(ref operand, _) => {
+                self.eval_operand(operand)?.into()
+            }
 
             CopyForDeref(place) => self.eval_place(place)?.into(),
 
@@ -626,6 +629,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         .offset_of_subfield(self.typing_env, op_layout, fields.iter())
                         .bytes(),
                     NullOp::UbChecks => return None,
+                    NullOp::ContractChecks => return None,
                 };
                 ImmTy::from_scalar(Scalar::from_target_usize(val, self), layout).into()
             }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 4af9a111bdf..b572f6ca0b3 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -421,11 +421,11 @@ fn mir_promoted(
     };
 
     // the `has_ffi_unwind_calls` query uses the raw mir, so make sure it is run.
-    tcx.ensure_with_value().has_ffi_unwind_calls(def);
+    tcx.ensure_done().has_ffi_unwind_calls(def);
 
     // the `by_move_body` query uses the raw mir, so make sure it is run.
     if tcx.needs_coroutine_by_move_body_def_id(def.to_def_id()) {
-        tcx.ensure_with_value().coroutine_by_move_body_def_id(def);
+        tcx.ensure_done().coroutine_by_move_body_def_id(def);
     }
 
     let mut body = tcx.mir_built(def).steal();
@@ -488,7 +488,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
 /// end up missing the source MIR due to stealing happening.
 fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
     if tcx.is_coroutine(def.to_def_id()) {
-        tcx.ensure_with_value().mir_coroutine_witnesses(def);
+        tcx.ensure_done().mir_coroutine_witnesses(def);
     }
 
     // We only need to borrowck non-synthetic MIR.
@@ -501,7 +501,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
         if pm::should_run_pass(tcx, &inline::Inline, pm::Optimizations::Allowed)
             || inline::ForceInline::should_run_pass_for_callee(tcx, def.to_def_id())
         {
-            tcx.ensure_with_value().mir_inliner_callees(ty::InstanceKind::Item(def.to_def_id()));
+            tcx.ensure_done().mir_inliner_callees(ty::InstanceKind::Item(def.to_def_id()));
         }
     }
 
@@ -733,7 +733,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
         // Run the `mir_for_ctfe` query, which depends on `mir_drops_elaborated_and_const_checked`
         // which we are going to steal below. Thus we need to run `mir_for_ctfe` first, so it
         // computes and caches its result.
-        Some(hir::ConstContext::ConstFn) => tcx.ensure_with_value().mir_for_ctfe(did),
+        Some(hir::ConstContext::ConstFn) => tcx.ensure_done().mir_for_ctfe(did),
         None => {}
         Some(other) => panic!("do not use `optimized_mir` for constants: {other:?}"),
     }
@@ -772,7 +772,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_
     }
 
     if !tcx.is_synthetic_mir(def) {
-        tcx.ensure_with_value().mir_borrowck(def);
+        tcx.ensure_done().mir_borrowck(def);
     }
     let mut promoted = tcx.mir_promoted(def).1.steal();
 
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index 9a9f66ed4fd..9c21bcfc0d2 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -34,6 +34,17 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                         });
                         terminator.kind = TerminatorKind::Goto { target };
                     }
+                    sym::contract_checks => {
+                        let target = target.unwrap();
+                        block.statements.push(Statement {
+                            source_info: terminator.source_info,
+                            kind: StatementKind::Assign(Box::new((
+                                *destination,
+                                Rvalue::NullaryOp(NullOp::ContractChecks, tcx.types.bool),
+                            ))),
+                        });
+                        terminator.kind = TerminatorKind::Goto { target };
+                    }
                     sym::forget => {
                         let target = target.unwrap();
                         block.statements.push(Statement {
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index 6aa3343bb6e..4dbbcae1756 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -293,7 +293,8 @@ impl<'tcx> Validator<'_, 'tcx> {
             // Recurse directly.
             ProjectionElem::ConstantIndex { .. }
             | ProjectionElem::Subtype(_)
-            | ProjectionElem::Subslice { .. } => {}
+            | ProjectionElem::Subslice { .. }
+            | ProjectionElem::UnwrapUnsafeBinder(_) => {}
 
             // Never recurse.
             ProjectionElem::OpaqueCast(..) | ProjectionElem::Downcast(..) => {
@@ -426,7 +427,9 @@ impl<'tcx> Validator<'_, 'tcx> {
 
     fn validate_rvalue(&mut self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> {
         match rvalue {
-            Rvalue::Use(operand) | Rvalue::Repeat(operand, _) => {
+            Rvalue::Use(operand)
+            | Rvalue::Repeat(operand, _)
+            | Rvalue::WrapUnsafeBinder(operand, _) => {
                 self.validate_operand(operand)?;
             }
             Rvalue::CopyForDeref(place) => {
@@ -454,6 +457,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                 NullOp::AlignOf => {}
                 NullOp::OffsetOf(_) => {}
                 NullOp::UbChecks => {}
+                NullOp::ContractChecks => {}
             },
 
             Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable),
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 5881264cba5..b7a3770fc6b 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -807,6 +807,25 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     )
                 }
             }
+            ProjectionElem::UnwrapUnsafeBinder(unwrapped_ty) => {
+                let binder_ty = place_ref.ty(&self.body.local_decls, self.tcx);
+                let ty::UnsafeBinder(binder_ty) = *binder_ty.ty.kind() else {
+                    self.fail(
+                        location,
+                        format!("WrapUnsafeBinder does not produce a ty::UnsafeBinder"),
+                    );
+                    return;
+                };
+                let binder_inner_ty = self.tcx.instantiate_bound_regions_with_erased(*binder_ty);
+                if !self.mir_assign_valid_types(unwrapped_ty, binder_inner_ty) {
+                    self.fail(
+                        location,
+                        format!(
+                            "Cannot unwrap unsafe binder {binder_ty:?} into type {unwrapped_ty:?}"
+                        ),
+                    );
+                }
+            }
             _ => {}
         }
         self.super_projection_elem(place_ref, elem, context, location);
@@ -1360,8 +1379,29 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             Rvalue::Repeat(_, _)
             | Rvalue::ThreadLocalRef(_)
             | Rvalue::RawPtr(_, _)
-            | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::UbChecks, _)
+            | Rvalue::NullaryOp(
+                NullOp::SizeOf | NullOp::AlignOf | NullOp::UbChecks | NullOp::ContractChecks,
+                _,
+            )
             | Rvalue::Discriminant(_) => {}
+
+            Rvalue::WrapUnsafeBinder(op, ty) => {
+                let unwrapped_ty = op.ty(self.body, self.tcx);
+                let ty::UnsafeBinder(binder_ty) = *ty.kind() else {
+                    self.fail(
+                        location,
+                        format!("WrapUnsafeBinder does not produce a ty::UnsafeBinder"),
+                    );
+                    return;
+                };
+                let binder_inner_ty = self.tcx.instantiate_bound_regions_with_erased(*binder_ty);
+                if !self.mir_assign_valid_types(unwrapped_ty, binder_inner_ty) {
+                    self.fail(
+                        location,
+                        format!("Cannot wrap {unwrapped_ty:?} into unsafe binder {binder_ty:?}"),
+                    );
+                }
+            }
         }
         self.super_rvalue(rvalue, location);
     }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 246faed50e3..ae31ed59391 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -953,7 +953,7 @@ fn visit_instance_use<'tcx>(
 
 /// 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.
-fn should_codegen_locally<'tcx>(tcx: TyCtxtAt<'tcx>, instance: Instance<'tcx>) -> bool {
+fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool {
     let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else {
         return true;
     };
@@ -976,7 +976,7 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxtAt<'tcx>, instance: Instance<'tcx>) -
         return true;
     }
 
-    if tcx.is_reachable_non_generic(def_id) || instance.upstream_monomorphization(*tcx).is_some() {
+    if tcx.is_reachable_non_generic(def_id) || instance.upstream_monomorphization(tcx).is_some() {
         // We can link to the item in question, no instance needed in this crate.
         return false;
     }
@@ -1222,7 +1222,7 @@ fn collect_items_of_instance<'tcx>(
     mode: CollectionMode,
 ) -> (MonoItems<'tcx>, MonoItems<'tcx>) {
     // This item is getting monomorphized, do mono-time checks.
-    tcx.ensure().check_mono_item(instance);
+    tcx.ensure_ok().check_mono_item(instance);
 
     let body = tcx.instance_mir(instance.def);
     // Naively, in "used" collection mode, all functions get added to *both* `used_items` and
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index c985ea04278..3ef061195da 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -1179,23 +1179,23 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio
         }
     }
 
+    #[cfg(not(llvm_enzyme))]
+    let autodiff_mono_items: Vec<_> = vec![];
+    #[cfg(llvm_enzyme)]
+    let mut autodiff_mono_items: Vec<_> = vec![];
     let mono_items: DefIdSet = items
         .iter()
         .filter_map(|mono_item| match *mono_item {
-            MonoItem::Fn(ref instance) => Some(instance.def_id()),
+            MonoItem::Fn(ref instance) => {
+                #[cfg(llvm_enzyme)]
+                autodiff_mono_items.push((mono_item, instance));
+                Some(instance.def_id())
+            }
             MonoItem::Static(def_id) => Some(def_id),
             _ => None,
         })
         .collect();
 
-    let autodiff_mono_items: Vec<_> = items
-        .iter()
-        .filter_map(|item| match *item {
-            MonoItem::Fn(ref instance) => Some((item, instance)),
-            _ => None,
-        })
-        .collect();
-
     let autodiff_items =
         autodiff::find_autodiff_source_functions(tcx, &usage_map, autodiff_mono_items);
     let autodiff_items = tcx.arena.alloc_from_iter(autodiff_items);
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index b1b84b0b701..86816819be2 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -4,7 +4,7 @@ use rustc_ast::{
     WhereClause, token,
 };
 use rustc_errors::{Applicability, PResult};
-use rustc_span::{Ident, Span, kw};
+use rustc_span::{Ident, Span, kw, sym};
 use thin_vec::ThinVec;
 
 use super::{ForceCollect, Parser, Trailing, UsePreAttrPos};
@@ -297,6 +297,42 @@ impl<'a> Parser<'a> {
         })
     }
 
+    /// Parses an experimental fn contract
+    /// (`contract_requires(WWW) contract_ensures(ZZZ)`)
+    pub(super) fn parse_contract(
+        &mut self,
+    ) -> PResult<'a, Option<rustc_ast::ptr::P<ast::FnContract>>> {
+        let gate = |span| {
+            if self.psess.contract_attribute_spans.contains(span) {
+                // span was generated via a builtin contracts attribute, so gate as end-user visible
+                self.psess.gated_spans.gate(sym::contracts, span);
+            } else {
+                // span was not generated via a builtin contracts attribute, so gate as internal machinery
+                self.psess.gated_spans.gate(sym::contracts_internals, span);
+            }
+        };
+
+        let requires = if self.eat_keyword_noexpect(exp!(ContractRequires).kw) {
+            let precond = self.parse_expr()?;
+            gate(precond.span);
+            Some(precond)
+        } else {
+            None
+        };
+        let ensures = if self.eat_keyword_noexpect(exp!(ContractEnsures).kw) {
+            let postcond = self.parse_expr()?;
+            gate(postcond.span);
+            Some(postcond)
+        } else {
+            None
+        };
+        if requires.is_none() && ensures.is_none() {
+            Ok(None)
+        } else {
+            Ok(Some(rustc_ast::ptr::P(ast::FnContract { requires, ensures })))
+        }
+    }
+
     /// Parses an optional where-clause.
     ///
     /// ```ignore (only-for-syntax-highlight)
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index f3e56be9f6e..dbdc31f06a2 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -213,9 +213,12 @@ impl<'a> Parser<'a> {
             self.parse_use_item()?
         } else if self.check_fn_front_matter(check_pub, case) {
             // FUNCTION ITEM
-            let (ident, sig, generics, body) =
+            let (ident, sig, generics, contract, body) =
                 self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;
-            (ident, ItemKind::Fn(Box::new(Fn { defaultness: def_(), sig, generics, body })))
+            (
+                ident,
+                ItemKind::Fn(Box::new(Fn { defaultness: def_(), sig, generics, contract, body })),
+            )
         } else if self.eat_keyword(exp!(Extern)) {
             if self.eat_keyword(exp!(Crate)) {
                 // EXTERN CRATE
@@ -2372,7 +2375,7 @@ impl<'a> Parser<'a> {
         sig_lo: Span,
         vis: &Visibility,
         case: Case,
-    ) -> PResult<'a, (Ident, FnSig, Generics, Option<P<Block>>)> {
+    ) -> PResult<'a, (Ident, FnSig, Generics, Option<P<FnContract>>, Option<P<Block>>)> {
         let fn_span = self.token.span;
         let header = self.parse_fn_front_matter(vis, case)?; // `const ... fn`
         let ident = self.parse_ident()?; // `foo`
@@ -2398,6 +2401,8 @@ impl<'a> Parser<'a> {
         // inside `parse_fn_body()`.
         let fn_params_end = self.prev_token.span.shrink_to_hi();
 
+        let contract = self.parse_contract()?;
+
         generics.where_clause = self.parse_where_clause()?; // `where T: Ord`
 
         // `fn_params_end` is needed only when it's followed by a where clause.
@@ -2409,7 +2414,7 @@ impl<'a> Parser<'a> {
         let body =
             self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?;
         let fn_sig_span = sig_lo.to(sig_hi);
-        Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, body))
+        Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body))
     }
 
     /// Provide diagnostics when function body is not found
diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs
index 73f3ac001c8..40631d9154d 100644
--- a/compiler/rustc_parse/src/parser/token_type.rs
+++ b/compiler/rustc_parse/src/parser/token_type.rs
@@ -83,6 +83,8 @@ pub enum TokenType {
     KwCatch,
     KwConst,
     KwContinue,
+    KwContractEnsures,
+    KwContractRequires,
     KwCrate,
     KwDefault,
     KwDyn,
@@ -217,6 +219,8 @@ impl TokenType {
             KwCatch,
             KwConst,
             KwContinue,
+            KwContractEnsures,
+            KwContractRequires,
             KwCrate,
             KwDefault,
             KwDyn,
@@ -289,6 +293,8 @@ impl TokenType {
             TokenType::KwCatch => Some(kw::Catch),
             TokenType::KwConst => Some(kw::Const),
             TokenType::KwContinue => Some(kw::Continue),
+            TokenType::KwContractEnsures => Some(kw::ContractEnsures),
+            TokenType::KwContractRequires => Some(kw::ContractRequires),
             TokenType::KwCrate => Some(kw::Crate),
             TokenType::KwDefault => Some(kw::Default),
             TokenType::KwDyn => Some(kw::Dyn),
@@ -519,6 +525,8 @@ macro_rules! exp {
     (Catch)          => { exp!(@kw, Catch,      KwCatch) };
     (Const)          => { exp!(@kw, Const,      KwConst) };
     (Continue)       => { exp!(@kw, Continue,   KwContinue) };
+    (ContractEnsures)  => { exp!(@kw, ContractEnsures, KwContractEnsures) };
+    (ContractRequires) => { exp!(@kw, ContractRequires, KwContractRequires) };
     (Crate)          => { exp!(@kw, Crate,      KwCrate) };
     (Default)        => { exp!(@kw, Default,    KwDefault) };
     (Dyn)            => { exp!(@kw, Dyn,        KwDyn) };
diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs
index f6b70d9389b..74038b24dcc 100644
--- a/compiler/rustc_passes/src/hir_id_validator.rs
+++ b/compiler/rustc_passes/src/hir_id_validator.rs
@@ -162,7 +162,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
         inner_visitor.check(i.owner_id, |this| intravisit::walk_impl_item(this, i));
     }
 
-    fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
-        self.visit_pat(p)
+    fn visit_pattern_type_pattern(&mut self, p: &'hir hir::TyPat<'hir>) {
+        intravisit::walk_ty_pat(self, p)
     }
 }
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index a52f080038d..34f1ca55c78 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -5,8 +5,8 @@ use std::mem::replace;
 use std::num::NonZero;
 
 use rustc_attr_parsing::{
-    self as attr, AllowedThroughUnstableModules, ConstStability, DeprecatedSince, Stability,
-    StabilityLevel, StableSince, UnstableReason, VERSION_PLACEHOLDER,
+    self as attr, ConstStability, DeprecatedSince, Stability, StabilityLevel, StableSince,
+    UnstableReason, VERSION_PLACEHOLDER,
 };
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
@@ -880,7 +880,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
 
             if item_is_allowed {
                 // The item itself is allowed; check whether the path there is also allowed.
-                let is_allowed_through_unstable_modules: Option<AllowedThroughUnstableModules> =
+                let is_allowed_through_unstable_modules: Option<Symbol> =
                     self.tcx.lookup_stability(def_id).and_then(|stab| match stab.level {
                         StabilityLevel::Stable { allowed_through_unstable_modules, .. } => {
                             allowed_through_unstable_modules
@@ -888,83 +888,79 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                         _ => None,
                     });
 
-                if is_allowed_through_unstable_modules.is_none() {
-                    // Check parent modules stability as well if the item the path refers to is itself
-                    // stable. We only emit warnings for unstable path segments if the item is stable
-                    // or allowed because stability is often inherited, so the most common case is that
-                    // both the segments and the item are unstable behind the same feature flag.
-                    //
-                    // We check here rather than in `visit_path_segment` to prevent visiting the last
-                    // path segment twice
-                    //
-                    // We include special cases via #[rustc_allowed_through_unstable_modules] for items
-                    // that were accidentally stabilized through unstable paths before this check was
-                    // added, such as `core::intrinsics::transmute`
-                    let parents = path.segments.iter().rev().skip(1);
-                    for path_segment in parents {
-                        if let Some(def_id) = path_segment.res.opt_def_id() {
-                            // use `None` for id to prevent deprecation check
-                            self.tcx.check_stability_allow_unstable(
-                                def_id,
-                                None,
-                                path.span,
-                                None,
-                                if is_unstable_reexport(self.tcx, id) {
-                                    AllowUnstable::Yes
-                                } else {
-                                    AllowUnstable::No
-                                },
-                            );
-                        }
-                    }
-                } else if let Some(AllowedThroughUnstableModules::WithDeprecation(deprecation)) =
-                    is_allowed_through_unstable_modules
-                {
-                    // Similar to above, but we cannot use `check_stability_allow_unstable` as that would
-                    // immediately show the stability error. We just want to know the result and disaplay
-                    // our own kind of error.
-                    let parents = path.segments.iter().rev().skip(1);
-                    for path_segment in parents {
-                        if let Some(def_id) = path_segment.res.opt_def_id() {
-                            // use `None` for id to prevent deprecation check
-                            let eval_result = self.tcx.eval_stability_allow_unstable(
-                                def_id,
-                                None,
-                                path.span,
-                                None,
-                                if is_unstable_reexport(self.tcx, id) {
-                                    AllowUnstable::Yes
-                                } else {
-                                    AllowUnstable::No
-                                },
-                            );
-                            let is_allowed = matches!(eval_result, EvalResult::Allow);
-                            if !is_allowed {
-                                // Calculating message for lint involves calling `self.def_path_str`,
-                                // which will by default invoke the expensive `visible_parent_map` query.
-                                // Skip all that work if the lint is allowed anyway.
-                                if self.tcx.lint_level_at_node(DEPRECATED, id).0
-                                    == lint::Level::Allow
-                                {
-                                    return;
-                                }
-                                // Show a deprecation message.
-                                let def_path =
-                                    with_no_trimmed_paths!(self.tcx.def_path_str(def_id));
-                                let def_kind = self.tcx.def_descr(def_id);
-                                let diag = Deprecated {
-                                    sub: None,
-                                    kind: def_kind.to_owned(),
-                                    path: def_path,
-                                    note: Some(deprecation),
-                                    since_kind: lint::DeprecatedSinceKind::InEffect,
-                                };
-                                self.tcx.emit_node_span_lint(
-                                    DEPRECATED,
-                                    id,
-                                    method_span.unwrap_or(path.span),
-                                    diag,
+                // Check parent modules stability as well if the item the path refers to is itself
+                // stable. We only emit errors for unstable path segments if the item is stable
+                // or allowed because stability is often inherited, so the most common case is that
+                // both the segments and the item are unstable behind the same feature flag.
+                //
+                // We check here rather than in `visit_path_segment` to prevent visiting the last
+                // path segment twice
+                //
+                // We include special cases via #[rustc_allowed_through_unstable_modules] for items
+                // that were accidentally stabilized through unstable paths before this check was
+                // added, such as `core::intrinsics::transmute`
+                let parents = path.segments.iter().rev().skip(1);
+                for path_segment in parents {
+                    if let Some(def_id) = path_segment.res.opt_def_id() {
+                        match is_allowed_through_unstable_modules {
+                            None => {
+                                // Emit a hard stability error if this path is not stable.
+
+                                // use `None` for id to prevent deprecation check
+                                self.tcx.check_stability_allow_unstable(
+                                    def_id,
+                                    None,
+                                    path.span,
+                                    None,
+                                    if is_unstable_reexport(self.tcx, id) {
+                                        AllowUnstable::Yes
+                                    } else {
+                                        AllowUnstable::No
+                                    },
+                                );
+                            }
+                            Some(deprecation) => {
+                                // Call the stability check directly so that we can control which
+                                // diagnostic is emitted.
+                                let eval_result = self.tcx.eval_stability_allow_unstable(
+                                    def_id,
+                                    None,
+                                    path.span,
+                                    None,
+                                    if is_unstable_reexport(self.tcx, id) {
+                                        AllowUnstable::Yes
+                                    } else {
+                                        AllowUnstable::No
+                                    },
                                 );
+                                let is_allowed = matches!(eval_result, EvalResult::Allow);
+                                if !is_allowed {
+                                    // Calculating message for lint involves calling `self.def_path_str`,
+                                    // which will by default invoke the expensive `visible_parent_map` query.
+                                    // Skip all that work if the lint is allowed anyway.
+                                    if self.tcx.lint_level_at_node(DEPRECATED, id).0
+                                        == lint::Level::Allow
+                                    {
+                                        return;
+                                    }
+                                    // Show a deprecation message.
+                                    let def_path =
+                                        with_no_trimmed_paths!(self.tcx.def_path_str(def_id));
+                                    let def_kind = self.tcx.def_descr(def_id);
+                                    let diag = Deprecated {
+                                        sub: None,
+                                        kind: def_kind.to_owned(),
+                                        path: def_path,
+                                        note: Some(deprecation),
+                                        since_kind: lint::DeprecatedSinceKind::InEffect,
+                                    };
+                                    self.tcx.emit_node_span_lint(
+                                        DEPRECATED,
+                                        id,
+                                        method_span.unwrap_or(path.span),
+                                        diag,
+                                    );
+                                }
                             }
                         }
                     }
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index d19df08519d..3842b7035e5 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -24,7 +24,7 @@ use rustc_ast::MacroDef;
 use rustc_ast::visit::{VisitorResult, try_visit};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::intern::Interned;
-use rustc_errors::MultiSpan;
+use rustc_errors::{MultiSpan, listify};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::{self, InferKind, Visitor};
@@ -958,29 +958,15 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
         //    |         ^^ field `gamma` is private  # `fields.2` is `false`
 
         // Get the list of all private fields for the main message.
-        let field_names: Vec<_> = fields.iter().map(|(name, _, _)| name).collect();
-        let field_names = match &field_names[..] {
-            [] => return,
-            [name] => format!("`{name}`"),
-            [fields @ .., last] => format!(
-                "{} and `{last}`",
-                fields.iter().map(|f| format!("`{f}`")).collect::<Vec<_>>().join(", "),
-            ),
-        };
+        let Some(field_names) = listify(&fields[..], |(n, _, _)| format!("`{n}`")) else { return };
         let span: MultiSpan = fields.iter().map(|(_, span, _)| *span).collect::<Vec<Span>>().into();
 
         // Get the list of all private fields when pointing at the `..rest`.
         let rest_field_names: Vec<_> =
             fields.iter().filter(|(_, _, is_present)| !is_present).map(|(n, _, _)| n).collect();
         let rest_len = rest_field_names.len();
-        let rest_field_names = match &rest_field_names[..] {
-            [] => String::new(),
-            [name] => format!("`{name}`"),
-            [fields @ .., last] => format!(
-                "{} and `{last}`",
-                fields.iter().map(|f| format!("`{f}`")).collect::<Vec<_>>().join(", "),
-            ),
-        };
+        let rest_field_names =
+            listify(&rest_field_names[..], |n| format!("`{n}`")).unwrap_or_default();
         // Get all the labels for each field or `..rest` in the primary MultiSpan.
         let labels = fields
             .iter()
@@ -1005,7 +991,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
             } else {
                 None
             },
-            field_names: field_names.clone(),
+            field_names,
             variant_descr: def.variant_descr(),
             def_path_str: self.tcx.def_path_str(def.did()),
             labels,
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index d2bb0b3f277..bbc83cca99d 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -224,7 +224,6 @@ pub fn query_system<'a>(
 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);
+    providers.hooks.alloc_self_profile_query_strings = alloc_self_profile_query_strings;
+    providers.hooks.query_key_hash_verify_all = query_key_hash_verify_all;
 }
diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
index 2902d17d687..9d3368607a2 100644
--- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
@@ -1,19 +1,20 @@
-//! This module defines the `DepNode` type which the compiler uses to represent
-//! nodes in the dependency graph. A `DepNode` consists of a `DepKind` (which
-//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc)
-//! and a `Fingerprint`, a 128 bit hash value the exact meaning of which
+//! This module defines the [`DepNode`] type which the compiler uses to represent
+//! nodes in the [dependency graph]. A `DepNode` consists of a [`DepKind`] (which
+//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
+//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which
 //! depends on the node's `DepKind`. Together, the kind and the fingerprint
 //! fully identify a dependency node, even across multiple compilation sessions.
 //! In other words, the value of the fingerprint does not depend on anything
 //! that is specific to a given compilation session, like an unpredictable
-//! interning key (e.g., NodeId, DefId, Symbol) or the numeric value of a
+//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a
 //! pointer. The concept behind this could be compared to how git commit hashes
-//! uniquely identify a given commit and has a few advantages:
+//! uniquely identify a given commit. The fingerprinting approach has
+//! a few advantages:
 //!
 //! * A `DepNode` can simply be serialized to disk and loaded in another session
-//!   without the need to do any "rebasing (like we have to do for Spans and
-//!   NodeIds) or "retracing" like we had to do for `DefId` in earlier
-//!   implementations of the dependency graph.
+//!   without the need to do any "rebasing" (like we have to do for Spans and
+//!   NodeIds) or "retracing" (like we had to do for `DefId` in earlier
+//!   implementations of the dependency graph).
 //! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
 //!   implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
 //! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
@@ -26,10 +27,12 @@
 //!   could not be instantiated because the current compilation session
 //!   contained no `DefId` for thing that had been removed.
 //!
-//! `DepNode` definition happens in `rustc_middle` with the `define_dep_nodes!()` macro.
-//! This macro defines the `DepKind` enum and a corresponding `DepConstructor` enum. The
-//! `DepConstructor` enum links a `DepKind` to the parameters that are needed at runtime in order
-//! to construct a valid `DepNode` fingerprint.
+//! `DepNode` definition happens in `rustc_middle` with the
+//! `define_dep_nodes!()` macro. This macro defines the `DepKind` enum. Each
+//! `DepKind` has its own parameters that are needed at runtime in order to
+//! construct a valid `DepNode` fingerprint. However, only `CompileCodegenUnit`
+//! and `CompileMonoItem` are constructed explicitly (with
+//! `make_compile_codegen_unit` and `make_compile_mono_item`).
 //!
 //! Because the macro sees what parameters a given `DepKind` requires, it can
 //! "infer" some properties for each kind of `DepNode`:
@@ -41,6 +44,16 @@
 //!   in which case it is possible to map the node's fingerprint back to the
 //!   `DefId` it was computed from. In other cases, too much information gets
 //!   lost during fingerprint computation.
+//!
+//! `make_compile_codegen_unit` and `make_compile_mono_items`, together with
+//! `DepNode::new()`, ensure that only valid `DepNode` instances can be
+//! constructed. For example, the API does not allow for constructing
+//! parameterless `DepNode`s with anything other than a zeroed out fingerprint.
+//! More generally speaking, it relieves the user of the `DepNode` API of
+//! having to know how to compute the expected fingerprint for a given set of
+//! node parameters.
+//!
+//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
 
 use std::fmt;
 use std::hash::Hash;
diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs
index e6f3d97742d..e11123dff26 100644
--- a/compiler/rustc_query_system/src/query/caches.rs
+++ b/compiler/rustc_query_system/src/query/caches.rs
@@ -11,18 +11,30 @@ use rustc_span::def_id::{DefId, DefIndex};
 
 use crate::dep_graph::DepNodeIndex;
 
+/// Trait for types that serve as an in-memory cache for query results,
+/// for a given key (argument) type and value (return) type.
+///
+/// Types implementing this trait are associated with actual key/value types
+/// by the `Cache` associated type of the `rustc_middle::query::Key` trait.
 pub trait QueryCache: Sized {
     type Key: Hash + Eq + Copy + Debug;
     type Value: Copy;
 
-    /// Checks if the query is already computed and in the cache.
+    /// Returns the cached value (and other information) associated with the
+    /// given key, if it is present in the cache.
     fn lookup(&self, key: &Self::Key) -> Option<(Self::Value, DepNodeIndex)>;
 
+    /// Adds a key/value entry to this cache.
+    ///
+    /// Called by some part of the query system, after having obtained the
+    /// value by executing the query or loading a cached value from disk.
     fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex);
 
     fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex));
 }
 
+/// In-memory cache for queries whose keys aren't suitable for any of the
+/// more specialized kinds of cache. Backed by a sharded hashmap.
 pub struct DefaultCache<K, V> {
     cache: Sharded<FxHashMap<K, (V, DepNodeIndex)>>,
 }
@@ -67,6 +79,8 @@ where
     }
 }
 
+/// In-memory cache for queries whose key type only has one value (e.g. `()`).
+/// The cache therefore only needs to store one query return value.
 pub struct SingleCache<V> {
     cache: OnceLock<(V, DepNodeIndex)>,
 }
@@ -101,6 +115,10 @@ where
     }
 }
 
+/// In-memory cache for queries whose key is a [`DefId`].
+///
+/// Selects between one of two internal caches, depending on whether the key
+/// is a local ID or foreign-crate ID.
 pub struct DefIdCache<V> {
     /// Stores the local DefIds in a dense map. Local queries are much more often dense, so this is
     /// a win over hashing query keys at marginal memory cost (~5% at most) compared to FxHashMap.
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 6fb5e37d2d0..18aae8c00b2 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -222,10 +222,10 @@ pub struct CycleError {
     pub cycle: Vec<QueryInfo>,
 }
 
-/// Checks if the query is already computed and in the cache.
-/// It returns the shard index and a lock guard to the shard,
-/// which will be used if the query is not in the cache and we need
-/// to compute it.
+/// Checks whether there is already a value for this key in the in-memory
+/// query cache, returning that value if present.
+///
+/// (Also performs some associated bookkeeping, if a value was found.)
 #[inline(always)]
 pub fn try_get_cached<Tcx, C>(tcx: Tcx, cache: &C, key: &C::Key) -> Option<C::Value>
 where
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 16c0a345f87..db607dbb419 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -174,10 +174,13 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
                 _ctxt,
                 _ident,
                 _vis,
-                Fn { sig: FnSig { header, decl, span: _ }, generics, body, .. },
+                Fn { sig: FnSig { header, decl, span: _ }, generics, contract, body, .. },
             ) if let Some(coroutine_kind) = header.coroutine_kind => {
                 self.visit_fn_header(header);
                 self.visit_generics(generics);
+                if let Some(contract) = contract {
+                    self.visit_contract(contract);
+                }
 
                 // For async functions, we need to create their inner defs inside of a
                 // closure to match their desugared representation. Besides that,
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 4842cbd556c..e37e7e98ee7 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1019,7 +1019,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
             // Create a label rib for the function.
             this.with_label_rib(RibKind::FnOrCoroutine, |this| {
                 match fn_kind {
-                    FnKind::Fn(_, _, _, Fn { sig, generics, body, .. }) => {
+                    FnKind::Fn(_, _, _, Fn { sig, generics, contract, body, .. }) => {
                         this.visit_generics(generics);
 
                         let declaration = &sig.decl;
@@ -1046,6 +1046,10 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
                             },
                         );
 
+                        if let Some(contract) = contract {
+                            this.visit_contract(contract);
+                        }
+
                         if let Some(body) = body {
                             // Ignore errors in function bodies if this is rustdoc
                             // Be sure not to set this until the function signature has been resolved.
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index c8a811985d5..2fb4b27b889 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1224,6 +1224,7 @@ impl Default for Options {
             color: ColorConfig::Auto,
             logical_env: FxIndexMap::default(),
             verbose: false,
+            target_modifiers: BTreeMap::default(),
         }
     }
 }
@@ -1819,7 +1820,7 @@ pub fn parse_error_format(
                 ErrorOutputType::HumanReadable(HumanReadableErrorType::Unicode, color)
             }
             Some(arg) => {
-                early_dcx.abort_if_error_and_set_error_format(ErrorOutputType::HumanReadable(
+                early_dcx.set_error_format(ErrorOutputType::HumanReadable(
                     HumanReadableErrorType::Default,
                     color,
                 ));
@@ -2360,7 +2361,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
 
     let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered);
 
-    early_dcx.abort_if_error_and_set_error_format(error_format);
+    early_dcx.set_error_format(error_format);
 
     let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
         early_dcx.early_fatal("`--diagnostic-width` must be an positive integer");
@@ -2370,14 +2371,16 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
     let crate_types = parse_crate_types_from_list(unparsed_crate_types)
         .unwrap_or_else(|e| early_dcx.early_fatal(e));
 
-    let mut unstable_opts = UnstableOptions::build(early_dcx, matches);
+    let mut target_modifiers = BTreeMap::<OptionsTargetModifiers, String>::new();
+
+    let mut unstable_opts = UnstableOptions::build(early_dcx, matches, &mut target_modifiers);
     let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
 
     check_error_format_stability(early_dcx, &unstable_opts, error_format);
 
     let output_types = parse_output_types(early_dcx, &unstable_opts, matches);
 
-    let mut cg = CodegenOptions::build(early_dcx, matches);
+    let mut cg = CodegenOptions::build(early_dcx, matches, &mut target_modifiers);
     let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
         early_dcx,
         &output_types,
@@ -2648,6 +2651,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
         color,
         logical_env,
         verbose,
+        target_modifiers,
     }
 }
 
@@ -2770,6 +2774,7 @@ pub mod nightly_options {
                         "the option `{}` is only accepted on the nightly compiler",
                         opt.name
                     );
+                    // The non-zero nightly_options_on_stable will force an early_fatal eventually.
                     let _ = early_dcx.early_err(msg);
                 }
                 OptionStability::Stable => {}
diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs
index d586f913335..52920e0372e 100644
--- a/compiler/rustc_session/src/config/cfg.rs
+++ b/compiler/rustc_session/src/config/cfg.rs
@@ -119,6 +119,7 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
             (sym::overflow_checks, None) => disallow(cfg, "-C overflow-checks"),
             (sym::debug_assertions, None) => disallow(cfg, "-C debug-assertions"),
             (sym::ub_checks, None) => disallow(cfg, "-Z ub-checks"),
+            (sym::contract_checks, None) => disallow(cfg, "-Z contract-checks"),
             (sym::sanitize, None | Some(_)) => disallow(cfg, "-Z sanitizer"),
             (
                 sym::sanitizer_cfi_generalize_pointers | sym::sanitizer_cfi_normalize_integers,
@@ -300,6 +301,11 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
     if sess.is_nightly_build() && sess.opts.unstable_opts.emscripten_wasm_eh {
         ins_none!(sym::emscripten_wasm_eh);
     }
+
+    if sess.contract_checks() {
+        ins_none!(sym::contract_checks);
+    }
+
     ret
 }
 
@@ -464,6 +470,7 @@ impl CheckCfg {
         ins!(sym::target_thread_local, no_values);
 
         ins!(sym::ub_checks, no_values);
+        ins!(sym::contract_checks, no_values);
 
         ins!(sym::unix, no_values);
         ins!(sym::windows, no_values);
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index dcf86d1a408..924350b8cbc 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -4,6 +4,9 @@
 #![feature(let_chains)]
 #![feature(map_many_mut)]
 #![feature(rustc_attrs)]
+// To generate CodegenOptionsTargetModifiers and UnstableOptionsTargetModifiers enums
+// with macro_rules, it is necessary to use recursive mechanic ("Incremental TT Munchers").
+#![recursion_limit = "256"]
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index cc86c85f3f0..35819f896c5 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -10,6 +10,7 @@ use rustc_data_structures::profiling::TimePassesFormat;
 use rustc_data_structures::stable_hasher::Hash64;
 use rustc_errors::{ColorConfig, LanguageIdentifier, TerminalUrl};
 use rustc_feature::UnstableFeatures;
+use rustc_macros::{Decodable, Encodable};
 use rustc_span::edition::Edition;
 use rustc_span::{RealFileName, SourceFileHashAlgorithm};
 use rustc_target::spec::{
@@ -59,18 +60,194 @@ macro_rules! hash_substruct {
     };
 }
 
+/// Extended target modifier info.
+/// For example, when external target modifier is '-Zregparm=2':
+/// Target modifier enum value + user value ('2') from external crate
+/// is converted into description: prefix ('Z'), name ('regparm'), tech value ('Some(2)').
+pub struct ExtendedTargetModifierInfo {
+    /// Flag prefix (usually, 'C' for codegen flags or 'Z' for unstable flags)
+    pub prefix: String,
+    /// Flag name
+    pub name: String,
+    /// Flag parsed technical value
+    pub tech_value: String,
+}
+
+/// A recorded -Zopt_name=opt_value (or -Copt_name=opt_value)
+/// which alter the ABI or effectiveness of exploit mitigations.
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable)]
+pub struct TargetModifier {
+    /// Option enum value
+    pub opt: OptionsTargetModifiers,
+    /// User-provided option value (before parsing)
+    pub value_name: String,
+}
+
+impl TargetModifier {
+    pub fn extend(&self) -> ExtendedTargetModifierInfo {
+        self.opt.reparse(&self.value_name)
+    }
+}
+
+fn tmod_push_impl(
+    opt: OptionsTargetModifiers,
+    tmod_vals: &BTreeMap<OptionsTargetModifiers, String>,
+    tmods: &mut Vec<TargetModifier>,
+) {
+    tmods.push(TargetModifier { opt, value_name: tmod_vals.get(&opt).cloned().unwrap_or_default() })
+}
+
+macro_rules! tmod_push {
+    ($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $mods:expr, $tmod_vals:expr) => {
+        tmod_push_impl(
+            OptionsTargetModifiers::$struct_name($tmod_enum_name::$opt_name),
+            $tmod_vals,
+            $mods,
+        );
+    };
+}
+
+macro_rules! gather_tmods {
+    ($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
+        [SUBSTRUCT], [TARGET_MODIFIER]) => {
+        compile_error!("SUBSTRUCT can't be target modifier");
+    };
+    ($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
+        [UNTRACKED], [TARGET_MODIFIER]) => {
+        tmod_push!($struct_name, $tmod_enum_name, $opt_name, $mods, $tmod_vals)
+    };
+    ($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
+        [TRACKED], [TARGET_MODIFIER]) => {
+        tmod_push!($struct_name, $tmod_enum_name, $opt_name, $mods, $tmod_vals)
+    };
+    ($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
+        [TRACKED_NO_CRATE_HASH], [TARGET_MODIFIER]) => {
+        tmod_push!($struct_name, $tmod_enum_name, $opt_name, $mods, $tmod_vals)
+    };
+    ($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
+        [SUBSTRUCT], []) => {
+        $opt_expr.gather_target_modifiers($mods, $tmod_vals);
+    };
+    ($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
+        [UNTRACKED], []) => {{}};
+    ($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
+        [TRACKED], []) => {{}};
+    ($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
+        [TRACKED_NO_CRATE_HASH], []) => {{}};
+}
+
+macro_rules! gather_tmods_top_level {
+    ($_opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [SUBSTRUCT $substruct_enum:ident]) => {
+        $opt_expr.gather_target_modifiers($mods, $tmod_vals);
+    };
+    ($opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [$non_substruct:ident TARGET_MODIFIER]) => {
+        compile_error!("Top level option can't be target modifier");
+    };
+    ($opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [$non_substruct:ident]) => {};
+}
+
+/// Macro for generating OptionsTargetsModifiers top-level enum with impl.
+/// Will generate something like:
+/// ```rust,ignore (illustrative)
+/// pub enum OptionsTargetModifiers {
+///     CodegenOptions(CodegenOptionsTargetModifiers),
+///     UnstableOptions(UnstableOptionsTargetModifiers),
+/// }
+/// impl OptionsTargetModifiers {
+///     pub fn reparse(&self, user_value: &str) -> ExtendedTargetModifierInfo {
+///         match self {
+///             Self::CodegenOptions(v) => v.reparse(user_value),
+///             Self::UnstableOptions(v) => v.reparse(user_value),
+///         }
+///     }
+///     pub fn is_target_modifier(flag_name: &str) -> bool {
+///         CodegenOptionsTargetModifiers::is_target_modifier(flag_name) ||
+///         UnstableOptionsTargetModifiers::is_target_modifier(flag_name)
+///     }
+/// }
+/// ```
+macro_rules! top_level_tmod_enum {
+    ($( {$($optinfo:tt)*} ),* $(,)*) => {
+        top_level_tmod_enum! { @parse {}, (user_value){}; $($($optinfo)*|)* }
+    };
+    // Termination
+    (
+        @parse
+        {$($variant:tt($substruct_enum:tt))*},
+        ($user_value:ident){$($pout:tt)*};
+    ) => {
+        #[allow(non_camel_case_types)]
+        #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, Decodable)]
+        pub enum OptionsTargetModifiers {
+            $($variant($substruct_enum)),*
+        }
+        impl OptionsTargetModifiers {
+            #[allow(unused_variables)]
+            pub fn reparse(&self, $user_value: &str) -> ExtendedTargetModifierInfo {
+                #[allow(unreachable_patterns)]
+                match self {
+                    $($pout)*
+                    _ => panic!("unknown target modifier option: {:?}", *self)
+                }
+            }
+            pub fn is_target_modifier(flag_name: &str) -> bool {
+                $($substruct_enum::is_target_modifier(flag_name))||*
+            }
+        }
+    };
+    // Adding SUBSTRUCT option group into $eout
+    (
+        @parse {$($eout:tt)*}, ($puser_value:ident){$($pout:tt)*};
+            [SUBSTRUCT $substruct_enum:ident $variant:ident] |
+        $($tail:tt)*
+    ) => {
+        top_level_tmod_enum! {
+            @parse
+            {
+                $($eout)*
+                $variant($substruct_enum)
+            },
+            ($puser_value){
+                $($pout)*
+                Self::$variant(v) => v.reparse($puser_value),
+            };
+            $($tail)*
+        }
+    };
+    // Skipping non-target-modifier and non-substruct
+    (
+        @parse {$($eout:tt)*}, ($puser_value:ident){$($pout:tt)*};
+            [$non_substruct:ident] |
+        $($tail:tt)*
+    ) => {
+        top_level_tmod_enum! {
+            @parse
+            {
+                $($eout)*
+            },
+            ($puser_value){
+                $($pout)*
+            };
+            $($tail)*
+        }
+    };
+}
+
 macro_rules! top_level_options {
     ( $( #[$top_level_attr:meta] )* pub struct Options { $(
         $( #[$attr:meta] )*
-        $opt:ident : $t:ty [$dep_tracking_marker:ident],
+        $opt:ident : $t:ty [$dep_tracking_marker:ident $( $tmod:ident $variant:ident )?],
     )* } ) => (
+        top_level_tmod_enum!( {$([$dep_tracking_marker $($tmod $variant),*])|*} );
+
         #[derive(Clone)]
         $( #[$top_level_attr] )*
         pub struct Options {
             $(
                 $( #[$attr] )*
                 pub $opt: $t
-            ),*
+            ),*,
+            pub target_modifiers: BTreeMap<OptionsTargetModifiers, String>,
         }
 
         impl Options {
@@ -98,6 +275,17 @@ macro_rules! top_level_options {
                 })*
                 hasher.finish()
             }
+
+            pub fn gather_target_modifiers(&self) -> Vec<TargetModifier> {
+                let mut mods = Vec::<TargetModifier>::new();
+                $({
+                    gather_tmods_top_level!($opt,
+                        &self.$opt, &mut mods, &self.target_modifiers,
+                        [$dep_tracking_marker $($tmod),*]);
+                })*
+                mods.sort_by(|a, b| a.opt.cmp(&b.opt));
+                mods
+            }
         }
     );
 }
@@ -165,9 +353,9 @@ top_level_options!(
         #[rustc_lint_opt_deny_field_access("should only be used via `Config::hash_untracked_state`")]
         untracked_state_hash: Hash64 [TRACKED_NO_CRATE_HASH],
 
-        unstable_opts: UnstableOptions [SUBSTRUCT],
+        unstable_opts: UnstableOptions [SUBSTRUCT UnstableOptionsTargetModifiers UnstableOptions],
         prints: Vec<PrintRequest> [UNTRACKED],
-        cg: CodegenOptions [SUBSTRUCT],
+        cg: CodegenOptions [SUBSTRUCT CodegenOptionsTargetModifiers CodegenOptions],
         externs: Externs [UNTRACKED],
         crate_name: Option<String> [TRACKED],
         /// Indicates how the compiler should treat unstable features.
@@ -226,6 +414,98 @@ top_level_options!(
     }
 );
 
+macro_rules! tmod_enum_opt {
+    ($struct_name:ident, $tmod_enum_name:ident, $opt:ident, $v:ident) => {
+        Some(OptionsTargetModifiers::$struct_name($tmod_enum_name::$opt))
+    };
+    ($struct_name:ident, $tmod_enum_name:ident, $opt:ident, ) => {
+        None
+    };
+}
+
+macro_rules! tmod_enum {
+    ($tmod_enum_name:ident, $prefix:expr, $( {$($optinfo:tt)*} ),* $(,)*) => {
+        tmod_enum! { $tmod_enum_name, $prefix, @parse {}, (user_value){}; $($($optinfo)*|)* }
+    };
+    // Termination
+    (
+        $tmod_enum_name:ident, $prefix:expr,
+        @parse
+        {$($eout:tt)*},
+        ($user_value:ident){$($pout:tt)*};
+    ) => {
+        #[allow(non_camel_case_types)]
+        #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, Decodable)]
+        pub enum $tmod_enum_name {
+            $($eout),*
+        }
+        impl $tmod_enum_name {
+            #[allow(unused_variables)]
+            pub fn reparse(&self, $user_value: &str) -> ExtendedTargetModifierInfo {
+                #[allow(unreachable_patterns)]
+                match self {
+                    $($pout)*
+                    _ => panic!("unknown target modifier option: {:?}", *self)
+                }
+            }
+            pub fn is_target_modifier(flag_name: &str) -> bool {
+                match flag_name.replace('-', "_").as_str() {
+                    $(stringify!($eout) => true,)*
+                    _ => false,
+                }
+            }
+        }
+    };
+    // Adding target-modifier option into $eout
+    (
+        $tmod_enum_name:ident, $prefix:expr,
+        @parse {$($eout:tt)*}, ($puser_value:ident){$($pout:tt)*};
+            $opt:ident, $parse:ident, $t:ty, [TARGET_MODIFIER] |
+        $($tail:tt)*
+    ) => {
+        tmod_enum! {
+            $tmod_enum_name, $prefix,
+            @parse
+            {
+                $($eout)*
+                $opt
+            },
+            ($puser_value){
+                $($pout)*
+                Self::$opt => {
+                    let mut parsed : $t = Default::default();
+                    parse::$parse(&mut parsed, Some($puser_value));
+                    ExtendedTargetModifierInfo {
+                        prefix: $prefix.to_string(),
+                        name: stringify!($opt).to_string().replace('_', "-"),
+                        tech_value: format!("{:?}", parsed),
+                    }
+                },
+            };
+            $($tail)*
+        }
+    };
+    // Skipping non-target-modifier
+    (
+        $tmod_enum_name:ident, $prefix:expr,
+        @parse {$($eout:tt)*}, ($puser_value:ident){$($pout:tt)*};
+            $opt:ident, $parse:ident, $t:ty, [] |
+        $($tail:tt)*
+    ) => {
+        tmod_enum! {
+            $tmod_enum_name, $prefix,
+            @parse
+            {
+                $($eout)*
+            },
+            ($puser_value){
+                $($pout)*
+            };
+            $($tail)*
+        }
+    };
+}
+
 /// Defines all `CodegenOptions`/`DebuggingOptions` fields and parsers all at once. The goal of this
 /// macro is to define an interface that can be programmatically used by the option parser
 /// to initialize the struct without hardcoding field names all over the place.
@@ -235,11 +515,11 @@ top_level_options!(
 /// generated code to parse an option into its respective field in the struct. There are a few
 /// hand-written parsers for parsing specific types of values in this module.
 macro_rules! options {
-    ($struct_name:ident, $stat:ident, $optmod:ident, $prefix:expr, $outputname:expr,
+    ($struct_name:ident, $tmod_enum_name:ident, $stat:ident, $optmod:ident, $prefix:expr, $outputname:expr,
      $($( #[$attr:meta] )* $opt:ident : $t:ty = (
         $init:expr,
         $parse:ident,
-        [$dep_tracking_marker:ident],
+        [$dep_tracking_marker:ident $( $tmod:ident )?],
         $desc:expr
         $(, deprecated_do_nothing: $dnn:literal )?)
      ),* ,) =>
@@ -248,6 +528,8 @@ macro_rules! options {
     #[rustc_lint_opt_ty]
     pub struct $struct_name { $( $( #[$attr] )* pub $opt: $t),* }
 
+    tmod_enum!( $tmod_enum_name, $prefix, {$($opt, $parse, $t, [$($tmod),*])|*} );
+
     impl Default for $struct_name {
         fn default() -> $struct_name {
             $struct_name { $($opt: $init),* }
@@ -258,8 +540,9 @@ macro_rules! options {
         pub fn build(
             early_dcx: &EarlyDiagCtxt,
             matches: &getopts::Matches,
+            target_modifiers: &mut BTreeMap<OptionsTargetModifiers, String>,
         ) -> $struct_name {
-            build_options(early_dcx, matches, $stat, $prefix, $outputname)
+            build_options(early_dcx, matches, target_modifiers, $stat, $prefix, $outputname)
         }
 
         fn dep_tracking_hash(&self, for_crate_hash: bool, error_format: ErrorOutputType) -> u64 {
@@ -279,11 +562,23 @@ macro_rules! options {
                                         );
             hasher.finish()
         }
+
+        pub fn gather_target_modifiers(
+            &self,
+            _mods: &mut Vec<TargetModifier>,
+            _tmod_vals: &BTreeMap<OptionsTargetModifiers, String>,
+        ) {
+            $({
+                gather_tmods!($struct_name, $tmod_enum_name, $opt, &self.$opt, _mods, _tmod_vals,
+                    [$dep_tracking_marker], [$($tmod),*]);
+            })*
+        }
     }
 
     pub const $stat: OptionDescrs<$struct_name> =
         &[ $( OptionDesc{ name: stringify!($opt), setter: $optmod::$opt,
-            type_desc: desc::$parse, desc: $desc, is_deprecated_and_do_nothing: false $( || $dnn )? } ),* ];
+            type_desc: desc::$parse, desc: $desc, is_deprecated_and_do_nothing: false $( || $dnn )?,
+            tmod: tmod_enum_opt!($struct_name, $tmod_enum_name, $opt, $($tmod),*) } ),* ];
 
     mod $optmod {
     $(
@@ -328,6 +623,7 @@ pub struct OptionDesc<O> {
     // description for option from options table
     desc: &'static str,
     is_deprecated_and_do_nothing: bool,
+    tmod: Option<OptionsTargetModifiers>,
 }
 
 impl<O> OptionDesc<O> {
@@ -344,6 +640,7 @@ impl<O> OptionDesc<O> {
 fn build_options<O: Default>(
     early_dcx: &EarlyDiagCtxt,
     matches: &getopts::Matches,
+    target_modifiers: &mut BTreeMap<OptionsTargetModifiers, String>,
     descrs: OptionDescrs<O>,
     prefix: &str,
     outputname: &str,
@@ -357,7 +654,14 @@ fn build_options<O: Default>(
 
         let option_to_lookup = key.replace('-', "_");
         match descrs.iter().find(|opt_desc| opt_desc.name == option_to_lookup) {
-            Some(OptionDesc { name: _, setter, type_desc, desc, is_deprecated_and_do_nothing }) => {
+            Some(OptionDesc {
+                name: _,
+                setter,
+                type_desc,
+                desc,
+                is_deprecated_and_do_nothing,
+                tmod,
+            }) => {
                 if *is_deprecated_and_do_nothing {
                     // deprecation works for prefixed options only
                     assert!(!prefix.is_empty());
@@ -377,6 +681,11 @@ fn build_options<O: Default>(
                         ),
                     }
                 }
+                if let Some(tmod) = *tmod
+                    && let Some(value) = value
+                {
+                    target_modifiers.insert(tmod, value.to_string());
+                }
             }
             None => early_dcx.early_fatal(format!("unknown {outputname} option: `{key}`")),
         }
@@ -1614,7 +1923,7 @@ pub mod parse {
 }
 
 options! {
-    CodegenOptions, CG_OPTIONS, cgopts, "C", "codegen",
+    CodegenOptions, CodegenOptionsTargetModifiers, CG_OPTIONS, cgopts, "C", "codegen",
 
     // If you add a new option, please update:
     // - compiler/rustc_interface/src/tests.rs
@@ -1745,6 +2054,8 @@ options! {
     target_feature: String = (String::new(), parse_target_feature, [TRACKED],
         "target specific attributes. (`rustc --print target-features` for details). \
         This feature is unsafe."),
+    unsafe_allow_abi_mismatch: Vec<String> = (Vec::new(), parse_comma_list, [UNTRACKED],
+        "Allow incompatible target modifiers in dependency crates (comma separated list)"),
     // tidy-alphabetical-end
 
     // If you add a new option, please update:
@@ -1753,7 +2064,7 @@ options! {
 }
 
 options! {
-    UnstableOptions, Z_OPTIONS, dbopts, "Z", "unstable",
+    UnstableOptions, UnstableOptionsTargetModifiers, Z_OPTIONS, dbopts, "Z", "unstable",
 
     // If you add a new option, please update:
     // - compiler/rustc_interface/src/tests.rs
@@ -1803,6 +2114,8 @@ options! {
         "the backend to use"),
     combine_cgu: bool = (false, parse_bool, [TRACKED],
         "combine CGUs into a single one"),
+    contract_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
+        "emit runtime checks for contract pre- and post-conditions (default: no)"),
     coverage_options: CoverageOptions = (CoverageOptions::default(), parse_coverage_options, [TRACKED],
         "control details of coverage instrumentation"),
     crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
@@ -2098,10 +2411,10 @@ options! {
         "enable queries of the dependency graph for regression testing (default: no)"),
     randomize_layout: bool = (false, parse_bool, [TRACKED],
         "randomize the layout of types (default: no)"),
-    reg_struct_return: bool = (false, parse_bool, [TRACKED],
+    reg_struct_return: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER],
         "On x86-32 targets, it overrides the default ABI to return small structs in registers.
         It is UNSOUND to link together crates that use different values for this flag!"),
-    regparm: Option<u32> = (None, parse_opt_number, [TRACKED],
+    regparm: Option<u32> = (None, parse_opt_number, [TRACKED TARGET_MODIFIER],
         "On x86-32 targets, setting this to N causes the compiler to pass N arguments \
         in registers EAX, EDX, and ECX instead of on the stack for\
         \"C\", \"cdecl\", and \"stdcall\" fn.\
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 90361efed84..abfd3efc611 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -207,6 +207,10 @@ pub struct ParseSess {
     pub config: Cfg,
     pub check_config: CheckCfg,
     pub edition: Edition,
+    /// Places where contract attributes were expanded into unstable AST forms.
+    /// This is used to allowlist those spans (so that we only check them against the feature
+    /// gate for the externally visible interface, and not internal implmentation machinery).
+    pub contract_attribute_spans: AppendOnlyVec<Span>,
     /// Places where raw identifiers were used. This is used to avoid complaining about idents
     /// clashing with keywords in new editions.
     pub raw_identifier_spans: AppendOnlyVec<Span>,
@@ -255,6 +259,7 @@ impl ParseSess {
             config: Cfg::default(),
             check_config: CheckCfg::default(),
             edition: ExpnId::root().expn_data().edition,
+            contract_attribute_spans: Default::default(),
             raw_identifier_spans: Default::default(),
             bad_unicode_identifiers: Lock::new(Default::default()),
             source_map,
@@ -277,14 +282,10 @@ impl ParseSess {
     ) -> Self {
         let fallback_bundle = fallback_fluent_bundle(locale_resources, false);
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let emitter = Box::new(HumanEmitter::new(
-            stderr_destination(ColorConfig::Auto),
-            Lrc::clone(&fallback_bundle),
-        ));
-        let fatal_dcx = DiagCtxt::new(emitter);
+        let fatal_emitter =
+            Box::new(HumanEmitter::new(stderr_destination(ColorConfig::Auto), fallback_bundle));
         let dcx = DiagCtxt::new(Box::new(SilentEmitter {
-            fallback_bundle,
-            fatal_dcx,
+            fatal_emitter,
             fatal_note: Some(fatal_note),
             emit_fatal_diagnostic,
         }))
@@ -341,8 +342,4 @@ impl ParseSess {
     pub fn dcx(&self) -> DiagCtxtHandle<'_> {
         self.dcx.handle()
     }
-
-    pub fn set_dcx(&mut self, dcx: DiagCtxt) {
-        self.dcx = dcx;
-    }
 }
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index c0f5f0d4a9e..c9bb42bdfa1 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -709,6 +709,10 @@ impl Session {
         self.opts.unstable_opts.ub_checks.unwrap_or(self.opts.debug_assertions)
     }
 
+    pub fn contract_checks(&self) -> bool {
+        self.opts.unstable_opts.contract_checks.unwrap_or(false)
+    }
+
     pub fn relocation_model(&self) -> RelocModel {
         self.opts.cg.relocation_model.unwrap_or(self.target.relocation_model)
     }
@@ -1362,12 +1366,6 @@ pub struct EarlyDiagCtxt {
     dcx: DiagCtxt,
 }
 
-impl Default for EarlyDiagCtxt {
-    fn default() -> Self {
-        Self::new(ErrorOutputType::default())
-    }
-}
-
 impl EarlyDiagCtxt {
     pub fn new(output: ErrorOutputType) -> Self {
         let emitter = mk_emitter(output);
@@ -1375,10 +1373,9 @@ impl EarlyDiagCtxt {
     }
 
     /// Swap out the underlying dcx once we acquire the user's preference on error emission
-    /// format. Any errors prior to that will cause an abort and all stashed diagnostics of the
-    /// previous dcx will be emitted.
-    pub fn abort_if_error_and_set_error_format(&mut self, output: ErrorOutputType) {
-        self.dcx.handle().abort_if_errors();
+    /// format. If `early_err` was previously called this will panic.
+    pub fn set_error_format(&mut self, output: ErrorOutputType) {
+        assert!(self.dcx.handle().has_errors().is_none());
 
         let emitter = mk_emitter(output);
         self.dcx = DiagCtxt::new(emitter);
@@ -1398,7 +1395,7 @@ impl EarlyDiagCtxt {
 
     #[allow(rustc::untranslatable_diagnostic)]
     #[allow(rustc::diagnostic_outside_of_impl)]
-    #[must_use = "ErrorGuaranteed must be returned from `run_compiler` in order to exit with a non-zero status code"]
+    #[must_use = "raise_fatal must be called on the returned ErrorGuaranteed in order to exit with a non-zero status code"]
     pub fn early_err(&self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
         self.dcx.handle().err(msg)
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index 150ec02b7db..bdd6e16a7c1 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -217,6 +217,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables))
             }
             CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)),
+            WrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
         }
     }
 }
@@ -290,6 +291,7 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
                 indices.iter().map(|idx| idx.stable(tables)).collect(),
             ),
             UbChecks => stable_mir::mir::NullOp::UbChecks,
+            ContractChecks => stable_mir::mir::NullOp::ContractChecks,
         }
     }
 }
@@ -395,6 +397,7 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
             Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)),
             OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables)),
             Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables)),
+            UnwrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
         }
     }
 }
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index a5826137181..dbbbb5077cb 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1163,6 +1163,8 @@ pub enum DesugaringKind {
     WhileLoop,
     /// `async Fn()` bound modifier
     BoundModifier,
+    /// Calls to contract checks (`#[requires]` to precond, `#[ensures]` to postcond)
+    Contract,
 }
 
 impl DesugaringKind {
@@ -1179,6 +1181,7 @@ impl DesugaringKind {
             DesugaringKind::ForLoop => "`for` loop",
             DesugaringKind::WhileLoop => "`while` loop",
             DesugaringKind::BoundModifier => "trait bound modifier",
+            DesugaringKind::Contract => "contract check",
         }
     }
 }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 51d809bd65d..b1f9f4a01c5 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -600,11 +600,43 @@ impl Span {
         !self.is_dummy() && sm.is_span_accessible(self)
     }
 
+    /// Returns whether `span` originates in a foreign crate's external macro.
+    ///
+    /// This is used to test whether a lint should not even begin to figure out whether it should
+    /// be reported on the current node.
+    pub fn in_external_macro(self, sm: &SourceMap) -> bool {
+        let expn_data = self.ctxt().outer_expn_data();
+        match expn_data.kind {
+            ExpnKind::Root
+            | ExpnKind::Desugaring(
+                DesugaringKind::ForLoop
+                | DesugaringKind::WhileLoop
+                | DesugaringKind::OpaqueTy
+                | DesugaringKind::Async
+                | DesugaringKind::Await,
+            ) => false,
+            ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
+            ExpnKind::Macro(MacroKind::Bang, _) => {
+                // Dummy span for the `def_site` means it's an external macro.
+                expn_data.def_site.is_dummy() || sm.is_imported(expn_data.def_site)
+            }
+            ExpnKind::Macro { .. } => true, // definitely a plugin
+        }
+    }
+
     /// Returns `true` if `span` originates in a derive-macro's expansion.
     pub fn in_derive_expansion(self) -> bool {
         matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _))
     }
 
+    /// Return whether `span` is generated by `async` or `await`.
+    pub fn is_from_async_await(self) -> bool {
+        matches!(
+            self.ctxt().outer_expn_data().kind,
+            ExpnKind::Desugaring(DesugaringKind::Async | DesugaringKind::Await),
+        )
+    }
+
     /// Gate suggestions that would not be appropriate in a context the user didn't write.
     pub fn can_be_used_for_suggestions(self) -> bool {
         !self.from_expansion()
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 7f7b460cf57..c819d433235 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -118,6 +118,8 @@ symbols! {
         MacroRules:         "macro_rules",
         Raw:                "raw",
         Reuse:              "reuse",
+        ContractEnsures:  "contract_ensures",
+        ContractRequires: "contract_requires",
         Safe:               "safe",
         Union:              "union",
         Yeet:               "yeet",
@@ -294,9 +296,12 @@ symbols! {
         ProceduralMasqueradeDummyType,
         Range,
         RangeBounds,
+        RangeCopy,
         RangeFrom,
+        RangeFromCopy,
         RangeFull,
         RangeInclusive,
+        RangeInclusiveCopy,
         RangeTo,
         RangeToInclusive,
         Rc,
@@ -314,8 +319,6 @@ symbols! {
         Right,
         Rust,
         RustaceansAreAwesome,
-        RustcDecodable,
-        RustcEncodable,
         RwLock,
         RwLockReadGuard,
         RwLockWriteGuard,
@@ -568,6 +571,7 @@ symbols! {
         cfg_attr,
         cfg_attr_multi,
         cfg_boolean_literals,
+        cfg_contract_checks,
         cfg_doctest,
         cfg_emscripten_wasm_eh,
         cfg_eval,
@@ -677,6 +681,14 @@ symbols! {
         const_ty_placeholder: "<const_ty>",
         constant,
         constructor,
+        contract_build_check_ensures,
+        contract_check_ensures,
+        contract_check_requires,
+        contract_checks,
+        contracts,
+        contracts_ensures,
+        contracts_internals,
+        contracts_requires,
         convert_identity,
         copy,
         copy_closures,
@@ -776,6 +788,7 @@ symbols! {
         discriminant_kind,
         discriminant_type,
         discriminant_value,
+        disjoint_bitor,
         dispatch_from_dyn,
         div,
         div_assign,
@@ -1150,6 +1163,7 @@ symbols! {
         iterator,
         iterator_collect_fn,
         kcfi,
+        keylocker_x86,
         keyword,
         kind,
         kreg,
@@ -1365,6 +1379,7 @@ symbols! {
         new_lower_hex,
         new_octal,
         new_pointer,
+        new_range,
         new_unchecked,
         new_upper_exp,
         new_upper_hex,
@@ -2152,7 +2167,6 @@ symbols! {
         unwrap,
         unwrap_binder,
         unwrap_or,
-        unwrap_unsafe_binder,
         use_extern_macros,
         use_nested_groups,
         used,
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 7b040a8b2c4..0ac6f17b97b 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -649,7 +649,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                 // HACK(jaic1): hide the `str` type behind a reference
                 // for the following transformation from valtree to raw bytes
                 let ref_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, ct_ty);
-                let slice = valtree.try_to_raw_bytes(tcx, ref_ty).unwrap_or_else(|| {
+                let cv = ty::Value { ty: ref_ty, valtree };
+                let slice = cv.try_to_raw_bytes(tcx).unwrap_or_else(|| {
                     bug!("expected to get raw bytes from valtree {:?} for type {:}", valtree, ct_ty)
                 });
                 let s = std::str::from_utf8(slice).expect("non utf8 str from MIR interpreter");
diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs
index 015ea97f2ac..a6b0ec072e8 100644
--- a/compiler/rustc_target/src/spec/json.rs
+++ b/compiler/rustc_target/src/spec/json.rs
@@ -128,6 +128,19 @@ impl Target {
                     Some(Ok(()))
                 })).unwrap_or(Ok(()))
             } );
+            ($key_name:ident, RustcAbi) => ( {
+                let name = (stringify!($key_name)).replace("_", "-");
+                obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
+                    match s.parse::<super::RustcAbi>() {
+                        Ok(rustc_abi) => base.$key_name = Some(rustc_abi),
+                        _ => return Some(Err(format!(
+                            "'{s}' is not a valid value for rustc-abi. \
+                            Use 'x86-softfloat' or leave the field unset."
+                        ))),
+                    }
+                    Some(Ok(()))
+                })).unwrap_or(Ok(()))
+            } );
             ($key_name:ident, RelocModel) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
@@ -612,6 +625,7 @@ impl Target {
         key!(llvm_mcount_intrinsic, optional);
         key!(llvm_abiname);
         key!(llvm_floatabi, FloatAbi)?;
+        key!(rustc_abi, RustcAbi)?;
         key!(relax_elf_relocations, bool);
         key!(llvm_args, list);
         key!(use_ctors_section, bool);
@@ -788,6 +802,7 @@ impl ToJson for Target {
         target_option_val!(llvm_mcount_intrinsic);
         target_option_val!(llvm_abiname);
         target_option_val!(llvm_floatabi);
+        target_option_val!(rustc_abi);
         target_option_val!(relax_elf_relocations);
         target_option_val!(llvm_args);
         target_option_val!(use_ctors_section);
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 3fc7a07fb91..72600225e7a 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1114,6 +1114,33 @@ impl ToJson for FloatAbi {
     }
 }
 
+/// The Rustc-specific variant of the ABI used for this target.
+#[derive(Clone, Copy, PartialEq, Hash, Debug)]
+pub enum RustcAbi {
+    /// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI.
+    X86Softfloat,
+}
+
+impl FromStr for RustcAbi {
+    type Err = ();
+
+    fn from_str(s: &str) -> Result<RustcAbi, ()> {
+        Ok(match s {
+            "x86-softfloat" => RustcAbi::X86Softfloat,
+            _ => return Err(()),
+        })
+    }
+}
+
+impl ToJson for RustcAbi {
+    fn to_json(&self) -> Json {
+        match *self {
+            RustcAbi::X86Softfloat => "x86-softfloat",
+        }
+        .to_json()
+    }
+}
+
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum TlsModel {
     GeneralDynamic,
@@ -2505,6 +2532,12 @@ pub struct TargetOptions {
     /// If not provided, LLVM will infer the float ABI from the target triple (`llvm_target`).
     pub llvm_floatabi: Option<FloatAbi>,
 
+    /// Picks a specific ABI for this target. This is *not* just for "Rust" ABI functions,
+    /// it can also affect "C" ABI functions; the point is that this flag is interpreted by
+    /// rustc and not forwarded to LLVM.
+    /// So far, this is only used on x86.
+    pub rustc_abi: Option<RustcAbi>,
+
     /// Whether or not RelaxElfRelocation flag will be passed to the linker
     pub relax_elf_relocations: bool,
 
@@ -2664,10 +2697,6 @@ impl TargetOptions {
                 .collect();
         }
     }
-
-    pub(crate) fn has_feature(&self, search_feature: &str) -> bool {
-        self.features.split(',').any(|f| f.strip_prefix('+').is_some_and(|f| f == search_feature))
-    }
 }
 
 impl Default for TargetOptions {
@@ -2774,6 +2803,7 @@ impl Default for TargetOptions {
             llvm_mcount_intrinsic: None,
             llvm_abiname: "".into(),
             llvm_floatabi: None,
+            rustc_abi: None,
             relax_elf_relocations: false,
             llvm_args: cvs![],
             use_ctors_section: false,
@@ -3240,6 +3270,17 @@ impl Target {
             _ => {}
         }
 
+        // Check consistency of Rust ABI declaration.
+        if let Some(rust_abi) = self.rustc_abi {
+            match rust_abi {
+                RustcAbi::X86Softfloat => check_matches!(
+                    &*self.arch,
+                    "x86" | "x86_64",
+                    "`x86-softfloat` ABI is only valid for x86 targets"
+                ),
+            }
+        }
+
         // Check that the given target-features string makes some basic sense.
         if !self.features.is_empty() {
             let mut features_enabled = FxHashSet::default();
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs
index 39d3a5a4633..c1ed565f0fe 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs
@@ -5,7 +5,7 @@
 // The cdecl ABI is used. It differs from the stdcall or fastcall ABI.
 // "i686-unknown-windows" is used to get the minimal subset of windows-specific features.
 
-use crate::spec::{Target, base};
+use crate::spec::{RustcAbi, Target, base};
 
 pub(crate) fn target() -> Target {
     let mut base = base::uefi_msvc::opts();
@@ -22,6 +22,7 @@ pub(crate) fn target() -> Target {
     // If you initialize FP units yourself, you can override these flags with custom linker
     // arguments, thus giving you access to full MMX/SSE acceleration.
     base.features = "-mmx,-sse,+soft-float".into();
+    base.rustc_abi = Some(RustcAbi::X86Softfloat);
 
     // Use -GNU here, because of the reason below:
     // Background and Problem:
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs
index cfefb1de993..e14a3673589 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs
@@ -5,8 +5,8 @@
 // features.
 
 use crate::spec::{
-    Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelroLevel, SanitizerSet, StackProbeType,
-    Target, TargetOptions,
+    Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelroLevel, RustcAbi, SanitizerSet,
+    StackProbeType, Target, TargetOptions,
 };
 
 pub(crate) fn target() -> Target {
@@ -20,6 +20,7 @@ pub(crate) fn target() -> Target {
         relro_level: RelroLevel::Full,
         linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
         linker: Some("rust-lld".into()),
+        rustc_abi: Some(RustcAbi::X86Softfloat),
         features: "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float".into(),
         supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
         disable_redzone: true,
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs
index a11a79ff41a..8fd92e8123b 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs
@@ -6,7 +6,7 @@
 // LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
 
 use crate::abi::call::Conv;
-use crate::spec::{Target, base};
+use crate::spec::{RustcAbi, Target, base};
 
 pub(crate) fn target() -> Target {
     let mut base = base::uefi_msvc::opts();
@@ -26,6 +26,7 @@ pub(crate) fn target() -> Target {
     // If you initialize FP units yourself, you can override these flags with custom linker
     // arguments, thus giving you access to full MMX/SSE acceleration.
     base.features = "-mmx,-sse,+soft-float".into();
+    base.rustc_abi = Some(RustcAbi::X86Softfloat);
 
     Target {
         llvm_target: "x86_64-unknown-windows".into(),
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 0d8a4988dce..eb2417e0a20 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_span::{Symbol, sym};
 
-use crate::spec::{FloatAbi, Target};
+use crate::spec::{FloatAbi, RustcAbi, Target};
 
 /// Features that control behaviour of rustc, rather than the codegen.
 /// These exist globally and are not in the target-specific lists below.
@@ -409,6 +409,7 @@ const X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("fma", Stable, &["avx"]),
     ("fxsr", Stable, &[]),
     ("gfni", Unstable(sym::avx512_target_feature), &["sse2"]),
+    ("kl", Unstable(sym::keylocker_x86), &["sse2"]),
     ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
     ("lzcnt", Stable, &[]),
     ("movbe", Stable, &[]),
@@ -422,7 +423,9 @@ const X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("sha512", Unstable(sym::sha512_sm_x86), &["avx2"]),
     ("sm3", Unstable(sym::sha512_sm_x86), &["avx"]),
     ("sm4", Unstable(sym::sha512_sm_x86), &["avx2"]),
-    ("soft-float", Stability::Forbidden { reason: "unsound because it changes float ABI" }, &[]),
+    // This cannot actually be toggled, the ABI always fixes it, so it'd make little sense to
+    // stabilize. It must be in this list for the ABI check to be able to use it.
+    ("soft-float", Stability::Unstable(sym::x87_target_feature), &[]),
     ("sse", Stable, &[]),
     ("sse2", Stable, &["sse"]),
     ("sse3", Stable, &["sse2"]),
@@ -433,6 +436,7 @@ const X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("tbm", Unstable(sym::tbm_target_feature), &[]),
     ("vaes", Unstable(sym::avx512_target_feature), &["avx2", "aes"]),
     ("vpclmulqdq", Unstable(sym::avx512_target_feature), &["avx", "pclmulqdq"]),
+    ("widekl", Unstable(sym::keylocker_x86), &["kl"]),
     ("x87", Unstable(sym::x87_target_feature), &[]),
     ("xop", Unstable(sym::xop_target_feature), &[/*"fma4", */ "avx", "sse4a"]),
     ("xsave", Stable, &[]),
@@ -773,23 +777,41 @@ impl Target {
         // questions "which ABI is used".
         match &*self.arch {
             "x86" => {
-                // We support 2 ABIs, hardfloat (default) and softfloat.
-                // x86 has no sane ABI indicator so we have to use the target feature.
-                if self.has_feature("soft-float") {
-                    NOTHING
-                } else {
-                    // Hardfloat ABI. x87 must be enabled.
-                    FeatureConstraints { required: &["x87"], incompatible: &[] }
+                // We use our own ABI indicator here; LLVM does not have anything native.
+                // Every case should require or forbid `soft-float`!
+                match self.rustc_abi {
+                    None => {
+                        // Default hardfloat ABI.
+                        // x87 must be enabled, soft-float must be disabled.
+                        FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
+                    }
+                    Some(RustcAbi::X86Softfloat) => {
+                        // Softfloat ABI, requires corresponding target feature. That feature trumps
+                        // `x87` and all other FPU features so those do not matter.
+                        // Note that this one requirement is the entire implementation of the ABI!
+                        // LLVM handles the rest.
+                        FeatureConstraints { required: &["soft-float"], incompatible: &[] }
+                    }
                 }
             }
             "x86_64" => {
-                // We support 2 ABIs, hardfloat (default) and softfloat.
-                // x86 has no sane ABI indicator so we have to use the target feature.
-                if self.has_feature("soft-float") {
-                    NOTHING
-                } else {
-                    // Hardfloat ABI. x87 and SSE2 must be enabled.
-                    FeatureConstraints { required: &["x87", "sse2"], incompatible: &[] }
+                // We use our own ABI indicator here; LLVM does not have anything native.
+                // Every case should require or forbid `soft-float`!
+                match self.rustc_abi {
+                    None => {
+                        // Default hardfloat ABI. On x86-64, this always includes SSE2.
+                        FeatureConstraints {
+                            required: &["x87", "sse2"],
+                            incompatible: &["soft-float"],
+                        }
+                    }
+                    Some(RustcAbi::X86Softfloat) => {
+                        // Softfloat ABI, requires corresponding target feature. That feature trumps
+                        // `x87` and all other FPU features so those do not matter.
+                        // Note that this one requirement is the entire implementation of the ABI!
+                        // LLVM handles the rest.
+                        FeatureConstraints { required: &["soft-float"], incompatible: &[] }
+                    }
                 }
             }
             "arm" => {
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 db4a14356cc..091773009e9 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -435,7 +435,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
         terr: TypeError<'tcx>,
         param_env: Option<ParamEnv<'tcx>>,
-        path: &mut Option<PathBuf>,
     ) {
         match *cause.code() {
             ObligationCauseCode::Pattern {
@@ -458,7 +457,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             format!("this is an iterator with items of type `{}`", args.type_at(0)),
                         );
                     } else {
-                        let expected_ty = self.tcx.short_ty_string(expected_ty, path);
+                        let expected_ty = self.tcx.short_string(expected_ty, err.long_ty_path());
                         err.span_label(span, format!("this expression has type `{expected_ty}`"));
                     }
                 }
@@ -1545,7 +1544,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         (false, Mismatch::Fixed("existential projection"))
                     }
                 };
-                let Some(vals) = self.values_str(values, cause) else {
+                let Some(vals) = self.values_str(values, cause, diag.long_ty_path()) else {
                     // Derived error. Cancel the emitter.
                     // NOTE(eddyb) this was `.cancel()`, but `diag`
                     // is borrowed, so we can't fully defuse it.
@@ -1600,9 +1599,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             return;
         }
 
-        let mut path = None;
-        if let Some((expected, found, p)) = expected_found {
-            path = p;
+        if let Some((expected, found)) = expected_found {
             let (expected_label, found_label, exp_found) = match exp_found {
                 Mismatch::Variable(ef) => (
                     ef.expected.prefix_string(self.tcx),
@@ -1725,32 +1722,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     }
                 }
                 TypeError::Sorts(values) => {
-                    let extra = expected == found;
+                    let extra = expected == found
+                        // Ensure that we don't ever say something like
+                        // expected `impl Trait` (opaque type `impl Trait`)
+                        //    found `impl Trait` (opaque type `impl Trait`)
+                        && values.expected.sort_string(self.tcx)
+                            != values.found.sort_string(self.tcx);
                     let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
                         (true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
                             let sm = self.tcx.sess.source_map();
                             let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
-                            format!(
+                            DiagStyledString::normal(format!(
                                 " (opaque type at <{}:{}:{}>)",
                                 sm.filename_for_diagnostics(&pos.file.name),
                                 pos.line,
                                 pos.col.to_usize() + 1,
-                            )
+                            ))
                         }
                         (true, ty::Alias(ty::Projection, proj))
                             if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
                         {
                             let sm = self.tcx.sess.source_map();
                             let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
-                            format!(
+                            DiagStyledString::normal(format!(
                                 " (trait associated opaque type at <{}:{}:{}>)",
                                 sm.filename_for_diagnostics(&pos.file.name),
                                 pos.line,
                                 pos.col.to_usize() + 1,
-                            )
+                            ))
                         }
-                        (true, _) => format!(" ({})", ty.sort_string(self.tcx)),
-                        (false, _) => "".to_string(),
+                        (true, _) => {
+                            let mut s = DiagStyledString::normal(" (");
+                            s.push_highlighted(ty.sort_string(self.tcx));
+                            s.push_normal(")");
+                            s
+                        }
+                        (false, _) => DiagStyledString::normal(""),
                     };
                     if !(values.expected.is_simple_text() && values.found.is_simple_text())
                         || (exp_found.is_some_and(|ef| {
@@ -1767,23 +1774,23 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             }
                         }))
                     {
-                        if let Some(ExpectedFound { found: found_ty, .. }) = exp_found {
+                        if let Some(ExpectedFound { found: found_ty, .. }) = exp_found
+                            && !self.tcx.ty_is_opaque_future(found_ty)
+                        {
                             // `Future` is a special opaque type that the compiler
                             // will try to hide in some case such as `async fn`, so
                             // to make an error more use friendly we will
                             // avoid to suggest a mismatch type with a
                             // type that the user usually are not using
                             // directly such as `impl Future<Output = u8>`.
-                            if !self.tcx.ty_is_opaque_future(found_ty) {
-                                diag.note_expected_found_extra(
-                                    &expected_label,
-                                    expected,
-                                    &found_label,
-                                    found,
-                                    &sort_string(values.expected),
-                                    &sort_string(values.found),
-                                );
-                            }
+                            diag.note_expected_found_extra(
+                                &expected_label,
+                                expected,
+                                &found_label,
+                                found,
+                                sort_string(values.expected),
+                                sort_string(values.found),
+                            );
                         }
                     }
                 }
@@ -1878,11 +1885,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         // It reads better to have the error origin as the final
         // thing.
-        self.note_error_origin(diag, cause, exp_found, terr, param_env, &mut path);
-        if let Some(path) = path {
-            diag.note(format!("the full type name has been written to '{}'", path.display()));
-            diag.note("consider using `--verbose` to print the full type name to the console");
-        }
+        self.note_error_origin(diag, cause, exp_found, terr, param_env);
 
         debug!(?diag);
     }
@@ -1891,6 +1894,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         &self,
         trace: &TypeTrace<'tcx>,
         terr: TypeError<'tcx>,
+        path: &mut Option<PathBuf>,
     ) -> Vec<TypeErrorAdditionalDiags> {
         let mut suggestions = Vec::new();
         let span = trace.cause.span;
@@ -1969,7 +1973,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         })
         | ObligationCauseCode::BlockTailExpression(.., source)) = code
             && let hir::MatchSource::TryDesugar(_) = source
-            && let Some((expected_ty, found_ty, _)) = self.values_str(trace.values, &trace.cause)
+            && let Some((expected_ty, found_ty)) = self.values_str(trace.values, &trace.cause, path)
         {
             suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert {
                 found: found_ty.content(),
@@ -2048,12 +2052,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr);
 
         let span = trace.cause.span;
+        let mut path = None;
         let failure_code = trace.cause.as_failure_code_diag(
             terr,
             span,
-            self.type_error_additional_suggestions(&trace, terr),
+            self.type_error_additional_suggestions(&trace, terr, &mut path),
         );
         let mut diag = self.dcx().create_err(failure_code);
+        *diag.long_ty_path() = path;
         self.note_type_err(
             &mut diag,
             &trace.cause,
@@ -2098,10 +2104,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         &self,
         values: ValuePairs<'tcx>,
         cause: &ObligationCause<'tcx>,
-    ) -> Option<(DiagStyledString, DiagStyledString, Option<PathBuf>)> {
+        file: &mut Option<PathBuf>,
+    ) -> Option<(DiagStyledString, DiagStyledString)> {
         match values {
             ValuePairs::Regions(exp_found) => self.expected_found_str(exp_found),
-            ValuePairs::Terms(exp_found) => self.expected_found_str_term(exp_found),
+            ValuePairs::Terms(exp_found) => self.expected_found_str_term(exp_found, file),
             ValuePairs::Aliases(exp_found) => self.expected_found_str(exp_found),
             ValuePairs::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found),
             ValuePairs::ExistentialProjection(exp_found) => self.expected_found_str(exp_found),
@@ -2111,7 +2118,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     found: exp_found.found.print_trait_sugared(),
                 };
                 match self.expected_found_str(pretty_exp_found) {
-                    Some((expected, found, _)) if expected == found => {
+                    Some((expected, found)) if expected == found => {
                         self.expected_found_str(exp_found)
                     }
                     ret => ret,
@@ -2133,9 +2140,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     (None, None)
                 };
 
-                let (exp, fnd) =
-                    self.cmp_fn_sig(&exp_found.expected, fn_def1, &exp_found.found, fn_def2);
-                Some((exp, fnd, None))
+                Some(self.cmp_fn_sig(&exp_found.expected, fn_def1, &exp_found.found, fn_def2))
             }
         }
     }
@@ -2143,7 +2148,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     fn expected_found_str_term(
         &self,
         exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>,
-    ) -> Option<(DiagStyledString, DiagStyledString, Option<PathBuf>)> {
+        path: &mut Option<PathBuf>,
+    ) -> Option<(DiagStyledString, DiagStyledString)> {
         let exp_found = self.resolve_vars_if_possible(exp_found);
         if exp_found.references_error() {
             return None;
@@ -2158,21 +2164,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 let len = self.tcx.sess().diagnostic_width() + 40;
                 let exp_s = exp.content();
                 let fnd_s = fnd.content();
-                let mut path = None;
                 if exp_s.len() > len {
-                    let exp_s = self.tcx.short_ty_string(expected, &mut path);
+                    let exp_s = self.tcx.short_string(expected, path);
                     exp = DiagStyledString::highlighted(exp_s);
                 }
                 if fnd_s.len() > len {
-                    let fnd_s = self.tcx.short_ty_string(found, &mut path);
+                    let fnd_s = self.tcx.short_string(found, path);
                     fnd = DiagStyledString::highlighted(fnd_s);
                 }
-                (exp, fnd, path)
+                (exp, fnd)
             }
             _ => (
                 DiagStyledString::highlighted(exp_found.expected.to_string()),
                 DiagStyledString::highlighted(exp_found.found.to_string()),
-                None,
             ),
         })
     }
@@ -2181,7 +2185,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     fn expected_found_str<T: fmt::Display + TypeFoldable<TyCtxt<'tcx>>>(
         &self,
         exp_found: ty::error::ExpectedFound<T>,
-    ) -> Option<(DiagStyledString, DiagStyledString, Option<PathBuf>)> {
+    ) -> Option<(DiagStyledString, DiagStyledString)> {
         let exp_found = self.resolve_vars_if_possible(exp_found);
         if exp_found.references_error() {
             return None;
@@ -2190,7 +2194,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         Some((
             DiagStyledString::highlighted(exp_found.expected.to_string()),
             DiagStyledString::highlighted(exp_found.found.to_string()),
-            None,
         ))
     }
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
index 68a53381230..99b70c87ccd 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -713,7 +713,7 @@ impl<'tcx> InferSourceKind<'tcx> {
                 if ty.is_closure() {
                     ("closure", closure_as_fn_str(infcx, ty), path)
                 } else if !ty.is_ty_or_numeric_infer() {
-                    ("normal", infcx.tcx.short_ty_string(ty, &mut path), path)
+                    ("normal", infcx.tcx.short_string(ty, &mut path), path)
                 } else {
                     ("other", String::new(), path)
                 }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs
deleted file mode 100644
index beae9962f7f..00000000000
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs
+++ /dev/null
@@ -1,422 +0,0 @@
-use rustc_errors::{Diag, Subdiagnostic};
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_middle::traits::ObligationCauseCode;
-use rustc_middle::ty::error::TypeError;
-use rustc_middle::ty::{self, IsSuggestable, Region, Ty};
-use rustc_span::kw;
-use tracing::debug;
-
-use super::ObligationCauseAsDiagArg;
-use crate::error_reporting::infer::{TypeErrCtxt, note_and_explain_region};
-use crate::errors::{
-    FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, RefLongerThanData,
-    RegionOriginNote, WhereClauseSuggestions, note_and_explain,
-};
-use crate::fluent_generated as fluent;
-use crate::infer::{self, SubregionOrigin};
-
-impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
-    pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) {
-        match *origin {
-            infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
-                span: trace.cause.span,
-                requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
-                expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)),
-            }
-            .add_to_diag(err),
-            infer::Reborrow(span) => {
-                RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diag(err)
-            }
-            infer::RelateObjectBound(span) => {
-                RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound }
-                    .add_to_diag(err);
-            }
-            infer::ReferenceOutlivesReferent(ty, span) => {
-                RegionOriginNote::WithName {
-                    span,
-                    msg: fluent::infer_reference_outlives_referent,
-                    name: &self.ty_to_string(ty),
-                    continues: false,
-                }
-                .add_to_diag(err);
-            }
-            infer::RelateParamBound(span, ty, opt_span) => {
-                RegionOriginNote::WithName {
-                    span,
-                    msg: fluent::infer_relate_param_bound,
-                    name: &self.ty_to_string(ty),
-                    continues: opt_span.is_some(),
-                }
-                .add_to_diag(err);
-                if let Some(span) = opt_span {
-                    RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 }
-                        .add_to_diag(err);
-                }
-            }
-            infer::RelateRegionParamBound(span, _) => {
-                RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound }
-                    .add_to_diag(err);
-            }
-            infer::CompareImplItemObligation { span, .. } => {
-                RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation }
-                    .add_to_diag(err);
-            }
-            infer::CheckAssociatedTypeBounds { ref parent, .. } => {
-                self.note_region_origin(err, parent);
-            }
-            infer::AscribeUserTypeProvePredicate(span) => {
-                RegionOriginNote::Plain {
-                    span,
-                    msg: fluent::infer_ascribe_user_type_prove_predicate,
-                }
-                .add_to_diag(err);
-            }
-        }
-    }
-
-    pub(super) fn report_concrete_failure(
-        &self,
-        generic_param_scope: LocalDefId,
-        origin: SubregionOrigin<'tcx>,
-        sub: Region<'tcx>,
-        sup: Region<'tcx>,
-    ) -> Diag<'a> {
-        let mut err = match origin {
-            infer::Subtype(box trace) => {
-                let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
-                let mut err = self.report_and_explain_type_error(trace, terr);
-                match (*sub, *sup) {
-                    (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
-                    (ty::RePlaceholder(_), _) => {
-                        note_and_explain_region(
-                            self.tcx,
-                            &mut err,
-                            generic_param_scope,
-                            "",
-                            sup,
-                            " doesn't meet the lifetime requirements",
-                            None,
-                        );
-                    }
-                    (_, ty::RePlaceholder(_)) => {
-                        note_and_explain_region(
-                            self.tcx,
-                            &mut err,
-                            generic_param_scope,
-                            "the required lifetime does not necessarily outlive ",
-                            sub,
-                            "",
-                            None,
-                        );
-                    }
-                    _ => {
-                        note_and_explain_region(
-                            self.tcx,
-                            &mut err,
-                            generic_param_scope,
-                            "",
-                            sup,
-                            "...",
-                            None,
-                        );
-                        note_and_explain_region(
-                            self.tcx,
-                            &mut err,
-                            generic_param_scope,
-                            "...does not necessarily outlive ",
-                            sub,
-                            "",
-                            None,
-                        );
-                    }
-                }
-                err
-            }
-            infer::Reborrow(span) => {
-                let reference_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    None,
-                    note_and_explain::PrefixKind::RefValidFor,
-                    note_and_explain::SuffixKind::Continues,
-                );
-                let content_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sup,
-                    None,
-                    note_and_explain::PrefixKind::ContentValidFor,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                self.dcx().create_err(OutlivesContent {
-                    span,
-                    notes: reference_valid.into_iter().chain(content_valid).collect(),
-                })
-            }
-            infer::RelateObjectBound(span) => {
-                let object_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    None,
-                    note_and_explain::PrefixKind::TypeObjValidFor,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                let pointer_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sup,
-                    None,
-                    note_and_explain::PrefixKind::SourcePointerValidFor,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                self.dcx().create_err(OutlivesBound {
-                    span,
-                    notes: object_valid.into_iter().chain(pointer_valid).collect(),
-                })
-            }
-            infer::RelateParamBound(span, ty, opt_span) => {
-                let prefix = match *sub {
-                    ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy,
-                    _ => note_and_explain::PrefixKind::TypeOutlive,
-                };
-                let suffix = if opt_span.is_some() {
-                    note_and_explain::SuffixKind::ReqByBinding
-                } else {
-                    note_and_explain::SuffixKind::Empty
-                };
-                let note = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    opt_span,
-                    prefix,
-                    suffix,
-                );
-                self.dcx().create_err(FulfillReqLifetime {
-                    span,
-                    ty: self.resolve_vars_if_possible(ty),
-                    note,
-                })
-            }
-            infer::RelateRegionParamBound(span, _) => {
-                let param_instantiated = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sup,
-                    None,
-                    note_and_explain::PrefixKind::LfParamInstantiatedWith,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                let param_must_outlive = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    None,
-                    note_and_explain::PrefixKind::LfParamMustOutlive,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                self.dcx().create_err(LfBoundNotSatisfied {
-                    span,
-                    notes: param_instantiated.into_iter().chain(param_must_outlive).collect(),
-                })
-            }
-            infer::ReferenceOutlivesReferent(ty, span) => {
-                let pointer_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    None,
-                    note_and_explain::PrefixKind::PointerValidFor,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                let data_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sup,
-                    None,
-                    note_and_explain::PrefixKind::DataValidFor,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                self.dcx().create_err(RefLongerThanData {
-                    span,
-                    ty: self.resolve_vars_if_possible(ty),
-                    notes: pointer_valid.into_iter().chain(data_valid).collect(),
-                })
-            }
-            infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => {
-                let mut err = self.infcx.report_extra_impl_obligation(
-                    span,
-                    impl_item_def_id,
-                    trait_item_def_id,
-                    &format!("`{sup}: {sub}`"),
-                );
-                // We should only suggest rewriting the `where` clause if the predicate is within that `where` clause
-                if let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id)
-                    && generics.where_clause_span.contains(span)
-                {
-                    self.suggest_copy_trait_method_bounds(
-                        trait_item_def_id,
-                        impl_item_def_id,
-                        &mut err,
-                    );
-                }
-                err
-            }
-            infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => {
-                let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup);
-
-                // Don't mention the item name if it's an RPITIT, since that'll just confuse
-                // folks.
-                if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) {
-                    let trait_item_span = self.tcx.def_span(trait_item_def_id);
-                    let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
-                    err.span_label(
-                        trait_item_span,
-                        format!("definition of `{item_name}` from trait"),
-                    );
-                }
-
-                self.suggest_copy_trait_method_bounds(
-                    trait_item_def_id,
-                    impl_item_def_id,
-                    &mut err,
-                );
-                err
-            }
-            infer::AscribeUserTypeProvePredicate(span) => {
-                let instantiated = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sup,
-                    None,
-                    note_and_explain::PrefixKind::LfInstantiatedWith,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                let must_outlive = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    None,
-                    note_and_explain::PrefixKind::LfMustOutlive,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                self.dcx().create_err(LfBoundNotSatisfied {
-                    span,
-                    notes: instantiated.into_iter().chain(must_outlive).collect(),
-                })
-            }
-        };
-        if sub.is_error() || sup.is_error() {
-            err.downgrade_to_delayed_bug();
-        }
-        err
-    }
-
-    pub fn suggest_copy_trait_method_bounds(
-        &self,
-        trait_item_def_id: DefId,
-        impl_item_def_id: LocalDefId,
-        err: &mut Diag<'_>,
-    ) {
-        // FIXME(compiler-errors): Right now this is only being used for region
-        // predicate mismatches. Ideally, we'd use it for *all* predicate mismatches,
-        // but right now it's not really very smart when it comes to implicit `Sized`
-        // predicates and bounds on the trait itself.
-
-        let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx)
-        else {
-            return;
-        };
-        let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else {
-            return;
-        };
-        let trait_args = trait_ref
-            .instantiate_identity()
-            // Replace the explicit self type with `Self` for better suggestion rendering
-            .with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
-            .args;
-        let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id)
-            .rebase_onto(self.tcx, impl_def_id, trait_args);
-
-        let Ok(trait_predicates) =
-            self.tcx
-                .explicit_predicates_of(trait_item_def_id)
-                .instantiate_own(self.tcx, trait_item_args)
-                .map(|(pred, _)| {
-                    if pred.is_suggestable(self.tcx, false) {
-                        Ok(pred.to_string())
-                    } else {
-                        Err(())
-                    }
-                })
-                .collect::<Result<Vec<_>, ()>>()
-        else {
-            return;
-        };
-
-        let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else {
-            return;
-        };
-
-        let suggestion = if trait_predicates.is_empty() {
-            WhereClauseSuggestions::Remove { span: generics.where_clause_span }
-        } else {
-            let space = if generics.where_clause_span.is_empty() { " " } else { "" };
-            WhereClauseSuggestions::CopyPredicates {
-                span: generics.where_clause_span,
-                space,
-                trait_predicates: trait_predicates.join(", "),
-            }
-        };
-        err.subdiagnostic(suggestion);
-    }
-
-    pub(super) fn report_placeholder_failure(
-        &self,
-        generic_param_scope: LocalDefId,
-        placeholder_origin: SubregionOrigin<'tcx>,
-        sub: Region<'tcx>,
-        sup: Region<'tcx>,
-    ) -> Diag<'a> {
-        // I can't think how to do better than this right now. -nikomatsakis
-        debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
-        match placeholder_origin {
-            infer::Subtype(box ref trace)
-                if matches!(
-                    &trace.cause.code().peel_derives(),
-                    ObligationCauseCode::WhereClause(..)
-                        | ObligationCauseCode::WhereClauseInExpr(..)
-                ) =>
-            {
-                // Hack to get around the borrow checker because trace.cause has an `Rc`.
-                if let ObligationCauseCode::WhereClause(_, span)
-                | ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
-                    &trace.cause.code().peel_derives()
-                    && !span.is_dummy()
-                {
-                    let span = *span;
-                    self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup)
-                        .with_span_note(span, "the lifetime requirement is introduced here")
-                } else {
-                    unreachable!(
-                        "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..."
-                    )
-                }
-            }
-            infer::Subtype(box trace) => {
-                let terr = TypeError::RegionsPlaceholderMismatch;
-                return self.report_and_explain_type_error(trace, terr);
-            }
-            _ => {
-                return self.report_concrete_failure(
-                    generic_param_scope,
-                    placeholder_origin,
-                    sub,
-                    sup,
-                );
-            }
-        }
-    }
-}
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
index 3acca47025c..f35a5349ecb 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
@@ -221,7 +221,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
                 span: trace.cause.span,
                 requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
-                expected_found: self.values_str(trace.values, &trace.cause).map(|(e, f, _)| (e, f)),
+                expected_found: self.values_str(trace.values, &trace.cause, err.long_ty_path()),
             }
             .add_to_diag(err),
             infer::Reborrow(span) => {
@@ -946,10 +946,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         if let infer::Subtype(ref sup_trace) = sup_origin
             && let infer::Subtype(ref sub_trace) = sub_origin
-            && let Some((sup_expected, sup_found, _)) =
-                self.values_str(sup_trace.values, &sup_trace.cause)
-            && let Some((sub_expected, sub_found, _)) =
-                self.values_str(sub_trace.values, &sup_trace.cause)
+            && let Some((sup_expected, sup_found)) =
+                self.values_str(sup_trace.values, &sup_trace.cause, err.long_ty_path())
+            && let Some((sub_expected, sub_found)) =
+                self.values_str(sub_trace.values, &sup_trace.cause, err.long_ty_path())
             && sub_expected == sup_expected
             && sub_found == sup_found
         {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
index 231fecf7a4a..562000e28ac 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
@@ -418,7 +418,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 };
 
                 let sugg = match (expected.is_ref(), found.is_ref()) {
-                    (true, false) => FunctionPointerSuggestion::UseRef { span, fn_name },
+                    (true, false) => {
+                        FunctionPointerSuggestion::UseRef { span: span.shrink_to_lo() }
+                    }
                     (false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name },
                     (true, true) => {
                         diag.subdiagnostic(FnItemsAreDistinct);
@@ -426,7 +428,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     }
                     (false, false) => {
                         diag.subdiagnostic(FnItemsAreDistinct);
-                        FunctionPointerSuggestion::Cast { span, fn_name, sig }
+                        FunctionPointerSuggestion::Cast { span: span.shrink_to_hi(), sig }
                     }
                 };
                 diag.subdiagnostic(sugg);
@@ -466,8 +468,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     }
                 } else {
                     FunctionPointerSuggestion::CastBoth {
-                        span,
-                        fn_name,
+                        span: span.shrink_to_hi(),
                         found_sig: *found_sig,
                         expected_sig: *expected_sig,
                     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
index b4d294a70c0..6beb108bc3a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
@@ -163,6 +163,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         let predicate = self.resolve_vars_if_possible(obligation.predicate);
         let span = obligation.cause.span;
+        let mut file = None;
 
         debug!(?predicate, obligation.cause.code = ?obligation.cause.code());
 
@@ -179,7 +180,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     return e;
                 }
 
-                if let Err(guar) = self.tcx.ensure().coherent_trait(trait_pred.def_id()) {
+                if let Err(guar) = self.tcx.ensure_ok().coherent_trait(trait_pred.def_id()) {
                     // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
                     // other `Foo` impls are incoherent.
                     return guar;
@@ -245,7 +246,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         span,
                         E0283,
                         "type annotations needed: cannot satisfy `{}`",
-                        predicate,
+                        self.tcx.short_string(predicate, &mut file),
                     )
                 };
 
@@ -292,7 +293,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         err.cancel();
                         return e;
                     }
-                    err.note(format!("cannot satisfy `{predicate}`"));
+                    let pred = self.tcx.short_string(predicate, &mut file);
+                    err.note(format!("cannot satisfy `{pred}`"));
                     let impl_candidates =
                         self.find_similar_impl_candidates(predicate.as_trait_clause().unwrap());
                     if impl_candidates.len() < 40 {
@@ -511,8 +513,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     return e;
                 }
 
-                if let Err(guar) =
-                    self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_term.def_id))
+                if let Err(guar) = self
+                    .tcx
+                    .ensure_ok()
+                    .coherent_trait(self.tcx.parent(data.projection_term.def_id))
                 {
                     // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
                     // other `Foo` impls are incoherent.
@@ -524,6 +528,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     .iter()
                     .chain(Some(data.term.into_arg()))
                     .find(|g| g.has_non_region_infer());
+                let predicate = self.tcx.short_string(predicate, &mut file);
                 if let Some(arg) = arg {
                     self.emit_inference_failure_err(
                         obligation.cause.body_id,
@@ -539,8 +544,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         self.dcx(),
                         span,
                         E0284,
-                        "type annotations needed: cannot satisfy `{}`",
-                        predicate,
+                        "type annotations needed: cannot satisfy `{predicate}`",
                     )
                     .with_span_label(span, format!("cannot satisfy `{predicate}`"))
                 }
@@ -565,12 +569,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     err
                 } else {
                     // If we can't find a generic parameter, just print a generic error
+                    let predicate = self.tcx.short_string(predicate, &mut file);
                     struct_span_code_err!(
                         self.dcx(),
                         span,
                         E0284,
-                        "type annotations needed: cannot satisfy `{}`",
-                        predicate,
+                        "type annotations needed: cannot satisfy `{predicate}`",
                     )
                     .with_span_label(span, format!("cannot satisfy `{predicate}`"))
                 }
@@ -590,6 +594,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 if let Some(e) = self.tainted_by_errors() {
                     return e;
                 }
+                let alias = self.tcx.short_string(alias, &mut file);
                 struct_span_code_err!(
                     self.dcx(),
                     span,
@@ -603,16 +608,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 if let Some(e) = self.tainted_by_errors() {
                     return e;
                 }
+                let predicate = self.tcx.short_string(predicate, &mut file);
                 struct_span_code_err!(
                     self.dcx(),
                     span,
                     E0284,
-                    "type annotations needed: cannot satisfy `{}`",
-                    predicate,
+                    "type annotations needed: cannot satisfy `{predicate}`",
                 )
                 .with_span_label(span, format!("cannot satisfy `{predicate}`"))
             }
         };
+        *err.long_ty_path() = file;
         self.note_obligation_cause(&mut err, obligation);
         err.emit()
     }
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 6416c539f26..3128577776a 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
@@ -1,5 +1,6 @@
 use core::ops::ControlFlow;
 use std::borrow::Cow;
+use std::path::PathBuf;
 
 use rustc_ast::TraitObjectSyntax;
 use rustc_data_structures::fx::FxHashMap;
@@ -9,7 +10,6 @@ use rustc_errors::{
     Applicability, Diag, ErrorGuaranteed, Level, MultiSpan, StashKey, StringPart, Suggestions,
     pluralize, struct_span_code_err,
 };
-use rustc_hir::def::Namespace;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{self as hir, LangItem, Node};
@@ -20,8 +20,8 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::print::{
-    FmtPrinter, Print, PrintPolyTraitPredicateExt, PrintTraitPredicateExt as _,
-    PrintTraitRefExt as _, with_forced_trimmed_paths,
+    PrintPolyTraitPredicateExt, PrintTraitPredicateExt as _, PrintTraitRefExt as _,
+    with_forced_trimmed_paths,
 };
 use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast};
 use rustc_middle::{bug, span_bug};
@@ -60,6 +60,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     ) -> ErrorGuaranteed {
         let tcx = self.tcx;
         let mut span = obligation.cause.span;
+        let mut long_ty_file = None;
 
         let mut err = match *error {
             SelectionError::Unimplemented => {
@@ -169,11 +170,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         if let Err(guar) = self.fn_arg_obligation(&obligation) {
                             return guar;
                         }
-                        let mut file = None;
                         let (post_message, pre_message, type_def) = self
                             .get_parent_trait_ref(obligation.cause.code())
                             .map(|(t, s)| {
-                                let t = self.tcx.short_ty_string(t, &mut file);
+                                let t = self.tcx.short_string(t, &mut long_ty_file);
                                 (
                                     format!(" in `{t}`"),
                                     format!("within `{t}`, "),
@@ -181,12 +181,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                                 )
                             })
                             .unwrap_or_default();
-                        let file_note = file.as_ref().map(|file| format!(
-                            "the full trait has been written to '{}'",
-                            file.display(),
-                        ));
-
-                        let mut long_ty_file = None;
 
                         let OnUnimplementedNote {
                             message,
@@ -223,6 +217,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             None,
                             append_const_msg,
                             post_message,
+                            &mut long_ty_file,
                         );
 
                         let (err_msg, safe_transmute_explanation) = if self.tcx.is_lang_item(main_trait_predicate.def_id(), LangItem::TransmuteTrait)
@@ -251,14 +246,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         };
 
                         let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);
+                        *err.long_ty_path() = long_ty_file;
 
-                        if let Some(long_ty_file) = long_ty_file {
-                            err.note(format!(
-                                "the full name for the type has been written to '{}'",
-                                long_ty_file.display(),
-                            ));
-                            err.note("consider using `--verbose` to print the full type name to the console");
-                        }
                         let mut suggested = false;
                         if is_try_conversion {
                             suggested = self.try_conversion_context(&obligation, main_trait_predicate, &mut err);
@@ -309,7 +298,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             return err.emit();
                         }
 
-                        file_note.map(|note| err.note(note));
                         if let Some(s) = label {
                             // If it has a custom `#[rustc_on_unimplemented]`
                             // error message, let's display it as the label!
@@ -715,7 +703,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         };
 
         self.note_obligation_cause(&mut err, &obligation);
-        self.point_at_returns_when_relevant(&mut err, &obligation);
         err.emit()
     }
 }
@@ -762,14 +749,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             trait_ref: predicate.trait_ref,
             polarity: ty::PredicatePolarity::Positive,
         });
+        let mut file = None;
         let err_msg = self.get_standard_error_message(
             trait_ref,
             None,
             Some(predicate.constness()),
             None,
             String::new(),
+            &mut file,
         );
         let mut diag = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);
+        *diag.long_ty_path() = file;
         if !self.predicate_may_hold(&Obligation::new(
             self.tcx,
             ObligationCause::dummy(),
@@ -815,7 +805,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     "Async",
                 );
                 self.note_obligation_cause(&mut err, &obligation);
-                self.point_at_returns_when_relevant(&mut err, &obligation);
                 return Some(err.emit());
             }
         }
@@ -861,7 +850,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     "",
                 );
                 self.note_obligation_cause(&mut err, &obligation);
-                self.point_at_returns_when_relevant(&mut err, &obligation);
                 return Some(err.emit());
             }
 
@@ -877,7 +865,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     kind: expected_kind.as_str(),
                 });
                 self.note_obligation_cause(&mut err, &obligation);
-                self.point_at_returns_when_relevant(&mut err, &obligation);
                 return Some(err.emit());
             }
         }
@@ -1381,6 +1368,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 _ => (None, error.err),
             };
 
+            let mut file = None;
             let (msg, span, closure_span) = values
                 .and_then(|(predicate, normalized_term, expected_term)| {
                     self.maybe_detailed_projection_msg(
@@ -1388,24 +1376,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         predicate,
                         normalized_term,
                         expected_term,
+                        &mut file,
                     )
                 })
                 .unwrap_or_else(|| {
-                    let mut cx = FmtPrinter::new_with_limit(
-                        self.tcx,
-                        Namespace::TypeNS,
-                        rustc_session::Limit(10),
-                    );
                     (
-                        with_forced_trimmed_paths!(format!("type mismatch resolving `{}`", {
-                            self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap();
-                            cx.into_buffer()
-                        })),
+                        with_forced_trimmed_paths!(format!(
+                            "type mismatch resolving `{}`",
+                            self.tcx
+                                .short_string(self.resolve_vars_if_possible(predicate), &mut file),
+                        )),
                         obligation.cause.span,
                         None,
                     )
                 });
             let mut diag = struct_span_code_err!(self.dcx(), span, E0271, "{msg}");
+            *diag.long_ty_path() = file;
             if let Some(span) = closure_span {
                 // Mark the closure decl so that it is seen even if we are pointing at the return
                 // type or expression.
@@ -1471,15 +1457,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         ty.span,
                         with_forced_trimmed_paths!(Cow::from(format!(
                             "type mismatch resolving `{}`",
-                            {
-                                let mut cx = FmtPrinter::new_with_limit(
-                                    self.tcx,
-                                    Namespace::TypeNS,
-                                    rustc_session::Limit(5),
-                                );
-                                self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap();
-                                cx.into_buffer()
-                            }
+                            self.tcx.short_string(
+                                self.resolve_vars_if_possible(predicate),
+                                diag.long_ty_path()
+                            ),
                         ))),
                         true,
                     )),
@@ -1512,13 +1493,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         projection_term: ty::AliasTerm<'tcx>,
         normalized_ty: ty::Term<'tcx>,
         expected_ty: ty::Term<'tcx>,
+        file: &mut Option<PathBuf>,
     ) -> Option<(String, Span, Option<Span>)> {
         let trait_def_id = projection_term.trait_def_id(self.tcx);
         let self_ty = projection_term.self_ty();
 
         with_forced_trimmed_paths! {
             if self.tcx.is_lang_item(projection_term.def_id, LangItem::FnOnceOutput) {
-                let fn_kind = self_ty.prefix_string(self.tcx);
                 let (span, closure_span) = if let ty::Closure(def_id, _) = self_ty.kind() {
                     let def_span = self.tcx.def_span(def_id);
                     if let Some(local_def_id) = def_id.as_local()
@@ -1552,11 +1533,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 };
                 let item = match self_ty.kind() {
                     ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(),
-                    _ => self_ty.to_string(),
+                    _ => self.tcx.short_string(self_ty, file),
                 };
                 Some((format!(
-                    "expected `{item}` to be a {fn_kind} that returns `{expected_ty}`, but it \
-                     returns `{normalized_ty}`",
+                    "expected `{item}` to return `{expected_ty}`, but it returns `{normalized_ty}`",
                 ), span, closure_span))
             } else if self.tcx.is_lang_item(trait_def_id, LangItem::Future) {
                 Some((format!(
@@ -1984,8 +1964,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         StringPart::normal(" implemented for `"),
                     ]);
                     if types_content.0 == types_content.1 {
-                        let ty =
-                            self.tcx.short_ty_string(obligation_trait_ref.self_ty(), &mut None);
+                        let ty = self
+                            .tcx
+                            .short_string(obligation_trait_ref.self_ty(), err.long_ty_path());
                         msg.push(StringPart::normal(ty));
                     } else {
                         msg.extend(types.0.0);
@@ -2342,7 +2323,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         // First, attempt to add note to this error with an async-await-specific
         // message, and fall back to regular note otherwise.
         if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
-            let mut long_ty_file = None;
             self.note_obligation_cause_code(
                 obligation.cause.body_id,
                 err,
@@ -2351,15 +2331,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 obligation.cause.code(),
                 &mut vec![],
                 &mut Default::default(),
-                &mut long_ty_file,
             );
-            if let Some(file) = long_ty_file {
-                err.note(format!(
-                    "the full name for the type has been written to '{}'",
-                    file.display(),
-                ));
-                err.note("consider using `--verbose` to print the full type name to the console");
-            }
             self.suggest_unsized_bound_if_applicable(err, obligation);
             if let Some(span) = err.span.primary_span()
                 && let Some(mut diag) =
@@ -2403,6 +2375,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         predicate_constness: Option<ty::BoundConstness>,
         append_const_msg: Option<AppendConstMessage>,
         post_message: String,
+        long_ty_file: &mut Option<PathBuf>,
     ) -> String {
         message
             .and_then(|cannot_do_this| {
@@ -2426,7 +2399,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             .unwrap_or_else(|| {
                 format!(
                     "the trait bound `{}` is not satisfied{post_message}",
-                    trait_predicate.print_with_bound_constness(predicate_constness)
+                    self.tcx.short_string(
+                        trait_predicate.print_with_bound_constness(predicate_constness),
+                        long_ty_file,
+                    ),
                 )
             })
     }
@@ -2846,7 +2822,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         err.span_note(self.tcx.def_span(def_id), "opaque type is declared here");
 
         self.note_obligation_cause(&mut err, &obligation);
-        self.point_at_returns_when_relevant(&mut err, &obligation);
         self.dcx().try_steal_replace_and_emit_err(self.tcx.def_span(def_id), StashKey::Cycle, err)
     }
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index b4e5cc6185c..658fb4009d5 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -306,7 +306,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 if let ObligationCauseCode::WhereClause(..)
                 | ObligationCauseCode::WhereClauseInExpr(..) = code
                 {
-                    let mut long_ty_file = None;
                     self.note_obligation_cause_code(
                         error.obligation.cause.body_id,
                         &mut diag,
@@ -315,17 +314,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         code,
                         &mut vec![],
                         &mut Default::default(),
-                        &mut long_ty_file,
                     );
-                    if let Some(file) = long_ty_file {
-                        diag.note(format!(
-                            "the full name for the type has been written to '{}'",
-                            file.display(),
-                        ));
-                        diag.note(
-                            "consider using `--verbose` to print the full type name to the console",
-                        );
-                    }
                 }
                 diag.emit()
             }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
index 3d79b0acf83..518323f6526 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
@@ -932,7 +932,7 @@ impl<'tcx> OnUnimplementedFormatString {
                 let value = match param.kind {
                     GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
                         if let Some(ty) = trait_ref.args[param.index as usize].as_type() {
-                            tcx.short_ty_string(ty, long_ty_file)
+                            tcx.short_string(ty, long_ty_file)
                         } else {
                             trait_ref.args[param.index as usize].to_string()
                         }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
index d82acc4e054..c5ed74420d4 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
@@ -141,7 +141,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             obligation.cause.span,
             suggest_increasing_limit,
             |err| {
-                let mut long_ty_file = None;
                 self.note_obligation_cause_code(
                     obligation.cause.body_id,
                     err,
@@ -150,17 +149,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     obligation.cause.code(),
                     &mut vec![],
                     &mut Default::default(),
-                    &mut long_ty_file,
                 );
-                if let Some(file) = long_ty_file {
-                    err.note(format!(
-                        "the full name for the type has been written to '{}'",
-                        file.display(),
-                    ));
-                    err.note(
-                        "consider using `--verbose` to print the full type name to the console",
-                    );
-                }
             },
         );
     }
@@ -196,7 +185,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             suggest_increasing_limit,
         );
         self.note_obligation_cause(&mut err, &obligation);
-        self.point_at_returns_when_relevant(&mut err, &obligation);
         err.emit()
     }
 }
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 ab25bef4120..c194cc11727 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -3,7 +3,6 @@
 use std::assert_matches::debug_assert_matches;
 use std::borrow::Cow;
 use std::iter;
-use std::path::PathBuf;
 
 use itertools::{EitherOrBoth, Itertools};
 use rustc_abi::ExternAbi;
@@ -1297,30 +1296,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     // Because of this, we modify the error to refer to the original obligation and
                     // return early in the caller.
 
-                    let msg = format!("the trait bound `{old_pred}` is not satisfied");
+                    let msg = format!(
+                        "the trait bound `{}` is not satisfied",
+                        self.tcx.short_string(old_pred, err.long_ty_path()),
+                    );
+                    let self_ty_str =
+                        self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path());
                     if has_custom_message {
                         err.note(msg);
                     } else {
                         err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)];
                     }
-                    let mut file = None;
                     err.span_label(
                         span,
                         format!(
-                            "the trait `{}` is not implemented for `{}`",
-                            old_pred.print_modifiers_and_trait_path(),
-                            self.tcx.short_ty_string(old_pred.self_ty().skip_binder(), &mut file),
+                            "the trait `{}` is not implemented for `{self_ty_str}`",
+                            old_pred.print_modifiers_and_trait_path()
                         ),
                     );
-                    if let Some(file) = file {
-                        err.note(format!(
-                            "the full type name has been written to '{}'",
-                            file.display()
-                        ));
-                        err.note(
-                            "consider using `--verbose` to print full type name to the console",
-                        );
-                    }
 
                     if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
                         err.span_suggestions(
@@ -1772,7 +1765,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         };
 
         err.code(E0746);
-        err.primary_message("return type cannot have an unboxed trait object");
+        err.primary_message("return type cannot be a trait object without pointer indirection");
         err.children.clear();
 
         let span = obligation.cause.span;
@@ -1788,25 +1781,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         } else {
             ("dyn ", span.shrink_to_lo())
         };
-        let alternatively = if visitor
-            .returns
-            .iter()
-            .map(|expr| self.typeck_results.as_ref().unwrap().expr_ty_adjusted_opt(expr))
-            .collect::<FxHashSet<_>>()
-            .len()
-            <= 1
-        {
-            err.span_suggestion_verbose(
-                impl_span,
-                "consider returning an `impl Trait` instead of a `dyn Trait`",
-                "impl ",
-                Applicability::MaybeIncorrect,
-            );
-            "alternatively, "
-        } else {
-            err.help("if there were a single returned type, you could use `impl Trait` instead");
-            ""
-        };
+
+        err.span_suggestion_verbose(
+            impl_span,
+            "consider returning an `impl Trait` instead of a `dyn Trait`",
+            "impl ",
+            Applicability::MaybeIncorrect,
+        );
 
         let mut sugg = vec![
             (span.shrink_to_lo(), format!("Box<{pre}")),
@@ -1838,7 +1819,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         err.multipart_suggestion(
             format!(
-                "{alternatively}box the return type, and wrap all of the returned values in \
+                "alternatively, box the return type, and wrap all of the returned values in \
                  `Box::new`",
             ),
             sugg,
@@ -1848,41 +1829,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         true
     }
 
-    pub(super) fn point_at_returns_when_relevant(
-        &self,
-        err: &mut Diag<'_>,
-        obligation: &PredicateObligation<'tcx>,
-    ) {
-        match obligation.cause.code().peel_derives() {
-            ObligationCauseCode::SizedReturnType => {}
-            _ => return,
-        }
-
-        let hir = self.tcx.hir();
-        let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id);
-        if let hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::Fn { body: body_id, .. }, ..
-        }) = node
-        {
-            let body = hir.body(*body_id);
-            // Point at all the `return`s in the function as they have failed trait bounds.
-            let mut visitor = ReturnsVisitor::default();
-            visitor.visit_body(body);
-            let typeck_results = self.typeck_results.as_ref().unwrap();
-            for expr in &visitor.returns {
-                if let Some(returned_ty) = typeck_results.node_type_opt(expr.hir_id) {
-                    let ty = self.resolve_vars_if_possible(returned_ty);
-                    if ty.references_error() {
-                        // don't print out the [type error] here
-                        err.downgrade_to_delayed_bug();
-                    } else {
-                        err.span_label(expr.span, format!("this returned value is of type `{ty}`"));
-                    }
-                }
-            }
-        }
-    }
-
     pub(super) fn report_closure_arg_mismatch(
         &self,
         span: Span,
@@ -2689,7 +2635,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         // Add a note for the item obligation that remains - normally a note pointing to the
         // bound that introduced the obligation (e.g. `T: Send`).
         debug!(?next_code);
-        let mut long_ty_file = None;
         self.note_obligation_cause_code(
             obligation.cause.body_id,
             err,
@@ -2698,7 +2643,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             next_code.unwrap(),
             &mut Vec::new(),
             &mut Default::default(),
-            &mut long_ty_file,
         );
     }
 
@@ -2711,7 +2655,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         cause_code: &ObligationCauseCode<'tcx>,
         obligated_types: &mut Vec<Ty<'tcx>>,
         seen_requirements: &mut FxHashSet<DefId>,
-        long_ty_file: &mut Option<PathBuf>,
     ) where
         T: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>,
     {
@@ -2965,9 +2908,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
             ObligationCauseCode::Coercion { source, target } => {
                 let source =
-                    tcx.short_ty_string(self.resolve_vars_if_possible(source), long_ty_file);
+                    tcx.short_string(self.resolve_vars_if_possible(source), err.long_ty_path());
                 let target =
-                    tcx.short_ty_string(self.resolve_vars_if_possible(target), long_ty_file);
+                    tcx.short_string(self.resolve_vars_if_possible(target), err.long_ty_path());
                 err.note(with_forced_trimmed_paths!(format!(
                     "required for the cast from `{source}` to `{target}`",
                 )));
@@ -3252,7 +3195,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 };
 
                 if !is_upvar_tys_infer_tuple {
-                    let ty_str = tcx.short_ty_string(ty, long_ty_file);
+                    let ty_str = tcx.short_string(ty, err.long_ty_path());
                     let msg = format!("required because it appears within the type `{ty_str}`");
                     match ty.kind() {
                         ty::Adt(def, _) => match tcx.opt_item_ident(def.did()) {
@@ -3330,7 +3273,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             &data.parent_code,
                             obligated_types,
                             seen_requirements,
-                            long_ty_file,
                         )
                     });
                 } else {
@@ -3343,7 +3285,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             cause_code.peel_derives(),
                             obligated_types,
                             seen_requirements,
-                            long_ty_file,
                         )
                     });
                 }
@@ -3353,7 +3294,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     self.resolve_vars_if_possible(data.derived.parent_trait_pred);
                 let parent_def_id = parent_trait_pred.def_id();
                 let self_ty_str =
-                    tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty(), long_ty_file);
+                    tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path());
                 let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string();
                 let msg = format!("required for `{self_ty_str}` to implement `{trait_name}`");
                 let mut is_auto_trait = false;
@@ -3449,8 +3390,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         count,
                         pluralize!(count)
                     ));
-                    let self_ty = tcx
-                        .short_ty_string(parent_trait_pred.skip_binder().self_ty(), long_ty_file);
+                    let self_ty = tcx.short_string(
+                        parent_trait_pred.skip_binder().self_ty(),
+                        err.long_ty_path(),
+                    );
                     err.note(format!(
                         "required for `{self_ty}` to implement `{}`",
                         parent_trait_pred.print_modifiers_and_trait_path()
@@ -3466,7 +3409,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         &data.parent_code,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
             }
@@ -3505,7 +3447,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         &data.derived.parent_code,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
             }
@@ -3519,7 +3460,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         &data.parent_code,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
             }
@@ -3536,7 +3476,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         &data.parent_code,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
             }
@@ -3551,7 +3490,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         nested,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
                 let mut multispan = MultiSpan::from(span);
@@ -3582,7 +3520,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         parent_code,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
             }
@@ -3622,7 +3559,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
             ObligationCauseCode::OpaqueReturnType(expr_info) => {
                 let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info {
-                    let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file);
+                    let expr_ty = tcx.short_string(expr_ty, err.long_ty_path());
                     let expr = tcx.hir().expect_expr(hir_id);
                     (expr_ty, expr)
                 } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id()
@@ -3637,7 +3574,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     && let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
                     && self.can_eq(param_env, pred.self_ty(), expr_ty)
                 {
-                    let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file);
+                    let expr_ty = tcx.short_string(expr_ty, err.long_ty_path());
                     (expr_ty, expr)
                 } else {
                     return;
@@ -5231,7 +5168,7 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>(
             format!(
                 "{pre_message}the trait `{}` is not implemented for{desc} `{}`",
                 trait_predicate.print_modifiers_and_trait_path(),
-                tcx.short_ty_string(trait_predicate.self_ty().skip_binder(), &mut None),
+                tcx.short_string(trait_predicate.self_ty().skip_binder(), &mut None),
             )
         } else {
             // "the trait bound `T: !Send` is not satisfied" reads better than "`!Send` is
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index c5ab8a71c78..62cac5b17bd 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -1391,15 +1391,13 @@ pub struct OpaqueCapturesLifetime<'tcx> {
 pub enum FunctionPointerSuggestion<'a> {
     #[suggestion(
         trait_selection_fps_use_ref,
-        code = "&{fn_name}",
+        code = "&",
         style = "verbose",
         applicability = "maybe-incorrect"
     )]
     UseRef {
         #[primary_span]
         span: Span,
-        #[skip_arg]
-        fn_name: String,
     },
     #[suggestion(
         trait_selection_fps_remove_ref,
@@ -1429,7 +1427,7 @@ pub enum FunctionPointerSuggestion<'a> {
     },
     #[suggestion(
         trait_selection_fps_cast,
-        code = "{fn_name} as {sig}",
+        code = " as {sig}",
         style = "verbose",
         applicability = "maybe-incorrect"
     )]
@@ -1437,13 +1435,11 @@ pub enum FunctionPointerSuggestion<'a> {
         #[primary_span]
         span: Span,
         #[skip_arg]
-        fn_name: String,
-        #[skip_arg]
         sig: Binder<'a, FnSig<'a>>,
     },
     #[suggestion(
         trait_selection_fps_cast_both,
-        code = "{fn_name} as {found_sig}",
+        code = " as {found_sig}",
         style = "hidden",
         applicability = "maybe-incorrect"
     )]
@@ -1451,8 +1447,6 @@ pub enum FunctionPointerSuggestion<'a> {
         #[primary_span]
         span: Span,
         #[skip_arg]
-        fn_name: String,
-        #[skip_arg]
         found_sig: Binder<'a, FnSig<'a>>,
         expected_sig: Binder<'a, FnSig<'a>>,
     },
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
index baa94ead9d4..617bc87a9d2 100644
--- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
+++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -4,19 +4,16 @@
 //!
 //! [^1]: Formerly known as "object safety".
 
-use std::iter;
 use std::ops::ControlFlow;
 
-use rustc_abi::BackendRepr;
 use rustc_errors::FatalError;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{
-    self, EarlyBinder, ExistentialPredicateStableCmpExt as _, GenericArgs, Ty, TyCtxt,
-    TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
-    TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
+    self, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
 };
 use rustc_span::Span;
 use rustc_type_ir::elaborate;
@@ -109,14 +106,6 @@ fn dyn_compatibility_violations_for_trait(
         violations.push(DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans));
     }
 
-    if violations.is_empty() {
-        for item in tcx.associated_items(trait_def_id).in_definition_order() {
-            if let ty::AssocKind::Fn = item.kind {
-                check_receiver_correct(tcx, trait_def_id, *item);
-            }
-        }
-    }
-
     violations
 }
 
@@ -499,55 +488,6 @@ fn virtual_call_violations_for_method<'tcx>(
     errors
 }
 
-/// This code checks that `receiver_is_dispatchable` is correctly implemented.
-///
-/// This check is outlined from the dyn-compatibility check to avoid cycles with
-/// layout computation, which relies on knowing whether methods are dyn-compatible.
-fn check_receiver_correct<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, method: ty::AssocItem) {
-    if !is_vtable_safe_method(tcx, trait_def_id, method) {
-        return;
-    }
-
-    let method_def_id = method.def_id;
-    let sig = tcx.fn_sig(method_def_id).instantiate_identity();
-    let typing_env = ty::TypingEnv::non_body_analysis(tcx, method_def_id);
-    let receiver_ty = tcx.liberate_late_bound_regions(method_def_id, sig.input(0));
-
-    if receiver_ty == tcx.types.self_param {
-        // Assumed OK, may change later if unsized_locals permits `self: Self` as dispatchable.
-        return;
-    }
-
-    // e.g., `Rc<()>`
-    let unit_receiver_ty = receiver_for_self_ty(tcx, receiver_ty, tcx.types.unit, method_def_id);
-    match tcx.layout_of(typing_env.as_query_input(unit_receiver_ty)).map(|l| l.backend_repr) {
-        Ok(BackendRepr::Scalar(..)) => (),
-        abi => {
-            tcx.dcx().span_delayed_bug(
-                tcx.def_span(method_def_id),
-                format!("receiver {unit_receiver_ty:?} when `Self = ()` should have a Scalar ABI; found {abi:?}"),
-            );
-        }
-    }
-
-    let trait_object_ty = object_ty_for_trait(tcx, trait_def_id, tcx.lifetimes.re_static);
-
-    // e.g., `Rc<dyn Trait>`
-    let trait_object_receiver =
-        receiver_for_self_ty(tcx, receiver_ty, trait_object_ty, method_def_id);
-    match tcx.layout_of(typing_env.as_query_input(trait_object_receiver)).map(|l| l.backend_repr) {
-        Ok(BackendRepr::ScalarPair(..)) => (),
-        abi => {
-            tcx.dcx().span_delayed_bug(
-                tcx.def_span(method_def_id),
-                format!(
-                    "receiver {trait_object_receiver:?} when `Self = {trait_object_ty}` should have a ScalarPair ABI; found {abi:?}"
-                ),
-            );
-        }
-    }
-}
-
 /// Performs a type instantiation to produce the version of `receiver_ty` when `Self = self_ty`.
 /// For example, for `receiver_ty = Rc<Self>` and `self_ty = Foo`, returns `Rc<Foo>`.
 fn receiver_for_self_ty<'tcx>(
@@ -569,49 +509,6 @@ fn receiver_for_self_ty<'tcx>(
     result
 }
 
-/// Creates the object type for the current trait. For example,
-/// if the current trait is `Deref`, then this will be
-/// `dyn Deref<Target = Self::Target> + 'static`.
-#[instrument(level = "trace", skip(tcx), ret)]
-fn object_ty_for_trait<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    trait_def_id: DefId,
-    lifetime: ty::Region<'tcx>,
-) -> Ty<'tcx> {
-    let trait_ref = ty::TraitRef::identity(tcx, trait_def_id);
-    debug!(?trait_ref);
-
-    let trait_predicate = ty::Binder::dummy(ty::ExistentialPredicate::Trait(
-        ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref),
-    ));
-    debug!(?trait_predicate);
-
-    let pred: ty::Predicate<'tcx> = trait_ref.upcast(tcx);
-    let mut elaborated_predicates: Vec<_> = elaborate(tcx, [pred])
-        .filter_map(|pred| {
-            debug!(?pred);
-            let pred = pred.as_projection_clause()?;
-            Some(pred.map_bound(|p| {
-                ty::ExistentialPredicate::Projection(ty::ExistentialProjection::erase_self_ty(
-                    tcx, p,
-                ))
-            }))
-        })
-        .collect();
-    // NOTE: Since #37965, the existential predicates list has depended on the
-    // list of predicates to be sorted. This is mostly to enforce that the primary
-    // predicate comes first.
-    elaborated_predicates.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
-    elaborated_predicates.dedup();
-
-    let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(
-        iter::once(trait_predicate).chain(elaborated_predicates),
-    );
-    debug!(?existential_predicates);
-
-    Ty::new_dynamic(tcx, existential_predicates, lifetime, ty::Dyn)
-}
-
 /// Checks the method's receiver (the `self` argument) can be dispatched on when `Self` is a
 /// trait object. We require that `DispatchableFromDyn` be implemented for the receiver type
 /// in the following way:
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 401b41c796d..cb3e81f5477 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -575,7 +575,7 @@ fn report_conflicting_impls<'tcx>(
     match used_to_be_allowed {
         None => {
             let reported = if overlap.with_impl.is_local()
-                || tcx.ensure().orphan_check_impl(impl_def_id).is_ok()
+                || tcx.ensure_ok().orphan_check_impl(impl_def_id).is_ok()
             {
                 let mut err = tcx.dcx().struct_span_err(impl_span, msg());
                 err.code(E0119);
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
index c351cf5aaac..f39c611d19f 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -379,7 +379,7 @@ pub(crate) fn assoc_def(
         // Ensure that the impl is constrained, otherwise projection may give us
         // bad unconstrained infer vars.
         if let Some(impl_def_id) = impl_def_id.as_local() {
-            tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
+            tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
         }
 
         let item = tcx.associated_item(impl_item_id);
@@ -402,7 +402,7 @@ pub(crate) fn assoc_def(
         if assoc_item.item.container == ty::AssocItemContainer::Impl
             && let Some(impl_def_id) = assoc_item.item.container_id(tcx).as_local()
         {
-            tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
+            tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
         }
 
         Ok(assoc_item)
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 37d49cc2f55..96051ad0aa5 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -830,8 +830,25 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                 // Let the visitor iterate into the argument/return
                 // types appearing in the fn signature.
             }
-            ty::UnsafeBinder(_) => {
-                // FIXME(unsafe_binders): We should also recurse into the binder here.
+            ty::UnsafeBinder(ty) => {
+                // FIXME(unsafe_binders): For now, we have no way to express
+                // that a type must be `ManuallyDrop` OR `Copy` (or a pointer).
+                if !ty.has_escaping_bound_vars() {
+                    self.out.push(traits::Obligation::new(
+                        self.tcx(),
+                        self.cause(ObligationCauseCode::Misc),
+                        self.param_env,
+                        ty.map_bound(|ty| {
+                            ty::TraitRef::new(
+                                self.tcx(),
+                                self.tcx().require_lang_item(LangItem::Copy, Some(self.span)),
+                                [ty],
+                            )
+                        }),
+                    ));
+                }
+
+                // We recurse into the binder below.
             }
 
             ty::Dynamic(data, r, _) => {
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index 931c36137ee..4038a1d68fa 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -116,6 +116,11 @@ fn recurse_build<'tcx>(
         | &ExprKind::ValueTypeAscription { source, .. } => {
             recurse_build(tcx, body, source, root_span)?
         }
+        &ExprKind::PlaceUnwrapUnsafeBinder { .. }
+        | &ExprKind::ValueUnwrapUnsafeBinder { .. }
+        | &ExprKind::WrapUnsafeBinder { .. } => {
+            todo!("FIXME(unsafe_binders)")
+        }
         &ExprKind::Literal { lit, neg } => {
             let sp = node.span;
             tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg })
@@ -347,6 +352,9 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
             | thir::ExprKind::Adt(_)
             | thir::ExprKind::PlaceTypeAscription { .. }
             | thir::ExprKind::ValueTypeAscription { .. }
+            | thir::ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | thir::ExprKind::ValueUnwrapUnsafeBinder { .. }
+            | thir::ExprKind::WrapUnsafeBinder { .. }
             | thir::ExprKind::Closure(_)
             | thir::ExprKind::Literal { .. }
             | thir::ExprKind::NonHirLiteral { .. }
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index d5e1937efaa..8c6e3c86bf5 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -225,7 +225,7 @@ fn resolve_associated_item<'tcx>(
             if trait_item_id != leaf_def.item.def_id
                 && let Some(leaf_def_item) = leaf_def.item.def_id.as_local()
             {
-                tcx.ensure().compare_impl_item(leaf_def_item)?;
+                tcx.ensure_ok().compare_impl_item(leaf_def_item)?;
             }
 
             Some(ty::Instance::new(leaf_def.item.def_id, args))
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs
index d337a1a8ad9..711e42ff055 100644
--- a/compiler/rustc_type_ir/src/fold.rs
+++ b/compiler/rustc_type_ir/src/fold.rs
@@ -73,7 +73,7 @@ type Never = std::convert::Infallible;
 /// which means in practice almost every foldable type needs to also be
 /// visitable. (However, there are some types that are visitable without being
 /// foldable.)
-pub trait TypeFoldable<I: Interner>: TypeVisitable<I> {
+pub trait TypeFoldable<I: Interner>: TypeVisitable<I> + Clone {
     /// The entry point for folding. To fold a value `t` with a folder `f`
     /// call: `t.try_fold_with(f)`.
     ///
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs
index 3213638afb2..0a074942170 100644
--- a/compiler/rustc_type_ir/src/visit.rs
+++ b/compiler/rustc_type_ir/src/visit.rs
@@ -59,7 +59,7 @@ use crate::{self as ty, Interner, TypeFlags};
 ///
 /// To implement this conveniently, use the derive macro located in
 /// `rustc_macros`.
-pub trait TypeVisitable<I: Interner>: fmt::Debug + Clone {
+pub trait TypeVisitable<I: Interner>: fmt::Debug {
     /// The entry point for visiting. To visit a value `t` with a visitor `v`
     /// call: `t.visit_with(v)`.
     ///
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index eec6cd8d49b..a6406e9db8e 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -608,7 +608,8 @@ impl Rvalue {
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
                 Ok(Ty::usize_ty())
             }
-            Rvalue::NullaryOp(NullOp::UbChecks, _) => Ok(Ty::bool_ty()),
+            Rvalue::NullaryOp(NullOp::ContractChecks, _)
+            | Rvalue::NullaryOp(NullOp::UbChecks, _) => Ok(Ty::bool_ty()),
             Rvalue::Aggregate(ak, ops) => match *ak {
                 AggregateKind::Array(ty) => Ty::try_new_array(ty, ops.len() as u64),
                 AggregateKind::Tuple => Ok(Ty::new_tuple(
@@ -1007,6 +1008,8 @@ pub enum NullOp {
     OffsetOf(Vec<(VariantIdx, FieldIdx)>),
     /// cfg!(ub_checks), but at codegen time
     UbChecks,
+    /// cfg!(contract_checks), but at codegen time
+    ContractChecks,
 }
 
 impl Operand {
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 0c9535dfaa6..b29f740ef0f 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -712,8 +712,8 @@ impl String {
         }
     }
 
-    /// Decode a UTF-16–encoded vector `v` into a `String`, returning [`Err`]
-    /// if `v` contains any invalid data.
+    /// Decode a native endian UTF-16–encoded vector `v` into a `String`,
+    /// returning [`Err`] if `v` contains any invalid data.
     ///
     /// # Examples
     ///
@@ -745,8 +745,8 @@ impl String {
         Ok(ret)
     }
 
-    /// Decode a UTF-16–encoded slice `v` into a `String`, replacing
-    /// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
+    /// Decode a native endian UTF-16–encoded slice `v` into a `String`,
+    /// replacing invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
     ///
     /// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
     /// `from_utf16_lossy` returns a `String` since the UTF-16 to UTF-8
@@ -777,8 +777,8 @@ impl String {
             .collect()
     }
 
-    /// Decode a UTF-16LE–encoded vector `v` into a `String`, returning [`Err`]
-    /// if `v` contains any invalid data.
+    /// Decode a UTF-16LE–encoded vector `v` into a `String`,
+    /// returning [`Err`] if `v` contains any invalid data.
     ///
     /// # Examples
     ///
@@ -852,8 +852,8 @@ impl String {
         }
     }
 
-    /// Decode a UTF-16BE–encoded vector `v` into a `String`, returning [`Err`]
-    /// if `v` contains any invalid data.
+    /// Decode a UTF-16BE–encoded vector `v` into a `String`,
+    /// returning [`Err`] if `v` contains any invalid data.
     ///
     /// # Examples
     ///
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 20187e478aa..320d8176011 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -2118,6 +2118,35 @@ impl<T> UnsafeCell<T> {
     pub const fn into_inner(self) -> T {
         self.value
     }
+
+    /// Replace the value in this `UnsafeCell` and return the old value.
+    ///
+    /// # Safety
+    ///
+    /// The caller must take care to avoid aliasing and data races.
+    ///
+    /// - It is Undefined Behavior to allow calls to race with
+    ///   any other access to the wrapped value.
+    /// - It is Undefined Behavior to call this while any other
+    ///   reference(s) to the wrapped value are alive.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unsafe_cell_access)]
+    /// use std::cell::UnsafeCell;
+    ///
+    /// let uc = UnsafeCell::new(5);
+    ///
+    /// let old = unsafe { uc.replace(10) };
+    /// assert_eq!(old, 5);
+    /// ```
+    #[inline]
+    #[unstable(feature = "unsafe_cell_access", issue = "136327")]
+    pub const unsafe fn replace(&self, value: T) -> T {
+        // SAFETY: pointer comes from `&self` so naturally satisfies invariants.
+        unsafe { ptr::replace(self.get(), value) }
+    }
 }
 
 impl<T: ?Sized> UnsafeCell<T> {
@@ -2230,6 +2259,61 @@ impl<T: ?Sized> UnsafeCell<T> {
         // no guarantee for user code that this will work in future versions of the compiler!
         this as *const T as *mut T
     }
+
+    /// Get a shared reference to the value within the `UnsafeCell`.
+    ///
+    /// # Safety
+    ///
+    /// - It is Undefined Behavior to call this while any mutable
+    ///   reference to the wrapped value is alive.
+    /// - Mutating the wrapped value while the returned
+    ///   reference is alive is Undefined Behavior.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unsafe_cell_access)]
+    /// use std::cell::UnsafeCell;
+    ///
+    /// let uc = UnsafeCell::new(5);
+    ///
+    /// let val = unsafe { uc.as_ref_unchecked() };
+    /// assert_eq!(val, &5);
+    /// ```
+    #[inline]
+    #[unstable(feature = "unsafe_cell_access", issue = "136327")]
+    pub const unsafe fn as_ref_unchecked(&self) -> &T {
+        // SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants.
+        unsafe { self.get().as_ref_unchecked() }
+    }
+
+    /// Get an exclusive reference to the value within the `UnsafeCell`.
+    ///
+    /// # Safety
+    ///
+    /// - It is Undefined Behavior to call this while any other
+    ///   reference(s) to the wrapped value are alive.
+    /// - Mutating the wrapped value through other means while the
+    ///   returned reference is alive is Undefined Behavior.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unsafe_cell_access)]
+    /// use std::cell::UnsafeCell;
+    ///
+    /// let uc = UnsafeCell::new(5);
+    ///
+    /// unsafe { *uc.as_mut_unchecked() += 1; }
+    /// assert_eq!(uc.into_inner(), 6);
+    /// ```
+    #[inline]
+    #[unstable(feature = "unsafe_cell_access", issue = "136327")]
+    #[allow(clippy::mut_from_ref)]
+    pub const unsafe fn as_mut_unchecked(&self) -> &mut T {
+        // SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants.
+        unsafe { self.get().as_mut_unchecked() }
+    }
 }
 
 #[stable(feature = "unsafe_cell_default", since = "1.10.0")]
diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs
index 6a85791916a..c6c96571d33 100644
--- a/library/core/src/cell/once.rs
+++ b/library/core/src/cell/once.rs
@@ -8,6 +8,9 @@ use crate::{fmt, mem};
 /// only immutable references can be obtained unless one has a mutable reference to the cell
 /// itself. In the same vein, the cell can only be re-initialized with such a mutable reference.
 ///
+/// A `OnceCell` can be thought of as a safe abstraction over uninitialized data that becomes
+/// initialized once written.
+///
 /// For a thread-safe version of this struct, see [`std::sync::OnceLock`].
 ///
 /// [`RefCell`]: crate::cell::RefCell
@@ -35,7 +38,7 @@ pub struct OnceCell<T> {
 }
 
 impl<T> OnceCell<T> {
-    /// Creates a new empty cell.
+    /// Creates a new uninitialized cell.
     #[inline]
     #[must_use]
     #[stable(feature = "once_cell", since = "1.70.0")]
@@ -46,7 +49,7 @@ impl<T> OnceCell<T> {
 
     /// Gets the reference to the underlying value.
     ///
-    /// Returns `None` if the cell is empty.
+    /// Returns `None` if the cell is uninitialized.
     #[inline]
     #[stable(feature = "once_cell", since = "1.70.0")]
     pub fn get(&self) -> Option<&T> {
@@ -56,19 +59,19 @@ impl<T> OnceCell<T> {
 
     /// Gets the mutable reference to the underlying value.
     ///
-    /// Returns `None` if the cell is empty.
+    /// Returns `None` if the cell is uninitialized.
     #[inline]
     #[stable(feature = "once_cell", since = "1.70.0")]
     pub fn get_mut(&mut self) -> Option<&mut T> {
         self.inner.get_mut().as_mut()
     }
 
-    /// Sets the contents of the cell to `value`.
+    /// Initializes the contents of the cell to `value`.
     ///
     /// # Errors
     ///
-    /// This method returns `Ok(())` if the cell was empty and `Err(value)` if
-    /// it was full.
+    /// This method returns `Ok(())` if the cell was uninitialized
+    /// and `Err(value)` if it was already initialized.
     ///
     /// # Examples
     ///
@@ -92,13 +95,13 @@ impl<T> OnceCell<T> {
         }
     }
 
-    /// Sets the contents of the cell to `value` if the cell was empty, then
-    /// returns a reference to it.
+    /// Initializes the contents of the cell to `value` if the cell was
+    /// uninitialized, then returns a reference to it.
     ///
     /// # Errors
     ///
-    /// This method returns `Ok(&value)` if the cell was empty and
-    /// `Err(&current_value, value)` if it was full.
+    /// This method returns `Ok(&value)` if the cell was uninitialized
+    /// and `Err((&current_value, value))` if it was already initialized.
     ///
     /// # Examples
     ///
@@ -130,12 +133,12 @@ impl<T> OnceCell<T> {
         Ok(slot.insert(value))
     }
 
-    /// Gets the contents of the cell, initializing it with `f`
-    /// if the cell was empty.
+    /// Gets the contents of the cell, initializing it to `f()`
+    /// if the cell was uninitialized.
     ///
     /// # Panics
     ///
-    /// If `f` panics, the panic is propagated to the caller, and the cell
+    /// If `f()` panics, the panic is propagated to the caller, and the cell
     /// remains uninitialized.
     ///
     /// It is an error to reentrantly initialize the cell from `f`. Doing
@@ -164,11 +167,11 @@ impl<T> OnceCell<T> {
     }
 
     /// Gets the mutable reference of the contents of the cell,
-    /// initializing it with `f` if the cell was empty.
+    /// initializing it to `f()` if the cell was uninitialized.
     ///
     /// # Panics
     ///
-    /// If `f` panics, the panic is propagated to the caller, and the cell
+    /// If `f()` panics, the panic is propagated to the caller, and the cell
     /// remains uninitialized.
     ///
     /// # Examples
@@ -199,13 +202,13 @@ impl<T> OnceCell<T> {
         }
     }
 
-    /// Gets the contents of the cell, initializing it with `f` if
-    /// the cell was empty. If the cell was empty and `f` failed, an
-    /// error is returned.
+    /// Gets the contents of the cell, initializing it to `f()` if
+    /// the cell was uninitialized. If the cell was uninitialized
+    /// and `f()` failed, an error is returned.
     ///
     /// # Panics
     ///
-    /// If `f` panics, the panic is propagated to the caller, and the cell
+    /// If `f()` panics, the panic is propagated to the caller, and the cell
     /// remains uninitialized.
     ///
     /// It is an error to reentrantly initialize the cell from `f`. Doing
@@ -239,12 +242,12 @@ impl<T> OnceCell<T> {
     }
 
     /// Gets the mutable reference of the contents of the cell, initializing
-    /// it with `f` if the cell was empty. If the cell was empty and `f` failed,
-    /// an error is returned.
+    /// it to `f()` if the cell was uninitialized. If the cell was uninitialized
+    /// and `f()` failed, an error is returned.
     ///
     /// # Panics
     ///
-    /// If `f` panics, the panic is propagated to the caller, and the cell
+    /// If `f()` panics, the panic is propagated to the caller, and the cell
     /// remains uninitialized.
     ///
     /// # Examples
@@ -256,7 +259,7 @@ impl<T> OnceCell<T> {
     ///
     /// let mut cell: OnceCell<u32> = OnceCell::new();
     ///
-    /// // Failed initializers do not change the value
+    /// // Failed attempts to initialize the cell do not change its contents
     /// assert!(cell.get_mut_or_try_init(|| "not a number!".parse()).is_err());
     /// assert!(cell.get().is_none());
     ///
@@ -295,7 +298,7 @@ impl<T> OnceCell<T> {
 
     /// Consumes the cell, returning the wrapped value.
     ///
-    /// Returns `None` if the cell was empty.
+    /// Returns `None` if the cell was uninitialized.
     ///
     /// # Examples
     ///
@@ -321,7 +324,7 @@ impl<T> OnceCell<T> {
 
     /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
     ///
-    /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
+    /// Has no effect and returns `None` if the `OnceCell` is uninitialized.
     ///
     /// Safety is guaranteed by requiring a mutable reference.
     ///
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index fb8a740aced..ccfdbf0eb70 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -92,7 +92,7 @@ impl char {
     #[stable(feature = "assoc_char_consts", since = "1.52.0")]
     pub const UNICODE_VERSION: (u8, u8, u8) = crate::unicode::UNICODE_VERSION;
 
-    /// Creates an iterator over the UTF-16 encoded code points in `iter`,
+    /// Creates an iterator over the native endian UTF-16 encoded code points in `iter`,
     /// returning unpaired surrogates as `Err`s.
     ///
     /// # Examples
@@ -704,7 +704,7 @@ impl char {
         unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) }
     }
 
-    /// Encodes this character as UTF-16 into the provided `u16` buffer,
+    /// Encodes this character as native endian UTF-16 into the provided `u16` buffer,
     /// and then returns the subslice of the buffer that contains the encoded character.
     ///
     /// # Panics
@@ -1828,7 +1828,7 @@ pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
     unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
 }
 
-/// Encodes a raw `u32` value as UTF-16 into the provided `u16` buffer,
+/// Encodes a raw `u32` value as native endian UTF-16 into the provided `u16` buffer,
 /// and then returns the subslice of the buffer that contains the encoded character.
 ///
 /// Unlike `char::encode_utf16`, this method also handles codepoints in the surrogate range.
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 97974d195fe..594236cf1d9 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -973,6 +973,24 @@ pub trait Ord: Eq + PartialOrd<Self> {
     /// assert_eq!(1.max(2), 2);
     /// assert_eq!(2.max(2), 2);
     /// ```
+    /// ```
+    /// use std::cmp::Ordering;
+    ///
+    /// #[derive(Eq)]
+    /// struct Equal(&'static str);
+    ///
+    /// impl PartialEq for Equal {
+    ///     fn eq(&self, other: &Self) -> bool { true }
+    /// }
+    /// impl PartialOrd for Equal {
+    ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
+    /// }
+    /// impl Ord for Equal {
+    ///     fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
+    /// }
+    ///
+    /// assert_eq!(Equal("self").max(Equal("other")).0, "other");
+    /// ```
     #[stable(feature = "ord_max_min", since = "1.21.0")]
     #[inline]
     #[must_use]
@@ -981,7 +999,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     where
         Self: Sized,
     {
-        max_by(self, other, Ord::cmp)
+        if other < self { self } else { other }
     }
 
     /// Compares and returns the minimum of two values.
@@ -994,6 +1012,24 @@ pub trait Ord: Eq + PartialOrd<Self> {
     /// assert_eq!(1.min(2), 1);
     /// assert_eq!(2.min(2), 2);
     /// ```
+    /// ```
+    /// use std::cmp::Ordering;
+    ///
+    /// #[derive(Eq)]
+    /// struct Equal(&'static str);
+    ///
+    /// impl PartialEq for Equal {
+    ///     fn eq(&self, other: &Self) -> bool { true }
+    /// }
+    /// impl PartialOrd for Equal {
+    ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
+    /// }
+    /// impl Ord for Equal {
+    ///     fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
+    /// }
+    ///
+    /// assert_eq!(Equal("self").min(Equal("other")).0, "self");
+    /// ```
     #[stable(feature = "ord_max_min", since = "1.21.0")]
     #[inline]
     #[must_use]
@@ -1002,7 +1038,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     where
         Self: Sized,
     {
-        min_by(self, other, Ord::cmp)
+        if other < self { other } else { self }
     }
 
     /// Restrict a value to a certain interval.
@@ -1414,6 +1450,24 @@ pub macro PartialOrd($item:item) {
 /// assert_eq!(cmp::min(1, 2), 1);
 /// assert_eq!(cmp::min(2, 2), 2);
 /// ```
+/// ```
+/// use std::cmp::{self, Ordering};
+///
+/// #[derive(Eq)]
+/// struct Equal(&'static str);
+///
+/// impl PartialEq for Equal {
+///     fn eq(&self, other: &Self) -> bool { true }
+/// }
+/// impl PartialOrd for Equal {
+///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
+/// }
+/// impl Ord for Equal {
+///     fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
+/// }
+///
+/// assert_eq!(cmp::min(Equal("v1"), Equal("v2")).0, "v1");
+/// ```
 #[inline]
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1431,20 +1485,22 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// let result = cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
-/// assert_eq!(result, 1);
+/// let abs_cmp = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
 ///
-/// let result = cmp::min_by(-2, 3, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
-/// assert_eq!(result, -2);
+/// let result = cmp::min_by(2, -1, abs_cmp);
+/// assert_eq!(result, -1);
+///
+/// let result = cmp::min_by(2, -3, abs_cmp);
+/// assert_eq!(result, 2);
+///
+/// let result = cmp::min_by(1, -1, abs_cmp);
+/// assert_eq!(result, 1);
 /// ```
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
 pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
-    match compare(&v1, &v2) {
-        Ordering::Less | Ordering::Equal => v1,
-        Ordering::Greater => v2,
-    }
+    if compare(&v2, &v1).is_lt() { v2 } else { v1 }
 }
 
 /// Returns the element that gives the minimum value from the specified function.
@@ -1456,17 +1512,20 @@ pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// let result = cmp::min_by_key(-2, 1, |x: &i32| x.abs());
-/// assert_eq!(result, 1);
+/// let result = cmp::min_by_key(2, -1, |x: &i32| x.abs());
+/// assert_eq!(result, -1);
 ///
-/// let result = cmp::min_by_key(-2, 2, |x: &i32| x.abs());
-/// assert_eq!(result, -2);
+/// let result = cmp::min_by_key(2, -3, |x: &i32| x.abs());
+/// assert_eq!(result, 2);
+///
+/// let result = cmp::min_by_key(1, -1, |x: &i32| x.abs());
+/// assert_eq!(result, 1);
 /// ```
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
 pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
-    min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
+    if f(&v2) < f(&v1) { v2 } else { v1 }
 }
 
 /// Compares and returns the maximum of two values.
@@ -1483,6 +1542,24 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 /// assert_eq!(cmp::max(1, 2), 2);
 /// assert_eq!(cmp::max(2, 2), 2);
 /// ```
+/// ```
+/// use std::cmp::{self, Ordering};
+///
+/// #[derive(Eq)]
+/// struct Equal(&'static str);
+///
+/// impl PartialEq for Equal {
+///     fn eq(&self, other: &Self) -> bool { true }
+/// }
+/// impl PartialOrd for Equal {
+///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
+/// }
+/// impl Ord for Equal {
+///     fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
+/// }
+///
+/// assert_eq!(cmp::max(Equal("v1"), Equal("v2")).0, "v2");
+/// ```
 #[inline]
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1500,20 +1577,22 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// let result = cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
+/// let abs_cmp = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
+///
+/// let result = cmp::max_by(3, -2, abs_cmp) ;
+/// assert_eq!(result, 3);
+///
+/// let result = cmp::max_by(1, -2, abs_cmp);
 /// assert_eq!(result, -2);
 ///
-/// let result = cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())) ;
-/// assert_eq!(result, 2);
+/// let result = cmp::max_by(1, -1, abs_cmp);
+/// assert_eq!(result, -1);
 /// ```
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
 pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
-    match compare(&v1, &v2) {
-        Ordering::Less | Ordering::Equal => v2,
-        Ordering::Greater => v1,
-    }
+    if compare(&v2, &v1).is_lt() { v1 } else { v2 }
 }
 
 /// Returns the element that gives the maximum value from the specified function.
@@ -1525,17 +1604,20 @@ pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// let result = cmp::max_by_key(-2, 1, |x: &i32| x.abs());
+/// let result = cmp::max_by_key(3, -2, |x: &i32| x.abs());
+/// assert_eq!(result, 3);
+///
+/// let result = cmp::max_by_key(1, -2, |x: &i32| x.abs());
 /// assert_eq!(result, -2);
 ///
-/// let result = cmp::max_by_key(-2, 2, |x: &i32| x.abs());
-/// assert_eq!(result, 2);
+/// let result = cmp::max_by_key(1, -1, |x: &i32| x.abs());
+/// assert_eq!(result, -1);
 /// ```
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
 pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
-    max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
+    if f(&v2) < f(&v1) { v1 } else { v2 }
 }
 
 /// Compares and sorts two values, returning minimum and maximum.
@@ -1549,13 +1631,32 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 /// use std::cmp;
 ///
 /// assert_eq!(cmp::minmax(1, 2), [1, 2]);
-/// assert_eq!(cmp::minmax(2, 2), [2, 2]);
+/// assert_eq!(cmp::minmax(2, 1), [1, 2]);
 ///
 /// // You can destructure the result using array patterns
 /// let [min, max] = cmp::minmax(42, 17);
 /// assert_eq!(min, 17);
 /// assert_eq!(max, 42);
 /// ```
+/// ```
+/// #![feature(cmp_minmax)]
+/// use std::cmp::{self, Ordering};
+///
+/// #[derive(Eq)]
+/// struct Equal(&'static str);
+///
+/// impl PartialEq for Equal {
+///     fn eq(&self, other: &Self) -> bool { true }
+/// }
+/// impl PartialOrd for Equal {
+///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
+/// }
+/// impl Ord for Equal {
+///     fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
+/// }
+///
+/// assert_eq!(cmp::minmax(Equal("v1"), Equal("v2")).map(|v| v.0), ["v1", "v2"]);
+/// ```
 #[inline]
 #[must_use]
 #[unstable(feature = "cmp_minmax", issue = "115939")]
@@ -1563,7 +1664,7 @@ pub fn minmax<T>(v1: T, v2: T) -> [T; 2]
 where
     T: Ord,
 {
-    if v1 <= v2 { [v1, v2] } else { [v2, v1] }
+    if v2 < v1 { [v2, v1] } else { [v1, v2] }
 }
 
 /// Returns minimum and maximum values with respect to the specified comparison function.
@@ -1576,11 +1677,14 @@ where
 /// #![feature(cmp_minmax)]
 /// use std::cmp;
 ///
-/// assert_eq!(cmp::minmax_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [1, -2]);
-/// assert_eq!(cmp::minmax_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [-2, 2]);
+/// let abs_cmp = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
+///
+/// assert_eq!(cmp::minmax_by(-2, 1, abs_cmp), [1, -2]);
+/// assert_eq!(cmp::minmax_by(-1, 2, abs_cmp), [-1, 2]);
+/// assert_eq!(cmp::minmax_by(-2, 2, abs_cmp), [-2, 2]);
 ///
 /// // You can destructure the result using array patterns
-/// let [min, max] = cmp::minmax_by(-42, 17, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
+/// let [min, max] = cmp::minmax_by(-42, 17, abs_cmp);
 /// assert_eq!(min, 17);
 /// assert_eq!(max, -42);
 /// ```
@@ -1591,7 +1695,7 @@ pub fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2]
 where
     F: FnOnce(&T, &T) -> Ordering,
 {
-    if compare(&v1, &v2).is_le() { [v1, v2] } else { [v2, v1] }
+    if compare(&v2, &v1).is_lt() { [v2, v1] } else { [v1, v2] }
 }
 
 /// Returns minimum and maximum values with respect to the specified key function.
@@ -1620,7 +1724,7 @@ where
     F: FnMut(&T) -> K,
     K: Ord,
 {
-    minmax_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
+    if f(&v2) < f(&v1) { [v2, v1] } else { [v1, v2] }
 }
 
 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
diff --git a/library/core/src/contracts.rs b/library/core/src/contracts.rs
new file mode 100644
index 00000000000..c769e219e4d
--- /dev/null
+++ b/library/core/src/contracts.rs
@@ -0,0 +1,21 @@
+//! Unstable module containing the unstable contracts lang items and attribute macros.
+#![cfg(not(bootstrap))]
+
+pub use crate::macros::builtin::{contracts_ensures as ensures, contracts_requires as requires};
+
+/// Emitted by rustc as a desugaring of `#[ensures(PRED)] fn foo() -> R { ... [return R;] ... }`
+/// into: `fn foo() { let _check = build_check_ensures(|ret| PRED) ... [return _check(R);] ... }`
+/// (including the implicit return of the tail expression, if any).
+#[unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)]
+#[lang = "contract_build_check_ensures"]
+#[track_caller]
+pub fn build_check_ensures<Ret, C>(cond: C) -> impl (Fn(Ret) -> Ret) + Copy
+where
+    C: for<'a> Fn(&'a Ret) -> bool + Copy + 'static,
+{
+    #[track_caller]
+    move |ret| {
+        crate::intrinsics::contract_check_ensures(&ret, cond);
+        ret
+    }
+}
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index 51687a3adcd..50968c57adc 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -37,175 +37,14 @@ pub use self::va_list::{VaList, VaListImpl};
 )]
 pub mod va_list;
 
-macro_rules! type_alias {
-    {
-      $Docfile:tt, $Alias:ident = $Real:ty;
-      $( $Cfg:tt )*
-    } => {
-        #[doc = include_str!($Docfile)]
-        $( $Cfg )*
-        #[stable(feature = "core_ffi_c", since = "1.64.0")]
-        pub type $Alias = $Real;
-    }
-}
-
-type_alias! { "c_char.md", c_char = c_char_definition::c_char; #[doc(cfg(all()))] }
-
-type_alias! { "c_schar.md", c_schar = i8; }
-type_alias! { "c_uchar.md", c_uchar = u8; }
-type_alias! { "c_short.md", c_short = i16; }
-type_alias! { "c_ushort.md", c_ushort = u16; }
-
-type_alias! { "c_int.md", c_int = c_int_definition::c_int; #[doc(cfg(all()))] }
-type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint; #[doc(cfg(all()))] }
-
-type_alias! { "c_long.md", c_long = c_long_definition::c_long; #[doc(cfg(all()))] }
-type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong; #[doc(cfg(all()))] }
-
-type_alias! { "c_longlong.md", c_longlong = i64; }
-type_alias! { "c_ulonglong.md", c_ulonglong = u64; }
-
-type_alias! { "c_float.md", c_float = f32; }
-type_alias! { "c_double.md", c_double = f64; }
-
-/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
-///
-/// This type is currently always [`usize`], however in the future there may be
-/// platforms where this is not the case.
-#[unstable(feature = "c_size_t", issue = "88345")]
-pub type c_size_t = usize;
-
-/// Equivalent to C's `ptrdiff_t` type, from `stddef.h` (or `cstddef` for C++).
-///
-/// This type is currently always [`isize`], however in the future there may be
-/// platforms where this is not the case.
+mod primitives;
+#[stable(feature = "core_ffi_c", since = "1.64.0")]
+pub use self::primitives::{
+    c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint,
+    c_ulong, c_ulonglong, c_ushort,
+};
 #[unstable(feature = "c_size_t", issue = "88345")]
-pub type c_ptrdiff_t = isize;
-
-/// Equivalent to C's `ssize_t` (on POSIX) or `SSIZE_T` (on Windows) type.
-///
-/// This type is currently always [`isize`], however in the future there may be
-/// platforms where this is not the case.
-#[unstable(feature = "c_size_t", issue = "88345")]
-pub type c_ssize_t = isize;
-
-mod c_char_definition {
-    cfg_if! {
-        // These are the targets on which c_char is unsigned. Usually the
-        // signedness is the same for all target_os values on a given architecture
-        // but there are some exceptions (see isSignedCharDefault() in clang).
-        //
-        // aarch64:
-        //   Section 10 "Arm C and C++ language mappings" in Procedure Call Standard for the Arm®
-        //   64-bit Architecture (AArch64) says C/C++ char is unsigned byte.
-        //   https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs64/aapcs64.rst#arm-c-and-c-language-mappings
-        // arm:
-        //   Section 8 "Arm C and C++ Language Mappings" in Procedure Call Standard for the Arm®
-        //   Architecture says C/C++ char is unsigned byte.
-        //   https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs32/aapcs32.rst#arm-c-and-c-language-mappings
-        // csky:
-        //   Section 2.1.2 "Primary Data Type" in C-SKY V2 CPU Applications Binary Interface
-        //   Standards Manual says ANSI C char is unsigned byte.
-        //   https://github.com/c-sky/csky-doc/blob/9f7121f7d40970ba5cc0f15716da033db2bb9d07/C-SKY_V2_CPU_Applications_Binary_Interface_Standards_Manual.pdf
-        //   Note: this doesn't seem to match Clang's default (https://github.com/rust-lang/rust/issues/129945).
-        // hexagon:
-        //   Section 3.1 "Basic data type" in Qualcomm Hexagon™ Application
-        //   Binary Interface User Guide says "By default, the `char` data type is unsigned."
-        //   https://docs.qualcomm.com/bundle/publicresource/80-N2040-23_REV_K_Qualcomm_Hexagon_Application_Binary_Interface_User_Guide.pdf
-        // msp430:
-        //   Section 2.1 "Basic Types" in MSP430 Embedded Application Binary
-        //   Interface says "The char type is unsigned by default".
-        //   https://www.ti.com/lit/an/slaa534a/slaa534a.pdf
-        // powerpc/powerpc64:
-        //   - PPC32 SysV: "Table 3-1 Scalar Types" in System V Application Binary Interface PowerPC
-        //     Processor Supplement says ANSI C char is unsigned byte
-        //     https://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf
-        //   - PPC64 ELFv1: Section 3.1.4 "Fundamental Types" in 64-bit PowerPC ELF Application
-        //     Binary Interface Supplement 1.9 says ANSI C is unsigned byte
-        //     https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#FUND-TYPE
-        //   - PPC64 ELFv2: Section 2.1.2.2 "Fundamental Types" in 64-Bit ELF V2 ABI Specification
-        //     says char is unsigned byte
-        //     https://openpowerfoundation.org/specifications/64bitelfabi/
-        //   - AIX: XL C for AIX Language Reference says "By default, char behaves like an unsigned char."
-        //     https://www.ibm.com/docs/en/xl-c-aix/13.1.3?topic=specifiers-character-types
-        // riscv32/riscv64:
-        //   C/C++ type representations section in RISC-V Calling Conventions
-        //   page in RISC-V ELF psABI Document says "char is unsigned."
-        //   https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20240829-13bfa9f54634cb60d86b9b333e109f077805b4b3/riscv-cc.adoc#cc-type-representations
-        // s390x:
-        //   - ELF: "Table 1.1.: Scalar types" in ELF Application Binary Interface s390x Supplement
-        //     Version 1.6.1 categorize ISO C char in unsigned integer
-        //     https://github.com/IBM/s390x-abi/releases/tag/v1.6.1
-        //   - z/OS: XL C/C++ Language Reference says: "By default, char behaves like an unsigned char."
-        //     https://www.ibm.com/docs/en/zos/3.1.0?topic=specifiers-character-types
-        // xtensa:
-        //   Section 2.17.1 "Data Types and Alignment" of Xtensa LX Microprocessor Overview handbook
-        //   says "`char` type is unsigned by default".
-        //   https://loboris.eu/ESP32/Xtensa_lx%20Overview%20handbook.pdf
-        //
-        // On the following operating systems, c_char is signed by default, regardless of architecture.
-        // Darwin (macOS, iOS, etc.):
-        //   Apple targets' c_char is signed by default even on arm
-        //   https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Handle-data-types-and-data-alignment-properly
-        // Windows:
-        //   Windows MSVC C++ Language Reference says "Microsoft-specific: Variables of type char
-        //   are promoted to int as if from type signed char by default, unless the /J compilation
-        //   option is used."
-        //   https://learn.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=msvc-170#character-types
-        // L4Re:
-        //   The kernel builds with -funsigned-char on all targets (but useserspace follows the
-        //   architecture defaults). As we only have a target for userspace apps so there are no
-        //   special cases for L4Re below.
-        //   https://github.com/rust-lang/rust/pull/132975#issuecomment-2484645240
-        if #[cfg(all(
-            not(windows),
-            not(target_vendor = "apple"),
-            any(
-                target_arch = "aarch64",
-                target_arch = "arm",
-                target_arch = "csky",
-                target_arch = "hexagon",
-                target_arch = "msp430",
-                target_arch = "powerpc",
-                target_arch = "powerpc64",
-                target_arch = "riscv32",
-                target_arch = "riscv64",
-                target_arch = "s390x",
-                target_arch = "xtensa",
-            )
-        ))] {
-            pub(super) type c_char = u8;
-        } else {
-            // On every other target, c_char is signed.
-            pub(super) type c_char = i8;
-        }
-    }
-}
-
-mod c_int_definition {
-    cfg_if! {
-        if #[cfg(any(target_arch = "avr", target_arch = "msp430"))] {
-            pub(super) type c_int = i16;
-            pub(super) type c_uint = u16;
-        } else {
-            pub(super) type c_int = i32;
-            pub(super) type c_uint = u32;
-        }
-    }
-}
-
-mod c_long_definition {
-    cfg_if! {
-        if #[cfg(all(target_pointer_width = "64", not(windows)))] {
-            pub(super) type c_long = i64;
-            pub(super) type c_ulong = u64;
-        } else {
-            // The minimal size of `long` in the C standard is 32 bits
-            pub(super) type c_long = i32;
-            pub(super) type c_ulong = u32;
-        }
-    }
-}
+pub use self::primitives::{c_ptrdiff_t, c_size_t, c_ssize_t};
 
 // N.B., for LLVM to recognize the void pointer type and by extension
 //     functions like malloc(), we need to have it represented as i8* in
diff --git a/library/core/src/ffi/primitives.rs b/library/core/src/ffi/primitives.rs
new file mode 100644
index 00000000000..ece3c7538da
--- /dev/null
+++ b/library/core/src/ffi/primitives.rs
@@ -0,0 +1,174 @@
+//! Defines primitive types that match C's type definitions for FFI compatibility.
+//!
+//! This module is intentionally standalone to facilitate parsing when retrieving
+//! core C types.
+
+macro_rules! type_alias {
+    {
+      $Docfile:tt, $Alias:ident = $Real:ty;
+      $( $Cfg:tt )*
+    } => {
+        #[doc = include_str!($Docfile)]
+        $( $Cfg )*
+        #[stable(feature = "core_ffi_c", since = "1.64.0")]
+        pub type $Alias = $Real;
+    }
+}
+
+type_alias! { "c_char.md", c_char = c_char_definition::c_char; #[doc(cfg(all()))] }
+
+type_alias! { "c_schar.md", c_schar = i8; }
+type_alias! { "c_uchar.md", c_uchar = u8; }
+type_alias! { "c_short.md", c_short = i16; }
+type_alias! { "c_ushort.md", c_ushort = u16; }
+
+type_alias! { "c_int.md", c_int = c_int_definition::c_int; #[doc(cfg(all()))] }
+type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint; #[doc(cfg(all()))] }
+
+type_alias! { "c_long.md", c_long = c_long_definition::c_long; #[doc(cfg(all()))] }
+type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong; #[doc(cfg(all()))] }
+
+type_alias! { "c_longlong.md", c_longlong = i64; }
+type_alias! { "c_ulonglong.md", c_ulonglong = u64; }
+
+type_alias! { "c_float.md", c_float = f32; }
+type_alias! { "c_double.md", c_double = f64; }
+
+mod c_char_definition {
+    cfg_if! {
+        // These are the targets on which c_char is unsigned. Usually the
+        // signedness is the same for all target_os values on a given architecture
+        // but there are some exceptions (see isSignedCharDefault() in clang).
+        //
+        // aarch64:
+        //   Section 10 "Arm C and C++ language mappings" in Procedure Call Standard for the Arm®
+        //   64-bit Architecture (AArch64) says C/C++ char is unsigned byte.
+        //   https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs64/aapcs64.rst#arm-c-and-c-language-mappings
+        // arm:
+        //   Section 8 "Arm C and C++ Language Mappings" in Procedure Call Standard for the Arm®
+        //   Architecture says C/C++ char is unsigned byte.
+        //   https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs32/aapcs32.rst#arm-c-and-c-language-mappings
+        // csky:
+        //   Section 2.1.2 "Primary Data Type" in C-SKY V2 CPU Applications Binary Interface
+        //   Standards Manual says ANSI C char is unsigned byte.
+        //   https://github.com/c-sky/csky-doc/blob/9f7121f7d40970ba5cc0f15716da033db2bb9d07/C-SKY_V2_CPU_Applications_Binary_Interface_Standards_Manual.pdf
+        //   Note: this doesn't seem to match Clang's default (https://github.com/rust-lang/rust/issues/129945).
+        // hexagon:
+        //   Section 3.1 "Basic data type" in Qualcomm Hexagon™ Application
+        //   Binary Interface User Guide says "By default, the `char` data type is unsigned."
+        //   https://docs.qualcomm.com/bundle/publicresource/80-N2040-23_REV_K_Qualcomm_Hexagon_Application_Binary_Interface_User_Guide.pdf
+        // msp430:
+        //   Section 2.1 "Basic Types" in MSP430 Embedded Application Binary
+        //   Interface says "The char type is unsigned by default".
+        //   https://www.ti.com/lit/an/slaa534a/slaa534a.pdf
+        // powerpc/powerpc64:
+        //   - PPC32 SysV: "Table 3-1 Scalar Types" in System V Application Binary Interface PowerPC
+        //     Processor Supplement says ANSI C char is unsigned byte
+        //     https://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf
+        //   - PPC64 ELFv1: Section 3.1.4 "Fundamental Types" in 64-bit PowerPC ELF Application
+        //     Binary Interface Supplement 1.9 says ANSI C is unsigned byte
+        //     https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#FUND-TYPE
+        //   - PPC64 ELFv2: Section 2.1.2.2 "Fundamental Types" in 64-Bit ELF V2 ABI Specification
+        //     says char is unsigned byte
+        //     https://openpowerfoundation.org/specifications/64bitelfabi/
+        //   - AIX: XL C for AIX Language Reference says "By default, char behaves like an unsigned char."
+        //     https://www.ibm.com/docs/en/xl-c-aix/13.1.3?topic=specifiers-character-types
+        // riscv32/riscv64:
+        //   C/C++ type representations section in RISC-V Calling Conventions
+        //   page in RISC-V ELF psABI Document says "char is unsigned."
+        //   https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20240829-13bfa9f54634cb60d86b9b333e109f077805b4b3/riscv-cc.adoc#cc-type-representations
+        // s390x:
+        //   - ELF: "Table 1.1.: Scalar types" in ELF Application Binary Interface s390x Supplement
+        //     Version 1.6.1 categorize ISO C char in unsigned integer
+        //     https://github.com/IBM/s390x-abi/releases/tag/v1.6.1
+        //   - z/OS: XL C/C++ Language Reference says: "By default, char behaves like an unsigned char."
+        //     https://www.ibm.com/docs/en/zos/3.1.0?topic=specifiers-character-types
+        // xtensa:
+        //   Section 2.17.1 "Data Types and Alignment" of Xtensa LX Microprocessor Overview handbook
+        //   says "`char` type is unsigned by default".
+        //   https://loboris.eu/ESP32/Xtensa_lx%20Overview%20handbook.pdf
+        //
+        // On the following operating systems, c_char is signed by default, regardless of architecture.
+        // Darwin (macOS, iOS, etc.):
+        //   Apple targets' c_char is signed by default even on arm
+        //   https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Handle-data-types-and-data-alignment-properly
+        // Windows:
+        //   Windows MSVC C++ Language Reference says "Microsoft-specific: Variables of type char
+        //   are promoted to int as if from type signed char by default, unless the /J compilation
+        //   option is used."
+        //   https://learn.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=msvc-170#character-types
+        // L4Re:
+        //   The kernel builds with -funsigned-char on all targets (but useserspace follows the
+        //   architecture defaults). As we only have a target for userspace apps so there are no
+        //   special cases for L4Re below.
+        //   https://github.com/rust-lang/rust/pull/132975#issuecomment-2484645240
+        if #[cfg(all(
+            not(windows),
+            not(target_vendor = "apple"),
+            any(
+                target_arch = "aarch64",
+                target_arch = "arm",
+                target_arch = "csky",
+                target_arch = "hexagon",
+                target_arch = "msp430",
+                target_arch = "powerpc",
+                target_arch = "powerpc64",
+                target_arch = "riscv32",
+                target_arch = "riscv64",
+                target_arch = "s390x",
+                target_arch = "xtensa",
+            )
+        ))] {
+            pub(super) type c_char = u8;
+        } else {
+            // On every other target, c_char is signed.
+            pub(super) type c_char = i8;
+        }
+    }
+}
+
+mod c_long_definition {
+    cfg_if! {
+        if #[cfg(all(target_pointer_width = "64", not(windows)))] {
+            pub(super) type c_long = i64;
+            pub(super) type c_ulong = u64;
+        } else {
+            // The minimal size of `long` in the C standard is 32 bits
+            pub(super) type c_long = i32;
+            pub(super) type c_ulong = u32;
+        }
+    }
+}
+
+/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
+///
+/// This type is currently always [`usize`], however in the future there may be
+/// platforms where this is not the case.
+#[unstable(feature = "c_size_t", issue = "88345")]
+pub type c_size_t = usize;
+
+/// Equivalent to C's `ptrdiff_t` type, from `stddef.h` (or `cstddef` for C++).
+///
+/// This type is currently always [`isize`], however in the future there may be
+/// platforms where this is not the case.
+#[unstable(feature = "c_size_t", issue = "88345")]
+pub type c_ptrdiff_t = isize;
+
+/// Equivalent to C's `ssize_t` (on POSIX) or `SSIZE_T` (on Windows) type.
+///
+/// This type is currently always [`isize`], however in the future there may be
+/// platforms where this is not the case.
+#[unstable(feature = "c_size_t", issue = "88345")]
+pub type c_ssize_t = isize;
+
+mod c_int_definition {
+    cfg_if! {
+        if #[cfg(any(target_arch = "avr", target_arch = "msp430"))] {
+            pub(super) type c_int = i16;
+            pub(super) type c_uint = u16;
+        } else {
+            pub(super) type c_int = i32;
+            pub(super) type c_uint = u32;
+        }
+    }
+}
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index 683e45b35f7..7166f106b8d 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -192,7 +192,8 @@ macro_rules! impl_Debug {
 }
 
 // 2 digit decimal look up table
-static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\
+static DEC_DIGITS_LUT: &[u8; 200] = b"\
+      0001020304050607080910111213141516171819\
       2021222324252627282930313233343536373839\
       4041424344454647484950515253545556575859\
       6061626364656667686970717273747576777879\
@@ -232,83 +233,89 @@ macro_rules! impl_Display {
 
         #[cfg(not(feature = "optimize_for_size"))]
         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);
-                let lut_ptr = DEC_DIGITS_LUT.as_ptr();
-
-                // SAFETY: Since `d1` and `d2` are always less than or equal to `198`, we
-                // can copy from `lut_ptr[d1..d1 + 1]` and `lut_ptr[d2..d2 + 1]`. To show
-                // that it's OK to copy into `buf_ptr`, notice that at the beginning
-                // `curr == buf.len() == 39 > log(n)` since `n < 2^128 < 10^39`, and at
-                // each step this is kept the same as `n` is divided. Since `n` is always
-                // non-negative, this means that `curr > 0` so `buf_ptr[curr..curr + 1]`
-                // is safe to access.
-                unsafe {
-                    // need at least 16 bits for the 4-characters-at-a-time to work.
-                    #[allow(overflowing_literals)]
-                    #[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::<$unsigned>() >= 2 {
-                        // eagerly decode 4 characters at a time
-                        while self >= 10000 {
-                            let rem = (self % 10000) as usize;
-                            self /= 10000;
-
-                            let d1 = (rem / 100) << 1;
-                            let d2 = (rem % 100) << 1;
-                            curr -= 4;
-
-                            // We are allowed to copy to `buf_ptr[curr..curr + 3]` here since
-                            // otherwise `curr < 0`. But then `n` was originally at least `10000^10`
-                            // which is `10^40 > 2^128 > n`.
-                            ptr::copy_nonoverlapping(lut_ptr.add(d1 as usize), buf_ptr.add(curr), 2);
-                            ptr::copy_nonoverlapping(lut_ptr.add(d2 as usize), buf_ptr.add(curr + 2), 2);
-                        }
-                    }
-
-                    // if we reach here numbers are <= 9999, so at most 4 chars long
-                    let mut n = self as usize; // possibly reduce 64bit math
+            fn _fmt(self, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                const MAX_DEC_N: usize = $unsigned::MAX.ilog(10) as usize + 1;
+                // Buffer decimals for $unsigned with right alignment.
+                let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
+                // Count the number of bytes in buf that are not initialized.
+                let mut offset = buf.len();
+                // Consume the least-significant decimals from a working copy.
+                let mut remain = self;
+
+                // Format per four digits from the lookup table.
+                // Four digits need a 16-bit $unsigned or wider.
+                while size_of::<Self>() > 1 && remain > 999.try_into().expect("branch is not hit for types that cannot fit 999 (u8)") {
+                    // SAFETY: All of the decimals fit in buf due to MAX_DEC_N
+                    // and the while condition ensures at least 4 more decimals.
+                    unsafe { core::hint::assert_unchecked(offset >= 4) }
+                    // SAFETY: The offset counts down from its initial buf.len()
+                    // without underflow due to the previous precondition.
+                    unsafe { core::hint::assert_unchecked(offset <= buf.len()) }
+                    offset -= 4;
+
+                    // pull two pairs
+                    let scale: Self = 1_00_00.try_into().expect("branch is not hit for types that cannot fit 1E4 (u8)");
+                    let quad = remain % scale;
+                    remain /= scale;
+                    let pair1 = (quad / 100) as usize;
+                    let pair2 = (quad % 100) as usize;
+                    buf[offset + 0].write(DEC_DIGITS_LUT[pair1 * 2 + 0]);
+                    buf[offset + 1].write(DEC_DIGITS_LUT[pair1 * 2 + 1]);
+                    buf[offset + 2].write(DEC_DIGITS_LUT[pair2 * 2 + 0]);
+                    buf[offset + 3].write(DEC_DIGITS_LUT[pair2 * 2 + 1]);
+                }
 
-                    // decode 2 more chars, if > 2 chars
-                    if n >= 100 {
-                        let d1 = (n % 100) << 1;
-                        n /= 100;
-                        curr -= 2;
-                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
-                    }
+                // Format per two digits from the lookup table.
+                if remain > 9 {
+                    // SAFETY: All of the decimals fit in buf due to MAX_DEC_N
+                    // and the while condition ensures at least 2 more decimals.
+                    unsafe { core::hint::assert_unchecked(offset >= 2) }
+                    // SAFETY: The offset counts down from its initial buf.len()
+                    // without underflow due to the previous precondition.
+                    unsafe { core::hint::assert_unchecked(offset <= buf.len()) }
+                    offset -= 2;
+
+                    let pair = (remain % 100) as usize;
+                    remain /= 100;
+                    buf[offset + 0].write(DEC_DIGITS_LUT[pair * 2 + 0]);
+                    buf[offset + 1].write(DEC_DIGITS_LUT[pair * 2 + 1]);
+                }
 
-                    // if we reach here numbers are <= 100, so at most 2 chars long
-                    // The biggest it can be is 99, and 99 << 1 == 198, so a `u8` is enough.
-                    // decode last 1 or 2 chars
-                    if n < 10 {
-                        curr -= 1;
-                        *buf_ptr.add(curr) = (n as u8) + b'0';
-                    } else {
-                        let d1 = n << 1;
-                        curr -= 2;
-                        ptr::copy_nonoverlapping(lut_ptr.add(d1), buf_ptr.add(curr), 2);
-                    }
+                // Format the last remaining digit, if any.
+                if remain != 0 || self == 0 {
+                    // SAFETY: All of the decimals fit in buf due to MAX_DEC_N
+                    // and the if condition ensures (at least) 1 more decimals.
+                    unsafe { core::hint::assert_unchecked(offset >= 1) }
+                    // SAFETY: The offset counts down from its initial buf.len()
+                    // without underflow due to the previous precondition.
+                    unsafe { core::hint::assert_unchecked(offset <= buf.len()) }
+                    offset -= 1;
+
+                    // Either the compiler sees that remain < 10, or it prevents
+                    // a boundary check up next.
+                    let last = (remain & 15) as usize;
+                    buf[offset].write(DEC_DIGITS_LUT[last * 2 + 1]);
+                    // not used: remain = 0;
                 }
 
-                // SAFETY: `curr` > 0 (since we made `buf` large enough), and all the chars are valid
-                // UTF-8 since `DEC_DIGITS_LUT` is
-                let buf_slice = unsafe {
-                    str::from_utf8_unchecked(
-                        slice::from_raw_parts(buf_ptr.add(curr), buf.len() - curr))
+                // SAFETY: All buf content since offset is set.
+                let written = unsafe { buf.get_unchecked(offset..) };
+                // SAFETY: Writes use ASCII from the lookup table exclusively.
+                let as_str = unsafe {
+                    str::from_utf8_unchecked(slice::from_raw_parts(
+                          MaybeUninit::slice_as_ptr(written),
+                          written.len(),
+                    ))
                 };
-                f.pad_integral(is_nonnegative, "", buf_slice)
+                f.pad_integral(is_nonnegative, "", as_str)
             }
         })*
 
         #[cfg(feature = "optimize_for_size")]
         fn $gen_name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            const SIZE: usize = $u::MAX.ilog(10) as usize + 1;
-            let mut buf = [MaybeUninit::<u8>::uninit(); SIZE];
-            let mut curr = buf.len();
+            const MAX_DEC_N: usize = $u::MAX.ilog(10) as usize + 1;
+            let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
+            let mut curr = MAX_DEC_N;
             let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
 
             // SAFETY: To show that it's OK to copy into `buf_ptr`, notice that at the beginning
diff --git a/library/core/src/intrinsics/fallback.rs b/library/core/src/intrinsics/fallback.rs
index 70484e4d0f2..eec5c4d646d 100644
--- a/library/core/src/intrinsics/fallback.rs
+++ b/library/core/src/intrinsics/fallback.rs
@@ -110,3 +110,41 @@ impl const CarryingMulAdd for i128 {
         (low, high)
     }
 }
+
+#[const_trait]
+#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
+pub trait DisjointBitOr: Copy + 'static {
+    /// See [`super::disjoint_bitor`]; we just need the trait indirection to handle
+    /// different types since calling intrinsics with generics doesn't work.
+    unsafe fn disjoint_bitor(self, other: Self) -> Self;
+}
+macro_rules! zero {
+    (bool) => {
+        false
+    };
+    ($t:ident) => {
+        0
+    };
+}
+macro_rules! impl_disjoint_bitor {
+    ($($t:ident,)+) => {$(
+        #[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
+        impl const DisjointBitOr for $t {
+            #[cfg_attr(miri, track_caller)]
+            #[inline]
+            unsafe fn disjoint_bitor(self, other: Self) -> Self {
+                // Note that the assume here is required for UB detection in Miri!
+
+                // SAFETY: our precondition is that there are no bits in common,
+                // so this is just telling that to the backend.
+                unsafe { super::assume((self & other) == zero!($t)) };
+                self | other
+            }
+        }
+    )+};
+}
+impl_disjoint_bitor! {
+    bool,
+    u8, u16, u32, u64, u128, usize,
+    i8, i16, i32, i64, i128, isize,
+}
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index c0d435f99c0..3b249c835f2 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -78,7 +78,11 @@ pub mod simd;
 use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
 
 #[stable(feature = "drop_in_place", since = "1.8.0")]
-#[rustc_allowed_through_unstable_modules]
+#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)]
+#[cfg_attr(
+    not(bootstrap),
+    rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead"
+)]
 #[deprecated(note = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.52.0")]
 #[inline]
 pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
@@ -3244,6 +3248,26 @@ pub const fn three_way_compare<T: Copy>(_lhs: T, _rhss: T) -> crate::cmp::Orderi
     unimplemented!()
 }
 
+/// Combine two values which have no bits in common.
+///
+/// This allows the backend to implement it as `a + b` *or* `a | b`,
+/// depending which is easier to implement on a specific target.
+///
+/// # Safety
+///
+/// Requires that `(a & b) == 0`, or equivalently that `(a | b) == (a + b)`.
+///
+/// Otherwise it's immediate UB.
+#[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")]
+#[rustc_nounwind]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+#[miri::intrinsic_fallback_is_spec] // the fallbacks all `assume` to tell Miri
+pub const unsafe fn disjoint_bitor<T: ~const fallback::DisjointBitOr>(a: T, b: T) -> T {
+    // SAFETY: same preconditions as this function.
+    unsafe { fallback::DisjointBitOr::disjoint_bitor(a, b) }
+}
+
 /// Performs checked integer addition.
 ///
 /// Note that, unlike most intrinsics, this is safe to call;
@@ -4040,6 +4064,52 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize)
     // Runtime NOP
 }
 
+/// Returns whether we should perform contract-checking at runtime.
+///
+/// This is meant to be similar to the ub_checks intrinsic, in terms
+/// of not prematurely commiting at compile-time to whether contract
+/// checking is turned on, so that we can specify contracts in libstd
+/// and let an end user opt into turning them on.
+#[cfg(not(bootstrap))]
+#[rustc_const_unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)]
+#[unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)]
+#[inline(always)]
+#[rustc_intrinsic]
+pub const fn contract_checks() -> bool {
+    // FIXME: should this be `false` or `cfg!(contract_checks)`?
+
+    // cfg!(contract_checks)
+    false
+}
+
+/// Check if the pre-condition `cond` has been met.
+///
+/// By default, if `contract_checks` is enabled, this will panic with no unwind if the condition
+/// returns false.
+#[cfg(not(bootstrap))]
+#[unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)]
+#[lang = "contract_check_requires"]
+#[rustc_intrinsic]
+pub fn contract_check_requires<C: Fn() -> bool>(cond: C) {
+    if contract_checks() && !cond() {
+        // Emit no unwind panic in case this was a safety requirement.
+        crate::panicking::panic_nounwind("failed requires check");
+    }
+}
+
+/// Check if the post-condition `cond` has been met.
+///
+/// By default, if `contract_checks` is enabled, this will panic with no unwind if the condition
+/// returns false.
+#[cfg(not(bootstrap))]
+#[unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)]
+#[rustc_intrinsic]
+pub fn contract_check_ensures<'a, Ret, C: Fn(&'a Ret) -> bool>(ret: &'a Ret, cond: C) {
+    if contract_checks() && !cond(ret) {
+        crate::panicking::panic_nounwind("failed ensures check");
+    }
+}
+
 /// The intrinsic will return the size stored in that vtable.
 ///
 /// # Safety
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index c18e0405f72..49ce1bbcf39 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -113,10 +113,12 @@
 #![feature(bigint_helper_methods)]
 #![feature(bstr)]
 #![feature(bstr_internals)]
+#![feature(closure_track_caller)]
 #![feature(const_carrying_mul_add)]
 #![feature(const_eval_select)]
 #![feature(core_intrinsics)]
 #![feature(coverage_attribute)]
+#![feature(disjoint_bitor)]
 #![feature(internal_impls_macro)]
 #![feature(ip)]
 #![feature(is_ascii_octdigit)]
@@ -246,6 +248,10 @@ pub mod autodiff {
     pub use crate::macros::builtin::autodiff;
 }
 
+#[cfg(not(bootstrap))]
+#[unstable(feature = "contracts", issue = "128044")]
+pub mod contracts;
+
 #[unstable(feature = "cfg_match", issue = "115585")]
 pub use crate::macros::cfg_match;
 
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 01a3c9d2ada..4c6fd196bd3 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1777,6 +1777,32 @@ pub(crate) mod builtin {
         /* compiler built-in */
     }
 
+    /// Attribute macro applied to a function to give it a post-condition.
+    ///
+    /// The attribute carries an argument token-tree which is
+    /// eventually parsed as a unary closure expression that is
+    /// invoked on a reference to the return value.
+    #[cfg(not(bootstrap))]
+    #[unstable(feature = "contracts", issue = "128044")]
+    #[allow_internal_unstable(contracts_internals)]
+    #[rustc_builtin_macro]
+    pub macro contracts_ensures($item:item) {
+        /* compiler built-in */
+    }
+
+    /// Attribute macro applied to a function to give it a precondition.
+    ///
+    /// The attribute carries an argument token-tree which is
+    /// eventually parsed as an boolean expression with access to the
+    /// function's formal parameters
+    #[cfg(not(bootstrap))]
+    #[unstable(feature = "contracts", issue = "128044")]
+    #[allow_internal_unstable(contracts_internals)]
+    #[rustc_builtin_macro]
+    pub macro contracts_requires($item:item) {
+        /* compiler built-in */
+    }
+
     /// Attribute macro applied to a function to register it as a handler for allocation failure.
     ///
     /// See also [`std::alloc::handle_alloc_error`](../../../std/alloc/fn.handle_alloc_error.html).
@@ -1831,32 +1857,4 @@ pub(crate) mod builtin {
     pub macro deref($pat:pat) {
         builtin # deref($pat)
     }
-
-    /// Derive macro for `rustc-serialize`. Should not be used in new code.
-    #[rustc_builtin_macro]
-    #[unstable(
-        feature = "rustc_encodable_decodable",
-        issue = "none",
-        soft,
-        reason = "derive macro for `rustc-serialize`; should not be used in new code"
-    )]
-    #[deprecated(since = "1.52.0", note = "rustc-serialize is deprecated and no longer supported")]
-    #[doc(hidden)] // While technically stable, using it is unstable, and deprecated. Hide it.
-    pub macro RustcDecodable($item:item) {
-        /* compiler built-in */
-    }
-
-    /// Derive macro for `rustc-serialize`. Should not be used in new code.
-    #[rustc_builtin_macro]
-    #[unstable(
-        feature = "rustc_encodable_decodable",
-        issue = "none",
-        soft,
-        reason = "derive macro for `rustc-serialize`; should not be used in new code"
-    )]
-    #[deprecated(since = "1.52.0", note = "rustc-serialize is deprecated and no longer supported")]
-    #[doc(hidden)] // While technically stable, using it is unstable, and deprecated. Hide it.
-    pub macro RustcEncodable($item:item) {
-        /* compiler built-in */
-    }
 }
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 18ada14d101..1a8ef20dd7b 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -1077,6 +1077,9 @@ marker_impls! {
 }
 
 /// A common trait implemented by all function pointers.
+//
+// Note that while the trait is internal and unstable it is nevertheless
+// exposed as a public bound of the stable `core::ptr::fn_addr_eq` function.
 #[unstable(
     feature = "fn_ptr_trait",
     issue = "none",
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 61e83ebfad7..a115acf42b1 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -474,6 +474,7 @@ macro_rules! nonzero_integer {
         #[$stability:meta]
         Self = $Ty:ident,
         Primitive = $signedness:ident $Int:ident,
+        SignedPrimitive = $Sint:ty,
         UnsignedPrimitive = $Uint:ty,
 
         // Used in doc comments.
@@ -905,6 +906,7 @@ macro_rules! nonzero_integer {
 
             nonzero_integer_signedness_dependent_methods! {
                 Primitive = $signedness $Int,
+                SignedPrimitive = $Sint,
                 UnsignedPrimitive = $Uint,
             }
 
@@ -1128,6 +1130,7 @@ macro_rules! nonzero_integer {
     (
         Self = $Ty:ident,
         Primitive = unsigned $Int:ident,
+        SignedPrimitive = $Sint:ident,
         rot = $rot:literal,
         rot_op = $rot_op:literal,
         rot_result = $rot_result:literal,
@@ -1140,6 +1143,7 @@ macro_rules! nonzero_integer {
             #[stable(feature = "nonzero", since = "1.28.0")]
             Self = $Ty,
             Primitive = unsigned $Int,
+            SignedPrimitive = $Sint,
             UnsignedPrimitive = $Int,
             rot = $rot,
             rot_op = $rot_op,
@@ -1154,7 +1158,7 @@ macro_rules! nonzero_integer {
     (
         Self = $Ty:ident,
         Primitive = signed $Int:ident,
-        UnsignedPrimitive = $UInt:ident,
+        UnsignedPrimitive = $Uint:ident,
         rot = $rot:literal,
         rot_op = $rot_op:literal,
         rot_result = $rot_result:literal,
@@ -1166,7 +1170,8 @@ macro_rules! nonzero_integer {
             #[stable(feature = "signed_nonzero", since = "1.34.0")]
             Self = $Ty,
             Primitive = signed $Int,
-            UnsignedPrimitive = $UInt,
+            SignedPrimitive = $Int,
+            UnsignedPrimitive = $Uint,
             rot = $rot,
             rot_op = $rot_op,
             rot_result = $rot_result,
@@ -1286,6 +1291,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
     // Associated items for unsigned nonzero types only.
     (
         Primitive = unsigned $Int:ident,
+        SignedPrimitive = $Sint:ty,
         UnsignedPrimitive = $Uint:ty,
     ) => {
         /// The smallest value that can be represented by this non-zero
@@ -1620,11 +1626,35 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
             // results will be sqrt(1), which is 1, so a result can't be zero.
             unsafe { Self::new_unchecked(result) }
         }
+
+        /// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(integer_sign_cast)]
+        /// # use std::num::NonZero;
+        ///
+        #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::MAX;")]
+        ///
+        #[doc = concat!("assert_eq!(n.cast_signed(), NonZero::new(-1", stringify!($Sint), ").unwrap());")]
+        /// ```
+        #[unstable(feature = "integer_sign_cast", issue = "125882")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline(always)]
+        pub const fn cast_signed(self) -> NonZero<$Sint> {
+            // SAFETY: `self.get()` can't be zero
+            unsafe { NonZero::new_unchecked(self.get().cast_signed()) }
+        }
     };
 
     // Associated items for signed nonzero types only.
     (
         Primitive = signed $Int:ident,
+        SignedPrimitive = $Sint:ty,
         UnsignedPrimitive = $Uint:ty,
     ) => {
         /// The smallest value that can be represented by this non-zero
@@ -2035,12 +2065,37 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
             // SAFETY: negation of nonzero cannot yield zero values.
             unsafe { Self::new_unchecked(result) }
         }
+
+        /// Returns the bit pattern of `self` reinterpreted as an unsigned integer of the same size.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(integer_sign_cast)]
+        /// # use std::num::NonZero;
+        ///
+        #[doc = concat!("let n = NonZero::new(-1", stringify!($Int), ").unwrap();")]
+        ///
+        #[doc = concat!("assert_eq!(n.cast_unsigned(), NonZero::<", stringify!($Uint), ">::MAX);")]
+        /// ```
+        #[unstable(feature = "integer_sign_cast", issue = "125882")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline(always)]
+        pub const fn cast_unsigned(self) -> NonZero<$Uint> {
+            // SAFETY: `self.get()` can't be zero
+            unsafe { NonZero::new_unchecked(self.get().cast_unsigned()) }
+        }
+
     };
 }
 
 nonzero_integer! {
     Self = NonZeroU8,
     Primitive = unsigned u8,
+    SignedPrimitive = i8,
     rot = 2,
     rot_op = "0x82",
     rot_result = "0xa",
@@ -2052,6 +2107,7 @@ nonzero_integer! {
 nonzero_integer! {
     Self = NonZeroU16,
     Primitive = unsigned u16,
+    SignedPrimitive = i16,
     rot = 4,
     rot_op = "0xa003",
     rot_result = "0x3a",
@@ -2063,6 +2119,7 @@ nonzero_integer! {
 nonzero_integer! {
     Self = NonZeroU32,
     Primitive = unsigned u32,
+    SignedPrimitive = i32,
     rot = 8,
     rot_op = "0x10000b3",
     rot_result = "0xb301",
@@ -2074,6 +2131,7 @@ nonzero_integer! {
 nonzero_integer! {
     Self = NonZeroU64,
     Primitive = unsigned u64,
+    SignedPrimitive = i64,
     rot = 12,
     rot_op = "0xaa00000000006e1",
     rot_result = "0x6e10aa",
@@ -2085,6 +2143,7 @@ nonzero_integer! {
 nonzero_integer! {
     Self = NonZeroU128,
     Primitive = unsigned u128,
+    SignedPrimitive = i128,
     rot = 16,
     rot_op = "0x13f40000000000000000000000004f76",
     rot_result = "0x4f7613f4",
@@ -2097,6 +2156,7 @@ nonzero_integer! {
 nonzero_integer! {
     Self = NonZeroUsize,
     Primitive = unsigned usize,
+    SignedPrimitive = isize,
     rot = 4,
     rot_op = "0xa003",
     rot_result = "0x3a",
@@ -2109,6 +2169,7 @@ nonzero_integer! {
 nonzero_integer! {
     Self = NonZeroUsize,
     Primitive = unsigned usize,
+    SignedPrimitive = isize,
     rot = 8,
     rot_op = "0x10000b3",
     rot_result = "0xb301",
@@ -2121,6 +2182,7 @@ nonzero_integer! {
 nonzero_integer! {
     Self = NonZeroUsize,
     Primitive = unsigned usize,
+    SignedPrimitive = isize,
     rot = 12,
     rot_op = "0xaa00000000006e1",
     rot_result = "0x6e10aa",
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index c8433b3bb16..29f6791ee6a 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1187,6 +1187,50 @@ macro_rules! uint_impl {
             self % rhs
         }
 
+        /// Same value as `self | other`, but UB if any bit position is set in both inputs.
+        ///
+        /// This is a situational micro-optimization for places where you'd rather
+        /// use addition on some platforms and bitwise or on other platforms, based
+        /// on exactly which instructions combine better with whatever else you're
+        /// doing.  Note that there's no reason to bother using this for places
+        /// where it's clear from the operations involved that they can't overlap.
+        /// For example, if you're combining `u16`s into a `u32` with
+        /// `((a as u32) << 16) | (b as u32)`, that's fine, as the backend will
+        /// know those sides of the `|` are disjoint without needing help.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(disjoint_bitor)]
+        ///
+        /// // SAFETY: `1` and `4` have no bits in common.
+        /// unsafe {
+        #[doc = concat!("    assert_eq!(1_", stringify!($SelfT), ".unchecked_disjoint_bitor(4), 5);")]
+        /// }
+        /// ```
+        ///
+        /// # Safety
+        ///
+        /// Requires that `(self & other) == 0`, otherwise it's immediate UB.
+        ///
+        /// Equivalently, requires that `(self | other) == (self + other)`.
+        #[unstable(feature = "disjoint_bitor", issue = "135758")]
+        #[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")]
+        #[inline]
+        pub const unsafe fn unchecked_disjoint_bitor(self, other: Self) -> Self {
+            assert_unsafe_precondition!(
+                check_language_ub,
+                concat!(stringify!($SelfT), "::unchecked_disjoint_bitor cannot have overlapping bits"),
+                (
+                    lhs: $SelfT = self,
+                    rhs: $SelfT = other,
+                ) => (lhs & rhs) == 0,
+            );
+
+            // SAFETY: Same precondition
+            unsafe { intrinsics::disjoint_bitor(self, other) }
+        }
+
         /// Returns the logarithm of the number with respect to an arbitrary base,
         /// rounded down.
         ///
@@ -2346,15 +2390,22 @@ macro_rules! uint_impl {
         /// assert_eq!((sum1, sum0), (9, 6));
         /// ```
         #[unstable(feature = "bigint_helper_methods", issue = "85532")]
+        #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
         pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
             // note: longer-term this should be done via an intrinsic, but this has been shown
             //   to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
-            let (a, b) = self.overflowing_add(rhs);
-            let (c, d) = a.overflowing_add(carry as $SelfT);
-            (c, b | d)
+            let (a, c1) = self.overflowing_add(rhs);
+            let (b, c2) = a.overflowing_add(carry as $SelfT);
+            // Ideally LLVM would know this is disjoint without us telling them,
+            // but it doesn't <https://github.com/llvm/llvm-project/issues/118162>
+            // SAFETY: Only one of `c1` and `c2` can be set.
+            // For c1 to be set we need to have overflowed, but if we did then
+            // `a` is at most `MAX-1`, which means that `c2` cannot possibly
+            // overflow because it's adding at most `1` (since it came from `bool`)
+            (b, unsafe { intrinsics::disjoint_bitor(c1, c2) })
         }
 
         /// Calculates `self` + `rhs` with a signed `rhs`.
diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs
index d3fda1cd273..0ab97f5bbd5 100644
--- a/library/core/src/prelude/mod.rs
+++ b/library/core/src/prelude/mod.rs
@@ -18,16 +18,6 @@ mod common;
 pub mod v1 {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::common::*;
-
-    // Do not `doc(inline)` these `doc(hidden)` items.
-    #[unstable(
-        feature = "rustc_encodable_decodable",
-        issue = "none",
-        soft,
-        reason = "derive macro for `rustc-serialize`; should not be used in new code"
-    )]
-    #[allow(deprecated)]
-    pub use crate::macros::builtin::{RustcDecodable, RustcEncodable};
 }
 
 /// The 2015 version of the core prelude.
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index c5f029363e5..bbf5939fe1b 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1160,9 +1160,9 @@ impl<T> (T,) {}
 ///
 /// Note that most common platforms will not support `f16` in hardware without enabling extra target
 /// features, with the notable exception of Apple Silicon (also known as M1, M2, etc.) processors.
-/// Hardware support on x86-64 requires the avx512fp16 feature, while RISC-V requires Zhf.
-/// Usually the fallback implementation will be to use `f32` hardware if it exists, and convert
-/// between `f16` and `f32` when performing math.
+/// Hardware support on x86/x86-64 requires the avx512fp16 or avx10.1 features, while RISC-V requires
+/// Zfh, and Arm/AArch64 requires FEAT_FP16.  Usually the fallback implementation will be to use `f32`
+/// hardware if it exists, and convert between `f16` and `f32` when performing math.
 ///
 /// *[See also the `std::f16::consts` module](crate::f16::consts).*
 ///
@@ -1344,10 +1344,10 @@ mod prim_f64 {}
 /// quad-precision values][wikipedia] for more information.
 ///
 /// Note that no platforms have hardware support for `f128` without enabling target specific features,
-/// as for all instruction set architectures `f128` is considered an optional feature.
-/// Only Power ISA ("PowerPC") and RISC-V specify it, and only certain microarchitectures
-/// actually implement it. For x86-64 and AArch64, ISA support is not even specified,
-/// so it will always be a software implementation significantly slower than `f64`.
+/// as for all instruction set architectures `f128` is considered an optional feature.  Only Power ISA
+/// ("PowerPC") and RISC-V (via the Q extension) specify it, and only certain microarchitectures
+/// actually implement it. For x86-64 and AArch64, ISA support is not even specified, so it will always
+/// be a software implementation significantly slower than `f64`.
 ///
 /// _Note: `f128` support is incomplete. Many platforms will not be able to link math functions. On
 /// x86 in particular, these functions do link but their results are always incorrect._
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index ec569291853..0c6eaf60d04 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -1681,7 +1681,7 @@ impl<T, const N: usize> *const [T; N] {
     }
 }
 
-// Equality for pointers
+/// Pointer equality is by address, as produced by the [`<*const T>::addr`](pointer::addr) method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialEq for *const T {
     #[inline]
@@ -1691,10 +1691,11 @@ impl<T: ?Sized> PartialEq for *const T {
     }
 }
 
+/// Pointer equality is an equivalence relation.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Eq for *const T {}
 
-// Comparison for pointers
+/// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Ord for *const T {
     #[inline]
@@ -1710,6 +1711,7 @@ impl<T: ?Sized> Ord for *const T {
     }
 }
 
+/// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialOrd for *const T {
     #[inline]
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 5d9d337f101..d1b0104c0fa 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -2097,7 +2097,7 @@ impl<T, const N: usize> *mut [T; N] {
     }
 }
 
-// Equality for pointers
+/// Pointer equality is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialEq for *mut T {
     #[inline(always)]
@@ -2107,9 +2107,11 @@ impl<T: ?Sized> PartialEq for *mut T {
     }
 }
 
+/// Pointer equality is an equivalence relation.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Eq for *mut T {}
 
+/// Pointer comparison is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Ord for *mut T {
     #[inline]
@@ -2125,6 +2127,7 @@ impl<T: ?Sized> Ord for *mut T {
     }
 }
 
+/// Pointer comparison is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialOrd for *mut T {
     #[inline(always)]
diff --git a/library/core/src/range.rs b/library/core/src/range.rs
index 427526fd14b..6a62928873f 100644
--- a/library/core/src/range.rs
+++ b/library/core/src/range.rs
@@ -48,6 +48,7 @@ pub use crate::ops::{Bound, OneSidedRange, RangeBounds, RangeFull, RangeTo, Rang
 /// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 });
 /// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum());
 /// ```
+#[cfg_attr(not(bootstrap), lang = "RangeCopy")]
 #[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
 #[unstable(feature = "new_range_api", issue = "125687")]
 pub struct Range<Idx> {
@@ -205,6 +206,7 @@ impl<T> From<legacy::Range<T>> for Range<T> {
 /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end: 5 });
 /// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum());
 /// ```
+#[cfg_attr(not(bootstrap), lang = "RangeInclusiveCopy")]
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
 #[unstable(feature = "new_range_api", issue = "125687")]
 pub struct RangeInclusive<Idx> {
@@ -388,6 +390,7 @@ impl<T> From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
 /// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 });
 /// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum());
 /// ```
+#[cfg_attr(not(bootstrap), lang = "RangeFromCopy")]
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
 #[unstable(feature = "new_range_api", issue = "125687")]
 pub struct RangeFrom<Idx> {
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 8a473b398bb..39fa6c1a25f 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -1108,7 +1108,8 @@ impl str {
         LinesAny(self.lines())
     }
 
-    /// Returns an iterator of `u16` over the string encoded as UTF-16.
+    /// Returns an iterator of `u16` over the string encoded
+    /// as native endian UTF-16 (without byte-order mark).
     ///
     /// # Examples
     ///
diff --git a/library/coretests/benches/fmt.rs b/library/coretests/benches/fmt.rs
index ed478b0f1e0..ee8e981b46b 100644
--- a/library/coretests/benches/fmt.rs
+++ b/library/coretests/benches/fmt.rs
@@ -124,42 +124,41 @@ fn write_str_macro_debug_ascii(bh: &mut Bencher) {
 #[bench]
 fn write_u128_max(bh: &mut Bencher) {
     bh.iter(|| {
-        test::black_box(format!("{}", u128::MAX));
+        black_box(format!("{}", black_box(u128::MAX)));
     });
 }
 
 #[bench]
 fn write_u128_min(bh: &mut Bencher) {
     bh.iter(|| {
-        let s = format!("{}", 0u128);
-        test::black_box(s);
+        black_box(format!("{}", black_box(u128::MIN)));
     });
 }
 
 #[bench]
 fn write_u64_max(bh: &mut Bencher) {
     bh.iter(|| {
-        test::black_box(format!("{}", u64::MAX));
+        black_box(format!("{}", black_box(u64::MAX)));
     });
 }
 
 #[bench]
 fn write_u64_min(bh: &mut Bencher) {
     bh.iter(|| {
-        test::black_box(format!("{}", 0u64));
+        black_box(format!("{}", black_box(u64::MIN)));
     });
 }
 
 #[bench]
 fn write_u8_max(bh: &mut Bencher) {
     bh.iter(|| {
-        test::black_box(format!("{}", u8::MAX));
+        black_box(format!("{}", black_box(u8::MAX)));
     });
 }
 
 #[bench]
 fn write_u8_min(bh: &mut Bencher) {
     bh.iter(|| {
-        test::black_box(format!("{}", 0u8));
+        black_box(format!("{}", black_box(u8::MIN)));
     });
 }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 9eab75b0696..944c3438557 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust.git"
 description = "The Rust Standard Library"
 edition = "2021"
+autobenches = false
 
 [lib]
 crate-type = ["dylib", "rlib"]
@@ -130,6 +131,18 @@ name = "pipe-subprocess"
 path = "tests/pipe_subprocess.rs"
 harness = false
 
+[[test]]
+name = "sync"
+path = "tests/sync/lib.rs"
+
+[[test]]
+name = "floats"
+path = "tests/floats/lib.rs"
+
+[[test]]
+name = "thread_local"
+path = "tests/thread_local/lib.rs"
+
 [[bench]]
 name = "stdbenches"
 path = "benches/lib.rs"
diff --git a/library/std/benches/lib.rs b/library/std/benches/lib.rs
index 1b21c230a0b..e749d9c0f79 100644
--- a/library/std/benches/lib.rs
+++ b/library/std/benches/lib.rs
@@ -5,3 +5,5 @@
 extern crate test;
 
 mod hash;
+mod path;
+mod time;
diff --git a/library/std/benches/path.rs b/library/std/benches/path.rs
new file mode 100644
index 00000000000..094c00894a8
--- /dev/null
+++ b/library/std/benches/path.rs
@@ -0,0 +1,114 @@
+use core::hint::black_box;
+use std::collections::{BTreeSet, HashSet};
+use std::hash::{DefaultHasher, Hash, Hasher};
+use std::path::*;
+
+#[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
+fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
+    let prefix = "my/home";
+    let mut paths: Vec<_> =
+        (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
+
+    paths.sort();
+
+    b.iter(|| {
+        black_box(paths.as_mut_slice()).sort_unstable();
+    });
+}
+
+#[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
+fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
+    let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
+    let paths: Vec<_> =
+        (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
+
+    let mut set = BTreeSet::new();
+
+    paths.iter().for_each(|p| {
+        set.insert(p.as_path());
+    });
+
+    b.iter(|| {
+        set.remove(paths[500].as_path());
+        set.insert(paths[500].as_path());
+    });
+}
+
+#[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
+fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
+    let prefix = "my/home";
+    let paths: Vec<_> =
+        (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
+
+    let mut set = BTreeSet::new();
+
+    paths.iter().for_each(|p| {
+        set.insert(p.as_path());
+    });
+
+    b.iter(|| {
+        set.remove(paths[500].as_path());
+        set.insert(paths[500].as_path());
+    });
+}
+
+#[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
+fn bench_path_hashset(b: &mut test::Bencher) {
+    let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
+    let paths: Vec<_> =
+        (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
+
+    let mut set = HashSet::new();
+
+    paths.iter().for_each(|p| {
+        set.insert(p.as_path());
+    });
+
+    b.iter(|| {
+        set.remove(paths[500].as_path());
+        set.insert(black_box(paths[500].as_path()))
+    });
+}
+
+#[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
+fn bench_path_hashset_miss(b: &mut test::Bencher) {
+    let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
+    let paths: Vec<_> =
+        (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
+
+    let mut set = HashSet::new();
+
+    paths.iter().for_each(|p| {
+        set.insert(p.as_path());
+    });
+
+    let probe = PathBuf::from(prefix).join("other");
+
+    b.iter(|| set.remove(black_box(probe.as_path())));
+}
+
+#[bench]
+fn bench_hash_path_short(b: &mut test::Bencher) {
+    let mut hasher = DefaultHasher::new();
+    let path = Path::new("explorer.exe");
+
+    b.iter(|| black_box(path).hash(&mut hasher));
+
+    black_box(hasher.finish());
+}
+
+#[bench]
+fn bench_hash_path_long(b: &mut test::Bencher) {
+    let mut hasher = DefaultHasher::new();
+    let path =
+        Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff");
+
+    b.iter(|| black_box(path).hash(&mut hasher));
+
+    black_box(hasher.finish());
+}
diff --git a/library/std/benches/time.rs b/library/std/benches/time.rs
new file mode 100644
index 00000000000..552481cad92
--- /dev/null
+++ b/library/std/benches/time.rs
@@ -0,0 +1,47 @@
+use std::time::Instant;
+
+#[cfg(not(target_arch = "wasm32"))]
+use test::{Bencher, black_box};
+
+macro_rules! bench_instant_threaded {
+    ($bench_name:ident, $thread_count:expr) => {
+        #[bench]
+        #[cfg(not(target_arch = "wasm32"))]
+        fn $bench_name(b: &mut Bencher) -> std::thread::Result<()> {
+            use std::sync::Arc;
+            use std::sync::atomic::{AtomicBool, Ordering};
+
+            let running = Arc::new(AtomicBool::new(true));
+
+            let threads: Vec<_> = (0..$thread_count)
+                .map(|_| {
+                    let flag = Arc::clone(&running);
+                    std::thread::spawn(move || {
+                        while flag.load(Ordering::Relaxed) {
+                            black_box(Instant::now());
+                        }
+                    })
+                })
+                .collect();
+
+            b.iter(|| {
+                let a = Instant::now();
+                let b = Instant::now();
+                assert!(b >= a);
+            });
+
+            running.store(false, Ordering::Relaxed);
+
+            for t in threads {
+                t.join()?;
+            }
+            Ok(())
+        }
+    };
+}
+
+bench_instant_threaded!(instant_contention_01_threads, 0);
+bench_instant_threaded!(instant_contention_02_threads, 1);
+bench_instant_threaded!(instant_contention_04_threads, 3);
+bench_instant_threaded!(instant_contention_08_threads, 7);
+bench_instant_threaded!(instant_contention_16_threads, 15);
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index bbd506127fb..c665dfd3624 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -10,9 +10,6 @@
 
 #![stable(feature = "env", since = "1.0.0")]
 
-#[cfg(test)]
-mod tests;
-
 use crate::error::Error;
 use crate::ffi::{OsStr, OsString};
 use crate::path::{Path, PathBuf};
diff --git a/library/std/src/env/tests.rs b/library/std/src/env/tests.rs
deleted file mode 100644
index d0217261068..00000000000
--- a/library/std/src/env/tests.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-use super::*;
-
-#[test]
-#[cfg_attr(any(target_os = "emscripten", target_os = "wasi", target_env = "sgx"), ignore)]
-fn test_self_exe_path() {
-    let path = current_exe();
-    assert!(path.is_ok());
-    let path = path.unwrap();
-
-    // Hard to test this function
-    assert!(path.is_absolute());
-}
-
-#[test]
-fn test() {
-    assert!((!Path::new("test-path").is_absolute()));
-
-    #[cfg(not(target_env = "sgx"))]
-    current_dir().unwrap();
-}
-
-#[test]
-#[cfg(windows)]
-fn split_paths_windows() {
-    use crate::path::PathBuf;
-
-    fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
-        split_paths(unparsed).collect::<Vec<_>>()
-            == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
-    }
-
-    assert!(check_parse("", &mut [""]));
-    assert!(check_parse(r#""""#, &mut [""]));
-    assert!(check_parse(";;", &mut ["", "", ""]));
-    assert!(check_parse(r"c:\", &mut [r"c:\"]));
-    assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
-    assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"]));
-    assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
-    assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#, &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
-}
-
-#[test]
-#[cfg(unix)]
-fn split_paths_unix() {
-    use crate::path::PathBuf;
-
-    fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
-        split_paths(unparsed).collect::<Vec<_>>()
-            == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
-    }
-
-    assert!(check_parse("", &mut [""]));
-    assert!(check_parse("::", &mut ["", "", ""]));
-    assert!(check_parse("/", &mut ["/"]));
-    assert!(check_parse("/:", &mut ["/", ""]));
-    assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
-}
-
-#[test]
-#[cfg(unix)]
-fn join_paths_unix() {
-    use crate::ffi::OsStr;
-
-    fn test_eq(input: &[&str], output: &str) -> bool {
-        &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
-    }
-
-    assert!(test_eq(&[], ""));
-    assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin"));
-    assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:"));
-    assert!(join_paths(["/te:st"].iter().cloned()).is_err());
-}
-
-#[test]
-#[cfg(windows)]
-fn join_paths_windows() {
-    use crate::ffi::OsStr;
-
-    fn test_eq(input: &[&str], output: &str) -> bool {
-        &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
-    }
-
-    assert!(test_eq(&[], ""));
-    assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\"));
-    assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;"));
-    assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#));
-    assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
-}
-
-#[test]
-fn args_debug() {
-    assert_eq!(
-        format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
-        format!("{:?}", args())
-    );
-}
-
-#[test]
-fn args_os_debug() {
-    assert_eq!(
-        format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
-        format!("{:?}", args_os())
-    );
-}
-
-#[test]
-fn vars_debug() {
-    assert_eq!(
-        format!("Vars {{ inner: {:?} }}", vars().collect::<Vec<_>>()),
-        format!("{:?}", vars())
-    );
-}
-
-#[test]
-fn vars_os_debug() {
-    assert_eq!(
-        format!("VarsOs {{ inner: {:?} }}", vars_os().collect::<Vec<_>>()),
-        format!("{:?}", vars_os())
-    );
-}
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index b3e63aaf1c5..def5f984c88 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -1,9 +1,6 @@
 #![doc = include_str!("../../core/src/error.md")]
 #![stable(feature = "rust1", since = "1.0.0")]
 
-#[cfg(test)]
-mod tests;
-
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::error::Error;
 #[unstable(feature = "error_generic_member_access", issue = "99301")]
diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs
index d65f5ed61cf..89612fa7475 100644
--- a/library/std/src/f128.rs
+++ b/library/std/src/f128.rs
@@ -4,9 +4,6 @@
 //!
 //! Mathematically significant numbers are provided in the `consts` sub-module.
 
-#[cfg(test)]
-mod tests;
-
 #[unstable(feature = "f128", issue = "116909")]
 pub use core::f128::consts;
 
diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs
index 5b0903bceab..cc523c93b4d 100644
--- a/library/std/src/f16.rs
+++ b/library/std/src/f16.rs
@@ -4,9 +4,6 @@
 //!
 //! Mathematically significant numbers are provided in the `consts` sub-module.
 
-#[cfg(test)]
-mod tests;
-
 #[unstable(feature = "f16", issue = "116909")]
 pub use core::f16::consts;
 
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index f9b6723788a..260c499b7f4 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -12,9 +12,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
-#[cfg(test)]
-mod tests;
-
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated, deprecated_in_future)]
 pub use core::f32::{
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index 0de55a15d48..7af646f8cfd 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -12,9 +12,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
-#[cfg(test)]
-mod tests;
-
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated, deprecated_in_future)]
 pub use core::f64::{
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index acb3a0578e5..7c18226874c 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -530,6 +530,8 @@ pub use core::option;
 pub use core::pin;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::ptr;
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub use core::range;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::result;
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs
index 1b0d7f3dbf2..e0f9f0bb5ce 100644
--- a/library/std/src/macros.rs
+++ b/library/std/src/macros.rs
@@ -372,18 +372,3 @@ macro_rules! dbg {
         ($($crate::dbg!($val)),+,)
     };
 }
-
-/// Verify that floats are within a tolerance of each other, 1.0e-6 by default.
-#[cfg(test)]
-macro_rules! assert_approx_eq {
-    ($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
-    ($a:expr, $b:expr, $lim:expr) => {{
-        let (a, b) = (&$a, &$b);
-        let diff = (*a - *b).abs();
-        assert!(
-            diff < $lim,
-            "{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
-            lim = $lim
-        );
-    }};
-}
diff --git a/library/std/src/num.rs b/library/std/src/num.rs
index d2f679e7dde..ffb8789c906 100644
--- a/library/std/src/num.rs
+++ b/library/std/src/num.rs
@@ -6,9 +6,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
-#[cfg(test)]
-mod tests;
-
 #[stable(feature = "int_error_matching", since = "1.55.0")]
 pub use core::num::IntErrorKind;
 #[stable(feature = "generic_nonzero", since = "1.79.0")]
@@ -29,28 +26,3 @@ pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError}
 pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize};
 #[stable(feature = "nonzero", since = "1.28.0")]
 pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
-
-#[cfg(test)]
-use crate::fmt;
-#[cfg(test)]
-use crate::ops::{Add, Div, Mul, Rem, Sub};
-
-/// Helper function for testing numeric operations
-#[cfg(test)]
-pub fn test_num<T>(ten: T, two: T)
-where
-    T: PartialEq
-        + Add<Output = T>
-        + Sub<Output = T>
-        + Mul<Output = T>
-        + Div<Output = T>
-        + Rem<Output = T>
-        + fmt::Debug
-        + Copy,
-{
-    assert_eq!(ten.add(two), ten + two);
-    assert_eq!(ten.sub(two), ten - two);
-    assert_eq!(ten.mul(two), ten * two);
-    assert_eq!(ten.div(two), ten / two);
-    assert_eq!(ten.rem(two), ten % two);
-}
diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index d649357a56d..153189b8b03 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -529,6 +529,3 @@ pub fn get_backtrace_style() -> Option<BacktraceStyle> {
         Err(new) => BacktraceStyle::from_u8(new),
     }
 }
-
-#[cfg(test)]
-mod tests;
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 7fd08a97f1f..97e17acadea 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -67,9 +67,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
 
-#[cfg(test)]
-mod tests;
-
 use core::clone::CloneToUninit;
 
 use crate::borrow::{Borrow, Cow};
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index 4ec328208f0..14e6c2715df 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -120,16 +120,6 @@ mod common;
 pub mod v1 {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::common::*;
-
-    // Do not `doc(inline)` these `doc(hidden)` items.
-    #[unstable(
-        feature = "rustc_encodable_decodable",
-        issue = "none",
-        soft,
-        reason = "derive macro for `rustc-serialize`; should not be used in new code"
-    )]
-    #[allow(deprecated)]
-    pub use core::prelude::v1::{RustcDecodable, RustcEncodable};
 }
 
 /// The 2015 version of the prelude of The Rust Standard Library.
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index e0dd2e14817..fd0fd1cb755 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -2318,14 +2318,10 @@ pub fn exit(code: i32) -> ! {
 /// Terminates the process in an abnormal fashion.
 ///
 /// The function will never return and will immediately terminate the current
-/// process in a platform specific "abnormal" manner.
-///
-/// Note that because this function never returns, and that it terminates the
-/// process, no destructors on the current stack or any other thread's stack
-/// will be run.
-///
-/// Rust IO buffers (eg, from `BufWriter`) will not be flushed.
-/// Likewise, C stdio buffers will (on most platforms) not be flushed.
+/// process in a platform specific "abnormal" manner. As a consequence,
+/// no destructors on the current stack or any other thread's stack
+/// will be run, Rust IO buffers (eg, from `BufWriter`) will not be flushed,
+/// and C stdio buffers will (on most platforms) not be flushed.
 ///
 /// This is in contrast to the default behavior of [`panic!`] which unwinds
 /// the current thread's stack and calls all destructors.
diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs
index 862753e4765..067ff66d9af 100644
--- a/library/std/src/sync/barrier.rs
+++ b/library/std/src/sync/barrier.rs
@@ -1,6 +1,3 @@
-#[cfg(test)]
-mod tests;
-
 use crate::fmt;
 // FIXME(nonpoison_mutex,nonpoison_condvar): switch to nonpoison versions once they are available
 use crate::sync::{Condvar, Mutex};
diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs
index 98c83d8d326..78cf8841efe 100644
--- a/library/std/src/sync/lazy_lock.rs
+++ b/library/std/src/sync/lazy_lock.rs
@@ -350,6 +350,3 @@ unsafe impl<T: Sync + Send, F: Send> Sync for LazyLock<T, F> {}
 impl<T: RefUnwindSafe + UnwindSafe, F: UnwindSafe> RefUnwindSafe for LazyLock<T, F> {}
 #[stable(feature = "lazy_cell", since = "1.80.0")]
 impl<T: UnwindSafe, F: UnwindSafe> UnwindSafe for LazyLock<T, F> {}
-
-#[cfg(test)]
-mod tests;
diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc.rs
index c86b546e011..f942937c14d 100644
--- a/library/std/src/sync/mpsc/mod.rs
+++ b/library/std/src/sync/mpsc.rs
@@ -137,12 +137,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
-mod tests;
-
-#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
-mod sync_tests;
-
 // MPSC channels are built as a wrapper around MPMC channels, which
 // were ported from the `crossbeam-channel` crate. MPMC channels are
 // not exposed publicly, but if you are curious about the implementation,
@@ -737,9 +731,10 @@ impl<T> SyncSender<T> {
     // Attempts to send for a value on this receiver, returning an error if the
     // corresponding channel has hung up, or if it waits more than `timeout`.
     //
-    // This method is currently private and only used for tests.
-    #[allow(unused)]
-    fn send_timeout(&self, t: T, timeout: Duration) -> Result<(), mpmc::SendTimeoutError<T>> {
+    // This method is currently only used for tests.
+    #[unstable(issue = "none", feature = "std_internals")]
+    #[doc(hidden)]
+    pub fn send_timeout(&self, t: T, timeout: Duration) -> Result<(), mpmc::SendTimeoutError<T>> {
         self.inner.send_timeout(t, timeout)
     }
 }
diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index 49f2dafd8fd..21e6b65a744 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -13,6 +13,9 @@ use crate::sync::Once;
 /// Where OnceLock shines is when LazyLock is too simple to support a given case, as LazyLock
 /// doesn't allow additional inputs to its function after you call [`LazyLock::new(|| ...)`].
 ///
+/// A `OnceLock` can be thought of as a safe abstraction over uninitialized data that becomes
+/// initialized once written.
+///
 /// [`OnceCell`]: crate::cell::OnceCell
 /// [`LazyLock<T, F>`]: crate::sync::LazyLock
 /// [`LazyLock::new(|| ...)`]: crate::sync::LazyLock::new
@@ -126,7 +129,7 @@ pub struct OnceLock<T> {
 }
 
 impl<T> OnceLock<T> {
-    /// Creates a new empty cell.
+    /// Creates a new uninitialized cell.
     #[inline]
     #[must_use]
     #[stable(feature = "once_cell", since = "1.70.0")]
@@ -141,8 +144,8 @@ impl<T> OnceLock<T> {
 
     /// Gets the reference to the underlying value.
     ///
-    /// Returns `None` if the cell is empty, or being initialized. This
-    /// method never blocks.
+    /// Returns `None` if the cell is uninitialized, or being initialized.
+    /// This method never blocks.
     #[inline]
     #[stable(feature = "once_cell", since = "1.70.0")]
     pub fn get(&self) -> Option<&T> {
@@ -156,7 +159,8 @@ impl<T> OnceLock<T> {
 
     /// Gets the mutable reference to the underlying value.
     ///
-    /// Returns `None` if the cell is empty. This method never blocks.
+    /// Returns `None` if the cell is uninitialized, or being initialized.
+    /// This method never blocks.
     #[inline]
     #[stable(feature = "once_cell", since = "1.70.0")]
     pub fn get_mut(&mut self) -> Option<&mut T> {
@@ -174,8 +178,6 @@ impl<T> OnceLock<T> {
     ///
     /// Waiting for a computation on another thread to finish:
     /// ```rust
-    /// #![feature(once_wait)]
-    ///
     /// use std::thread;
     /// use std::sync::OnceLock;
     ///
@@ -189,19 +191,20 @@ impl<T> OnceLock<T> {
     /// })
     /// ```
     #[inline]
-    #[unstable(feature = "once_wait", issue = "127527")]
+    #[stable(feature = "once_wait", since = "CURRENT_RUSTC_VERSION")]
     pub fn wait(&self) -> &T {
         self.once.wait_force();
 
         unsafe { self.get_unchecked() }
     }
 
-    /// Sets the contents of this cell to `value`.
+    /// Initializes the contents of the cell to `value`.
     ///
     /// May block if another thread is currently attempting to initialize the cell. The cell is
-    /// guaranteed to contain a value when set returns, though not necessarily the one provided.
+    /// guaranteed to contain a value when `set` returns, though not necessarily the one provided.
     ///
-    /// Returns `Ok(())` if the cell's value was set by this call.
+    /// Returns `Ok(())` if the cell was uninitialized and
+    /// `Err(value)` if the cell was already initialized.
     ///
     /// # Examples
     ///
@@ -230,13 +233,15 @@ impl<T> OnceLock<T> {
         }
     }
 
-    /// Sets the contents of this cell to `value` if the cell was empty, then
-    /// returns a reference to it.
+    /// Initializes the contents of the cell to `value` if the cell was uninitialized,
+    /// then returns a reference to it.
     ///
     /// May block if another thread is currently attempting to initialize the cell. The cell is
-    /// guaranteed to contain a value when set returns, though not necessarily the one provided.
+    /// guaranteed to contain a value when `try_insert` returns, though not necessarily the
+    /// one provided.
     ///
-    /// Returns `Ok(&value)` if the cell was empty and `Err(&current_value, value)` if it was full.
+    /// Returns `Ok(&value)` if the cell was uninitialized and
+    /// `Err((&current_value, value))` if it was already initialized.
     ///
     /// # Examples
     ///
@@ -269,8 +274,8 @@ impl<T> OnceLock<T> {
         }
     }
 
-    /// Gets the contents of the cell, initializing it with `f` if the cell
-    /// was empty.
+    /// Gets the contents of the cell, initializing it to `f()` if the cell
+    /// was uninitialized.
     ///
     /// Many threads may call `get_or_init` concurrently with different
     /// initializing functions, but it is guaranteed that only one function
@@ -278,7 +283,7 @@ impl<T> OnceLock<T> {
     ///
     /// # Panics
     ///
-    /// If `f` panics, the panic is propagated to the caller, and the cell
+    /// If `f()` panics, the panic is propagated to the caller, and the cell
     /// remains uninitialized.
     ///
     /// It is an error to reentrantly initialize the cell from `f`. The
@@ -308,13 +313,13 @@ impl<T> OnceLock<T> {
     }
 
     /// Gets the mutable reference of the contents of the cell, initializing
-    /// it with `f` if the cell was empty.
+    /// it to `f()` if the cell was uninitialized.
     ///
     /// This method never blocks.
     ///
     /// # Panics
     ///
-    /// If `f` panics, the panic is propagated to the caller, and the cell
+    /// If `f()` panics, the panic is propagated to the caller, and the cell
     /// remains uninitialized.
     ///
     /// # Examples
@@ -345,13 +350,13 @@ impl<T> OnceLock<T> {
         }
     }
 
-    /// Gets the contents of the cell, initializing it with `f` if
-    /// the cell was empty. If the cell was empty and `f` failed, an
-    /// error is returned.
+    /// Gets the contents of the cell, initializing it to `f()` if
+    /// the cell was uninitialized. If the cell was uninitialized
+    /// and `f()` failed, an error is returned.
     ///
     /// # Panics
     ///
-    /// If `f` panics, the panic is propagated to the caller, and
+    /// If `f()` panics, the panic is propagated to the caller, and
     /// the cell remains uninitialized.
     ///
     /// It is an error to reentrantly initialize the cell from `f`.
@@ -397,14 +402,14 @@ impl<T> OnceLock<T> {
     }
 
     /// Gets the mutable reference of the contents of the cell, initializing
-    /// it with `f` if the cell was empty. If the cell was empty and `f` failed,
-    /// an error is returned.
+    /// it to `f()` if the cell was uninitialized. If the cell was uninitialized
+    /// and `f()` failed, an error is returned.
     ///
     /// This method never blocks.
     ///
     /// # Panics
     ///
-    /// If `f` panics, the panic is propagated to the caller, and
+    /// If `f()` panics, the panic is propagated to the caller, and
     /// the cell remains uninitialized.
     ///
     /// # Examples
@@ -416,7 +421,7 @@ impl<T> OnceLock<T> {
     ///
     /// let mut cell: OnceLock<u32> = OnceLock::new();
     ///
-    /// // Failed initializers do not change the value
+    /// // Failed attempts to initialize the cell do not change its contents
     /// assert!(cell.get_mut_or_try_init(|| "not a number!".parse()).is_err());
     /// assert!(cell.get().is_none());
     ///
@@ -440,7 +445,7 @@ impl<T> OnceLock<T> {
     }
 
     /// Consumes the `OnceLock`, returning the wrapped value. Returns
-    /// `None` if the cell was empty.
+    /// `None` if the cell was uninitialized.
     ///
     /// # Examples
     ///
@@ -462,7 +467,7 @@ impl<T> OnceLock<T> {
 
     /// Takes the value out of this `OnceLock`, moving it back to an uninitialized state.
     ///
-    /// Has no effect and returns `None` if the `OnceLock` hasn't been initialized.
+    /// Has no effect and returns `None` if the `OnceLock` was uninitialized.
     ///
     /// Safety is guaranteed by requiring a mutable reference.
     ///
@@ -528,7 +533,7 @@ impl<T> OnceLock<T> {
 
     /// # Safety
     ///
-    /// The value must be initialized
+    /// The cell must be initialized
     #[inline]
     unsafe fn get_unchecked(&self) -> &T {
         debug_assert!(self.is_initialized());
@@ -537,7 +542,7 @@ impl<T> OnceLock<T> {
 
     /// # Safety
     ///
-    /// The value must be initialized
+    /// The cell must be initialized
     #[inline]
     unsafe fn get_unchecked_mut(&mut self) -> &mut T {
         debug_assert!(self.is_initialized());
@@ -562,7 +567,7 @@ impl<T: UnwindSafe> UnwindSafe for OnceLock<T> {}
 
 #[stable(feature = "once_cell", since = "1.70.0")]
 impl<T> Default for OnceLock<T> {
-    /// Creates a new empty cell.
+    /// Creates a new uninitialized cell.
     ///
     /// # Example
     ///
@@ -676,6 +681,3 @@ unsafe impl<#[may_dangle] T> Drop for OnceLock<T> {
         }
     }
 }
-
-#[cfg(test)]
-mod tests;
diff --git a/library/std/src/sync/poison/condvar.rs b/library/std/src/sync/poison/condvar.rs
index a6e2389c93b..7f0f3f652bc 100644
--- a/library/std/src/sync/poison/condvar.rs
+++ b/library/std/src/sync/poison/condvar.rs
@@ -1,6 +1,3 @@
-#[cfg(test)]
-mod tests;
-
 use crate::fmt;
 use crate::sync::poison::{self, LockResult, MutexGuard, PoisonError, mutex};
 use crate::sys::sync as sys;
diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs
index 01ef71a187f..9362c764173 100644
--- a/library/std/src/sync/poison/mutex.rs
+++ b/library/std/src/sync/poison/mutex.rs
@@ -1,6 +1,3 @@
-#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
-mod tests;
-
 use crate::cell::UnsafeCell;
 use crate::fmt;
 use crate::marker::PhantomData;
@@ -181,10 +178,29 @@ pub struct Mutex<T: ?Sized> {
     data: UnsafeCell<T>,
 }
 
-// these are the only places where `T: Send` matters; all other
-// functionality works fine on a single thread.
+/// `T` must be `Send` for a [`Mutex`] to be `Send` because it is possible to acquire
+/// the owned `T` from the `Mutex` via [`into_inner`].
+///
+/// [`into_inner`]: Mutex::into_inner
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
+
+/// `T` must be `Send` for [`Mutex`] to be `Sync`.
+/// This ensures that the protected data can be accessed safely from multiple threads
+/// without causing data races or other unsafe behavior.
+///
+/// [`Mutex<T>`] provides mutable access to `T` to one thread at a time. However, it's essential
+/// for `T` to be `Send` because it's not safe for non-`Send` structures to be accessed in
+/// this manner. For instance, consider [`Rc`], a non-atomic reference counted smart pointer,
+/// which is not `Send`. With `Rc`, we can have multiple copies pointing to the same heap
+/// allocation with a non-atomic reference count. If we were to use `Mutex<Rc<_>>`, it would
+/// only protect one instance of `Rc` from shared access, leaving other copies vulnerable
+/// to potential data races.
+///
+/// Also note that it is not necessary for `T` to be `Sync` as `&T` is only made available
+/// to one thread at a time if `T` is not `Sync`.
+///
+/// [`Rc`]: crate::rc::Rc
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
 
@@ -211,8 +227,17 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> {
     poison: poison::Guard,
 }
 
+/// A [`MutexGuard`] is not `Send` to maximize platform portablity.
+///
+/// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to
+/// release mutex locks on the same thread they were acquired.
+/// For this reason, [`MutexGuard`] must not implement `Send` to prevent it being dropped from
+/// another thread.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
+
+/// `T` must be `Sync` for a [`MutexGuard<T>`] to be `Sync`
+/// because it is possible to get a `&T` from `&MutexGuard` (via `Deref`).
 #[stable(feature = "mutexguard", since = "1.19.0")]
 unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
 
diff --git a/library/std/src/sync/poison/once.rs b/library/std/src/sync/poison/once.rs
index 27db4b634fb..d2938b7a0c1 100644
--- a/library/std/src/sync/poison/once.rs
+++ b/library/std/src/sync/poison/once.rs
@@ -3,9 +3,6 @@
 //! This primitive is meant to be used to run one-time initialization. An
 //! example use case would be for initializing an FFI library.
 
-#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
-mod tests;
-
 use crate::fmt;
 use crate::panic::{RefUnwindSafe, UnwindSafe};
 use crate::sys::sync as sys;
@@ -269,8 +266,6 @@ impl Once {
     /// # Example
     ///
     /// ```rust
-    /// #![feature(once_wait)]
-    ///
     /// use std::sync::Once;
     /// use std::thread;
     ///
@@ -289,7 +284,7 @@ impl Once {
     /// If this [`Once`] has been poisoned because an initialization closure has
     /// panicked, this method will also panic. Use [`wait_force`](Self::wait_force)
     /// if this behavior is not desired.
-    #[unstable(feature = "once_wait", issue = "127527")]
+    #[stable(feature = "once_wait", since = "CURRENT_RUSTC_VERSION")]
     pub fn wait(&self) {
         if !self.inner.is_completed() {
             self.inner.wait(false);
@@ -298,7 +293,7 @@ impl Once {
 
     /// Blocks the current thread until initialization has completed, ignoring
     /// poisoning.
-    #[unstable(feature = "once_wait", issue = "127527")]
+    #[stable(feature = "once_wait", since = "CURRENT_RUSTC_VERSION")]
     pub fn wait_force(&self) {
         if !self.inner.is_completed() {
             self.inner.wait(true);
diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs
index 1519baf99a8..f9d9321f5f2 100644
--- a/library/std/src/sync/poison/rwlock.rs
+++ b/library/std/src/sync/poison/rwlock.rs
@@ -1,6 +1,3 @@
-#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
-mod tests;
-
 use crate::cell::UnsafeCell;
 use crate::fmt;
 use crate::marker::PhantomData;
diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs
index 0140e0d2129..e009eb410ef 100644
--- a/library/std/src/sync/reentrant_lock.rs
+++ b/library/std/src/sync/reentrant_lock.rs
@@ -1,6 +1,3 @@
-#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
-mod tests;
-
 use cfg_if::cfg_if;
 
 use crate::cell::UnsafeCell;
@@ -324,7 +321,10 @@ impl<T: ?Sized> ReentrantLock<T> {
     /// Otherwise, an RAII guard is returned.
     ///
     /// This function does not block.
-    pub(crate) fn try_lock(&self) -> Option<ReentrantLockGuard<'_, T>> {
+    // FIXME maybe make it a public part of the API?
+    #[unstable(issue = "none", feature = "std_internals")]
+    #[doc(hidden)]
+    pub fn try_lock(&self) -> Option<ReentrantLockGuard<'_, T>> {
         let this_thread = current_id();
         // Safety: We only touch lock_count when we own the inner mutex.
         // Additionally, we only call `self.owner.set()` while holding
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index fdf011c1948..6c41781fe85 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -740,29 +740,27 @@ impl Iterator for ReadDir {
                 // to `byte_offset` and thus does not require the full extent of `*entry_ptr`
                 // to be in bounds of the same allocation, only the offset of the field
                 // being referenced.
-                macro_rules! entry_field_ptr {
-                    ($field:ident) => {
-                        &raw const (*entry_ptr).$field
-                    };
-                }
 
                 // d_name is guaranteed to be null-terminated.
-                let name = CStr::from_ptr(entry_field_ptr!(d_name).cast());
+                let name = CStr::from_ptr((&raw const (*entry_ptr).d_name).cast());
                 let name_bytes = name.to_bytes();
                 if name_bytes == b"." || name_bytes == b".." {
                     continue;
                 }
 
+                // When loading from a field, we can skip the `&raw const`; `(*entry_ptr).d_ino` as
+                // a value expression will do the right thing: `byte_offset` to the field and then
+                // only access those bytes.
                 #[cfg(not(target_os = "vita"))]
                 let entry = dirent64_min {
-                    d_ino: *entry_field_ptr!(d_ino) as u64,
+                    d_ino: (*entry_ptr).d_ino as u64,
                     #[cfg(not(any(
                         target_os = "solaris",
                         target_os = "illumos",
                         target_os = "aix",
                         target_os = "nto",
                     )))]
-                    d_type: *entry_field_ptr!(d_type) as u8,
+                    d_type: (*entry_ptr).d_type as u8,
                 };
 
                 #[cfg(target_os = "vita")]
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index c003503ca8b..ca04aa4ada4 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -2,12 +2,6 @@
 
 #![unstable(feature = "thread_local_internals", issue = "none")]
 
-#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
-mod tests;
-
-#[cfg(test)]
-mod dynamic_tests;
-
 use crate::cell::{Cell, RefCell};
 use crate::error::Error;
 use crate::fmt;
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index 9f4f8a0d088..88b3e9e0ceb 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -31,9 +31,6 @@
 
 #![stable(feature = "time", since = "1.3.0")]
 
-#[cfg(test)]
-mod tests;
-
 #[stable(feature = "time", since = "1.3.0")]
 pub use core::time::Duration;
 #[stable(feature = "duration_checked_float", since = "1.66.0")]
diff --git a/library/std/tests/env.rs b/library/std/tests/env.rs
index 44fe84c989f..e754cf8263b 100644
--- a/library/std/tests/env.rs
+++ b/library/std/tests/env.rs
@@ -1,163 +1,123 @@
 use std::env::*;
-use std::ffi::{OsStr, OsString};
-
-use rand::distributions::{Alphanumeric, DistString};
+use std::path::Path;
 
 mod common;
-use std::thread;
-
-use common::test_rng;
-
-#[track_caller]
-fn make_rand_name() -> OsString {
-    let n = format!("TEST{}", Alphanumeric.sample_string(&mut test_rng(), 10));
-    let n = OsString::from(n);
-    assert!(var_os(&n).is_none());
-    n
-}
-
-fn eq(a: Option<OsString>, b: Option<&str>) {
-    assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
-}
 
 #[test]
-fn test_set_var() {
-    let n = make_rand_name();
-    set_var(&n, "VALUE");
-    eq(var_os(&n), Some("VALUE"));
+#[cfg_attr(any(target_os = "emscripten", target_os = "wasi", target_env = "sgx"), ignore)]
+fn test_self_exe_path() {
+    let path = current_exe();
+    assert!(path.is_ok());
+    let path = path.unwrap();
+
+    // Hard to test this function
+    assert!(path.is_absolute());
 }
 
 #[test]
-fn test_remove_var() {
-    let n = make_rand_name();
-    set_var(&n, "VALUE");
-    remove_var(&n);
-    eq(var_os(&n), None);
-}
+fn test() {
+    assert!((!Path::new("test-path").is_absolute()));
 
-#[test]
-fn test_set_var_overwrite() {
-    let n = make_rand_name();
-    set_var(&n, "1");
-    set_var(&n, "2");
-    eq(var_os(&n), Some("2"));
-    set_var(&n, "");
-    eq(var_os(&n), Some(""));
+    #[cfg(not(target_env = "sgx"))]
+    current_dir().unwrap();
 }
 
 #[test]
-#[cfg_attr(target_os = "emscripten", ignore)]
-fn test_var_big() {
-    let mut s = "".to_string();
-    let mut i = 0;
-    while i < 100 {
-        s.push_str("aaaaaaaaaa");
-        i += 1;
+#[cfg(windows)]
+fn split_paths_windows() {
+    use std::path::PathBuf;
+
+    fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
+        split_paths(unparsed).collect::<Vec<_>>()
+            == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
     }
-    let n = make_rand_name();
-    set_var(&n, &s);
-    eq(var_os(&n), Some(&s));
-}
 
-#[test]
-#[cfg_attr(target_os = "emscripten", ignore)]
-fn test_env_set_get_huge() {
-    let n = make_rand_name();
-    let s = "x".repeat(10000);
-    set_var(&n, &s);
-    eq(var_os(&n), Some(&s));
-    remove_var(&n);
-    eq(var_os(&n), None);
+    assert!(check_parse("", &mut [""]));
+    assert!(check_parse(r#""""#, &mut [""]));
+    assert!(check_parse(";;", &mut ["", "", ""]));
+    assert!(check_parse(r"c:\", &mut [r"c:\"]));
+    assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
+    assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"]));
+    assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
+    assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#, &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
 }
 
 #[test]
-fn test_env_set_var() {
-    let n = make_rand_name();
+#[cfg(unix)]
+fn split_paths_unix() {
+    use std::path::PathBuf;
 
-    let mut e = vars_os();
-    set_var(&n, "VALUE");
-    assert!(!e.any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
+    fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
+        split_paths(unparsed).collect::<Vec<_>>()
+            == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
+    }
 
-    assert!(vars_os().any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
+    assert!(check_parse("", &mut [""]));
+    assert!(check_parse("::", &mut ["", "", ""]));
+    assert!(check_parse("/", &mut ["/"]));
+    assert!(check_parse("/:", &mut ["/", ""]));
+    assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
 }
 
 #[test]
-#[cfg_attr(not(any(unix, windows)), ignore, allow(unused))]
-#[allow(deprecated)]
-fn env_home_dir() {
-    use std::path::PathBuf;
+#[cfg(unix)]
+fn join_paths_unix() {
+    use std::ffi::OsStr;
 
-    fn var_to_os_string(var: Result<String, VarError>) -> Option<OsString> {
-        match var {
-            Ok(var) => Some(OsString::from(var)),
-            Err(VarError::NotUnicode(var)) => Some(var),
-            _ => None,
-        }
+    fn test_eq(input: &[&str], output: &str) -> bool {
+        &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
     }
 
-    cfg_if::cfg_if! {
-        if #[cfg(unix)] {
-            let oldhome = var_to_os_string(var("HOME"));
-
-            set_var("HOME", "/home/MountainView");
-            assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
-
-            remove_var("HOME");
-            if cfg!(target_os = "android") {
-                assert!(home_dir().is_none());
-            } else {
-                // When HOME is not set, some platforms return `None`,
-                // but others return `Some` with a default.
-                // Just check that it is not "/home/MountainView".
-                assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
-            }
-
-            if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
-        } else if #[cfg(windows)] {
-            let oldhome = var_to_os_string(var("HOME"));
-            let olduserprofile = var_to_os_string(var("USERPROFILE"));
-
-            remove_var("HOME");
-            remove_var("USERPROFILE");
-
-            assert!(home_dir().is_some());
-
-            set_var("HOME", "/home/PaloAlto");
-            assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used");
+    assert!(test_eq(&[], ""));
+    assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin"));
+    assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:"));
+    assert!(join_paths(["/te:st"].iter().cloned()).is_err());
+}
 
-            set_var("USERPROFILE", "/home/MountainView");
-            assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
+#[test]
+#[cfg(windows)]
+fn join_paths_windows() {
+    use std::ffi::OsStr;
 
-            remove_var("HOME");
+    fn test_eq(input: &[&str], output: &str) -> bool {
+        &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
+    }
 
-            assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
+    assert!(test_eq(&[], ""));
+    assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\"));
+    assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;"));
+    assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#));
+    assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
+}
 
-            set_var("USERPROFILE", "");
-            assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored");
+#[test]
+fn args_debug() {
+    assert_eq!(
+        format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
+        format!("{:?}", args())
+    );
+}
 
-            remove_var("USERPROFILE");
+#[test]
+fn args_os_debug() {
+    assert_eq!(
+        format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
+        format!("{:?}", args_os())
+    );
+}
 
-            if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
-            if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
-        }
-    }
+#[test]
+fn vars_debug() {
+    assert_eq!(
+        format!("Vars {{ inner: {:?} }}", vars().collect::<Vec<_>>()),
+        format!("{:?}", vars())
+    );
 }
 
-#[test] // miri shouldn't detect any data race in this fn
-#[cfg_attr(any(not(miri), target_os = "emscripten"), ignore)]
-fn test_env_get_set_multithreaded() {
-    let getter = thread::spawn(|| {
-        for _ in 0..100 {
-            let _ = var_os("foo");
-        }
-    });
-
-    let setter = thread::spawn(|| {
-        for _ in 0..100 {
-            set_var("foo", "bar");
-        }
-    });
-
-    let _ = getter.join();
-    let _ = setter.join();
+#[test]
+fn vars_os_debug() {
+    assert_eq!(
+        format!("VarsOs {{ inner: {:?} }}", vars_os().collect::<Vec<_>>()),
+        format!("{:?}", vars_os())
+    );
 }
diff --git a/library/std/tests/env_modify.rs b/library/std/tests/env_modify.rs
new file mode 100644
index 00000000000..60747447350
--- /dev/null
+++ b/library/std/tests/env_modify.rs
@@ -0,0 +1,166 @@
+// These tests are in a separate integration test as they modify the environment,
+// and would otherwise cause some other tests to fail.
+
+use std::env::*;
+use std::ffi::{OsStr, OsString};
+
+use rand::distributions::{Alphanumeric, DistString};
+
+mod common;
+use std::thread;
+
+use common::test_rng;
+
+#[track_caller]
+fn make_rand_name() -> OsString {
+    let n = format!("TEST{}", Alphanumeric.sample_string(&mut test_rng(), 10));
+    let n = OsString::from(n);
+    assert!(var_os(&n).is_none());
+    n
+}
+
+fn eq(a: Option<OsString>, b: Option<&str>) {
+    assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
+}
+
+#[test]
+fn test_set_var() {
+    let n = make_rand_name();
+    set_var(&n, "VALUE");
+    eq(var_os(&n), Some("VALUE"));
+}
+
+#[test]
+fn test_remove_var() {
+    let n = make_rand_name();
+    set_var(&n, "VALUE");
+    remove_var(&n);
+    eq(var_os(&n), None);
+}
+
+#[test]
+fn test_set_var_overwrite() {
+    let n = make_rand_name();
+    set_var(&n, "1");
+    set_var(&n, "2");
+    eq(var_os(&n), Some("2"));
+    set_var(&n, "");
+    eq(var_os(&n), Some(""));
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn test_var_big() {
+    let mut s = "".to_string();
+    let mut i = 0;
+    while i < 100 {
+        s.push_str("aaaaaaaaaa");
+        i += 1;
+    }
+    let n = make_rand_name();
+    set_var(&n, &s);
+    eq(var_os(&n), Some(&s));
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn test_env_set_get_huge() {
+    let n = make_rand_name();
+    let s = "x".repeat(10000);
+    set_var(&n, &s);
+    eq(var_os(&n), Some(&s));
+    remove_var(&n);
+    eq(var_os(&n), None);
+}
+
+#[test]
+fn test_env_set_var() {
+    let n = make_rand_name();
+
+    let mut e = vars_os();
+    set_var(&n, "VALUE");
+    assert!(!e.any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
+
+    assert!(vars_os().any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
+}
+
+#[test]
+#[cfg_attr(not(any(unix, windows)), ignore, allow(unused))]
+#[allow(deprecated)]
+fn env_home_dir() {
+    use std::path::PathBuf;
+
+    fn var_to_os_string(var: Result<String, VarError>) -> Option<OsString> {
+        match var {
+            Ok(var) => Some(OsString::from(var)),
+            Err(VarError::NotUnicode(var)) => Some(var),
+            _ => None,
+        }
+    }
+
+    cfg_if::cfg_if! {
+        if #[cfg(unix)] {
+            let oldhome = var_to_os_string(var("HOME"));
+
+            set_var("HOME", "/home/MountainView");
+            assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
+
+            remove_var("HOME");
+            if cfg!(target_os = "android") {
+                assert!(home_dir().is_none());
+            } else {
+                // When HOME is not set, some platforms return `None`,
+                // but others return `Some` with a default.
+                // Just check that it is not "/home/MountainView".
+                assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
+            }
+
+            if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
+        } else if #[cfg(windows)] {
+            let oldhome = var_to_os_string(var("HOME"));
+            let olduserprofile = var_to_os_string(var("USERPROFILE"));
+
+            remove_var("HOME");
+            remove_var("USERPROFILE");
+
+            assert!(home_dir().is_some());
+
+            set_var("HOME", "/home/PaloAlto");
+            assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used");
+
+            set_var("USERPROFILE", "/home/MountainView");
+            assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
+
+            remove_var("HOME");
+
+            assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
+
+            set_var("USERPROFILE", "");
+            assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored");
+
+            remove_var("USERPROFILE");
+
+            if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
+            if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
+        }
+    }
+}
+
+#[test] // miri shouldn't detect any data race in this fn
+#[cfg_attr(any(not(miri), target_os = "emscripten"), ignore)]
+fn test_env_get_set_multithreaded() {
+    let getter = thread::spawn(|| {
+        for _ in 0..100 {
+            let _ = var_os("foo");
+        }
+    });
+
+    let setter = thread::spawn(|| {
+        for _ in 0..100 {
+            set_var("foo", "bar");
+        }
+    });
+
+    let _ = getter.join();
+    let _ = setter.join();
+}
diff --git a/library/std/src/error/tests.rs b/library/std/tests/error.rs
index 88a9f33c079..8fd6eb3c020 100644
--- a/library/std/src/error/tests.rs
+++ b/library/std/tests/error.rs
@@ -1,7 +1,8 @@
-use core::error::Request;
+#![feature(error_generic_member_access, error_reporter)]
 
-use super::Error;
-use crate::fmt;
+use std::backtrace::Backtrace;
+use std::error::{Error, Report, Request};
+use std::fmt;
 
 #[derive(Debug, PartialEq)]
 struct A;
@@ -38,9 +39,6 @@ fn downcasting() {
     }
 }
 
-use crate::backtrace::Backtrace;
-use crate::error::Report;
-
 #[derive(Debug)]
 struct SuperError {
     source: SuperErrorSideKick,
diff --git a/library/std/src/f128/tests.rs b/library/std/tests/floats/f128.rs
index cbcf9f96239..d0e8b157e6b 100644
--- a/library/std/src/f128/tests.rs
+++ b/library/std/tests/floats/f128.rs
@@ -1,11 +1,11 @@
 // FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
 #![cfg(reliable_f128)]
 
-use crate::f128::consts;
-use crate::num::FpCategory as Fp;
+use std::f128::consts;
+use std::num::FpCategory as Fp;
 #[cfg(reliable_f128_math)]
-use crate::ops::Rem;
-use crate::ops::{Add, Div, Mul, Sub};
+use std::ops::Rem;
+use std::ops::{Add, Div, Mul, Sub};
 
 // Note these tolerances make sense around zero, but not for more extreme exponents.
 
@@ -762,8 +762,6 @@ fn test_ln_gamma() {
 
 #[test]
 fn test_real_consts() {
-    use super::consts;
-
     let pi: f128 = consts::PI;
     let frac_pi_2: f128 = consts::FRAC_PI_2;
     let frac_pi_3: f128 = consts::FRAC_PI_3;
diff --git a/library/std/src/f16/tests.rs b/library/std/tests/floats/f16.rs
index 684ee3f3855..5180f3d40f3 100644
--- a/library/std/src/f16/tests.rs
+++ b/library/std/tests/floats/f16.rs
@@ -1,8 +1,8 @@
 // FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
 #![cfg(reliable_f16)]
 
-use crate::f16::consts;
-use crate::num::{FpCategory as Fp, *};
+use std::f16::consts;
+use std::num::FpCategory as Fp;
 
 /// Tolerance for results on the order of 10.0e-2
 #[allow(unused)]
@@ -54,7 +54,7 @@ macro_rules! assert_f16_biteq {
 
 #[test]
 fn test_num_f16() {
-    test_num(10f16, 2f16);
+    crate::test_num(10f16, 2f16);
 }
 
 #[test]
@@ -734,7 +734,6 @@ fn test_ln_gamma() {
 #[test]
 fn test_real_consts() {
     // FIXME(f16_f128): add math tests when available
-    use super::consts;
 
     let pi: f16 = consts::PI;
     let frac_pi_2: f16 = consts::FRAC_PI_2;
diff --git a/library/std/src/f32/tests.rs b/library/std/tests/floats/f32.rs
index 99cfcfb231d..bf7641986ad 100644
--- a/library/std/src/f32/tests.rs
+++ b/library/std/tests/floats/f32.rs
@@ -1,5 +1,5 @@
-use crate::f32::consts;
-use crate::num::{FpCategory as Fp, *};
+use std::f32::consts;
+use std::num::FpCategory as Fp;
 
 /// Smallest number
 const TINY_BITS: u32 = 0x1;
@@ -35,7 +35,7 @@ macro_rules! assert_f32_biteq {
 
 #[test]
 fn test_num_f32() {
-    test_num(10f32, 2f32);
+    crate::test_num(10f32, 2f32);
 }
 
 #[test]
@@ -700,8 +700,6 @@ fn test_ln_gamma() {
 
 #[test]
 fn test_real_consts() {
-    use super::consts;
-
     let pi: f32 = consts::PI;
     let frac_pi_2: f32 = consts::FRAC_PI_2;
     let frac_pi_3: f32 = consts::FRAC_PI_3;
diff --git a/library/std/src/f64/tests.rs b/library/std/tests/floats/f64.rs
index f5ba2c7b594..cbbfcd15efd 100644
--- a/library/std/src/f64/tests.rs
+++ b/library/std/tests/floats/f64.rs
@@ -1,5 +1,5 @@
-use crate::f64::consts;
-use crate::num::{FpCategory as Fp, *};
+use std::f64::consts;
+use std::num::FpCategory as Fp;
 
 /// Smallest number
 const TINY_BITS: u64 = 0x1;
@@ -35,7 +35,7 @@ macro_rules! assert_f64_biteq {
 
 #[test]
 fn test_num_f64() {
-    test_num(10f64, 2f64);
+    crate::test_num(10f64, 2f64);
 }
 
 #[test]
@@ -680,7 +680,6 @@ fn test_ln_gamma() {
 
 #[test]
 fn test_real_consts() {
-    use super::consts;
     let pi: f64 = consts::PI;
     let frac_pi_2: f64 = consts::FRAC_PI_2;
     let frac_pi_3: f64 = consts::FRAC_PI_3;
diff --git a/library/std/tests/floats/lib.rs b/library/std/tests/floats/lib.rs
new file mode 100644
index 00000000000..ad82f1a44e7
--- /dev/null
+++ b/library/std/tests/floats/lib.rs
@@ -0,0 +1,42 @@
+#![feature(f16, f128, float_gamma, float_minimum_maximum)]
+
+use std::fmt;
+use std::ops::{Add, Div, Mul, Rem, Sub};
+
+/// Verify that floats are within a tolerance of each other, 1.0e-6 by default.
+macro_rules! assert_approx_eq {
+    ($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
+    ($a:expr, $b:expr, $lim:expr) => {{
+        let (a, b) = (&$a, &$b);
+        let diff = (*a - *b).abs();
+        assert!(
+            diff < $lim,
+            "{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
+            lim = $lim
+        );
+    }};
+}
+
+/// Helper function for testing numeric operations
+pub fn test_num<T>(ten: T, two: T)
+where
+    T: PartialEq
+        + Add<Output = T>
+        + Sub<Output = T>
+        + Mul<Output = T>
+        + Div<Output = T>
+        + Rem<Output = T>
+        + fmt::Debug
+        + Copy,
+{
+    assert_eq!(ten.add(two), ten + two);
+    assert_eq!(ten.sub(two), ten - two);
+    assert_eq!(ten.mul(two), ten * two);
+    assert_eq!(ten.div(two), ten / two);
+    assert_eq!(ten.rem(two), ten % two);
+}
+
+mod f128;
+mod f16;
+mod f32;
+mod f64;
diff --git a/library/std/src/num/tests.rs b/library/std/tests/num.rs
index df0df3f23f7..a7400f1c02d 100644
--- a/library/std/src/num/tests.rs
+++ b/library/std/tests/num.rs
@@ -1,4 +1,4 @@
-use crate::ops::Mul;
+use std::ops::Mul;
 
 #[test]
 fn test_saturating_add_uint() {
@@ -190,8 +190,8 @@ fn test_uint_to_str_overflow() {
     assert_eq!(u64_val.to_string(), "0");
 }
 
-fn from_str<T: crate::str::FromStr>(t: &str) -> Option<T> {
-    crate::str::FromStr::from_str(t).ok()
+fn from_str<T: std::str::FromStr>(t: &str) -> Option<T> {
+    std::str::FromStr::from_str(t).ok()
 }
 
 #[test]
diff --git a/library/std/src/panic/tests.rs b/library/std/tests/panic.rs
index b37d74011cc..f13b931dd22 100644
--- a/library/std/src/panic/tests.rs
+++ b/library/std/tests/panic.rs
@@ -1,9 +1,9 @@
 #![allow(dead_code)]
 
-use crate::cell::RefCell;
-use crate::panic::{AssertUnwindSafe, UnwindSafe};
-use crate::rc::Rc;
-use crate::sync::{Arc, Mutex, RwLock};
+use std::cell::RefCell;
+use std::panic::{AssertUnwindSafe, UnwindSafe};
+use std::rc::Rc;
+use std::sync::{Arc, Mutex, RwLock};
 
 struct Foo {
     a: i32,
diff --git a/library/std/src/path/tests.rs b/library/std/tests/path.rs
index 3f96ac4672a..978402b6fda 100644
--- a/library/std/src/path/tests.rs
+++ b/library/std/tests/path.rs
@@ -1,10 +1,19 @@
-use core::hint::black_box;
-
-use super::*;
-use crate::collections::{BTreeSet, HashSet};
-use crate::hash::DefaultHasher;
-use crate::mem::MaybeUninit;
-use crate::ptr;
+#![feature(
+    clone_to_uninit,
+    path_add_extension,
+    path_file_prefix,
+    maybe_uninit_slice,
+    os_string_pathbuf_leak
+)]
+
+use std::clone::CloneToUninit;
+use std::ffi::OsStr;
+use std::hash::{DefaultHasher, Hash, Hasher};
+use std::mem::MaybeUninit;
+use std::path::*;
+use std::ptr;
+use std::rc::Rc;
+use std::sync::Arc;
 
 #[allow(unknown_lints, unused_macro_rules)]
 macro_rules! t (
@@ -110,7 +119,7 @@ macro_rules! t (
 
 #[test]
 fn into() {
-    use crate::borrow::Cow;
+    use std::borrow::Cow;
 
     let static_path = Path::new("/home/foo");
     let static_cow_path: Cow<'static, Path> = static_path.into();
@@ -1525,7 +1534,7 @@ pub fn test_with_added_extension() {
 
 #[test]
 fn test_eq_receivers() {
-    use crate::borrow::Cow;
+    use std::borrow::Cow;
 
     let borrowed: &Path = Path::new("foo/bar");
     let mut owned: PathBuf = PathBuf::new();
@@ -1550,7 +1559,7 @@ fn test_eq_receivers() {
 
 #[test]
 pub fn test_compare() {
-    use crate::hash::{DefaultHasher, Hash, Hasher};
+    use std::hash::{DefaultHasher, Hash, Hasher};
 
     fn hash<T: Hash>(t: T) -> u64 {
         let mut s = DefaultHasher::new();
@@ -1867,12 +1876,12 @@ fn test_ord() {
 #[test]
 #[cfg(any(unix, target_os = "wasi"))]
 fn test_unix_absolute() {
-    use crate::path::absolute;
+    use std::path::absolute;
 
     assert!(absolute("").is_err());
 
     let relative = "a/b";
-    let mut expected = crate::env::current_dir().unwrap();
+    let mut expected = std::env::current_dir().unwrap();
     expected.push(relative);
     assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
 
@@ -1888,7 +1897,7 @@ fn test_unix_absolute() {
     );
 
     // Test leading `.` and `..` components
-    let curdir = crate::env::current_dir().unwrap();
+    let curdir = std::env::current_dir().unwrap();
     assert_eq!(absolute("./a").unwrap().as_os_str(), curdir.join("a").as_os_str());
     assert_eq!(absolute("../a").unwrap().as_os_str(), curdir.join("../a").as_os_str()); // return /pwd/../a
 }
@@ -1896,12 +1905,12 @@ fn test_unix_absolute() {
 #[test]
 #[cfg(windows)]
 fn test_windows_absolute() {
-    use crate::path::absolute;
+    use std::path::absolute;
     // An empty path is an error.
     assert!(absolute("").is_err());
 
     let relative = r"a\b";
-    let mut expected = crate::env::current_dir().unwrap();
+    let mut expected = std::env::current_dir().unwrap();
     expected.push(relative);
     assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
 
@@ -1953,116 +1962,6 @@ fn test_extension_path_sep_alternate() {
     assert_eq!(path, Path::new("path/to/file.d\\test"));
 }
 
-#[bench]
-#[cfg_attr(miri, ignore)] // Miri isn't fast...
-fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
-    let prefix = "my/home";
-    let mut paths: Vec<_> =
-        (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
-
-    paths.sort();
-
-    b.iter(|| {
-        black_box(paths.as_mut_slice()).sort_unstable();
-    });
-}
-
-#[bench]
-#[cfg_attr(miri, ignore)] // Miri isn't fast...
-fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
-    let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
-    let paths: Vec<_> =
-        (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
-
-    let mut set = BTreeSet::new();
-
-    paths.iter().for_each(|p| {
-        set.insert(p.as_path());
-    });
-
-    b.iter(|| {
-        set.remove(paths[500].as_path());
-        set.insert(paths[500].as_path());
-    });
-}
-
-#[bench]
-#[cfg_attr(miri, ignore)] // Miri isn't fast...
-fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
-    let prefix = "my/home";
-    let paths: Vec<_> =
-        (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
-
-    let mut set = BTreeSet::new();
-
-    paths.iter().for_each(|p| {
-        set.insert(p.as_path());
-    });
-
-    b.iter(|| {
-        set.remove(paths[500].as_path());
-        set.insert(paths[500].as_path());
-    });
-}
-
-#[bench]
-#[cfg_attr(miri, ignore)] // Miri isn't fast...
-fn bench_path_hashset(b: &mut test::Bencher) {
-    let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
-    let paths: Vec<_> =
-        (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
-
-    let mut set = HashSet::new();
-
-    paths.iter().for_each(|p| {
-        set.insert(p.as_path());
-    });
-
-    b.iter(|| {
-        set.remove(paths[500].as_path());
-        set.insert(black_box(paths[500].as_path()))
-    });
-}
-
-#[bench]
-#[cfg_attr(miri, ignore)] // Miri isn't fast...
-fn bench_path_hashset_miss(b: &mut test::Bencher) {
-    let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
-    let paths: Vec<_> =
-        (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
-
-    let mut set = HashSet::new();
-
-    paths.iter().for_each(|p| {
-        set.insert(p.as_path());
-    });
-
-    let probe = PathBuf::from(prefix).join("other");
-
-    b.iter(|| set.remove(black_box(probe.as_path())));
-}
-
-#[bench]
-fn bench_hash_path_short(b: &mut test::Bencher) {
-    let mut hasher = DefaultHasher::new();
-    let path = Path::new("explorer.exe");
-
-    b.iter(|| black_box(path).hash(&mut hasher));
-
-    black_box(hasher.finish());
-}
-
-#[bench]
-fn bench_hash_path_long(b: &mut test::Bencher) {
-    let mut hasher = DefaultHasher::new();
-    let path =
-        Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff");
-
-    b.iter(|| black_box(path).hash(&mut hasher));
-
-    black_box(hasher.finish());
-}
-
 #[test]
 fn clone_to_uninit() {
     let a = Path::new("hello.txt");
diff --git a/library/std/src/sync/barrier/tests.rs b/library/std/tests/sync/barrier.rs
index 0fbcd998812..8aefff9d507 100644
--- a/library/std/src/sync/barrier/tests.rs
+++ b/library/std/tests/sync/barrier.rs
@@ -1,6 +1,6 @@
-use crate::sync::mpsc::{TryRecvError, channel};
-use crate::sync::{Arc, Barrier};
-use crate::thread;
+use std::sync::mpsc::{TryRecvError, channel};
+use std::sync::{Arc, Barrier};
+use std::thread;
 
 #[test]
 #[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
diff --git a/library/std/src/sync/poison/condvar/tests.rs b/library/std/tests/sync/condvar.rs
index f9e9066bc92..834de6bb1c2 100644
--- a/library/std/src/sync/poison/condvar/tests.rs
+++ b/library/std/tests/sync/condvar.rs
@@ -1,8 +1,8 @@
-use crate::sync::atomic::{AtomicBool, Ordering};
-use crate::sync::mpsc::channel;
-use crate::sync::{Arc, Condvar, Mutex};
-use crate::thread;
-use crate::time::Duration;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::mpsc::channel;
+use std::sync::{Arc, Condvar, Mutex};
+use std::thread;
+use std::time::Duration;
 
 #[test]
 fn smoke() {
diff --git a/library/std/src/sync/lazy_lock/tests.rs b/library/std/tests/sync/lazy_lock.rs
index 7d7dde54349..6c14b79f2ce 100644
--- a/library/std/src/sync/lazy_lock/tests.rs
+++ b/library/std/tests/sync/lazy_lock.rs
@@ -1,8 +1,8 @@
-use crate::cell::LazyCell;
-use crate::sync::atomic::AtomicUsize;
-use crate::sync::atomic::Ordering::SeqCst;
-use crate::sync::{LazyLock, Mutex, OnceLock};
-use crate::{panic, thread};
+use std::cell::LazyCell;
+use std::sync::atomic::AtomicUsize;
+use std::sync::atomic::Ordering::SeqCst;
+use std::sync::{LazyLock, Mutex, OnceLock};
+use std::{panic, thread};
 
 fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
     thread::spawn(f).join().unwrap()
@@ -149,7 +149,7 @@ fn is_sync_send() {
 #[should_panic = "has previously been poisoned"]
 fn lazy_force_mut_panic() {
     let mut lazy = LazyLock::<String>::new(|| panic!());
-    crate::panic::catch_unwind(crate::panic::AssertUnwindSafe(|| {
+    panic::catch_unwind(panic::AssertUnwindSafe(|| {
         let _ = LazyLock::force_mut(&mut lazy);
     }))
     .unwrap_err();
diff --git a/library/std/tests/sync/lib.rs b/library/std/tests/sync/lib.rs
new file mode 100644
index 00000000000..51190f0894f
--- /dev/null
+++ b/library/std/tests/sync/lib.rs
@@ -0,0 +1,31 @@
+#![feature(lazy_get)]
+#![feature(mapped_lock_guards)]
+#![feature(mpmc_channel)]
+#![feature(once_cell_try)]
+#![feature(lock_value_accessors)]
+#![feature(reentrant_lock)]
+#![feature(rwlock_downgrade)]
+#![feature(std_internals)]
+#![allow(internal_features)]
+
+mod barrier;
+mod condvar;
+mod lazy_lock;
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
+mod mpmc;
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
+mod mpsc;
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
+mod mpsc_sync;
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
+mod mutex;
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
+mod once;
+mod once_lock;
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
+mod reentrant_lock;
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
+mod rwlock;
+
+#[path = "../common/mod.rs"]
+mod common;
diff --git a/library/std/src/sync/mpmc/tests.rs b/library/std/tests/sync/mpmc.rs
index ab14050df6c..81b92297f76 100644
--- a/library/std/src/sync/mpmc/tests.rs
+++ b/library/std/tests/sync/mpmc.rs
@@ -1,5 +1,6 @@
-use super::*;
-use crate::{env, thread};
+use std::sync::mpmc::*;
+use std::time::{Duration, Instant};
+use std::{env, thread};
 
 pub fn stress_factor() -> usize {
     match env::var("RUST_TEST_STRESS") {
diff --git a/library/std/src/sync/mpsc/tests.rs b/library/std/tests/sync/mpsc.rs
index 13892fa0d18..1d8edfde44b 100644
--- a/library/std/src/sync/mpsc/tests.rs
+++ b/library/std/tests/sync/mpsc.rs
@@ -1,5 +1,6 @@
-use super::*;
-use crate::{env, thread};
+use std::sync::mpsc::*;
+use std::time::{Duration, Instant};
+use std::{env, thread};
 
 pub fn stress_factor() -> usize {
     match env::var("RUST_TEST_STRESS") {
diff --git a/library/std/src/sync/mpsc/sync_tests.rs b/library/std/tests/sync/mpsc_sync.rs
index 49b65c8efe6..a7f326d201b 100644
--- a/library/std/src/sync/mpsc/sync_tests.rs
+++ b/library/std/tests/sync/mpsc_sync.rs
@@ -1,7 +1,8 @@
-use super::*;
-use crate::rc::Rc;
-use crate::sync::mpmc::SendTimeoutError;
-use crate::{env, thread};
+use std::rc::Rc;
+use std::sync::mpmc::SendTimeoutError;
+use std::sync::mpsc::*;
+use std::time::Duration;
+use std::{env, thread};
 
 pub fn stress_factor() -> usize {
     match env::var("RUST_TEST_STRESS") {
diff --git a/library/std/src/sync/poison/mutex/tests.rs b/library/std/tests/sync/mutex.rs
index 395c8aada08..74c62720107 100644
--- a/library/std/src/sync/poison/mutex/tests.rs
+++ b/library/std/tests/sync/mutex.rs
@@ -1,10 +1,10 @@
-use crate::fmt::Debug;
-use crate::ops::FnMut;
-use crate::panic::{self, AssertUnwindSafe};
-use crate::sync::atomic::{AtomicUsize, Ordering};
-use crate::sync::mpsc::channel;
-use crate::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError};
-use crate::{hint, mem, thread};
+use std::fmt::Debug;
+use std::ops::FnMut;
+use std::panic::{self, AssertUnwindSafe};
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::mpsc::channel;
+use std::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError};
+use std::{hint, mem, thread};
 
 struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
 
diff --git a/library/std/src/sync/poison/once/tests.rs b/library/std/tests/sync/once.rs
index ce96468aeb6..a3ffc73fe06 100644
--- a/library/std/src/sync/poison/once/tests.rs
+++ b/library/std/tests/sync/once.rs
@@ -1,9 +1,9 @@
-use super::Once;
-use crate::sync::atomic::AtomicBool;
-use crate::sync::atomic::Ordering::Relaxed;
-use crate::sync::mpsc::channel;
-use crate::time::Duration;
-use crate::{panic, thread};
+use std::sync::Once;
+use std::sync::atomic::AtomicBool;
+use std::sync::atomic::Ordering::Relaxed;
+use std::sync::mpsc::channel;
+use std::time::Duration;
+use std::{panic, thread};
 
 #[test]
 fn smoke_once() {
diff --git a/library/std/src/sync/once_lock/tests.rs b/library/std/tests/sync/once_lock.rs
index 5113d436c3c..ac9aaa8892e 100644
--- a/library/std/src/sync/once_lock/tests.rs
+++ b/library/std/tests/sync/once_lock.rs
@@ -1,8 +1,8 @@
-use crate::sync::OnceLock;
-use crate::sync::atomic::AtomicUsize;
-use crate::sync::atomic::Ordering::SeqCst;
-use crate::sync::mpsc::channel;
-use crate::{panic, thread};
+use std::sync::OnceLock;
+use std::sync::atomic::AtomicUsize;
+use std::sync::atomic::Ordering::SeqCst;
+use std::sync::mpsc::channel;
+use std::{panic, thread};
 
 fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
     thread::spawn(f).join().unwrap()
@@ -34,15 +34,6 @@ fn sync_once_cell_get_mut() {
 }
 
 #[test]
-fn sync_once_cell_get_unchecked() {
-    let c = OnceLock::new();
-    c.set(92).unwrap();
-    unsafe {
-        assert_eq!(c.get_unchecked(), &92);
-    }
-}
-
-#[test]
 #[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
 fn sync_once_cell_drop() {
     static DROP_CNT: AtomicUsize = AtomicUsize::new(0);
@@ -88,7 +79,6 @@ fn get_or_try_init() {
 
     let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
     assert!(res.is_err());
-    assert!(!cell.is_initialized());
     assert!(cell.get().is_none());
 
     assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
@@ -174,7 +164,7 @@ fn sync_once_cell_does_not_leak_partially_constructed_boxes() {
                     break;
                 }
                 #[cfg(target_env = "sgx")]
-                crate::thread::yield_now();
+                std::thread::yield_now();
             }
         });
     }
diff --git a/library/std/src/sync/reentrant_lock/tests.rs b/library/std/tests/sync/reentrant_lock.rs
index aeef0289d28..2b7b87e3623 100644
--- a/library/std/src/sync/reentrant_lock/tests.rs
+++ b/library/std/tests/sync/reentrant_lock.rs
@@ -1,7 +1,6 @@
-use super::ReentrantLock;
-use crate::cell::RefCell;
-use crate::sync::Arc;
-use crate::thread;
+use std::cell::RefCell;
+use std::sync::{Arc, ReentrantLock};
+use std::thread;
 
 #[test]
 fn smoke() {
diff --git a/library/std/src/sync/poison/rwlock/tests.rs b/library/std/tests/sync/rwlock.rs
index 057c2f1a5d7..bd4bc7a14bc 100644
--- a/library/std/src/sync/poison/rwlock/tests.rs
+++ b/library/std/tests/sync/rwlock.rs
@@ -1,15 +1,15 @@
-use rand::Rng;
-
-use crate::fmt::Debug;
-use crate::ops::FnMut;
-use crate::panic::{self, AssertUnwindSafe};
-use crate::sync::atomic::{AtomicUsize, Ordering};
-use crate::sync::mpsc::channel;
-use crate::sync::{
+use std::fmt::Debug;
+use std::ops::FnMut;
+use std::panic::{self, AssertUnwindSafe};
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::mpsc::channel;
+use std::sync::{
     Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
     TryLockError,
 };
-use crate::{hint, mem, thread};
+use std::{hint, mem, thread};
+
+use rand::Rng;
 
 #[derive(Eq, PartialEq, Debug)]
 struct NonCopy(i32);
@@ -57,7 +57,7 @@ fn frob() {
         let tx = tx.clone();
         let r = r.clone();
         thread::spawn(move || {
-            let mut rng = crate::test_helpers::test_rng();
+            let mut rng = crate::common::test_rng();
             for _ in 0..M {
                 if rng.gen_bool(1.0 / (N as f64)) {
                     drop(r.write().unwrap());
@@ -704,7 +704,7 @@ fn test_downgrade_atomic() {
 
     // Wait for a good amount of time so that evil threads go to sleep.
     // Note: this is not strictly necessary...
-    let eternity = crate::time::Duration::from_millis(42);
+    let eternity = std::time::Duration::from_millis(42);
     thread::sleep(eternity);
 
     // Once everyone is asleep, set the value to `NEW_VALUE`.
diff --git a/library/std/src/thread/local/dynamic_tests.rs b/library/std/tests/thread_local/dynamic_tests.rs
index dd180041648..454462b3925 100644
--- a/library/std/src/thread/local/dynamic_tests.rs
+++ b/library/std/tests/thread_local/dynamic_tests.rs
@@ -1,6 +1,6 @@
-use crate::cell::RefCell;
-use crate::collections::HashMap;
-use crate::thread_local;
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::thread_local;
 
 #[test]
 fn smoke() {
diff --git a/library/std/tests/thread_local/lib.rs b/library/std/tests/thread_local/lib.rs
new file mode 100644
index 00000000000..c5291435425
--- /dev/null
+++ b/library/std/tests/thread_local/lib.rs
@@ -0,0 +1,4 @@
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
+mod tests;
+
+mod dynamic_tests;
diff --git a/library/std/src/thread/local/tests.rs b/library/std/tests/thread_local/tests.rs
index 9d4f52a0921..aa020c2559c 100644
--- a/library/std/src/thread/local/tests.rs
+++ b/library/std/tests/thread_local/tests.rs
@@ -1,8 +1,8 @@
-use crate::cell::{Cell, UnsafeCell};
-use crate::sync::atomic::{AtomicU8, Ordering};
-use crate::sync::{Arc, Condvar, Mutex};
-use crate::thread::{self, Builder, LocalKey};
-use crate::thread_local;
+use std::cell::{Cell, UnsafeCell};
+use std::sync::atomic::{AtomicU8, Ordering};
+use std::sync::{Arc, Condvar, Mutex};
+use std::thread::{self, Builder, LocalKey};
+use std::thread_local;
 
 #[derive(Clone, Default)]
 struct Signal(Arc<(Mutex<bool>, Condvar)>);
diff --git a/library/std/src/time/tests.rs b/library/std/tests/time.rs
index e88f2d5e806..40709eae37c 100644
--- a/library/std/src/time/tests.rs
+++ b/library/std/tests/time.rs
@@ -1,9 +1,7 @@
-use core::fmt::Debug;
+#![feature(duration_constants)]
 
-#[cfg(not(target_arch = "wasm32"))]
-use test::{Bencher, black_box};
-
-use super::{Duration, Instant, SystemTime, UNIX_EPOCH};
+use std::fmt::Debug;
+use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
 
 macro_rules! assert_almost_eq {
     ($a:expr, $b:expr) => {{
@@ -29,10 +27,10 @@ fn instant_monotonic() {
 
 #[test]
 #[cfg(not(target_arch = "wasm32"))]
-fn instant_monotonic_concurrent() -> crate::thread::Result<()> {
+fn instant_monotonic_concurrent() -> std::thread::Result<()> {
     let threads: Vec<_> = (0..8)
         .map(|_| {
-            crate::thread::spawn(|| {
+            std::thread::spawn(|| {
                 let mut old = Instant::now();
                 let count = if cfg!(miri) { 1_000 } else { 5_000_000 };
                 for _ in 0..count {
@@ -229,46 +227,3 @@ fn big_math() {
     check(instant.checked_add(Duration::from_secs(100)), Instant::checked_sub);
     check(instant.checked_add(Duration::from_secs(i64::MAX as _)), Instant::checked_sub);
 }
-
-macro_rules! bench_instant_threaded {
-    ($bench_name:ident, $thread_count:expr) => {
-        #[bench]
-        #[cfg(not(target_arch = "wasm32"))]
-        fn $bench_name(b: &mut Bencher) -> crate::thread::Result<()> {
-            use crate::sync::Arc;
-            use crate::sync::atomic::{AtomicBool, Ordering};
-
-            let running = Arc::new(AtomicBool::new(true));
-
-            let threads: Vec<_> = (0..$thread_count)
-                .map(|_| {
-                    let flag = Arc::clone(&running);
-                    crate::thread::spawn(move || {
-                        while flag.load(Ordering::Relaxed) {
-                            black_box(Instant::now());
-                        }
-                    })
-                })
-                .collect();
-
-            b.iter(|| {
-                let a = Instant::now();
-                let b = Instant::now();
-                assert!(b >= a);
-            });
-
-            running.store(false, Ordering::Relaxed);
-
-            for t in threads {
-                t.join()?;
-            }
-            Ok(())
-        }
-    };
-}
-
-bench_instant_threaded!(instant_contention_01_threads, 0);
-bench_instant_threaded!(instant_contention_02_threads, 1);
-bench_instant_threaded!(instant_contention_04_threads, 3);
-bench_instant_threaded!(instant_contention_08_threads, 7);
-bench_instant_threaded!(instant_contention_16_threads, 15);
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index 5fcf7eda8df..441674936c6 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -11,12 +11,12 @@ use std::str::FromStr;
 use std::{env, process};
 
 use bootstrap::{
-    Build, CONFIG_CHANGE_HISTORY, Config, Flags, Subcommand, find_recent_config_change_ids,
+    Build, CONFIG_CHANGE_HISTORY, Config, Flags, Subcommand, debug, find_recent_config_change_ids,
     human_readable_changes, t,
 };
 use build_helper::ci::CiEnv;
 #[cfg(feature = "tracing")]
-use tracing::{debug, instrument};
+use tracing::instrument;
 
 #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "main"))]
 fn main() {
@@ -29,10 +29,8 @@ fn main() {
         return;
     }
 
-    #[cfg(feature = "tracing")]
     debug!("parsing flags");
     let flags = Flags::parse(&args);
-    #[cfg(feature = "tracing")]
     debug!("parsing config based on flags");
     let config = Config::parse(flags);
 
@@ -95,7 +93,6 @@ fn main() {
     let dump_bootstrap_shims = config.dump_bootstrap_shims;
     let out_dir = config.out.clone();
 
-    #[cfg(feature = "tracing")]
     debug!("creating new build based on config");
     Build::new(config).build();
 
@@ -207,8 +204,9 @@ fn check_version(config: &Config) -> Option<String> {
 // Due to the conditional compilation via the `tracing` cargo feature, this means that `tracing`
 // usages in bootstrap need to be also gated behind the `tracing` feature:
 //
-// - `tracing` macros (like `trace!`) and anything from `tracing`, `tracing_subscriber` and
-//   `tracing-tree` will need to be gated by `#[cfg(feature = "tracing")]`.
+// - `tracing` macros with log levels (`trace!`, `debug!`, `warn!`, `info`, `error`) should not be
+//   used *directly*. You should use the wrapped `tracing` macros which gate the actual invocations
+//   behind `feature = "tracing"`.
 // - `tracing`'s `#[instrument(..)]` macro will need to be gated like `#![cfg_attr(feature =
 //   "tracing", instrument(..))]`.
 #[cfg(feature = "tracing")]
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index f4a86e26396..21afb031203 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -455,6 +455,7 @@ tool_check_step!(Rls { path: "src/tools/rls" });
 tool_check_step!(Rustfmt { path: "src/tools/rustfmt" });
 tool_check_step!(MiroptTestTools { path: "src/tools/miropt-test-tools" });
 tool_check_step!(TestFloatParse { path: "src/etc/test-float-parse" });
+tool_check_step!(FeaturesStatusDump { path: "src/tools/features-status-dump" });
 
 tool_check_step!(Bootstrap { path: "src/bootstrap", default: false });
 
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index f447d186a52..cd3558ac6a4 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -339,7 +339,7 @@ fn copy_self_contained_objects(
     // to using gcc from a glibc-targeting toolchain for linking.
     // To do that we have to distribute musl startup objects as a part of Rust toolchain
     // and link with them manually in the self-contained mode.
-    if target.contains("musl") && !target.contains("unikraft") {
+    if target.needs_crt_begin_end() {
         let srcdir = builder.musl_libdir(target).unwrap_or_else(|| {
             panic!("Target {:?} does not have a \"musl-libdir\" key", target.triple)
         });
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 3cf25373b89..82779dc6306 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -1295,7 +1295,9 @@ impl Step for CrtBeginEnd {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(CrtBeginEnd { target: run.target });
+        if run.target.needs_crt_begin_end() {
+            run.builder.ensure(CrtBeginEnd { target: run.target });
+        }
     }
 
     /// Build crtbegin.o/crtend.o for musl target.
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index 8513c59808c..167b8a5b168 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -311,3 +311,34 @@ impl Step for UnicodeTableGenerator {
         cmd.run(builder);
     }
 }
+
+#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
+pub struct FeaturesStatusDump;
+
+impl Step for FeaturesStatusDump {
+    type Output = ();
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("src/tools/features-status-dump")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(FeaturesStatusDump);
+    }
+
+    fn run(self, builder: &Builder<'_>) {
+        let mut cmd = builder.tool_cmd(Tool::FeaturesStatusDump);
+
+        cmd.arg("--library-path");
+        cmd.arg(builder.src.join("library"));
+
+        cmd.arg("--compiler-path");
+        cmd.arg(builder.src.join("compiler"));
+
+        cmd.arg("--output-path");
+        cmd.arg(builder.out.join("features-status-dump.json"));
+
+        cmd.run(builder);
+    }
+}
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index a0abd439de0..75fac88252b 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -365,6 +365,7 @@ bootstrap_tool!(
     RustcPerfWrapper, "src/tools/rustc-perf-wrapper", "rustc-perf-wrapper";
     WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
     UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator";
+    FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump";
 );
 
 /// These are the submodules that are required for rustbook to work due to
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index f6a03a386d1..2ecab262413 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -659,7 +659,10 @@ impl Builder<'_> {
                 // Build proc macros both for the host and the target unless proc-macros are not
                 // supported by the target.
                 if target != compiler.host && cmd_kind != Kind::Check {
-                    let error = command(self.rustc(compiler))
+                    let mut rustc_cmd = command(self.rustc(compiler));
+                    self.add_rustc_lib_path(compiler, &mut rustc_cmd);
+
+                    let error = rustc_cmd
                         .arg("--target")
                         .arg(target.rustc_target_arg())
                         .arg("--print=file-names")
@@ -667,6 +670,7 @@ impl Builder<'_> {
                         .arg("-")
                         .run_capture(self)
                         .stderr();
+
                     let not_supported = error
                         .lines()
                         .any(|line| line.contains("unsupported crate type `proc-macro`"));
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 04a00fde3ab..08421dc1f5b 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -938,6 +938,7 @@ impl<'a> Builder<'a> {
                 check::Bootstrap,
                 check::RunMakeSupport,
                 check::Compiletest,
+                check::FeaturesStatusDump,
             ),
             Kind::Test => describe!(
                 crate::core::build_steps::toolstate::ToolStateCheck,
@@ -1089,6 +1090,7 @@ impl<'a> Builder<'a> {
                 run::GenerateWindowsSys,
                 run::GenerateCompletions,
                 run::UnicodeTableGenerator,
+                run::FeaturesStatusDump,
             ),
             Kind::Setup => {
                 describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor)
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 98490118f7d..4694dd2ca4e 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -575,6 +575,10 @@ impl TargetSelection {
         env::var("OSTYPE").is_ok_and(|v| v.to_lowercase().contains("cygwin"))
     }
 
+    pub fn needs_crt_begin_end(&self) -> bool {
+        self.contains("musl") && !self.contains("unikraft")
+    }
+
     /// Path to the file defining the custom target, if any.
     pub fn filepath(&self) -> Option<&Path> {
         self.file.as_ref().map(Path::new)
@@ -700,7 +704,7 @@ trait Merge {
 impl Merge for TomlConfig {
     fn merge(
         &mut self,
-        TomlConfig { build, install, llvm, rust, dist, target, profile: _, change_id }: Self,
+        TomlConfig { build, install, llvm, rust, dist, target, profile, change_id }: Self,
         replace: ReplaceOpt,
     ) {
         fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) {
@@ -712,7 +716,10 @@ impl Merge for TomlConfig {
                 }
             }
         }
+
         self.change_id.inner.merge(change_id.inner, replace);
+        self.profile.merge(profile, replace);
+
         do_merge(&mut self.build, build, replace);
         do_merge(&mut self.install, install, replace);
         do_merge(&mut self.llvm, llvm, replace);
@@ -1505,6 +1512,10 @@ impl Config {
             build.cargo = build.cargo.take().or(std::env::var_os("CARGO").map(|p| p.into()));
         }
 
+        if GitInfo::new(false, &config.src).is_from_tarball() && toml.profile.is_none() {
+            toml.profile = Some("dist".into());
+        }
+
         if let Some(include) = &toml.profile {
             // Allows creating alias for profile names, allowing
             // profiles to be renamed while maintaining back compatibility
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index d56f35f866c..2dd83d5938e 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -28,8 +28,6 @@ use std::{env, fs, io, str};
 use build_helper::ci::gha;
 use build_helper::exit;
 use termcolor::{ColorChoice, StandardStream, WriteColor};
-#[cfg(feature = "tracing")]
-use tracing::{debug, instrument, span, trace};
 use utils::build_stamp::BuildStamp;
 use utils::channel::GitInfo;
 
@@ -46,6 +44,8 @@ pub use core::builder::PathSet;
 pub use core::config::Config;
 pub use core::config::flags::{Flags, Subcommand};
 
+#[cfg(feature = "tracing")]
+use tracing::{instrument, span};
 pub use utils::change_tracker::{
     CONFIG_CHANGE_HISTORY, find_recent_config_change_ids, human_readable_changes,
 };
@@ -541,72 +541,71 @@ impl Build {
     /// Executes the entire build, as configured by the flags and configuration.
     #[cfg_attr(feature = "tracing", instrument(level = "debug", name = "Build::build", skip_all))]
     pub fn build(&mut self) {
-        #[cfg(feature = "tracing")]
         trace!("setting up job management");
         unsafe {
             crate::utils::job::setup(self);
         }
 
-        #[cfg(feature = "tracing")]
-        trace!("downloading rustfmt early");
-
         // Download rustfmt early so that it can be used in rust-analyzer configs.
+        trace!("downloading rustfmt early");
         let _ = &builder::Builder::new(self).initial_rustfmt();
 
-        #[cfg(feature = "tracing")]
-        let hardcoded_span =
-            span!(tracing::Level::DEBUG, "handling hardcoded subcommands (Format, Suggest, Perf)")
-                .entered();
-
-        // hardcoded subcommands
-        match &self.config.cmd {
-            Subcommand::Format { check, all } => {
-                return core::build_steps::format::format(
-                    &builder::Builder::new(self),
-                    *check,
-                    *all,
-                    &self.config.paths,
-                );
-            }
-            Subcommand::Suggest { run } => {
-                return core::build_steps::suggest::suggest(&builder::Builder::new(self), *run);
-            }
-            Subcommand::Perf { .. } => {
-                return core::build_steps::perf::perf(&builder::Builder::new(self));
-            }
-            _cmd => {
-                #[cfg(feature = "tracing")]
-                debug!(cmd = ?_cmd, "not a hardcoded subcommand; returning to normal handling");
+        // Handle hard-coded subcommands.
+        {
+            #[cfg(feature = "tracing")]
+            let _hardcoded_span = span!(
+                tracing::Level::DEBUG,
+                "handling hardcoded subcommands (Format, Suggest, Perf)"
+            )
+            .entered();
+
+            match &self.config.cmd {
+                Subcommand::Format { check, all } => {
+                    return core::build_steps::format::format(
+                        &builder::Builder::new(self),
+                        *check,
+                        *all,
+                        &self.config.paths,
+                    );
+                }
+                Subcommand::Suggest { run } => {
+                    return core::build_steps::suggest::suggest(&builder::Builder::new(self), *run);
+                }
+                Subcommand::Perf { .. } => {
+                    return core::build_steps::perf::perf(&builder::Builder::new(self));
+                }
+                _cmd => {
+                    debug!(cmd = ?_cmd, "not a hardcoded subcommand; returning to normal handling");
+                }
             }
-        }
 
-        #[cfg(feature = "tracing")]
-        drop(hardcoded_span);
-        #[cfg(feature = "tracing")]
-        debug!("handling subcommand normally");
+            debug!("handling subcommand normally");
+        }
 
         if !self.config.dry_run() {
             #[cfg(feature = "tracing")]
             let _real_run_span = span!(tracing::Level::DEBUG, "executing real run").entered();
 
+            // We first do a dry-run. This is a sanity-check to ensure that
+            // steps don't do anything expensive in the dry-run.
             {
                 #[cfg(feature = "tracing")]
                 let _sanity_check_span =
                     span!(tracing::Level::DEBUG, "(1) executing dry-run sanity-check").entered();
-
-                // We first do a dry-run. This is a sanity-check to ensure that
-                // steps don't do anything expensive in the dry-run.
                 self.config.dry_run = DryRun::SelfCheck;
                 let builder = builder::Builder::new(self);
                 builder.execute_cli();
             }
 
-            #[cfg(feature = "tracing")]
-            let _actual_run_span =
-                span!(tracing::Level::DEBUG, "(2) executing actual run").entered();
-            self.config.dry_run = DryRun::Disabled;
-            let builder = builder::Builder::new(self);
-            builder.execute_cli();
+            // Actual run.
+            {
+                #[cfg(feature = "tracing")]
+                let _actual_run_span =
+                    span!(tracing::Level::DEBUG, "(2) executing actual run").entered();
+                self.config.dry_run = DryRun::Disabled;
+                let builder = builder::Builder::new(self);
+                builder.execute_cli();
+            }
         } else {
             #[cfg(feature = "tracing")]
             let _dry_run_span = span!(tracing::Level::DEBUG, "executing dry run").entered();
diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs
index ea56932b404..caef8ce3088 100644
--- a/src/bootstrap/src/utils/mod.rs
+++ b/src/bootstrap/src/utils/mod.rs
@@ -14,6 +14,8 @@ pub(crate) mod render_tests;
 pub(crate) mod shared_helpers;
 pub(crate) mod tarball;
 
+pub(crate) mod tracing;
+
 #[cfg(feature = "build-metrics")]
 pub(crate) mod metrics;
 
diff --git a/src/bootstrap/src/utils/tracing.rs b/src/bootstrap/src/utils/tracing.rs
new file mode 100644
index 00000000000..e89decf9e55
--- /dev/null
+++ b/src/bootstrap/src/utils/tracing.rs
@@ -0,0 +1,49 @@
+//! Wrapper macros for `tracing` macros to avoid having to write `cfg(feature = "tracing")`-gated
+//! `debug!`/`trace!` everytime, e.g.
+//!
+//! ```rust,ignore (example)
+//! #[cfg(feature = "tracing")]
+//! trace!("...");
+//! ```
+//!
+//! When `feature = "tracing"` is inactive, these macros expand to nothing.
+
+#[macro_export]
+macro_rules! trace {
+    ($($tokens:tt)*) => {
+        #[cfg(feature = "tracing")]
+        ::tracing::trace!($($tokens)*)
+    }
+}
+
+#[macro_export]
+macro_rules! debug {
+    ($($tokens:tt)*) => {
+        #[cfg(feature = "tracing")]
+        ::tracing::debug!($($tokens)*)
+    }
+}
+
+#[macro_export]
+macro_rules! warn {
+    ($($tokens:tt)*) => {
+        #[cfg(feature = "tracing")]
+        ::tracing::warn!($($tokens)*)
+    }
+}
+
+#[macro_export]
+macro_rules! info {
+    ($($tokens:tt)*) => {
+        #[cfg(feature = "tracing")]
+        ::tracing::info!($($tokens)*)
+    }
+}
+
+#[macro_export]
+macro_rules! error {
+    ($($tokens:tt)*) => {
+        #[cfg(feature = "tracing")]
+        ::tracing::error!($($tokens)*)
+    }
+}
diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh
index 8776e0f0be9..3eb85ab215e 100755
--- a/src/ci/docker/scripts/rfl-build.sh
+++ b/src/ci/docker/scripts/rfl-build.sh
@@ -2,7 +2,7 @@
 
 set -euo pipefail
 
-LINUX_VERSION=v6.13-rc1
+LINUX_VERSION=50e57739141b41f731ab31f8380821c7969f9dc4
 
 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt
 ../x.py build --stage 2 library rustdoc clippy rustfmt
@@ -28,7 +28,7 @@ rm -rf linux || true
 # Download Linux at a specific commit
 mkdir -p linux
 git -C linux init
-git -C linux remote add origin https://github.com/Rust-for-Linux/linux.git
+git -C linux remote add origin https://github.com/Darksonn/linux.git
 git -C linux fetch --depth 1 origin ${LINUX_VERSION}
 git -C linux checkout FETCH_HEAD
 
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 37299a5a76b..58a9eb69666 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -525,8 +525,7 @@ auto:
     env:
       RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
       SCRIPT: make ci-mingw
-      # We are intentionally allowing an old toolchain on this builder (and that's
-      # incompatible with LLVM downloads today).
+      # There is no dist-i686-mingw-alt, so there is no prebuilt LLVM with assertions
       NO_DOWNLOAD_CI_LLVM: 1
     <<: *job-windows-25-8c
 
@@ -535,8 +534,7 @@ auto:
     env:
       SCRIPT: make ci-mingw-x
       RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
-      # We are intentionally allowing an old toolchain on this builder (and that's
-      # incompatible with LLVM downloads today).
+      # There is no dist-x86_64-mingw-alt, so there is no prebuilt LLVM with assertions
       NO_DOWNLOAD_CI_LLVM: 1
     <<: *job-windows
 
@@ -544,8 +542,7 @@ auto:
     env:
       SCRIPT: make ci-mingw-bootstrap
       RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
-      # We are intentionally allowing an old toolchain on this builder (and that's
-      # incompatible with LLVM downloads today).
+      # There is no dist-x86_64-mingw-alt, so there is no prebuilt LLVM with assertions
       NO_DOWNLOAD_CI_LLVM: 1
     <<: *job-windows
 
@@ -561,7 +558,7 @@ auto:
       SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist windows-ci -- python x.py dist bootstrap --include-default-paths
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
-    <<: *job-windows-8c
+    <<: *job-windows-25-8c
 
   - name: dist-i686-msvc
     env:
@@ -593,9 +590,6 @@ auto:
       RUST_CONFIGURE_ARGS: >-
         --build=i686-pc-windows-gnu
         --enable-full-tools
-      # We are intentionally allowing an old toolchain on this builder (and that's
-      # incompatible with LLVM downloads today).
-      NO_DOWNLOAD_CI_LLVM: 1
       SCRIPT: python x.py dist bootstrap --include-default-paths
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
@@ -607,9 +601,6 @@ auto:
       RUST_CONFIGURE_ARGS: >-
         --build=x86_64-pc-windows-gnu
         --enable-full-tools
-      # We are intentionally allowing an old toolchain on this builder (and that's
-      # incompatible with LLVM downloads today).
-      NO_DOWNLOAD_CI_LLVM: 1
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
     <<: *job-windows
diff --git a/src/ci/scripts/free-disk-space.sh b/src/ci/scripts/free-disk-space.sh
index 4a7dad0090b..8850e168145 100755
--- a/src/ci/scripts/free-disk-space.sh
+++ b/src/ci/scripts/free-disk-space.sh
@@ -1,8 +1,19 @@
 #!/bin/bash
+set -euo pipefail
 
 # Free disk space on Linux GitHub action runners
 # Script inspired by https://github.com/jlumbroso/free-disk-space
 
+isX86() {
+    local arch
+    arch=$(uname -m)
+    if [ "$arch" = "x86_64" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
 # print a line of the specified character
 printSeparationLine() {
     for ((i = 0; i < 80; i++)); do
@@ -14,11 +25,15 @@ printSeparationLine() {
 # compute available space
 # REF: https://unix.stackexchange.com/a/42049/60849
 # REF: https://stackoverflow.com/a/450821/408734
-getAvailableSpace() { echo $(df -a | awk 'NR > 1 {avail+=$4} END {print avail}'); }
+getAvailableSpace() {
+    df -a | awk 'NR > 1 {avail+=$4} END {print avail}'
+}
 
 # make Kb human readable (assume the input is Kb)
 # REF: https://unix.stackexchange.com/a/44087/60849
-formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); }
+formatByteCount() {
+    numfmt --to=iec-i --suffix=B --padding=7 "$1"'000'
+}
 
 # macro to output saved space
 printSavedSpace() {
@@ -58,11 +73,27 @@ removeDir() {
     dir=${1}
 
     local before
-    before=$(getAvailableSpace)
+    if [ ! -d "$dir" ]; then
+        echo "::warning::Directory $dir does not exist, skipping."
+    else
+        before=$(getAvailableSpace)
+        sudo rm -rf "$dir"
+        printSavedSpace "$before" "Removed $dir"
+    fi
+}
+
+removeUnusedDirectories() {
+    local dirs_to_remove=(
+        "/usr/local/lib/android"
+        "/usr/share/dotnet"
 
-    sudo rm -rf "$dir" || true
+        # Haskell runtime
+        "/usr/local/.ghcup"
+    )
 
-    printSavedSpace "$before" "$dir"
+    for dir in "${dirs_to_remove[@]}"; do
+        removeDir "$dir"
+    done
 }
 
 execAndMeasureSpaceChange() {
@@ -79,21 +110,29 @@ execAndMeasureSpaceChange() {
 # Remove large packages
 # REF: https://github.com/apache/flink/blob/master/tools/azure-pipelines/free_disk_space.sh
 cleanPackages() {
-    sudo apt-get -qq remove -y --fix-missing \
-        '^aspnetcore-.*'       \
-        '^dotnet-.*'           \
-        '^llvm-.*'             \
-        'php.*'                \
-        '^mongodb-.*'          \
-        '^mysql-.*'            \
-        'azure-cli'            \
-        'google-chrome-stable' \
-        'firefox'              \
-        'powershell'           \
-        'mono-devel'           \
-        'libgl1-mesa-dri'      \
-        'google-cloud-sdk'     \
-        'google-cloud-cli'
+    local packages=(
+        '^aspnetcore-.*'
+        '^dotnet-.*'
+        '^llvm-.*'
+        '^mongodb-.*'
+        '^mysql-.*'
+        'azure-cli'
+        'firefox'
+        'libgl1-mesa-dri'
+        'mono-devel'
+        'php.*'
+    )
+
+    if isX86; then
+        packages+=(
+            'google-chrome-stable'
+            'google-cloud-cli'
+            'google-cloud-sdk'
+            'powershell'
+        )
+    fi
+
+    sudo apt-get -qq remove -y --fix-missing "${packages[@]}"
 
     sudo apt-get autoremove -y || echo "::warning::The command [sudo apt-get autoremove -y] failed"
     sudo apt-get clean || echo "::warning::The command [sudo apt-get clean] failed failed"
@@ -101,9 +140,9 @@ cleanPackages() {
 
 # Remove Docker images
 cleanDocker() {
-    echo "Removing the following docker images:"
+    echo "=> Removing the following docker images:"
     sudo docker image ls
-    echo "Removing docker images..."
+    echo "=> Removing docker images..."
     sudo docker image prune --all --force || true
 }
 
@@ -121,17 +160,12 @@ AVAILABLE_INITIAL=$(getAvailableSpace)
 printDF "BEFORE CLEAN-UP:"
 echo ""
 
-removeDir /usr/local/lib/android
-removeDir /usr/share/dotnet
-
-# Haskell runtime
-removeDir /opt/ghc
-removeDir /usr/local/.ghcup
-
-execAndMeasureSpaceChange cleanPackages "Large misc. packages"
+execAndMeasureSpaceChange cleanPackages "Unused packages"
 execAndMeasureSpaceChange cleanDocker "Docker images"
 execAndMeasureSpaceChange cleanSwap "Swap storage"
 
+removeUnusedDirectories
+
 # Output saved space statistic
 echo ""
 printDF "AFTER CLEAN-UP:"
diff --git a/src/doc/book b/src/doc/book
-Subproject fa312a343fbff01bc6cef393e326817f7071981
+Subproject e2fa4316c5a7c0d2499c5d6b799adcfad6ef7a4
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 4ed5a1a4a2a7ecc2e529a5baaef04f7bc7917ed
+Subproject f56aecc3b036dff16404b525a83b00f911b9bbe
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject bc2298865544695c63454fc1f9f98a3dc22e994
+Subproject 336f75835a6c0514852cc65aba9a698b699b13c
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 93b921c7d3213d38d920f7f905a3bec093d2217
+Subproject 4249fb411dd27f945e2881eb0378044b94cee06
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 054259ed1bf01cdee4309ee764c7e103f6df3de
+Subproject 743766929f1e53e72fab74394ae259bbfb4a761
diff --git a/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs b/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs
index be37dd867b2..2355cb85ab3 100644
--- a/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs
+++ b/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs
@@ -10,6 +10,8 @@ extern crate rustc_interface;
 extern crate rustc_session;
 extern crate rustc_span;
 
+use std::sync::{Arc, Mutex};
+
 use rustc_errors::emitter::Emitter;
 use rustc_errors::registry::{self, Registry};
 use rustc_errors::translation::Translate;
@@ -17,8 +19,6 @@ use rustc_errors::{DiagCtxt, DiagInner, FluentBundle};
 use rustc_session::config;
 use rustc_span::source_map::SourceMap;
 
-use std::sync::{Arc, Mutex};
-
 struct DebugEmitter {
     source_map: Arc<SourceMap>,
     diagnostics: Arc<Mutex<Vec<DiagInner>>>,
@@ -67,10 +67,10 @@ fn main() {
         locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES.to_owned(),
         lint_caps: rustc_hash::FxHashMap::default(),
         psess_created: Some(Box::new(|parse_sess| {
-            parse_sess.set_dcx(DiagCtxt::new(Box::new(DebugEmitter {
+            parse_sess.dcx().set_emitter(Box::new(DebugEmitter {
                 source_map: parse_sess.clone_source_map(),
                 diagnostics,
-            })));
+            }));
         })),
         register_lints: None,
         override_queries: None,
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 8227dfa043e..3b6abdd8483 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -34,9 +34,9 @@ target | notes
 -------|-------
 [`aarch64-apple-darwin`](platform-support/apple-darwin.md) | ARM64 macOS (11.0+, Big Sur+)
 `aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+)
-`i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI]
-`i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI]
-`i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) [^x86_32-floats-return-ABI]
+`i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI]
+`i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI]
+`i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+, Pentium 4) [^x86_32-floats-return-ABI]
 [`x86_64-apple-darwin`](platform-support/apple-darwin.md) | 64-bit macOS (10.12+, Sierra+)
 `x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 10+, Windows Server 2016+)
 `x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 10+, Windows Server 2016+)
@@ -162,14 +162,14 @@ target | std | notes
 [`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare Armv7-A
 [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R
 [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat
-`i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE [^x86_32-floats-x87]
-`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17) [^x86_32-floats-x87]
-`i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, musl 1.2.3 [^x86_32-floats-x87]
-[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android [^x86_32-floats-return-ABI]
-[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+), LLVM ABI [^x86_32-floats-return-ABI]
-[`i686-unknown-freebsd`](platform-support/freebsd.md) | ✓ | 32-bit x86 FreeBSD [^x86_32-floats-return-ABI]
-`i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 [^x86_32-floats-return-ABI]
-[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 32-bit UEFI
+`i586-pc-windows-msvc` | * | 32-bit Windows (original Pentium) [^x86_32-floats-x87]
+`i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2, glibc 2.17, original Pentium) [^x86_32-floats-x87]
+`i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.3, original Pentium) [^x86_32-floats-x87]
+[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([PentiumPro with SSE](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI]
+[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+, Pentium 4), LLVM ABI [^x86_32-floats-return-ABI]
+[`i686-unknown-freebsd`](platform-support/freebsd.md) | ✓ | 32-bit x86 FreeBSD (Pentium 4) [^x86_32-floats-return-ABI]
+`i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 (Pentium 4) [^x86_32-floats-return-ABI]
+[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? (Pentium 4, softfloat) | 32-bit UEFI
 [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI)
 [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64S ABI)
 [`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs]
@@ -307,15 +307,15 @@ target | std | host | notes
 `csky-unknown-linux-gnuabiv2hf` | ✓ |  | C-SKY abiv2 Linux, hardfloat (little endian)
 [`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.3
 [`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX)
-[`i386-apple-ios`](platform-support/apple-ios.md) | ✓ |  | 32-bit x86 iOS [^x86_32-floats-return-ABI]
-[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * |  | 32-bit x86 QNX Neutrino 7.0 RTOS  [^x86_32-floats-return-ABI]
-[`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ |  | 32-bit x86, restricted to Pentium
-[`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+) [^x86_32-floats-return-ABI]
-`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku [^x86_32-floats-return-ABI]
-[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd [^x86_32-floats-return-ABI]
-[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 [^x86_32-floats-return-ABI]
-[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD [^x86_32-floats-return-ABI]
-[`i686-unknown-redox`](platform-support/redox.md) | ✓ |  | i686 Redox OS
+[`i386-apple-ios`](platform-support/apple-ios.md) | ✓ |  | 32-bit x86 iOS (Penryn) [^x86_32-floats-return-ABI]
+[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * |  | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI]
+[`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ |  | 32-bit x86 (original Pentium) [^x86_32-floats-x87]
+[`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+, Penryn) [^x86_32-floats-return-ABI]
+`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku (Pentium 4) [^x86_32-floats-return-ABI]
+[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (PentiumPro) [^x86_32-floats-x87]
+[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 (Pentium 4) [^x86_32-floats-return-ABI]
+[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD (Pentium 4) [^x86_32-floats-return-ABI]
+[`i686-unknown-redox`](platform-support/redox.md) | ✓ |  | i686 Redox OS (PentiumPro) [^x86_32-floats-x87]
 `i686-uwp-windows-gnu` | ✓ |  | [^x86_32-floats-return-ABI]
 [`i686-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ |  | [^x86_32-floats-return-ABI]
 [`i686-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ |   | 32-bit Windows 7 support [^x86_32-floats-return-ABI]
diff --git a/src/doc/unstable-book/src/language-features/new-range.md b/src/doc/unstable-book/src/language-features/new-range.md
new file mode 100644
index 00000000000..e7464f31e53
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/new-range.md
@@ -0,0 +1,9 @@
+# `new_range`
+
+The tracking issue for this feature is: [#123741]
+
+[#123741]: https://github.com/rust-lang/rust/issues/123741
+
+---
+
+Switch the syntaxes `a..`, `a..b`, and `a..=b` to resolve the new range types.
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 7853e311a04..55bd7da8816 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1104,17 +1104,29 @@ fn clean_args_from_types_and_names<'tcx>(
     types: &[hir::Ty<'tcx>],
     names: &[Ident],
 ) -> Arguments {
+    fn nonempty_name(ident: &Ident) -> Option<Symbol> {
+        if ident.name == kw::Underscore || ident.name == kw::Empty {
+            None
+        } else {
+            Some(ident.name)
+        }
+    }
+
+    // If at least one argument has a name, use `_` as the name of unnamed
+    // arguments. Otherwise omit argument names.
+    let default_name = if names.iter().any(|ident| nonempty_name(ident).is_some()) {
+        kw::Underscore
+    } else {
+        kw::Empty
+    };
+
     Arguments {
         values: types
             .iter()
             .enumerate()
             .map(|(i, ty)| Argument {
                 type_: clean_ty(ty, cx),
-                name: names
-                    .get(i)
-                    .map(|ident| ident.name)
-                    .filter(|ident| !ident.is_empty())
-                    .unwrap_or(kw::Underscore),
+                name: names.get(i).and_then(nonempty_name).unwrap_or(default_name),
                 is_const: false,
             })
             .collect(),
@@ -1934,7 +1946,7 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
     preds: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
     tcx: TyCtxt<'tcx>,
 ) -> bool {
-    // Below we quote extracts from https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes
+    // Below we quote extracts from https://doc.rust-lang.org/stable/reference/lifetime-elision.html#default-trait-object-lifetimes
 
     // > If the trait object is used as a type argument of a generic type then the containing type is
     // > first used to try to infer a bound.
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 6e817af0d6e..a44d74e6df6 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -5,9 +5,7 @@ use std::{fmt, iter};
 
 use arrayvec::ArrayVec;
 use rustc_abi::{ExternAbi, VariantIdx};
-use rustc_attr_parsing::{
-    AllowedThroughUnstableModules, ConstStability, Deprecation, Stability, StableSince,
-};
+use rustc_attr_parsing::{ConstStability, Deprecation, Stability, StableSince};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
@@ -411,15 +409,9 @@ impl Item {
                 ..
             } = stab.level
             {
-                let note = match note {
-                    AllowedThroughUnstableModules::WithDeprecation(note) => Some(note),
-                    // FIXME: Would be better to say *something* here about the *path* being
-                    // deprecated rather than the item.
-                    AllowedThroughUnstableModules::WithoutDeprecation => None,
-                };
                 Some(Deprecation {
                     since: rustc_attr_parsing::DeprecatedSince::Unspecified,
-                    note,
+                    note: Some(note),
                     suggestion: None,
                 })
             } else {
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 0b4fd9c2258..f1921b90cc6 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -588,9 +588,9 @@ pub(crate) fn attrs_have_doc_flag<'a>(
 /// so that the channel is consistent.
 ///
 /// Set by `bootstrap::Builder::doc_rust_lang_org_channel` in order to keep tests passing on beta/stable.
-pub(crate) const DOC_RUST_LANG_ORG_CHANNEL: &str = env!("DOC_RUST_LANG_ORG_CHANNEL");
-pub(crate) static DOC_CHANNEL: Lazy<&'static str> =
-    Lazy::new(|| DOC_RUST_LANG_ORG_CHANNEL.rsplit('/').find(|c| !c.is_empty()).unwrap());
+pub(crate) const DOC_RUST_LANG_ORG_VERSION: &str = env!("DOC_RUST_LANG_ORG_CHANNEL");
+pub(crate) static RUSTDOC_VERSION: Lazy<&'static str> =
+    Lazy::new(|| DOC_RUST_LANG_ORG_VERSION.rsplit('/').find(|c| !c.is_empty()).unwrap());
 
 /// Render a sequence of macro arms in a format suitable for displaying to the user
 /// as part of an item declaration.
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index cfba7895208..c6fb70eee08 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -9,8 +9,8 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::DiagCtxtHandle;
 use rustc_session::config::{
     self, CodegenOptions, CrateType, ErrorOutputType, Externs, Input, JsonUnusedExterns,
-    UnstableOptions, get_cmd_lint_options, nightly_options, parse_crate_types_from_list,
-    parse_externs, parse_target_triple,
+    OptionsTargetModifiers, UnstableOptions, get_cmd_lint_options, nightly_options,
+    parse_crate_types_from_list, parse_externs, parse_target_triple,
 };
 use rustc_session::lint::Level;
 use rustc_session::search_paths::SearchPath;
@@ -389,8 +389,9 @@ impl Options {
             config::parse_error_format(early_dcx, matches, color, json_color, json_rendered);
         let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default();
 
-        let codegen_options = CodegenOptions::build(early_dcx, matches);
-        let unstable_opts = UnstableOptions::build(early_dcx, matches);
+        let mut target_modifiers = BTreeMap::<OptionsTargetModifiers, String>::new();
+        let codegen_options = CodegenOptions::build(early_dcx, matches, &mut target_modifiers);
+        let unstable_opts = UnstableOptions::build(early_dcx, matches, &mut target_modifiers);
 
         let remap_path_prefix = match parse_remap_path_prefix(matches) {
             Ok(prefix_mappings) => prefix_mappings,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 0437ebb5857..6af35157a43 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -336,14 +336,14 @@ pub(crate) fn run_global_ctxt(
 
     // NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
     let _ = tcx.sess.time("wf_checking", || {
-        tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
+        tcx.hir().try_par_for_each_module(|module| tcx.ensure_ok().check_mod_type_wf(module))
     });
 
     tcx.dcx().abort_if_errors();
 
     tcx.sess.time("missing_docs", || rustc_lint::check_crate(tcx));
     tcx.sess.time("check_mod_attrs", || {
-        tcx.hir().for_each_module(|module| tcx.ensure().check_mod_attrs(module))
+        tcx.hir().for_each_module(|module| tcx.ensure_ok().check_mod_attrs(module))
     });
     rustc_passes::stability::check_unused_or_stable_features(tcx);
 
@@ -387,7 +387,7 @@ pub(crate) fn run_global_ctxt(
         let help = format!(
             "The following guide may be of use:\n\
             {}/rustdoc/how-to-write-documentation.html",
-            crate::DOC_RUST_LANG_ORG_CHANNEL
+            crate::DOC_RUST_LANG_ORG_VERSION
         );
         tcx.node_lint(
             crate::lint::MISSING_CRATE_LEVEL_DOCS,
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 20a8dc72491..ffd457c8273 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1408,7 +1408,9 @@ impl clean::Arguments {
     ) -> impl Display + 'a + Captures<'tcx> {
         fmt::from_fn(move |f| {
             for (i, input) in self.values.iter().enumerate() {
-                write!(f, "{}: ", input.name)?;
+                if !input.name.is_empty() {
+                    write!(f, "{}: ", input.name)?;
+                }
                 input.type_.print(cx).fmt(f)?;
                 if i + 1 < self.values.len() {
                     write!(f, ", ")?;
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index b4bc0b80d6c..d957cf1b569 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -112,7 +112,7 @@ pub(crate) fn render<T: Print, S: Print>(
         display_krate_with_trailing_slash,
         display_krate_version_number,
         display_krate_version_extra,
-        rust_channel: *crate::clean::utils::DOC_CHANNEL,
+        rust_channel: *crate::clean::utils::RUSTDOC_VERSION,
         rustdoc_version,
     }
     .render()
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 5d96dbc0ee6..1cefdf96bbc 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -32,7 +32,7 @@ use crate::html::render::write_shared::write_shared;
 use crate::html::url_parts_builder::UrlPartsBuilder;
 use crate::html::{layout, sources, static_files};
 use crate::scrape_examples::AllCallLocations;
-use crate::try_err;
+use crate::{DOC_RUST_LANG_ORG_VERSION, try_err};
 
 /// Major driving force in all rustdoc rendering. This contains information
 /// about where in the tree-like hierarchy rendering is occurring and controls
@@ -730,7 +730,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
                          <noscript>\
                             <section>\
                                 <p>You need to enable JavaScript to use keyboard commands or search.</p>\
-                                <p>For more information, browse the <a href=\"https://doc.rust-lang.org/rustdoc/\">rustdoc handbook</a>.</p>\
+                                <p>For more information, browse the <a href=\"{DOC_RUST_LANG_ORG_VERSION}/rustdoc/\">rustdoc handbook</a>.</p>\
                             </section>\
                          </noscript>",
                     )
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index a27a9d202eb..f7dcb87e4f3 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -79,7 +79,7 @@ use crate::html::markdown::{
 use crate::html::static_files::SCRAPE_EXAMPLES_HELP_MD;
 use crate::html::{highlight, sources};
 use crate::scrape_examples::{CallData, CallLocation};
-use crate::{DOC_RUST_LANG_ORG_CHANNEL, try_none};
+use crate::{DOC_RUST_LANG_ORG_VERSION, try_none};
 
 pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
     fmt::from_fn(move |f| {
@@ -480,7 +480,7 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String {
     content.push_str(&format!(
         "## More information\n\n\
       If you want more information about this feature, please read the [corresponding chapter in \
-      the Rustdoc book]({DOC_RUST_LANG_ORG_CHANNEL}/rustdoc/scraped-examples.html)."
+      the Rustdoc book]({DOC_RUST_LANG_ORG_VERSION}/rustdoc/scraped-examples.html)."
     ));
 
     let mut ids = IdMap::default();
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 37fea09ace3..c50adf11616 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -924,7 +924,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
                 <a href=\"{base}/reference/items/traits.html#dyn-compatibility\">dyn compatible</a>.</p>\
                 <p><i>In older versions of Rust, dyn compatibility was called \"object safety\", \
                 so this trait is not object safe.</i></p></div>",
-                base = crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL
+                base = crate::clean::utils::DOC_RUST_LANG_ORG_VERSION
             ),
         );
     }
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index ccf4002bb30..a348c6c5678 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -196,15 +196,13 @@ function switchDisplayedElement(elemToDisplay) {
     removeClass(el, "hidden");
 
     const mainHeading = elemToDisplay.querySelector(".main-heading");
-    // @ts-expect-error
-    if (mainHeading && searchState.rustdocToolbar) {
-        // @ts-expect-error
-        if (searchState.rustdocToolbar.parentElement) {
-            // @ts-expect-error
-            searchState.rustdocToolbar.parentElement.removeChild(searchState.rustdocToolbar);
+    if (mainHeading && window.searchState.rustdocToolbar) {
+        if (window.searchState.rustdocToolbar.parentElement) {
+            window.searchState.rustdocToolbar.parentElement.removeChild(
+                window.searchState.rustdocToolbar,
+            );
         }
-        // @ts-expect-error
-        mainHeading.appendChild(searchState.rustdocToolbar);
+        mainHeading.appendChild(window.searchState.rustdocToolbar);
     }
 }
 
@@ -212,7 +210,12 @@ function browserSupportsHistoryApi() {
     return window.history && typeof window.history.pushState === "function";
 }
 
-// @ts-expect-error
+/**
+ * Download CSS from the web without making it the active stylesheet.
+ * We use this in the settings popover so that you don't get FOUC when switching.
+ *
+ * @param {string} cssUrl
+ */
 function preLoadCss(cssUrl) {
     // https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload
     const link = document.createElement("link");
@@ -225,7 +228,11 @@ function preLoadCss(cssUrl) {
 (function() {
     const isHelpPage = window.location.pathname.endsWith("/help.html");
 
-    // @ts-expect-error
+    /**
+     * Run a JavaScript file asynchronously.
+     * @param {string} url
+     * @param {function(): any} errorCallback
+     */
     function loadScript(url, errorCallback) {
         const script = document.createElement("script");
         script.src = url;
@@ -235,13 +242,12 @@ function preLoadCss(cssUrl) {
         document.head.append(script);
     }
 
-    if (getSettingsButton()) {
-        // @ts-expect-error
-        getSettingsButton().onclick = event => {
+    const settingsButton = getSettingsButton();
+    if (settingsButton) {
+        settingsButton.onclick = event => {
             if (event.ctrlKey || event.altKey || event.metaKey) {
                 return;
             }
-            // @ts-expect-error
             window.hideAllModals(false);
             addClass(getSettingsButton(), "rotate");
             event.preventDefault();
@@ -470,7 +476,6 @@ function preLoadCss(cssUrl) {
                     }
                     return onEachLazy(implElem.parentElement.parentElement.querySelectorAll(
                         `[id^="${assocId}"]`),
-                        // @ts-expect-error
                         item => {
                             const numbered = /^(.+?)-([0-9]+)$/.exec(item.id);
                             if (item.id === assocId || (numbered && numbered[1] === assocId)) {
@@ -522,7 +527,6 @@ function preLoadCss(cssUrl) {
         ev.preventDefault();
         // @ts-expect-error
         searchState.defocus();
-        // @ts-expect-error
         window.hideAllModals(true); // true = reset focus for tooltips
     }
 
@@ -687,7 +691,6 @@ function preLoadCss(cssUrl) {
             //
             // By the way, this is only used by and useful for traits implemented automatically
             // (like "Send" and "Sync").
-            // @ts-expect-error
             onEachLazy(synthetic_implementors.getElementsByClassName("impl"), el => {
                 const aliases = el.getAttribute("data-aliases");
                 if (!aliases) {
@@ -740,7 +743,6 @@ function preLoadCss(cssUrl) {
                 code.innerHTML = struct[TEXT_IDX];
                 addClass(code, "code-header");
 
-                // @ts-expect-error
                 onEachLazy(code.getElementsByTagName("a"), elem => {
                     const href = elem.getAttribute("href");
 
@@ -886,7 +888,6 @@ function preLoadCss(cssUrl) {
             const template = document.createElement("template");
             template.innerHTML = text;
 
-            // @ts-expect-error
             onEachLazy(template.content.querySelectorAll("a"), elem => {
                 const href = elem.getAttribute("href");
 
@@ -894,7 +895,6 @@ function preLoadCss(cssUrl) {
                     elem.setAttribute("href", window.rootPath + href);
                 }
             });
-            // @ts-expect-error
             onEachLazy(template.content.querySelectorAll("[id]"), el => {
                 let i = 0;
                 if (idMap.has(el.id)) {
@@ -912,7 +912,6 @@ function preLoadCss(cssUrl) {
                     const oldHref = `#${el.id}`;
                     const newHref = `#${el.id}-${i}`;
                     el.id = `${el.id}-${i}`;
-                    // @ts-expect-error
                     onEachLazy(template.content.querySelectorAll("a[href]"), link => {
                         if (link.getAttribute("href") === oldHref) {
                             link.href = newHref;
@@ -933,7 +932,6 @@ function preLoadCss(cssUrl) {
                 // @ts-expect-error
                 sidebarTraitList.append(li);
             } else {
-                // @ts-expect-error
                 onEachLazy(templateAssocItems, item => {
                     let block = hasClass(item, "associatedtype") ? associatedTypes : (
                         hasClass(item, "associatedconstant") ? associatedConstants : (
@@ -1040,7 +1038,6 @@ function preLoadCss(cssUrl) {
     function expandAllDocs() {
         const innerToggle = document.getElementById(toggleAllDocsId);
         removeClass(innerToggle, "will-expand");
-        // @ts-expect-error
         onEachLazy(document.getElementsByClassName("toggle"), e => {
             if (!hasClass(e, "type-contents-toggle") && !hasClass(e, "more-examples-toggle")) {
                 e.open = true;
@@ -1053,7 +1050,6 @@ function preLoadCss(cssUrl) {
     function collapseAllDocs() {
         const innerToggle = document.getElementById(toggleAllDocsId);
         addClass(innerToggle, "will-expand");
-        // @ts-expect-error
         onEachLazy(document.getElementsByClassName("toggle"), e => {
             if (e.parentNode.id !== "implementations-list" ||
                 (!hasClass(e, "implementors-toggle") &&
@@ -1092,7 +1088,6 @@ function preLoadCss(cssUrl) {
         function setImplementorsTogglesOpen(id, open) {
             const list = document.getElementById(id);
             if (list !== null) {
-                // @ts-expect-error
                 onEachLazy(list.getElementsByClassName("implementors-toggle"), e => {
                     e.open = open;
                 });
@@ -1104,7 +1099,6 @@ function preLoadCss(cssUrl) {
             setImplementorsTogglesOpen("blanket-implementations-list", false);
         }
 
-        // @ts-expect-error
         onEachLazy(document.getElementsByClassName("toggle"), e => {
             if (!hideLargeItemContents && hasClass(e, "type-contents-toggle")) {
                 e.open = true;
@@ -1124,7 +1118,6 @@ function preLoadCss(cssUrl) {
         }
         onEachLazy(document.querySelectorAll(
             ":not(.scraped-example) > .example-wrap > pre:not(.example-line-numbers)",
-        // @ts-expect-error
         ), x => {
             const parent = x.parentNode;
             const line_numbers = parent.querySelectorAll(".example-line-numbers");
@@ -1145,7 +1138,6 @@ function preLoadCss(cssUrl) {
 
     // @ts-expect-error
     window.rustdoc_remove_line_numbers_from_examples = () => {
-        // @ts-expect-error
         onEachLazy(document.querySelectorAll(".example-wrap > .example-line-numbers"), x => {
             x.parentNode.removeChild(x);
         });
@@ -1157,16 +1149,13 @@ function preLoadCss(cssUrl) {
     }
 
     function showSidebar() {
-        // @ts-expect-error
         window.hideAllModals(false);
         const sidebar = document.getElementsByClassName("sidebar")[0];
-        // @ts-expect-error
         addClass(sidebar, "shown");
     }
 
     function hideSidebar() {
         const sidebar = document.getElementsByClassName("sidebar")[0];
-        // @ts-expect-error
         removeClass(sidebar, "shown");
     }
 
@@ -1193,7 +1182,6 @@ function preLoadCss(cssUrl) {
         mainElem.addEventListener("click", hideSidebar);
     }
 
-    // @ts-expect-error
     onEachLazy(document.querySelectorAll("a[href^='#']"), el => {
         // For clicks on internal links (<A> tags with a hash property), we expand the section we're
         // jumping to *before* jumping there. We can't do this in onHashChange, because it changes
@@ -1204,7 +1192,6 @@ function preLoadCss(cssUrl) {
         });
     });
 
-    // @ts-expect-error
     onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"), el => {
         // @ts-expect-error
         el.addEventListener("click", e => {
@@ -1241,7 +1228,6 @@ function preLoadCss(cssUrl) {
             clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);
             return;
         }
-        // @ts-expect-error
         window.hideAllModals(false);
         const wrapper = document.createElement("div");
         if (notable_ty) {
@@ -1422,7 +1408,6 @@ function preLoadCss(cssUrl) {
         }
     }
 
-    // @ts-expect-error
     onEachLazy(document.getElementsByClassName("tooltip"), e => {
         e.onclick = () => {
             e.TOOLTIP_FORCE_VISIBLE = e.TOOLTIP_FORCE_VISIBLE ? false : true;
@@ -1527,17 +1512,16 @@ function preLoadCss(cssUrl) {
             // @ts-expect-error
             !getSettingsButton().contains(event.relatedTarget)
         ) {
-            // @ts-expect-error
             window.hidePopoverMenus();
         }
     }
 
     function buildHelpMenu() {
         const book_info = document.createElement("span");
-        const channel = getVar("channel");
+        const drloChannel = `https://doc.rust-lang.org/${getVar("channel")}`;
         book_info.className = "top";
         book_info.innerHTML = `You can find more information in \
-<a href="https://doc.rust-lang.org/${channel}/rustdoc/">the rustdoc book</a>.`;
+<a href="${drloChannel}/rustdoc/">the rustdoc book</a>.`;
 
         const shortcuts = [
             ["?", "Show this help dialog"],
@@ -1557,8 +1541,8 @@ function preLoadCss(cssUrl) {
         div_shortcuts.innerHTML = "<h2>Keyboard Shortcuts</h2><dl>" + shortcuts + "</dl></div>";
 
         const infos = [
-            `For a full list of all search features, take a look <a \
-href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.html">here</a>.`,
+            `For a full list of all search features, take a look \
+             <a href="${drloChannel}/rustdoc/read-documentation/search.html">here</a>.`,
             "Prefix searches with a type followed by a colon (e.g., <code>fn:</code>) to \
              restrict the search to a given item kind.",
             "Accepted kinds are: <code>fn</code>, <code>mod</code>, <code>struct</code>, \
@@ -1568,10 +1552,10 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
              <code>-&gt; vec</code> or <code>String, enum:Cow -&gt; bool</code>)",
             "You can look for items with an exact name by putting double quotes around \
              your request: <code>\"string\"</code>",
-             "Look for functions that accept or return \
-              <a href=\"https://doc.rust-lang.org/std/primitive.slice.html\">slices</a> and \
-              <a href=\"https://doc.rust-lang.org/std/primitive.array.html\">arrays</a> by writing \
-              square brackets (e.g., <code>-&gt; [u8]</code> or <code>[] -&gt; Option</code>)",
+             `Look for functions that accept or return \
+              <a href="${drloChannel}/std/primitive.slice.html">slices</a> and \
+              <a href="${drloChannel}/std/primitive.array.html">arrays</a> by writing square \
+              brackets (e.g., <code>-&gt; [u8]</code> or <code>[] -&gt; Option</code>)`,
             "Look for items inside another one by searching for a path: <code>vec::Vec</code>",
         ].map(x => "<p>" + x + "</p>").join("");
         const div_infos = document.createElement("div");
@@ -1626,10 +1610,8 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
      *
      * Pass "true" to reset focus for tooltip popovers.
      */
-    // @ts-expect-error
     window.hideAllModals = switchFocus => {
         hideSidebar();
-        // @ts-expect-error
         window.hidePopoverMenus();
         hideTooltip(switchFocus);
     };
@@ -1637,9 +1619,7 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
     /**
      * Hide all the popover menus.
      */
-    // @ts-expect-error
     window.hidePopoverMenus = () => {
-        // @ts-expect-error
         onEachLazy(document.querySelectorAll("rustdoc-toolbar .popover"), elem => {
             elem.style.display = "none";
         });
@@ -1708,7 +1688,6 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
             if (shouldShowHelp) {
                 showHelp();
             } else {
-                // @ts-expect-error
                 window.hidePopoverMenus();
             }
         });
@@ -1780,30 +1759,42 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
         });
     }
 
-    // Pointer capture.
-    //
-    // Resizing is a single-pointer gesture. Any secondary pointer is ignored
-    // @ts-expect-error
+    /**
+     * Pointer capture.
+     *
+     * Resizing is a single-pointer gesture. Any secondary pointer is ignored
+     *
+     * @type {null|number}
+     */
     let currentPointerId = null;
 
-    // "Desired" sidebar size.
-    //
-    // This is stashed here for window resizing. If the sidebar gets
-    // shrunk to maintain BODY_MIN, and then the user grows the window again,
-    // it gets the sidebar to restore its size.
-    // @ts-expect-error
+    /**
+     * "Desired" sidebar size.
+     *
+     * This is stashed here for window resizing. If the sidebar gets
+     * shrunk to maintain BODY_MIN, and then the user grows the window again,
+     * it gets the sidebar to restore its size.
+     *
+     * @type {null|number}
+     */
     let desiredSidebarSize = null;
 
-    // Sidebar resize debouncer.
-    //
-    // The sidebar itself is resized instantly, but the body HTML can be too
-    // big for that, causing reflow jank. To reduce this, we queue up a separate
-    // animation frame and throttle it.
+    /**
+     * Sidebar resize debouncer.
+     *
+     * The sidebar itself is resized instantly, but the body HTML can be too
+     * big for that, causing reflow jank. To reduce this, we queue up a separate
+     * animation frame and throttle it.
+     *
+     * @type {false|ReturnType<typeof setTimeout>}
+     */
     let pendingSidebarResizingFrame = false;
 
-    // If this page has no sidebar at all, bail out.
+    /** @type {HTMLElement|null} */
     const resizer = document.querySelector(".sidebar-resizer");
+    /** @type {HTMLElement|null} */
     const sidebar = document.querySelector(".sidebar");
+    // If this page has no sidebar at all, bail out.
     if (!resizer || !sidebar) {
         return;
     }
@@ -1820,11 +1811,9 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
     // from settings.js, which uses a separate function. It's done here because
     // the minimum sidebar size is rather uncomfortable, and it must pass
     // through that size when using the shrink-to-nothing gesture.
-    function hideSidebar() {
+    const hideSidebar = function() {
         if (isSrcPage) {
-            // @ts-expect-error
             window.rustdocCloseSourceSidebar();
-            // @ts-expect-error
             updateLocalStorage("src-sidebar-width", null);
             // [RUSTDOCIMPL] CSS variable fast path
             //
@@ -1837,22 +1826,17 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
             //
             // So, to clear it, we need to clear all three.
             document.documentElement.style.removeProperty("--src-sidebar-width");
-            // @ts-expect-error
             sidebar.style.removeProperty("--src-sidebar-width");
-            // @ts-expect-error
             resizer.style.removeProperty("--src-sidebar-width");
         } else {
             addClass(document.documentElement, "hide-sidebar");
             updateLocalStorage("hide-sidebar", "true");
-            // @ts-expect-error
             updateLocalStorage("desktop-sidebar-width", null);
             document.documentElement.style.removeProperty("--desktop-sidebar-width");
-            // @ts-expect-error
             sidebar.style.removeProperty("--desktop-sidebar-width");
-            // @ts-expect-error
             resizer.style.removeProperty("--desktop-sidebar-width");
         }
-    }
+    };
 
     // Call this function to show the sidebar from the resize handle.
     // On docs pages, this can only happen if the user has grabbed the resize
@@ -1860,15 +1844,14 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
     // the visible range without releasing it. You can, however, grab the
     // resize handle on a source page with the sidebar closed, because it
     // remains visible all the time on there.
-    function showSidebar() {
+    const showSidebar = function() {
         if (isSrcPage) {
-            // @ts-expect-error
             window.rustdocShowSourceSidebar();
         } else {
             removeClass(document.documentElement, "hide-sidebar");
             updateLocalStorage("hide-sidebar", "false");
         }
-    }
+    };
 
     /**
      * Call this to set the correct CSS variable and setting.
@@ -1876,44 +1859,40 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
      *
      * @param {number} size - CSS px width of the sidebar.
      */
-    function changeSidebarSize(size) {
+    const changeSidebarSize = function(size) {
         if (isSrcPage) {
-            // @ts-expect-error
-            updateLocalStorage("src-sidebar-width", size);
+            updateLocalStorage("src-sidebar-width", size.toString());
             // [RUSTDOCIMPL] CSS variable fast path
             //
             // While this property is set on the HTML element at load time,
             // because the sidebar isn't actually loaded yet,
             // we scope this update to the sidebar to avoid hitting a slow
             // path in WebKit.
-            // @ts-expect-error
             sidebar.style.setProperty("--src-sidebar-width", size + "px");
-            // @ts-expect-error
             resizer.style.setProperty("--src-sidebar-width", size + "px");
         } else {
-            // @ts-expect-error
-            updateLocalStorage("desktop-sidebar-width", size);
-            // @ts-expect-error
+            updateLocalStorage("desktop-sidebar-width", size.toString());
             sidebar.style.setProperty("--desktop-sidebar-width", size + "px");
-            // @ts-expect-error
             resizer.style.setProperty("--desktop-sidebar-width", size + "px");
         }
-    }
+    };
 
     // Check if the sidebar is hidden. Since src pages and doc pages have
     // different settings, this function has to check that.
-    function isSidebarHidden() {
+    const isSidebarHidden = function() {
         return isSrcPage ?
             !hasClass(document.documentElement, "src-sidebar-expanded") :
             hasClass(document.documentElement, "hide-sidebar");
-    }
+    };
 
-    // Respond to the resize handle event.
-    // This function enforces size constraints, and implements the
-    // shrink-to-nothing gesture based on thresholds defined above.
-    // @ts-expect-error
-    function resize(e) {
-        // @ts-expect-error
+    /**
+     * Respond to the resize handle event.
+     * This function enforces size constraints, and implements the
+     * shrink-to-nothing gesture based on thresholds defined above.
+     *
+     * @param {PointerEvent} e
+     */
+    const resize = function(e) {
         if (currentPointerId === null || currentPointerId !== e.pointerId) {
             return;
         }
@@ -1931,97 +1910,83 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
             changeSidebarSize(constrainedPos);
             desiredSidebarSize = constrainedPos;
             if (pendingSidebarResizingFrame !== false) {
-                // @ts-expect-error
                 clearTimeout(pendingSidebarResizingFrame);
             }
-            // @ts-expect-error
             pendingSidebarResizingFrame = setTimeout(() => {
-                // @ts-expect-error
                 if (currentPointerId === null || pendingSidebarResizingFrame === false) {
                     return;
                 }
                 pendingSidebarResizingFrame = false;
                 document.documentElement.style.setProperty(
                     "--resizing-sidebar-width",
-                    // @ts-expect-error
                     desiredSidebarSize + "px",
                 );
             }, 100);
         }
-    }
+    };
     // Respond to the window resize event.
     window.addEventListener("resize", () => {
         if (window.innerWidth < RUSTDOC_MOBILE_BREAKPOINT) {
             return;
         }
         stopResize();
-        // @ts-expect-error
-        if (desiredSidebarSize >= (window.innerWidth - BODY_MIN)) {
+        if (desiredSidebarSize !== null && desiredSidebarSize >= (window.innerWidth - BODY_MIN)) {
             changeSidebarSize(window.innerWidth - BODY_MIN);
-        // @ts-expect-error
         } else if (desiredSidebarSize !== null && desiredSidebarSize > SIDEBAR_MIN) {
-            // @ts-expect-error
             changeSidebarSize(desiredSidebarSize);
         }
     });
-    // @ts-expect-error
-    function stopResize(e) {
-        // @ts-expect-error
+
+    /**
+     * @param {PointerEvent=} e
+     */
+    const stopResize = function(e) {
         if (currentPointerId === null) {
             return;
         }
         if (e) {
             e.preventDefault();
         }
-        // @ts-expect-error
         desiredSidebarSize = sidebar.getBoundingClientRect().width;
-        // @ts-expect-error
         removeClass(resizer, "active");
         window.removeEventListener("pointermove", resize, false);
         window.removeEventListener("pointerup", stopResize, false);
         removeClass(document.documentElement, "sidebar-resizing");
         document.documentElement.style.removeProperty( "--resizing-sidebar-width");
-        // @ts-expect-error
         if (resizer.releasePointerCapture) {
-            // @ts-expect-error
             resizer.releasePointerCapture(currentPointerId);
             currentPointerId = null;
         }
-    }
-    // @ts-expect-error
-    function initResize(e) {
-        // @ts-expect-error
+    };
+
+    /**
+     * @param {PointerEvent} e
+     */
+    const initResize = function(e) {
         if (currentPointerId !== null || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
             return;
         }
-        // @ts-expect-error
         if (resizer.setPointerCapture) {
-            // @ts-expect-error
             resizer.setPointerCapture(e.pointerId);
-            // @ts-expect-error
             if (!resizer.hasPointerCapture(e.pointerId)) {
                 // unable to capture pointer; something else has it
                 // on iOS, this usually means you long-clicked a link instead
-                // @ts-expect-error
                 resizer.releasePointerCapture(e.pointerId);
                 return;
             }
             currentPointerId = e.pointerId;
         }
-        // @ts-expect-error
         window.hideAllModals(false);
         e.preventDefault();
         window.addEventListener("pointermove", resize, false);
         window.addEventListener("pointercancel", stopResize, false);
         window.addEventListener("pointerup", stopResize, false);
-        // @ts-expect-error
         addClass(resizer, "active");
         addClass(document.documentElement, "sidebar-resizing");
-        // @ts-expect-error
         const pos = e.clientX - sidebar.offsetLeft - 3;
         document.documentElement.style.setProperty( "--resizing-sidebar-width", pos + "px");
         desiredSidebarSize = null;
-    }
+    };
     resizer.addEventListener("pointerdown", initResize, false);
 }());
 
@@ -2029,8 +1994,13 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
 // and the copy buttons on the code examples.
 (function() {
     // Common functions to copy buttons.
-    // @ts-expect-error
+    /**
+     * @param {string|null} content
+     */
     function copyContentToClipboard(content) {
+        if (content === null) {
+            return;
+        }
         const el = document.createElement("textarea");
         el.value = content;
         el.setAttribute("readonly", "");
@@ -2044,15 +2014,17 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
         document.body.removeChild(el);
     }
 
-    // @ts-expect-error
+    /**
+     * @param {HTMLElement & {reset_button_timeout?: ReturnType<typeof setTimeout>}} button
+     */
     function copyButtonAnimation(button) {
         button.classList.add("clicked");
 
         if (button.reset_button_timeout !== undefined) {
-            window.clearTimeout(button.reset_button_timeout);
+            clearTimeout(button.reset_button_timeout);
         }
 
-        button.reset_button_timeout = window.setTimeout(() => {
+        button.reset_button_timeout = setTimeout(() => {
             button.reset_button_timeout = undefined;
             button.classList.remove("clicked");
         }, 1000);
@@ -2067,9 +2039,7 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
         // Most page titles are '<Item> in <path::to::module> - Rust', except
         // modules (which don't have the first part) and keywords/primitives
         // (which don't have a module path)
-        // @ts-expect-error
-        const title = document.querySelector("title").textContent.replace(" - Rust", "");
-        const [item, module] = title.split(" in ");
+        const [item, module] = document.title.split(" in ");
         const path = [item];
         if (module !== undefined) {
             path.unshift(module);
@@ -2079,8 +2049,10 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
         copyButtonAnimation(but);
     };
 
-    // Copy buttons on code examples.
-    // @ts-expect-error
+    /**
+     * Copy buttons on code examples.
+     * @param {HTMLElement|null} codeElem
+     */
     function copyCode(codeElem) {
         if (!codeElem) {
             // Should never happen, but the world is a dark and dangerous place.
@@ -2089,23 +2061,34 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
         copyContentToClipboard(codeElem.textContent);
     }
 
-    // @ts-expect-error
+    /**
+     * @param {UIEvent} event
+     * @returns {HTMLElement|null}
+     */
     function getExampleWrap(event) {
-        let elem = event.target;
-        while (!hasClass(elem, "example-wrap")) {
-            if (elem === document.body ||
-                elem.tagName === "A" ||
-                elem.tagName === "BUTTON" ||
-                hasClass(elem, "docblock")
-            ) {
-                return null;
+        const target = event.target;
+        if (target instanceof HTMLElement) {
+            /** @type {HTMLElement|null} */
+            let elem = target;
+            while (elem !== null && !hasClass(elem, "example-wrap")) {
+                if (elem === document.body ||
+                    elem.tagName === "A" ||
+                    elem.tagName === "BUTTON" ||
+                    hasClass(elem, "docblock")
+                ) {
+                    return null;
+                }
+                elem = elem.parentElement;
             }
-            elem = elem.parentElement;
+            return elem;
+        } else {
+            return null;
         }
-        return elem;
     }
 
-    // @ts-expect-error
+    /**
+     * @param {UIEvent} event
+     */
     function addCopyButton(event) {
         const elem = getExampleWrap(event);
         if (elem === null) {
@@ -2132,15 +2115,17 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
         });
         parent.appendChild(copyButton);
 
-        if (!elem.parentElement.classList.contains("scraped-example")) {
+        if (!elem.parentElement || !elem.parentElement.classList.contains("scraped-example") ||
+            !window.updateScrapedExample) {
             return;
         }
         const scrapedWrapped = elem.parentElement;
-        // @ts-expect-error
         window.updateScrapedExample(scrapedWrapped, parent);
     }
 
-    // @ts-expect-error
+    /**
+     * @param {UIEvent} event
+     */
     function showHideCodeExampleButtons(event) {
         const elem = getExampleWrap(event);
         if (elem === null) {
@@ -2159,7 +2144,6 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
         buttons.classList.toggle("keep-visible");
     }
 
-    // @ts-expect-error
     onEachLazy(document.querySelectorAll(".docblock .example-wrap"), elem => {
         elem.addEventListener("mouseover", addCopyButton);
         elem.addEventListener("click", showHideCodeExampleButtons);
diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts
index 18a3e22113b..acea7828e86 100644
--- a/src/librustdoc/html/static/js/rustdoc.d.ts
+++ b/src/librustdoc/html/static/js/rustdoc.d.ts
@@ -20,6 +20,28 @@ declare global {
          * As a multi-page application, we know this never changes once set.
          */
         currentCrate: string|null;
+        /**
+         * Hide popovers, tooltips, or the mobile sidebar.
+         */
+        hideAllModals: function(boolean),
+        /**
+         * Hide popovers, but leave other modals alone.
+         */
+        hidePopoverMenus: function(),
+        /**
+         * Hide the source page sidebar. If it's already closed,
+         * or if this is a docs page, this function does nothing.
+         */
+        rustdocCloseSourceSidebar: function(),
+        /**
+         * Show the source page sidebar. If it's already opened,
+         * or if this is a docs page, this function does nothing.
+         */
+        rustdocShowSourceSidebar: function(),
+        /**
+         * Set up event listeners for a scraped source example.
+         */
+        updateScrapedExample?: function(HTMLElement, HTMLElement),
     }
     interface HTMLElement {
         /** Used by the popover tooltip code. */
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 1ad32721e06..121a43e3d92 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -1,5 +1,5 @@
 // ignore-tidy-filelength
-/* global addClass, getNakedUrl, getSettingValue */
+/* global addClass, getNakedUrl, getSettingValue, getVar */
 /* global onEachLazy, removeClass, searchState, browserSupportsHistoryApi, exports */
 
 "use strict";
@@ -4732,10 +4732,8 @@ function printTab(nb) {
         // Corrections only kick in on type-based searches.
         const correctionsElem = document.getElementsByClassName("search-corrections");
         if (isTypeSearch) {
-            // @ts-expect-error
             removeClass(correctionsElem[0], "hidden");
         } else {
-            // @ts-expect-error
             addClass(correctionsElem[0], "hidden");
         }
     } else if (nb !== 0) {
@@ -4923,17 +4921,18 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             }
         });
     } else if (query.error === null) {
+        const dlroChannel = `https://doc.rust-lang.org/${getVar("channel")}`;
         output.className = "search-failed" + extraClass;
         output.innerHTML = "No results :(<br/>" +
             "Try on <a href=\"https://duckduckgo.com/?q=" +
             encodeURIComponent("rust " + query.userQuery) +
             "\">DuckDuckGo</a>?<br/><br/>" +
             "Or try looking in one of these:<ul><li>The <a " +
-            "href=\"https://doc.rust-lang.org/reference/index.html\">Rust Reference</a> " +
+            `href="${dlroChannel}/reference/index.html">Rust Reference</a> ` +
             " for technical details about the language.</li><li><a " +
-            "href=\"https://doc.rust-lang.org/rust-by-example/index.html\">Rust By " +
+            `href="${dlroChannel}/rust-by-example/index.html">Rust By ` +
             "Example</a> for expository code examples.</a></li><li>The <a " +
-            "href=\"https://doc.rust-lang.org/book/index.html\">Rust Book</a> for " +
+            `href="${dlroChannel}/book/index.html">Rust Book</a> for ` +
             "introductions to language features and the language itself.</li><li><a " +
             "href=\"https://docs.rs\">Docs.rs</a> for documentation of crates released on" +
             " <a href=\"https://crates.io/\">crates.io</a>.</li></ul>";
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index 10369e77320..3042373fb09 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -59,7 +59,7 @@ function hasClass(elem, className) {
  * Add a class to a DOM Element. If `elem` is null,
  * does nothing. This function is idempotent.
  *
- * @param {HTMLElement|null} elem
+ * @param {Element|null} elem
  * @param {string} className
  */
 function addClass(elem, className) {
@@ -72,7 +72,7 @@ function addClass(elem, className) {
  * Remove a class from a DOM Element. If `elem` is null,
  * does nothing. This function is idempotent.
  *
- * @param {HTMLElement|null} elem
+ * @param {Element|null} elem
  * @param {string} className
  */
 // eslint-disable-next-line no-unused-vars
@@ -85,7 +85,7 @@ function removeClass(elem, className) {
 /**
  * Run a callback for every element of an Array.
  * @param {Array<?>}                       arr  - The array to iterate over
- * @param {function(?): boolean|undefined} func - The callback
+ * @param {function(?): boolean|void} func - The callback
  */
 function onEach(arr, func) {
     for (const elem of arr) {
@@ -103,7 +103,7 @@ function onEach(arr, func) {
  * https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection
  * https://developer.mozilla.org/en-US/docs/Web/API/NodeList
  * @param {NodeList|HTMLCollection} lazyArray  - An array to iterate over
- * @param {function(?): boolean}    func       - The callback
+ * @param {function(?): boolean|void}    func       - The callback
  */
 // eslint-disable-next-line no-unused-vars
 function onEachLazy(lazyArray, func) {
@@ -119,11 +119,15 @@ function onEachLazy(lazyArray, func) {
  * If localStorage is disabled, this function does nothing.
  *
  * @param {string} name
- * @param {string} value
+ * @param {string|null} value
  */
 function updateLocalStorage(name, value) {
     try {
-        window.localStorage.setItem("rustdoc-" + name, value);
+        if (value === null) {
+            window.localStorage.removeItem("rustdoc-" + name);
+        } else {
+            window.localStorage.setItem("rustdoc-" + name, value);
+        }
     } catch (e) {
         // localStorage is not accessible, do nothing
     }
diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html
index 9c62826ccc2..0034552bdd3 100644
--- a/src/librustdoc/html/templates/type_layout.html
+++ b/src/librustdoc/html/templates/type_layout.html
@@ -10,7 +10,7 @@
                 unstable</strong> and may even differ between compilations. {#+ #}
             The only exception is types with certain <code>repr(...)</code> {#+ #}
             attributes. Please see the Rust Reference's {#+ #}
-            <a href="https://doc.rust-lang.org/reference/type-layout.html">“Type Layout”</a> {#+ #}
+            <a href="{{ crate::DOC_RUST_LANG_ORG_VERSION }}/reference/type-layout.html">“Type Layout”</a> {#+ #}
             chapter for details on type layout guarantees. {# #}
         </p> {# #}
     </div> {# #}
diff --git a/src/librustdoc/html/templates/type_layout_size.html b/src/librustdoc/html/templates/type_layout_size.html
index 9c2b39edc9f..5256b6c8f2a 100644
--- a/src/librustdoc/html/templates/type_layout_size.html
+++ b/src/librustdoc/html/templates/type_layout_size.html
@@ -7,6 +7,6 @@
     {{ size +}} bytes
   {% endif %}
   {% if is_uninhabited %}
-    {# +#} (<a href="https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited">uninhabited</a>)
+    {# +#} (<a href="{{ crate::DOC_RUST_LANG_ORG_VERSION }}/reference/glossary.html#uninhabited">uninhabited</a>)
   {% endif %}
 {% endif %}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 44adf92ff0e..96ef400d903 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -82,7 +82,7 @@ use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_opti
 use rustc_session::{EarlyDiagCtxt, getopts};
 use tracing::info;
 
-use crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL;
+use crate::clean::utils::DOC_RUST_LANG_ORG_VERSION;
 
 /// A macro to create a FxHashMap.
 ///
@@ -177,9 +177,8 @@ pub fn main() {
     rustc_driver::init_logger(&early_dcx, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG"));
 
     let exit_code = rustc_driver::catch_with_exit_code(|| {
-        let at_args = rustc_driver::args::raw_args(&early_dcx)?;
+        let at_args = rustc_driver::args::raw_args(&early_dcx);
         main_args(&mut early_dcx, &at_args);
-        Ok(())
     });
     process::exit(exit_code);
 }
@@ -710,7 +709,7 @@ fn usage(argv0: &str) {
     println!("{}", options.usage(&format!("{argv0} [options] <input>")));
     println!("    @path               Read newline separated options from `path`\n");
     println!(
-        "More information available at {DOC_RUST_LANG_ORG_CHANNEL}/rustdoc/what-is-rustdoc.html",
+        "More information available at {DOC_RUST_LANG_ORG_VERSION}/rustdoc/what-is-rustdoc.html",
     );
 }
 
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index a777b45b807..9fe8b99e8af 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -2168,7 +2168,7 @@ fn disambiguator_error(
     report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, _sp, _link_range| {
         let msg = format!(
             "see {}/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators",
-            crate::DOC_RUST_LANG_ORG_CHANNEL
+            crate::DOC_RUST_LANG_ORG_VERSION
         );
         diag.note(msg);
     });
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index e67e17a73cb..a92f3ded774 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -61,6 +61,13 @@ pub struct Crate {
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 pub struct ExternalCrate {
     /// The name of the crate.
+    ///
+    /// Note: This is the [*crate* name][crate-name], which may not be the same as the
+    /// [*package* name][package-name]. For example, for <https://crates.io/crates/regex-syntax>,
+    /// this field will be `regex_syntax` (which uses an `_`, not a `-`).
+    ///
+    /// [crate-name]: https://doc.rust-lang.org/stable/cargo/reference/cargo-targets.html#the-name-field
+    /// [package-name]: https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-name-field
     pub name: String,
     /// The root URL at which the crate's documentation lives.
     pub html_root_url: Option<String>,
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject cecde95c119a456c30e57d3e4b31fff5a7d83df
+Subproject 0e3d73849ab8cbbab3ec5c65cbd555586cb2133
diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md
index c26ad319f4f..48506127dee 100644
--- a/src/tools/clippy/book/src/development/adding_lints.md
+++ b/src/tools/clippy/book/src/development/adding_lints.md
@@ -788,7 +788,7 @@ don't hesitate to ask on [Zulip] or in the issue/PR.
 [`snippet`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/source/fn.snippet.html
 [let-chains]: https://github.com/rust-lang/rust/pull/94927
 [from_expansion]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
-[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
+[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro
 [span]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html
 [applicability]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html
 [rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/
diff --git a/src/tools/clippy/book/src/development/common_tools_writing_lints.md b/src/tools/clippy/book/src/development/common_tools_writing_lints.md
index b44ad80a25c..051febc2ca5 100644
--- a/src/tools/clippy/book/src/development/common_tools_writing_lints.md
+++ b/src/tools/clippy/book/src/development/common_tools_writing_lints.md
@@ -218,7 +218,7 @@ functions to deal with macros:
   > context. And so just using `span.from_expansion()` is often good enough.
 
 
-- `in_external_macro(span)`: detect if the given span is from a macro defined in
+- `span.in_external_macro(sm)`: detect if the given span is from a macro defined in
   a foreign crate. If you want the lint to work with macro-generated code, this
   is the next line of defense to avoid macros not defined in the current crate.
   It doesn't make sense to lint code that the coder can't change.
@@ -227,15 +227,13 @@ functions to deal with macros:
   crates
 
   ```rust
-  use rustc_middle::lint::in_external_macro;
-
   use a_crate_with_macros::foo;
 
   // `foo` is defined in `a_crate_with_macros`
   foo!("bar");
 
   // if we lint the `match` of `foo` call and test its span
-  assert_eq!(in_external_macro(cx.sess(), match_span), true);
+  assert_eq!(match_span.in_external_macro(cx.sess().source_map()), true);
   ```
 
 - `span.ctxt()`: the span's context represents whether it is from expansion, and
diff --git a/src/tools/clippy/book/src/development/macro_expansions.md b/src/tools/clippy/book/src/development/macro_expansions.md
index 125b6c4bc5b..36092f82e26 100644
--- a/src/tools/clippy/book/src/development/macro_expansions.md
+++ b/src/tools/clippy/book/src/development/macro_expansions.md
@@ -120,7 +120,7 @@ assert_ne!(x_is_some_span.ctxt(), x_unwrap_span.ctxt());
 
 ### The `in_external_macro` function
 
-`rustc_middle::lint` provides a function ([`in_external_macro`]) that can
+`Span` provides a method ([`in_external_macro`]) that can
 detect if the given span is from a macro defined in a foreign crate.
 
 Therefore, if we really want a new lint to work with macro-generated code,
@@ -144,7 +144,7 @@ Also assume that we get the corresponding variable `foo_span` for the
 results in `true` (note that `cx` can be `EarlyContext` or `LateContext`):
 
 ```rust
-if in_external_macro(cx.sess(), foo_span) {
+if foo_span.in_external_macro(cx.sess().source_map()) {
     // We should ignore macro from a foreign crate.
     return;
 }
@@ -153,6 +153,6 @@ if in_external_macro(cx.sess(), foo_span) {
 [`ctxt`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.ctxt
 [expansion]: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#expansion-and-ast-integration
 [`from_expansion`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
-[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
+[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro
 [Span]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html
 [SyntaxContext]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/hygiene/struct.SyntaxContext.html
diff --git a/src/tools/clippy/clippy_lints/src/almost_complete_range.rs b/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
index 2af5178920d..0f7f779e8ea 100644
--- a/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
+++ b/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
@@ -5,7 +5,6 @@ use clippy_utils::source::{trim_span, walk_span_to_context};
 use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -45,7 +44,7 @@ impl EarlyLintPass for AlmostCompleteRange {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) {
         if let ExprKind::Range(Some(start), Some(end), RangeLimits::HalfOpen) = &e.kind
             && is_incomplete_range(start, end)
-            && !in_external_macro(cx.sess(), e.span)
+            && !e.span.in_external_macro(cx.sess().source_map())
         {
             span_lint_and_then(
                 cx,
@@ -74,7 +73,7 @@ impl EarlyLintPass for AlmostCompleteRange {
         if let PatKind::Range(Some(start), Some(end), kind) = &p.kind
             && matches!(kind.node, RangeEnd::Excluded)
             && is_incomplete_range(start, end)
-            && !in_external_macro(cx.sess(), p.span)
+            && !p.span.in_external_macro(cx.sess().source_map())
         {
             span_lint_and_then(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
index 0389223c3e0..f519a65fc27 100644
--- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
+++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -9,7 +9,6 @@ use rustc_hir::{
     Variant, VariantData,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -248,7 +247,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
             ItemKind::Enum(enum_def, _generics) if self.enable_ordering_for_enum => {
                 let mut cur_v: Option<&Variant<'_>> = None;
                 for variant in enum_def.variants {
-                    if in_external_macro(cx.sess(), variant.span) {
+                    if variant.span.in_external_macro(cx.sess().source_map()) {
                         continue;
                     }
 
@@ -263,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
             ItemKind::Struct(VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => {
                 let mut cur_f: Option<&FieldDef<'_>> = None;
                 for field in *fields {
-                    if in_external_macro(cx.sess(), field.span) {
+                    if field.span.in_external_macro(cx.sess().source_map()) {
                         continue;
                     }
 
@@ -281,7 +280,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
                 let mut cur_t: Option<&TraitItemRef> = None;
 
                 for item in *item_ref {
-                    if in_external_macro(cx.sess(), item.span) {
+                    if item.span.in_external_macro(cx.sess().source_map()) {
                         continue;
                     }
 
@@ -304,7 +303,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
                 let mut cur_t: Option<&ImplItemRef> = None;
 
                 for item in trait_impl.items {
-                    if in_external_macro(cx.sess(), item.span) {
+                    if item.span.in_external_macro(cx.sess().source_map()) {
                         continue;
                     }
 
@@ -348,7 +347,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
         // as no sorting by source map/line of code has to be applied.
         //
         for item in items {
-            if in_external_macro(cx.sess(), item.span) {
+            if item.span.in_external_macro(cx.sess().source_map()) {
                 continue;
             }
 
diff --git a/src/tools/clippy/clippy_lints/src/as_conversions.rs b/src/tools/clippy/clippy_lints/src/as_conversions.rs
index fefd8195f8e..847653ed6e9 100644
--- a/src/tools/clippy/clippy_lints/src/as_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/as_conversions.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -49,7 +48,7 @@ declare_lint_pass!(AsConversions => [AS_CONVERSIONS]);
 impl<'tcx> LateLintPass<'tcx> for AsConversions {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
         if let ExprKind::Cast(_, _) = expr.kind
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, expr)
         {
             #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
diff --git a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs
index 1879391ec29..53d9725703c 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs
@@ -4,11 +4,10 @@ use clippy_utils::is_from_proc_macro;
 use rustc_ast::{AttrStyle, Attribute};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 
 // Separate each crate's features.
 pub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) {
-    if !in_external_macro(cx.sess(), attr.span)
+    if !attr.span.in_external_macro(cx.sess().source_map())
         && let AttrStyle::Outer = attr.style
         && let Some(ident) = attr.ident()
         && !is_from_proc_macro(cx, attr)
diff --git a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
index 788377fe83c..5bf077990e1 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
@@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
 use rustc_ast::{MetaItemInner, MetaItemKind};
 use rustc_lint::{EarlyContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::sym;
 use rustc_span::symbol::Symbol;
 
@@ -17,7 +16,7 @@ pub(super) fn check<'cx>(cx: &EarlyContext<'cx>, name: Symbol, items: &[MetaItem
     }
 
     // Check if the attribute is in an external macro and therefore out of the developer's control
-    if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, attr) {
+    if attr.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, attr) {
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
index e7158a6a6b6..e3e081ce08e 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
@@ -5,14 +5,13 @@ use clippy_utils::source::{SpanRangeExt, first_line_of_span};
 use rustc_ast::{Attribute, Item, ItemKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::sym;
 
 pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
     let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
 
     for attr in attrs {
-        if in_external_macro(cx.sess(), attr.span) {
+        if attr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         if let Some(lint_list) = &attr.meta_item_list() {
diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
index eb05dc96cde..aab0af0d743 100644
--- a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
+++ b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
@@ -4,7 +4,6 @@ use clippy_utils::{higher, is_from_proc_macro};
 use rustc_errors::Applicability;
 use rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -54,7 +53,7 @@ const BRACED_EXPR_MESSAGE: &str = "omit braces around single expression conditio
 
 impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if in_external_macro(cx.sess(), expr.span) {
+        if expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/box_default.rs b/src/tools/clippy/clippy_lints/src/box_default.rs
index 79fd6ffe46c..3b861848f94 100644
--- a/src/tools/clippy/clippy_lints/src/box_default.rs
+++ b/src/tools/clippy/clippy_lints/src/box_default.rs
@@ -7,7 +7,6 @@ use rustc_hir::def::Res;
 use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};
 use rustc_hir::{AmbigArg, Block, Expr, ExprKind, HirId, LetStmt, Node, QPath, Ty, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::{Span, sym};
 
@@ -50,7 +49,7 @@ impl LateLintPass<'_> for BoxDefault {
             // This is the `T::default()` (or default equivalent) of `Box::new(T::default())`
             && let ExprKind::Call(arg_path, _) = arg.kind
             // And we are not in a foreign crate's macro
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             // And the argument expression has the same context as the outer call expression
             // or that we are inside a `vec!` macro expansion
             && (expr.span.eq_ctxt(arg.span) || is_local_vec_expn(cx, arg, expr))
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index d90cf124fe4..521bd394901 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -29,7 +29,6 @@ use clippy_utils::is_hir_ty_cfg_dependant;
 use clippy_utils::msrvs::{self, Msrv};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -796,7 +795,7 @@ impl_lint_pass!(Casts => [
 
 impl<'tcx> LateLintPass<'tcx> for Casts {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if in_external_macro(cx.sess(), expr.span) {
+        if expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index 9e1876e40f9..7885f171461 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -8,7 +8,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind, Lit, Node, Path, QPath, TyKind, UnOp};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, FloatTy, InferTy, Ty};
 use std::ops::ControlFlow;
 
@@ -142,7 +141,7 @@ pub(super) fn check<'tcx>(
         }
     }
 
-    if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) {
+    if cast_from.kind() == cast_to.kind() && !expr.span.in_external_macro(cx.sess().source_map()) {
         if let Some(id) = path_to_local(cast_expr)
             && !cx.tcx.hir().span(id).eq_ctxt(cast_expr.span)
         {
diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
index 1edfde97422..9516af7334d 100644
--- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
@@ -6,7 +6,6 @@ use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -64,7 +63,7 @@ impl LateLintPass<'_> for CheckedConversions {
                 },
                 _ => return,
             }
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && !is_in_const_context(cx)
             && self.msrv.meets(msrvs::TRY_FROM)
             && let Some(cv) = match op2 {
diff --git a/src/tools/clippy/clippy_lints/src/ctfe.rs b/src/tools/clippy/clippy_lints/src/ctfe.rs
index 589b99518a0..7bae04a10f1 100644
--- a/src/tools/clippy/clippy_lints/src/ctfe.rs
+++ b/src/tools/clippy/clippy_lints/src/ctfe.rs
@@ -21,6 +21,6 @@ impl<'tcx> LateLintPass<'tcx> for ClippyCtfe {
         _: Span,
         defid: LocalDefId,
     ) {
-        cx.tcx.ensure().mir_drops_elaborated_and_const_checked(defid); // Lint
+        cx.tcx.ensure_ok().mir_drops_elaborated_and_const_checked(defid); // Lint
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/dbg_macro.rs b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
index a96c86f0765..06376c57119 100644
--- a/src/tools/clippy/clippy_lints/src/dbg_macro.rs
+++ b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
@@ -7,7 +7,6 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Node};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, SyntaxContext, sym};
 
@@ -60,7 +59,7 @@ impl LateLintPass<'_> for DbgMacro {
 
         if cur_syntax_ctxt != self.prev_ctxt &&
             let Some(macro_call) = first_dbg_macro_in_expansion(cx, expr.span) &&
-            !in_external_macro(cx.sess(), macro_call.span) &&
+            !macro_call.span.in_external_macro(cx.sess().source_map()) &&
             self.checked_dbg_call_site.insert(macro_call.span) &&
             // allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
             !(self.allow_dbg_in_tests && is_in_test(cx.tcx, expr.hir_id))
diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
index ca3eaae7b85..772268e7899 100644
--- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
+++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
@@ -9,7 +9,6 @@ use rustc_hir::{
     StructTailExpr,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
 use rustc_session::declare_lint_pass;
 use std::iter;
@@ -86,7 +85,7 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
 
     /// Check whether a passed literal has potential to cause fallback or not.
     fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>, emit_hir_id: HirId) {
-        if !in_external_macro(self.cx.sess(), lit.span)
+        if !lit.span.in_external_macro(self.cx.sess().source_map())
             && matches!(self.ty_bounds.last(), Some(ExplicitTyBound(false)))
             && matches!(
                 lit.node,
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 15530c3dbc5..3d8ce7becdb 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -22,7 +22,6 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_resolve::rustdoc::{
     DocFragment, add_doc_fragment, attrs_to_doc_fragments, main_body_opts, source_span_for_markdown_range,
@@ -675,7 +674,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
                 match item.kind {
                     ItemKind::Fn { sig, body: body_id, .. } => {
                         if !(is_entrypoint_fn(cx, item.owner_id.to_def_id())
-                            || in_external_macro(cx.tcx.sess, item.span))
+                            || item.span.in_external_macro(cx.tcx.sess.source_map()))
                         {
                             let body = cx.tcx.hir().body(body_id);
 
@@ -711,7 +710,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
             },
             Node::TraitItem(trait_item) => {
                 if let TraitItemKind::Fn(sig, ..) = trait_item.kind
-                    && !in_external_macro(cx.tcx.sess, trait_item.span)
+                    && !trait_item.span.in_external_macro(cx.tcx.sess.source_map())
                 {
                     missing_headers::check(
                         cx,
@@ -726,7 +725,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
             },
             Node::ImplItem(impl_item) => {
                 if let ImplItemKind::Fn(sig, body_id) = impl_item.kind
-                    && !in_external_macro(cx.tcx.sess, impl_item.span)
+                    && !impl_item.span.in_external_macro(cx.tcx.sess.source_map())
                     && !is_trait_impl_item(cx, impl_item.hir_id())
                 {
                     let body = cx.tcx.hir().body(body_id);
@@ -791,7 +790,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
 
     let (fragments, _) = attrs_to_doc_fragments(
         attrs.iter().filter_map(|attr| {
-            if in_external_macro(cx.sess(), attr.span) {
+            if attr.span.in_external_macro(cx.sess().source_map()) {
                 None
             } else {
                 Some((attr, None))
diff --git a/src/tools/clippy/clippy_lints/src/else_if_without_else.rs b/src/tools/clippy/clippy_lints/src/else_if_without_else.rs
index 5315f55ba38..a38e853172f 100644
--- a/src/tools/clippy/clippy_lints/src/else_if_without_else.rs
+++ b/src/tools/clippy/clippy_lints/src/else_if_without_else.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_ast::ast::{Expr, ExprKind};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -50,7 +49,7 @@ impl EarlyLintPass for ElseIfWithoutElse {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, item: &Expr) {
         if let ExprKind::If(_, _, Some(ref els)) = item.kind
             && let ExprKind::If(_, _, None) = els.kind
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
         {
             #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/endian_bytes.rs b/src/tools/clippy/clippy_lints/src/endian_bytes.rs
index 209104c5385..29deaaf3bc7 100644
--- a/src/tools/clippy/clippy_lints/src/endian_bytes.rs
+++ b/src/tools/clippy/clippy_lints/src/endian_bytes.rs
@@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_lint_allowed;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::Ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::Symbol;
@@ -119,7 +118,7 @@ impl LateLintPass<'_> for EndianBytes {
             },
             _ => return,
         };
-        if !in_external_macro(cx.sess(), expr.span)
+        if !expr.span.in_external_macro(cx.sess().source_map())
             && let ty = cx.typeck_results().expr_ty(ty_expr)
             && ty.is_primitive_ty()
         {
diff --git a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
index 7ca2c953699..cd9ab2764ac 100644
--- a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
+++ b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
@@ -4,7 +4,6 @@ use clippy_utils::ty::implements_trait;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::Ty;
 use rustc_session::declare_lint_pass;
 
@@ -72,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         if let ExprKind::Let(let_expr) = expr.kind
             && unary_pattern(let_expr.pat)
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
         {
             let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
             let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
diff --git a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
index dfea40db182..36567b3ded0 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
@@ -5,7 +5,6 @@ use rustc_ast::node_id::NodeSet;
 use rustc_ast::visit::{Visitor, walk_block, walk_item};
 use rustc_ast::{Block, Crate, Inline, Item, ItemKind, ModKind, NodeId};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 
@@ -125,7 +124,7 @@ struct NestingVisitor<'conf, 'cx> {
 
 impl NestingVisitor<'_, '_> {
     fn check_indent(&mut self, span: Span, id: NodeId) -> bool {
-        if self.nest_level > self.conf.excessive_nesting_threshold && !in_external_macro(self.cx.sess(), span) {
+        if self.nest_level > self.conf.excessive_nesting_threshold && !span.in_external_macro(self.cx.sess().source_map()) {
             self.conf.nodes.insert(id);
 
             return true;
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 cdbfe7af8f9..5d93aceb33f 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
@@ -10,7 +10,6 @@ use rustc_hir::{
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::{DefId, LocalDefId};
@@ -261,7 +260,7 @@ impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters {
             && !generics.params.is_empty()
             && !is_empty_body(cx, body_id)
             && (!self.avoid_breaking_exported_api || !cx.effective_visibilities.is_exported(item.owner_id.def_id))
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, item)
         {
             let mut walker = TypeWalker::new(cx, generics);
@@ -277,7 +276,7 @@ impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters {
             && trait_ref_of_method(cx, item.owner_id.def_id).is_none()
             && !is_empty_body(cx, body_id)
             && (!self.avoid_breaking_exported_api || !cx.effective_visibilities.is_exported(item.owner_id.def_id))
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, item)
         {
             let mut walker = TypeWalker::new(cx, item.generics);
diff --git a/src/tools/clippy/clippy_lints/src/formatting.rs b/src/tools/clippy/clippy_lints/src/formatting.rs
index 34e93bdb9b9..c8fe7ac73cb 100644
--- a/src/tools/clippy/clippy_lints/src/formatting.rs
+++ b/src/tools/clippy/clippy_lints/src/formatting.rs
@@ -3,7 +3,6 @@ use clippy_utils::is_span_if;
 use clippy_utils::source::snippet_opt;
 use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 
@@ -202,7 +201,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) {
     if let ExprKind::If(_, then, Some(else_)) = &expr.kind
         && (is_block(else_) || is_if(else_))
         && !then.span.from_expansion() && !else_.span.from_expansion()
-        && !in_external_macro(cx.sess(), expr.span)
+        && !expr.span.in_external_macro(cx.sess().source_map())
 
         // workaround for rust-lang/rust#43081
         && expr.span.lo().0 != 0 && expr.span.hi().0 != 0
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index 90d3db2700f..e480805cac2 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -5,7 +5,6 @@ use rustc_hir::def_id::DefIdSet;
 use rustc_hir::{self as hir, Attribute, QPath};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::{Span, sym};
 
@@ -107,7 +106,7 @@ fn check_needless_must_use(
     attrs: &[Attribute],
     sig: &FnSig<'_>,
 ) {
-    if in_external_macro(cx.sess(), item_span) {
+    if item_span.in_external_macro(cx.sess().source_map()) {
         return;
     }
     if returns_unit(decl) {
@@ -185,7 +184,7 @@ fn check_must_use_candidate<'tcx>(
 ) {
     if has_mutable_arg(cx, body)
         || mutates_static(cx, body)
-        || in_external_macro(cx.sess(), item_span)
+        || item_span.in_external_macro(cx.sess().source_map())
         || returns_unit(decl)
         || !cx.effective_visibilities.is_exported(item_id.def_id)
         || is_must_use_ty(cx, return_ty(cx, item_id))
diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs
index 9c396986f62..74d365a7255 100644
--- a/src/tools/clippy/clippy_lints/src/functions/result.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/result.rs
@@ -2,7 +2,6 @@ use clippy_utils::msrvs::{self, Msrv};
 use rustc_errors::Diag;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::{Span, sym};
 
@@ -20,7 +19,7 @@ fn result_err_ty<'tcx>(
     id: hir::def_id::LocalDefId,
     item_span: Span,
 ) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> {
-    if !in_external_macro(cx.sess(), item_span)
+    if !item_span.in_external_macro(cx.sess().source_map())
         && let hir::FnRetTy::Return(hir_ty) = decl.output
         && let ty = cx
             .tcx
diff --git a/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs b/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
index 0f5ce340c44..4f90d9655b4 100644
--- a/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
@@ -3,7 +3,6 @@ use clippy_utils::source::SpanRangeExt;
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::Span;
 
 use super::TOO_MANY_LINES;
@@ -17,7 +16,7 @@ pub(super) fn check_fn(
 ) {
     // Closures must be contained in a parent body, which will be checked for `too_many_lines`.
     // Don't check closures for `too_many_lines` to avoid duplicated lints.
-    if matches!(kind, FnKind::Closure) || in_external_macro(cx.sess(), span) {
+    if matches!(kind, FnKind::Closure) || span.in_external_macro(cx.sess().source_map()) {
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
index 3fc0a696522..51e2944e6f9 100644
--- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
+++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
@@ -11,7 +11,6 @@ use rustc_errors::Applicability;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -79,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
             && is_res_lang_ctor(cx, path_res(cx, peel_blocks(els)), OptionNone)
             && !is_else_clause(cx.tcx, expr)
             && !is_in_const_context(cx)
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && self.msrv.meets(msrvs::BOOL_THEN)
             && !contains_return(then_block.stmts)
         {
diff --git a/src/tools/clippy/clippy_lints/src/implicit_return.rs b/src/tools/clippy/clippy_lints/src/implicit_return.rs
index ba06567b957..5f95464e4d4 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_return.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_return.rs
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{Span, SyntaxContext};
@@ -227,7 +226,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitReturn {
     ) {
         if (!matches!(kind, FnKind::Closure) && matches!(decl.output, FnRetTy::DefaultReturn(_)))
             || !span.eq_ctxt(body.value.span)
-            || in_external_macro(cx.sess(), span)
+            || span.in_external_macro(cx.sess().source_map())
         {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/items_after_statements.rs b/src/tools/clippy/clippy_lints/src/items_after_statements.rs
index 4f066113aea..f5ad79a0027 100644
--- a/src/tools/clippy/clippy_lints/src/items_after_statements.rs
+++ b/src/tools/clippy/clippy_lints/src/items_after_statements.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_hir;
 use rustc_hir::{Block, ItemKind, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -70,7 +69,7 @@ impl LateLintPass<'_> for ItemsAfterStatements {
                 // Don't use `next` due to the complex filter chain.
                 .for_each(|item| {
                     // Only do the macro check once, but delay it until it's needed.
-                    if !*in_external.get_or_insert_with(|| in_external_macro(cx.sess(), block.span)) {
+                    if !*in_external.get_or_insert_with(|| block.span.in_external_macro(cx.sess().source_map())) {
                         span_lint_hir(
                             cx,
                             ITEMS_AFTER_STATEMENTS,
diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
index 906da81b183..238f66d6675 100644
--- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
@@ -6,7 +6,6 @@ use rustc_ast::Mutability;
 use rustc_errors::Applicability;
 use rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, ItemKind, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
@@ -131,7 +130,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter {
             && trait_ref
                 .trait_def_id()
                 .is_some_and(|did| cx.tcx.is_diagnostic_item(sym::IntoIterator, did))
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && let &ty::Ref(_, ty, mtbl) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
             && let expected_method_name = match mtbl {
                 Mutability::Mut => sym::iter_mut,
@@ -193,7 +192,7 @@ impl {self_ty_without_ref} {{
             _ => return,
         };
 
-        if !in_external_macro(cx.sess(), item.span)
+        if !item.span.in_external_macro(cx.sess().source_map())
             && let ImplItemKind::Fn(sig, _) = item.kind
             && let FnRetTy::Return(ret) = sig.decl.output
             && is_nameable_in_impl_trait(ret)
diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
index 923089c7223..d9953dbc261 100644
--- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
+++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
@@ -5,7 +5,6 @@ use clippy_utils::ty::{AdtVariantInfo, approx_ty_size, is_copy};
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
@@ -78,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
             && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
             && let ty::Adt(adt, subst) = ty.kind()
             && adt.variants().len() > 1
-            && !in_external_macro(cx.tcx.sess, item.span)
+            && !item.span.in_external_macro(cx.tcx.sess.source_map())
         {
             let variants_size = AdtVariantInfo::new(cx, *adt, subst);
 
diff --git a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
index fb46bdcab6e..6f2ce04e8f8 100644
--- a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::{ExprKind, Item, ItemKind, QPath, UseKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::kw;
 use rustc_span::{Symbol, sym};
@@ -54,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
         // so lint on the `use` statement directly.
         if let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind
             && self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && let Some(def_id) = path.res[0].opt_def_id()
         {
             let module = if is_integer_module(cx, def_id) {
@@ -139,7 +138,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
         };
 
         if self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, expr)
         {
             span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| {
diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs
index b522c22a44d..bdbf5b37c5f 100644
--- a/src/tools/clippy/clippy_lints/src/let_underscore.rs
+++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs
@@ -3,7 +3,6 @@ use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
 use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};
 use rustc_hir::{LetStmt, LocalSource, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{GenericArgKind, IsSuggestable};
 use rustc_session::declare_lint_pass;
 use rustc_span::{BytePos, Span};
@@ -141,7 +140,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
         if matches!(local.source, LocalSource::Normal)
             && let PatKind::Wild = local.pat.kind
             && let Some(init) = local.init
-            && !in_external_macro(cx.tcx.sess, local.span)
+            && !local.span.in_external_macro(cx.tcx.sess.source_map())
         {
             let init_ty = cx.typeck_results().expr_ty(init);
             let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
diff --git a/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs b/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs
index 34ded6c6500..9c8488ff381 100644
--- a/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs
+++ b/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::is_from_proc_macro;
 use rustc_hir::{LetStmt, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -30,7 +29,7 @@ impl<'tcx> LateLintPass<'tcx> for UnderscoreTyped {
         if let Some(ty) = local.ty // Ensure that it has a type defined
             && let TyKind::Infer(()) = &ty.kind // that type is '_'
             && local.span.eq_ctxt(ty.span)
-            && !in_external_macro(cx.tcx.sess, local.span)
+            && !local.span.in_external_macro(cx.tcx.sess.source_map())
             && !is_from_proc_macro(cx, ty)
         {
             span_lint_and_help(
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index c9ab0beb5df..860c0584acc 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -21,7 +21,6 @@ use rustc_hir::{
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::map::Map;
 use rustc_middle::hir::nested_filter as middle_nested_filter;
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
@@ -164,7 +163,7 @@ fn check_fn_inner<'tcx>(
     report_extra_lifetimes: bool,
     msrv: &Msrv,
 ) {
-    if in_external_macro(cx.sess(), span) || has_where_lifetimes(cx, generics) {
+    if span.in_external_macro(cx.sess().source_map()) || has_where_lifetimes(cx, generics) {
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/literal_representation.rs b/src/tools/clippy/clippy_lints/src/literal_representation.rs
index a4cedf3bed3..805de23408b 100644
--- a/src/tools/clippy/clippy_lints/src/literal_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/literal_representation.rs
@@ -6,7 +6,6 @@ use rustc_ast::ast::{Expr, ExprKind, LitKind};
 use rustc_ast::token;
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use std::iter;
@@ -207,7 +206,7 @@ impl_lint_pass!(LiteralDigitGrouping => [
 impl EarlyLintPass for LiteralDigitGrouping {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
         if let ExprKind::Lit(lit) = expr.kind
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
         {
             self.check_lit(cx, lit, expr.span);
         }
@@ -421,7 +420,7 @@ impl_lint_pass!(DecimalLiteralRepresentation => [DECIMAL_LITERAL_REPRESENTATION]
 impl EarlyLintPass for DecimalLiteralRepresentation {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
         if let ExprKind::Lit(lit) = expr.kind
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
         {
             self.check_lit(cx, lit, expr.span);
         }
diff --git a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
index 6be30f3c957..4d206850c99 100644
--- a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
@@ -6,7 +6,6 @@ use rustc_ast::Label;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::sym;
 
 use super::INFINITE_LOOP;
@@ -30,7 +29,7 @@ pub(super) fn check<'tcx>(
         return;
     }
 
-    if in_external_macro(cx.sess(), expr.span) || is_from_proc_macro(cx, expr) {
+    if expr.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, expr) {
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
index a1951b9da44..052e6502da9 100644
--- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
@@ -9,7 +9,6 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::impl_lint_pass;
 
@@ -142,7 +141,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
             // 16 possible alignments of constants/operands. For now, let's use `partition`.
             && let mut exprs = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
             && exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && (
                 is_not_const(cx.tcx, cx.tcx.hir().enclosing_body_owner(expr.hir_id).into())
                     || self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY)
diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
index 274785061b3..3643b8c4425 100644
--- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
@@ -9,7 +9,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 
 use rustc_span::Span;
 use rustc_span::symbol::{Symbol, sym};
@@ -55,7 +54,7 @@ impl<'tcx> QuestionMark {
             && init.span.eq_ctxt(stmt.span)
             && let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init)
             && self.msrv.meets(msrvs::LET_ELSE)
-            && !in_external_macro(cx.sess(), stmt.span)
+            && !stmt.span.in_external_macro(cx.sess().source_map())
         {
             match if_let_or_match {
                 IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else, ..) => {
diff --git a/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs b/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
index 2e5a92915d9..bf4f2bff319 100644
--- a/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
@@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::{PatExpr, PatExprKind, PatKind, RangeEnd};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::{DUMMY_SP, Span};
 
@@ -80,7 +79,7 @@ impl LateLintPass<'_> for ManualRangePatterns {
         // like described https://github.com/rust-lang/rust-clippy/issues/11825)
         if let PatKind::Or(pats) = pat.kind
             && (pats.len() >= 3 || (pats.len() > 1 && pats.iter().any(|p| matches!(p.kind, PatKind::Range(..)))))
-            && !in_external_macro(cx.sess(), pat.span)
+            && !pat.span.in_external_macro(cx.sess().source_map())
         {
             let mut min = Num::dummy(i128::MAX);
             let mut max = Num::dummy(i128::MIN);
diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
index 8aeec89f0bf..469b4b7cf89 100644
--- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
@@ -7,7 +7,6 @@ use clippy_utils::{is_in_const_context, path_to_local};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -60,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
             && rem_rhs.span.ctxt() == ctxt
             && add_lhs.span.ctxt() == ctxt
             && add_rhs.span.ctxt() == ctxt
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && self.msrv.meets(msrvs::REM_EUCLID)
             && (self.msrv.meets(msrvs::REM_EUCLID_CONST) || !is_in_const_context(cx))
             && let Some(const1) = check_for_unsigned_int_constant(cx, rem_rhs)
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index a7fdd483c16..9ca914af281 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -33,7 +33,6 @@ use clippy_utils::{
 };
 use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{SpanData, SyntaxContext};
 
@@ -1054,7 +1053,7 @@ impl_lint_pass!(Matches => [
 impl<'tcx> LateLintPass<'tcx> for Matches {
     #[expect(clippy::too_many_lines)]
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if is_direct_expn_of(expr.span, "matches").is_none() && in_external_macro(cx.sess(), expr.span) {
+        if is_direct_expn_of(expr.span, "matches").is_none() && expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         let from_expansion = expr.span.from_expansion();
diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs
index 5597cd85abc..41528c5dee3 100644
--- a/src/tools/clippy/clippy_lints/src/mem_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs
@@ -11,7 +11,6 @@ use rustc_errors::Applicability;
 use rustc_hir::LangItem::OptionNone;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::symbol::sym;
@@ -188,7 +187,7 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<
     if is_non_aggregate_primitive_type(expr_type) {
         return;
     }
-    if is_default_equivalent(cx, src) && !in_external_macro(cx.tcx.sess, expr_span) {
+    if is_default_equivalent(cx, src) && !expr_span.in_external_macro(cx.tcx.sess.source_map()) {
         let Some(top_crate) = std_or_core(cx) else { return };
         span_lint_and_then(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
index 129e6925428..d550c145466 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
@@ -6,13 +6,12 @@ use clippy_utils::{is_from_proc_macro, is_trait_method, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::Binder;
 use rustc_middle::ty::adjustment::Adjust;
 use rustc_span::{Span, sym};
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &Expr<'_>, call_span: Span) {
-    if !in_external_macro(cx.sess(), expr.span)
+    if !expr.span.in_external_macro(cx.sess().source_map())
         && is_trait_method(cx, expr, sym::Iterator)
         && let ExprKind::Closure(closure) = arg.kind
         && let body = cx.tcx.hir().body(closure.body)
diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
index a0c21faaa4c..92c81b3c49d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
@@ -4,7 +4,6 @@ use clippy_utils::macros::{is_assert_macro, root_macro_call};
 use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context, path_to_local};
 use rustc_hir::{Expr, HirId};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::sym;
 
 use super::CONST_IS_EMPTY;
@@ -12,7 +11,7 @@ use super::CONST_IS_EMPTY;
 /// Expression whose initialization depend on a constant conditioned by a `#[cfg(…)]` directive will
 /// not trigger the lint.
 pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_>) {
-    if in_external_macro(cx.sess(), expr.span) || !receiver.span.eq_ctxt(expr.span) {
+    if expr.span.in_external_macro(cx.sess().source_map()) || !receiver.span.eq_ctxt(expr.span) {
         return;
     }
     if let Some(parent) = get_parent_expr(cx, expr) {
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs b/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
index 4a48d4b547c..a56378b5b73 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::{Span, sym};
 
 use super::MANUAL_TRY_FOLD;
@@ -20,7 +19,7 @@ pub(super) fn check<'tcx>(
     fold_span: Span,
     msrv: &Msrv,
 ) {
-    if !in_external_macro(cx.sess(), fold_span)
+    if !fold_span.in_external_macro(cx.sess().source_map())
         && msrv.meets(msrvs::ITERATOR_TRY_FOLD)
         && is_trait_method(cx, expr, sym::Iterator)
         && let init_ty = cx.typeck_results().expr_ty(init)
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 42418318fda..2f447775fa5 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -152,7 +152,6 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, TraitRef, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, sym};
@@ -4625,7 +4624,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
 
     #[allow(clippy::too_many_lines)]
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
-        if in_external_macro(cx.sess(), impl_item.span) {
+        if impl_item.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         let name = impl_item.ident.name.as_str();
@@ -4713,7 +4712,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
-        if in_external_macro(cx.tcx.sess, item.span) {
+        if item.span.in_external_macro(cx.tcx.sess.source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
index a99e21d938c..4119b1d1051 100644
--- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
@@ -6,7 +6,6 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{Visitor, walk_item, walk_trait_item};
 use rustc_hir::{GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node, Pat, PatKind, TraitItem, UsePath};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use std::borrow::Cow;
@@ -55,7 +54,7 @@ impl MinIdentChars {
 
     #[expect(clippy::cast_possible_truncation)]
     fn is_ident_too_short(&self, cx: &LateContext<'_>, str: &str, span: Span) -> bool {
-        !in_external_macro(cx.sess(), span)
+        !span.in_external_macro(cx.sess().source_map())
             && str.len() <= self.min_ident_chars_threshold as usize
             && !str.starts_with('_')
             && !str.is_empty()
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index b511b1e46b3..fa0eb9a94b7 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -13,7 +13,6 @@ use rustc_hir::{
     BinOpKind, BindingMode, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
@@ -162,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
             for arg in iter_input_pats(decl, body) {
                 if let PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..) = arg.pat.kind
                     && is_lint_allowed(cx, REF_PATTERNS, arg.pat.hir_id)
-                    && !in_external_macro(cx.tcx.sess, arg.span)
+                    && !arg.span.in_external_macro(cx.tcx.sess.source_map())
                 {
                     span_lint_hir(
                         cx,
@@ -183,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
             && let Some(init) = local.init
             // Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue.
             && is_lint_allowed(cx, REF_PATTERNS, local.pat.hir_id)
-            && !in_external_macro(cx.tcx.sess, stmt.span)
+            && !stmt.span.in_external_macro(cx.tcx.sess.source_map())
         {
             let ctxt = local.span.ctxt();
             let mut app = Applicability::MachineApplicable;
@@ -239,7 +238,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if in_external_macro(cx.sess(), expr.span)
+        if expr.span.in_external_macro(cx.sess().source_map())
             || expr.span.desugaring_kind().is_some()
             || in_automatically_derived(cx.tcx, expr.hir_id)
         {
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
index 637d6ed3ad2..f880f1f329f 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
@@ -14,7 +14,6 @@ use rustc_ast::token;
 use rustc_ast::visit::FnKind;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 
@@ -350,7 +349,7 @@ impl EarlyLintPass for MiscEarlyLints {
     }
 
     fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) {
-        if in_external_macro(cx.sess(), pat.span) {
+        if pat.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
@@ -387,7 +386,7 @@ impl EarlyLintPass for MiscEarlyLints {
     }
 
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
-        if in_external_macro(cx.sess(), expr.span) {
+        if expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs
index 0c81ee5eced..f2cf93465c0 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs
@@ -2,12 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use rustc_ast::{Pat, PatKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 
 use super::REDUNDANT_AT_REST_PATTERN;
 
 pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
-    if !in_external_macro(cx.sess(), pat.span)
+    if !pat.span.in_external_macro(cx.sess().source_map())
         && let PatKind::Slice(slice) = &pat.kind
         && let [one] = &**slice
         && let PatKind::Ident(annotation, ident, Some(rest)) = &one.kind
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 2572e186ce6..962d85c6a9d 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -8,7 +8,6 @@ use rustc_hir::def_id::CRATE_DEF_ID;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{self as hir, Body, Constness, FnDecl, GenericParamKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
@@ -106,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
             return;
         }
 
-        if in_external_macro(cx.tcx.sess, span) || is_entrypoint_fn(cx, def_id.to_def_id()) {
+        if span.in_external_macro(cx.tcx.sess.source_map()) || is_entrypoint_fn(cx, def_id.to_def_id()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index bba1b63be27..18385ac9269 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -88,7 +88,7 @@ declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]);
 
 impl<'tcx> LateLintPass<'tcx> for MissingInline {
     fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
-        if rustc_middle::lint::in_external_macro(cx.sess(), it.span) || is_executable_or_proc_macro(cx) {
+        if it.span.in_external_macro(cx.sess().source_map()) || is_executable_or_proc_macro(cx) {
             return;
         }
 
@@ -139,7 +139,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
-        if rustc_middle::lint::in_external_macro(cx.sess(), impl_item.span) || is_executable_or_proc_macro(cx) {
+        if impl_item.span.in_external_macro(cx.sess().source_map()) || is_executable_or_proc_macro(cx) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
index aad6ae52a6d..302db2c914c 100644
--- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
+++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
@@ -6,7 +6,6 @@ use hir::{BlockCheckMode, ExprKind, QPath, UnOp};
 use rustc_ast::Mutability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::{DesugaringKind, Span};
@@ -65,7 +64,7 @@ declare_lint_pass!(MultipleUnsafeOpsPerBlock => [MULTIPLE_UNSAFE_OPS_PER_BLOCK])
 impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
         if !matches!(block.rules, BlockCheckMode::UnsafeBlock(_))
-            || in_external_macro(cx.tcx.sess, block.span)
+            || block.span.in_external_macro(cx.tcx.sess.source_map())
             || block.span.is_desugaring(DesugaringKind::Await)
         {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/mut_mut.rs b/src/tools/clippy/clippy_lints/src/mut_mut.rs
index 0ee851a4cf9..3c4ba5141dd 100644
--- a/src/tools/clippy/clippy_lints/src/mut_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_mut.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::{span_lint, span_lint_hir};
 use clippy_utils::higher;
 use rustc_hir::{self as hir, AmbigArg, intravisit};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 
@@ -38,7 +37,7 @@ impl<'tcx> LateLintPass<'tcx> for MutMut {
             && mty.mutbl == hir::Mutability::Mut
             && let hir::TyKind::Ref(_, mty) = mty.ty.kind
             && mty.mutbl == hir::Mutability::Mut
-            && !in_external_macro(cx.sess(), ty.span)
+            && !ty.span.in_external_macro(cx.sess().source_map())
         {
             span_lint(
                 cx,
@@ -56,7 +55,7 @@ pub struct MutVisitor<'a, 'tcx> {
 
 impl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
-        if in_external_macro(self.cx.sess(), expr.span) {
+        if expr.span.in_external_macro(self.cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/needless_if.rs b/src/tools/clippy/clippy_lints/src/needless_if.rs
index 8e14fbf2f80..7eefb016aca 100644
--- a/src/tools/clippy/clippy_lints/src/needless_if.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_if.rs
@@ -5,7 +5,6 @@ use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
 use rustc_hir::{ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -47,7 +46,7 @@ impl LateLintPass<'_> for NeedlessIf {
             && let ExprKind::Block(block, ..) = then.kind
             && block.stmts.is_empty()
             && block.expr.is_none()
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && then.span.check_source_text(cx, |src| {
                 // Ignore
                 // - empty macro expansions
diff --git a/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs b/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs
index fa90ee60612..4f62ba2e58d 100644
--- a/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs
+++ b/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::implements_trait;
 use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
 
@@ -48,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for NoNegCompOpForPartialOrd {
         if let ExprKind::Unary(UnOp::Not, inner) = expr.kind
             && let ExprKind::Binary(ref op, left, _) = inner.kind
             && let BinOpKind::Le | BinOpKind::Ge | BinOpKind::Lt | BinOpKind::Gt = op.node
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
         {
             let ty = cx.typeck_results().expr_ty(left);
 
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index 688374b5676..cc56df3a23d 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -6,7 +6,6 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::HirIdSet;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::sym;
 
@@ -69,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
             for assoc_item in *items {
                 if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) {
                     let impl_item = cx.tcx.hir().impl_item(assoc_item.id);
-                    if in_external_macro(cx.sess(), impl_item.span) {
+                    if impl_item.span.in_external_macro(cx.sess().source_map()) {
                         return;
                     }
                     if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index ccd50758044..4d3e6aa79d0 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -12,7 +12,6 @@ use rustc_hir::{
 };
 use rustc_infer::infer::TyCtxtInferExt as _;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -268,7 +267,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 
 fn check_unnecessary_operation(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
     if let StmtKind::Semi(expr) = stmt.kind
-        && !in_external_macro(cx.sess(), stmt.span)
+        && !stmt.span.in_external_macro(cx.sess().source_map())
         && let ctxt = stmt.span.ctxt()
         && expr.span.ctxt() == ctxt
         && let Some(reduced) = reduce_expression(cx, expr)
diff --git a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
index 94855c46567..dad1e8a3d6a 100644
--- a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
@@ -5,7 +5,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::EarlyBinder;
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
@@ -129,7 +128,7 @@ impl LateLintPass<'_> for NonCanonicalImpls {
         let ExprKind::Block(block, ..) = body.value.kind else {
             return;
         };
-        if in_external_macro(cx.sess(), block.span) || is_from_proc_macro(cx, impl_item) {
+        if block.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, impl_item) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
index 56c4157d6fe..1a3b43cbb10 100644
--- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
+++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
@@ -5,7 +5,6 @@ use rustc_ast::ast::{
 };
 use rustc_ast::visit::{Visitor, walk_block, walk_expr, walk_pat};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::{Span, sym};
@@ -381,7 +380,7 @@ impl<'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'_, 'tcx> {
 
 impl EarlyLintPass for NonExpressiveNames {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if in_external_macro(cx.sess(), item.span) {
+        if item.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
@@ -396,7 +395,7 @@ impl EarlyLintPass for NonExpressiveNames {
     }
 
     fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &AssocItem) {
-        if in_external_macro(cx.sess(), item.span) {
+        if item.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
index 793eb5d9456..9542fed3875 100644
--- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
+++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
@@ -7,7 +7,6 @@ use rustc_ast::ImplPolarity;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{FieldDef, Item, ItemKind, Node};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, GenericArgKind, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::sym;
@@ -81,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
         // We start from `Send` impl instead of `check_field_def()` because
         // single `AdtDef` may have multiple `Send` impls due to generic
         // parameters, and the lint is much easier to implement in this way.
-        if !in_external_macro(cx.tcx.sess, item.span)
+        if !item.span.in_external_macro(cx.tcx.sess.source_map())
             && let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send)
             && let ItemKind::Impl(hir_impl) = &item.kind
             && let Some(trait_ref) = &hir_impl.of_trait
diff --git a/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs b/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs
index 312610db042..22116505a1c 100644
--- a/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs
+++ b/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs
@@ -9,7 +9,6 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::{self as hir, BodyId, Expr, ExprKind, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 
@@ -139,7 +138,7 @@ impl<'hir> LateLintPass<'hir> for NonStdLazyStatic {
             return;
         }
 
-        if in_external_macro(cx.sess(), item.span) {
+        if item.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/octal_escapes.rs b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
index 2eae9b23746..6e7ee727965 100644
--- a/src/tools/clippy/clippy_lints/src/octal_escapes.rs
+++ b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
@@ -4,7 +4,6 @@ use rustc_ast::token::LitKind;
 use rustc_ast::{Expr, ExprKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::{BytePos, Pos, SpanData};
 
@@ -59,7 +58,7 @@ impl EarlyLintPass for OctalEscapes {
                 LitKind::ByteStr | LitKind::CStr => 2,
                 _ => return,
             })
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
         {
             let s = lit.symbol.as_str();
             let mut iter = s.as_bytes().iter();
diff --git a/src/tools/clippy/clippy_lints/src/panicking_overflow_checks.rs b/src/tools/clippy/clippy_lints/src/panicking_overflow_checks.rs
index 7f100a746d5..bc1821a48a3 100644
--- a/src/tools/clippy/clippy_lints/src/panicking_overflow_checks.rs
+++ b/src/tools/clippy/clippy_lints/src/panicking_overflow_checks.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint;
 use clippy_utils::eq_expr_value;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 
@@ -72,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for PanickingOverflowChecks {
             && matches!(ty.kind(), ty::Uint(_))
             && ty == typeck.expr_ty(op_rhs)
             && ty == typeck.expr_ty(other)
-            && !in_external_macro(cx.tcx.sess, expr.span)
+            && !expr.span.in_external_macro(cx.tcx.sess.source_map())
             && (eq_expr_value(cx, op_lhs, other) || (commutative && eq_expr_value(cx, op_rhs, other)))
         {
             span_lint(
diff --git a/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs b/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
index 668f09bbfd5..b653b459b04 100644
--- a/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
+++ b/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, Symbol, sym};
 
@@ -136,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for PathbufThenPush<'tcx> {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         if let Some(init_expr) = local.init
             && let PatKind::Binding(BindingMode::MUT, id, name, None) = local.pat.kind
-            && !in_external_macro(cx.sess(), local.span)
+            && !local.span.in_external_macro(cx.sess().source_map())
             && let ty = cx.typeck_results().pat_ty(local.pat)
             && is_type_diagnostic_item(cx, ty, sym::PathBuf)
         {
@@ -157,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for PathbufThenPush<'tcx> {
             && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind
             && let [name] = &path.segments
             && let Res::Local(id) = path.res
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && let ty = cx.typeck_results().expr_ty(left)
             && is_type_diagnostic_item(cx, ty, sym::PathBuf)
         {
diff --git a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
index 42fbba8ef6d..8f1a1ee76c6 100644
--- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
@@ -3,7 +3,6 @@ use rustc_hir::{
     Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind, intravisit,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
@@ -84,7 +83,7 @@ declare_lint_pass!(PatternTypeMismatch => [PATTERN_TYPE_MISMATCH]);
 impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
         if let StmtKind::Let(local) = stmt.kind {
-            if in_external_macro(cx.sess(), local.pat.span) {
+            if local.pat.span.in_external_macro(cx.sess().source_map()) {
                 return;
             }
             let deref_possible = match local.source {
@@ -171,7 +170,7 @@ fn find_first_mismatch(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(Span, Mut
         if result.is_some() {
             return false;
         }
-        if in_external_macro(cx.sess(), p.span) {
+        if p.span.in_external_macro(cx.sess().source_map()) {
             return true;
         }
         let adjust_pat = match p.kind {
diff --git a/src/tools/clippy/clippy_lints/src/raw_strings.rs b/src/tools/clippy/clippy_lints/src/raw_strings.rs
index 23d0e768c2f..c6e6e782f9d 100644
--- a/src/tools/clippy/clippy_lints/src/raw_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/raw_strings.rs
@@ -5,7 +5,6 @@ use rustc_ast::ast::{Expr, ExprKind};
 use rustc_ast::token::LitKind;
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{BytePos, Pos, Span};
 use std::iter::once;
@@ -72,7 +71,7 @@ impl RawStrings {
 impl EarlyLintPass for RawStrings {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
         if let ExprKind::FormatArgs(format_args) = &expr.kind
-            && !in_external_macro(cx.sess(), format_args.span)
+            && !format_args.span.in_external_macro(cx.sess().source_map())
             && format_args.span.check_source_text(cx, |src| src.starts_with('r'))
             && let Some(str) = snippet_opt(cx.sess(), format_args.span)
             && let count_hash = str.bytes().skip(1).take_while(|b| *b == b'#').count()
@@ -95,7 +94,7 @@ impl EarlyLintPass for RawStrings {
                 LitKind::CStrRaw(max) => ("cr", max),
                 _ => return,
             }
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && expr.span.check_source_text(cx, |src| src.starts_with(prefix))
         {
             self.check_raw_string(cx, lit.symbol.as_str(), expr.span, prefix, max, lit.kind.descr());
diff --git a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
index 3ade6bcee84..65fd312b3a0 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
@@ -10,7 +10,6 @@ use rustc_hir::{
     Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, MatchSource,
 };
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::UpvarCapture;
 use rustc_session::declare_lint_pass;
 
@@ -47,7 +46,7 @@ declare_lint_pass!(RedundantAsyncBlock => [REDUNDANT_ASYNC_BLOCK]);
 impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         let span = expr.span;
-        if !in_external_macro(cx.tcx.sess, span) &&
+        if !span.in_external_macro(cx.tcx.sess.source_map()) &&
             let Some(body_expr) = desugar_async_block(cx, expr) &&
             let Some(expr) = desugar_await(peel_blocks(body_expr)) &&
             // The await prefix must not come from a macro as its content could change in the future.
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index b4dadef57a3..91d023500ca 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -10,7 +10,6 @@ use rustc_hir::{
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::ExpnKind;
@@ -138,7 +137,7 @@ fn get_parent_call_exprs<'tcx>(
 
 impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
-        if in_external_macro(cx.sess(), expr.span) {
+        if expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/redundant_else.rs b/src/tools/clippy/clippy_lints/src/redundant_else.rs
index a27f9b63114..3476f56cf33 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_else.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_else.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_ast::ast::{Block, Expr, ExprKind, Stmt, StmtKind};
 use rustc_ast::visit::{Visitor, walk_expr};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -46,7 +45,7 @@ declare_lint_pass!(RedundantElse => [REDUNDANT_ELSE]);
 
 impl EarlyLintPass for RedundantElse {
     fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &Stmt) {
-        if in_external_macro(cx.sess(), stmt.span) {
+        if stmt.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         // Only look at expressions that are a whole statement
diff --git a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
index 347540e7344..707abc008a8 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
@@ -4,7 +4,6 @@ use clippy_utils::msrvs::{self, Msrv};
 use rustc_ast::ast::{Expr, ExprKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -56,7 +55,7 @@ impl EarlyLintPass for RedundantFieldNames {
             return;
         }
 
-        if in_external_macro(cx.sess(), expr.span) {
+        if expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         if let ExprKind::Struct(ref se) = expr.kind {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
index 658d93e634c..ebe3e7c2019 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
@@ -6,7 +6,6 @@ use rustc_hir::def::Res;
 use rustc_hir::{BindingMode, ByRef, ExprKind, HirId, LetStmt, Node, Pat, PatKind, QPath};
 use rustc_hir_typeck::expr_use_visitor::PlaceBase;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::UpvarCapture;
 use rustc_session::declare_lint_pass;
 use rustc_span::DesugaringKind;
@@ -69,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
             // the local does not affect the code's drop behavior
             && !needs_ordered_drop(cx, cx.typeck_results().expr_ty(expr))
             // the local is user-controlled
-            && !in_external_macro(cx.sess(), local.span)
+            && !local.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, expr)
             && !is_by_value_closure_capture(cx, local.hir_id, binding_id)
         {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
index 8d6b1c7274d..6a17b83b3d0 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
@@ -4,7 +4,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::CRATE_DEF_ID;
@@ -51,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
             && !cx.effective_visibilities.is_exported(item.owner_id.def_id)
             && self.is_exported.last() == Some(&false)
             && is_not_macro_export(item)
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
         {
             let span = item.span.with_hi(item.ident.span.hi());
             let descr = cx.tcx.def_kind(item.owner_id).descr(item.owner_id.to_def_id());
diff --git a/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs b/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs
index 6157adad059..152d7450f5f 100644
--- a/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs
@@ -6,7 +6,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 
@@ -72,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         if let Some(init_expr) = local.init
             && let PatKind::Binding(BindingMode::MUT, id, _, None) = local.pat.kind
-            && !in_external_macro(cx.sess(), local.span)
+            && !local.span.in_external_macro(cx.sess().source_map())
             && let Some(init) = get_vec_init_kind(cx, init_expr)
             && !matches!(
                 init,
@@ -101,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization {
             && let ExprKind::Assign(left, right, _) = expr.kind
             && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind
             && let Res::Local(id) = path.res
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && let Some(init) = get_vec_init_kind(cx, right)
             && !matches!(
                 init,
diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
index 42d9cf2c88c..5a25483c397 100644
--- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
@@ -5,7 +5,6 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::{Span, sym};
 
@@ -69,7 +68,7 @@ declare_clippy_lint! {
 declare_lint_pass!(ReturnSelfNotMustUse => [RETURN_SELF_NOT_MUST_USE]);
 
 fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, span: Span, owner_id: OwnerId) {
-    if !in_external_macro(cx.sess(), span)
+    if !span.in_external_macro(cx.sess().source_map())
         // If it comes from an external macro, better ignore it.
         && decl.implicit_self.has_implicit_self()
         // We only show this warning for public exported methods.
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 664e984fece..a1cf16e6ce9 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -17,7 +17,6 @@ use rustc_hir::{
     StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass, Level, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::{self, GenericArgKind, Ty};
 use rustc_session::declare_lint_pass;
@@ -191,7 +190,7 @@ fn stmt_needs_never_type(cx: &LateContext<'_>, stmt_hir_id: HirId) -> bool {
 
 impl<'tcx> LateLintPass<'tcx> for Return {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
-        if !in_external_macro(cx.sess(), stmt.span)
+        if !stmt.span.in_external_macro(cx.sess().source_map())
             && let StmtKind::Semi(expr) = stmt.kind
             && let ExprKind::Ret(Some(ret)) = expr.kind
             // return Err(...)? desugars to a match
@@ -237,8 +236,8 @@ impl<'tcx> LateLintPass<'tcx> for Return {
             && let PatKind::Binding(_, local_id, _, _) = local.pat.kind
             && path_to_local_id(retexpr, local_id)
             && !last_statement_borrows(cx, initexpr)
-            && !in_external_macro(cx.sess(), initexpr.span)
-            && !in_external_macro(cx.sess(), retexpr.span)
+            && !initexpr.span.in_external_macro(cx.sess().source_map())
+            && !retexpr.span.in_external_macro(cx.sess().source_map())
             && !local.span.from_expansion()
             && !span_contains_cfg(cx, stmt.span.between(retexpr.span))
         {
diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
index 0176077c70e..fdbccbaa8a5 100644
--- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
@@ -6,7 +6,6 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{Expr, ExprKind, HirId, Node};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 
@@ -88,7 +87,7 @@ impl SingleCallFn {
         fn_span: Span,
     ) -> bool {
         (self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(fn_def_id))
-            || in_external_macro(cx.sess(), fn_span)
+            || fn_span.in_external_macro(cx.sess().source_map())
             || cx
                 .tcx
                 .hir()
diff --git a/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs b/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs
index d92b890950a..50a6ee316c8 100644
--- a/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs
+++ b/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_ast::ast::{GenericParam, GenericParamKind};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -42,7 +41,7 @@ declare_lint_pass!(SingleCharLifetimeNames => [SINGLE_CHAR_LIFETIME_NAMES]);
 
 impl EarlyLintPass for SingleCharLifetimeNames {
     fn check_generic_param(&mut self, ctx: &EarlyContext<'_>, param: &GenericParam) {
-        if in_external_macro(ctx.sess(), param.ident.span) {
+        if param.ident.span.in_external_macro(ctx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index 8ec7bfe9edd..59c13a1e2c5 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -8,7 +8,6 @@ use rustc_hir::def::Res;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{HirId, Path, PathSegment};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::kw;
 use rustc_span::{Span, sym};
@@ -112,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
         if let Res::Def(_, def_id) = path.res
             && let Some(first_segment) = get_first_segment(path)
             && is_stable(cx, def_id, &self.msrv)
-            && !in_external_macro(cx.sess(), path.span)
+            && !path.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, &first_segment.ident)
         {
             let (lint, used_mod, replace_with) = match first_segment.ident.name {
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index 2925f355d0b..6164a6191db 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -9,7 +9,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, LangItem, Node, QPath};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
@@ -147,7 +146,7 @@ declare_lint_pass!(StringAdd => [STRING_ADD, STRING_ADD_ASSIGN, STRING_SLICE]);
 
 impl<'tcx> LateLintPass<'tcx> for StringAdd {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
-        if in_external_macro(cx.sess(), e.span) {
+        if e.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         match e.kind {
@@ -284,7 +283,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
             );
         }
 
-        if !in_external_macro(cx.sess(), e.span)
+        if !e.span.in_external_macro(cx.sess().source_map())
             && let ExprKind::MethodCall(path, receiver, ..) = &e.kind
             && path.ident.name.as_str() == "as_bytes"
             && let ExprKind::Lit(lit) = &receiver.kind
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs b/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs
index d1d822a5532..e55d17818e4 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs
@@ -5,7 +5,6 @@ use rustc_ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -32,7 +31,7 @@ declare_lint_pass!(ConfusingXorAndPow => [SUSPICIOUS_XOR_USED_AS_POW]);
 
 impl LateLintPass<'_> for ConfusingXorAndPow {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
-        if !in_external_macro(cx.sess(), expr.span)
+        if !expr.span.in_external_macro(cx.sess().source_map())
             && let ExprKind::Binary(op, left, right) = &expr.kind
             && op.node == BinOpKind::BitXor
             && left.span.eq_ctxt(right.span)
diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs
index 9b4c3d275ae..7176d533b61 100644
--- a/src/tools/clippy/clippy_lints/src/swap.rs
+++ b/src/tools/clippy/clippy_lints/src/swap.rs
@@ -12,7 +12,6 @@ use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Block, Expr, ExprKind, LetStmt, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
@@ -212,7 +211,7 @@ fn check_suspicious_swap(cx: &LateContext<'_>, block: &Block<'_>) {
         if let Some((lhs0, rhs0)) = parse(first)
             && let Some((lhs1, rhs1)) = parse(second)
             && first.span.eq_ctxt(second.span)
-			&& !in_external_macro(cx.sess(), first.span)
+			&& !first.span.in_external_macro(cx.sess().source_map())
             && is_same(cx, lhs0, rhs1)
             && is_same(cx, lhs1, rhs0)
 			&& !is_same(cx, lhs1, rhs1) // Ignore a = b; a = a (#10421)
diff --git a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
index bed4e60ba62..4961dd6b280 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use rustc_errors::Applicability;
 use rustc_hir::{GenericArg, HirId, LetStmt, Node, Path, TyKind};
 use rustc_lint::LateContext;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::Ty;
 
 use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS;
@@ -44,7 +43,7 @@ pub(super) fn check<'tcx>(
     expr_hir_id: HirId,
 ) -> bool {
     let last = path.segments.last().unwrap();
-    if in_external_macro(cx.tcx.sess, last.ident.span) {
+    if last.ident.span.in_external_macro(cx.tcx.sess.source_map()) {
         // If it comes from a non-local macro, we ignore it.
         return false;
     }
diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
index 008e09dd8bd..c7aefc65f70 100644
--- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
@@ -7,7 +7,6 @@ use itertools::Itertools;
 use rustc_ast::LitKind;
 use rustc_hir::{Expr, ExprKind, Node, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
 use std::iter::once;
@@ -56,7 +55,7 @@ impl TupleArrayConversions {
 
 impl LateLintPass<'_> for TupleArrayConversions {
     fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        if in_external_macro(cx.sess(), expr.span) || !self.msrv.meets(msrvs::TUPLE_ARRAY_CONVERSIONS) {
+        if expr.span.in_external_macro(cx.sess().source_map()) || !self.msrv.meets(msrvs::TUPLE_ARRAY_CONVERSIONS) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
index 45d730985bb..5e5d6a9e333 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -11,7 +11,6 @@ use rustc_hir as hir;
 use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource};
 use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{BytePos, Pos, RelativeBytePos, Span, SyntaxContext};
 
@@ -111,7 +110,7 @@ impl_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS, UNNECES
 impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
         if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
-            && !in_external_macro(cx.tcx.sess, block.span)
+            && !block.span.in_external_macro(cx.tcx.sess.source_map())
             && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id)
             && !is_unsafe_from_proc_macro(cx, block.span)
             && !block_has_safety_comment(cx, block.span)
@@ -143,7 +142,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
 
         if let Some(tail) = block.expr
             && !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, tail.hir_id)
-            && !in_external_macro(cx.tcx.sess, tail.span)
+            && !tail.span.in_external_macro(cx.tcx.sess.source_map())
             && let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, tail.span, tail.hir_id)
             && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, tail, pos)
         {
@@ -167,7 +166,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
             return;
         };
         if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, stmt.hir_id)
-            && !in_external_macro(cx.tcx.sess, stmt.span)
+            && !stmt.span.in_external_macro(cx.tcx.sess.source_map())
             && let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, stmt.span, stmt.hir_id)
             && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, expr, pos)
         {
@@ -184,7 +183,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
     }
 
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
-        if in_external_macro(cx.tcx.sess, item.span) {
+        if item.span.in_external_macro(cx.tcx.sess.source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/uninhabited_references.rs b/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
index ee9ef017253..b342f37f0c5 100644
--- a/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
+++ b/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
@@ -3,7 +3,6 @@ use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind, UnOp};
 use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
@@ -40,7 +39,7 @@ declare_lint_pass!(UninhabitedReferences => [UNINHABITED_REFERENCES]);
 
 impl LateLintPass<'_> for UninhabitedReferences {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
-        if in_external_macro(cx.tcx.sess, expr.span) {
+        if expr.span.in_external_macro(cx.tcx.sess.source_map()) {
             return;
         }
 
@@ -66,7 +65,7 @@ impl LateLintPass<'_> for UninhabitedReferences {
         span: Span,
         _: LocalDefId,
     ) {
-        if in_external_macro(cx.tcx.sess, span) || matches!(kind, FnKind::Closure) {
+        if span.in_external_macro(cx.tcx.sess.source_map()) || matches!(kind, FnKind::Closure) {
             return;
         }
         if let FnRetTy::Return(hir_ty) = fndecl.output
diff --git a/src/tools/clippy/clippy_lints/src/uninit_vec.rs b/src/tools/clippy/clippy_lints/src/uninit_vec.rs
index 93ed15777e0..7803d5115c9 100644
--- a/src/tools/clippy/clippy_lints/src/uninit_vec.rs
+++ b/src/tools/clippy/clippy_lints/src/uninit_vec.rs
@@ -4,7 +4,6 @@ use clippy_utils::ty::{is_type_diagnostic_item, is_uninit_value_valid_for_ty};
 use clippy_utils::{SpanlessEq, is_integer_literal, is_lint_allowed, path_to_local_id, peel_hir_expr_while};
 use rustc_hir::{Block, Expr, ExprKind, HirId, PatKind, PathSegment, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::{Span, sym};
@@ -64,7 +63,7 @@ declare_lint_pass!(UninitVec => [UNINIT_VEC]);
 // Threads: https://github.com/rust-lang/rust-clippy/pull/7682#discussion_r710998368
 impl<'tcx> LateLintPass<'tcx> for UninitVec {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {
-        if !in_external_macro(cx.tcx.sess, block.span) {
+        if !block.span.in_external_macro(cx.tcx.sess.source_map()) {
             for w in block.stmts.windows(2) {
                 if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = w[1].kind {
                     handle_uninit_vec_pair(cx, &w[0], expr);
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
index 660bdb9e2be..00b80e827d8 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
@@ -7,7 +7,6 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{Visitor, walk_body};
 use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, LetStmt, MatchSource, Node, PatKind, QPath, TyKind};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::{in_external_macro, is_from_async_await};
 use rustc_middle::ty;
 
 use super::LET_UNIT_VALUE;
@@ -22,8 +21,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
 
     if let Some(init) = local.init
         && !local.pat.span.from_expansion()
-        && !in_external_macro(cx.sess(), local.span)
-        && !is_from_async_await(local.span)
+        && !local.span.in_external_macro(cx.sess().source_map())
+        && !local.span.is_from_async_await()
         && cx.typeck_results().pat_ty(local.pat).is_unit()
     {
         // skip `let awa = ()`
diff --git a/src/tools/clippy/clippy_lints/src/unused_result_ok.rs b/src/tools/clippy/clippy_lints/src/unused_result_ok.rs
index 0c0d10eac5b..958f19d1833 100644
--- a/src/tools/clippy/clippy_lints/src/unused_result_ok.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_result_ok.rs
@@ -4,7 +4,6 @@ use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_errors::Applicability;
 use rustc_hir::{ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
 
@@ -39,7 +38,7 @@ impl LateLintPass<'_> for UnusedResultOk {
             && let ExprKind::MethodCall(ok_path, recv, [], ..) = expr.kind //check is expr.ok() has type Result<T,E>.ok(, _)
             && ok_path.ident.as_str() == "ok"
             && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result)
-            && !in_external_macro(cx.sess(), stmt.span)
+            && !stmt.span.in_external_macro(cx.sess().source_map())
         {
             let ctxt = expr.span.ctxt();
             let mut applicability = Applicability::MaybeIncorrect;
diff --git a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
index 17ee5fc20ca..f8341583435 100644
--- a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Item, ItemKind, UseKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext as _};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::Visibility;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::kw;
@@ -63,7 +62,7 @@ impl_lint_pass!(UnusedTraitNames => [UNUSED_TRAIT_NAMES]);
 impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
         if self.msrv.meets(msrvs::UNDERSCORE_IMPORTS)
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && let ItemKind::Use(path, UseKind::Single) = item.kind
             // Ignore imports that already use Underscore
             && item.ident.name != kw::Underscore
diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs
index eaa119b045f..6a952c0d97a 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap.rs
@@ -8,7 +8,6 @@ use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, PathSegmen
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceWithHirId};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::declare_lint_pass;
@@ -292,7 +291,7 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> {
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         // Shouldn't lint when `expr` is in macro.
-        if in_external_macro(self.cx.tcx.sess, expr.span) {
+        if expr.span.in_external_macro(self.cx.tcx.sess.source_map()) {
             return;
         }
         if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr) {
diff --git a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
index c3843279ba2..3449468ef48 100644
--- a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
+++ b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
@@ -4,7 +4,6 @@ use core::mem::replace;
 use rustc_errors::Applicability;
 use rustc_hir::{HirId, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::Ident;
 
@@ -126,7 +125,7 @@ fn check_ident(cx: &LateContext<'_>, ident: &Ident, hir_id: HirId, be_aggressive
 impl LateLintPass<'_> for UpperCaseAcronyms {
     fn check_item(&mut self, cx: &LateContext<'_>, it: &Item<'_>) {
         // do not lint public items or in macros
-        if in_external_macro(cx.sess(), it.span)
+        if it.span.in_external_macro(cx.sess().source_map())
             || (self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(it.owner_id.def_id))
         {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
index d87d554eb07..3c23662e9d1 100644
--- a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
+++ b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
@@ -8,7 +8,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, Symbol};
 
@@ -158,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         if let Some(init_expr) = local.init
             && let PatKind::Binding(BindingMode::MUT, id, name, None) = local.pat.kind
-            && !in_external_macro(cx.sess(), local.span)
+            && !local.span.in_external_macro(cx.sess().source_map())
             && let Some(init) = get_vec_init_kind(cx, init_expr)
             && !matches!(init, VecInitKind::WithExprCapacity(_))
         {
@@ -181,7 +180,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
             && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind
             && let [name] = &path.segments
             && let Res::Local(id) = path.res
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && let Some(init) = get_vec_init_kind(cx, right)
             && !matches!(init, VecInitKind::WithExprCapacity(_))
         {
diff --git a/src/tools/clippy/clippy_lints/src/visibility.rs b/src/tools/clippy/clippy_lints/src/visibility.rs
index 2e5fc5834e2..d17b3df9921 100644
--- a/src/tools/clippy/clippy_lints/src/visibility.rs
+++ b/src/tools/clippy/clippy_lints/src/visibility.rs
@@ -3,7 +3,6 @@ use clippy_utils::source::SpanRangeExt;
 use rustc_ast::ast::{Item, VisibilityKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 use rustc_span::symbol::kw;
@@ -79,7 +78,7 @@ declare_lint_pass!(Visibility => [NEEDLESS_PUB_SELF, PUB_WITH_SHORTHAND, PUB_WIT
 
 impl EarlyLintPass for Visibility {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if !in_external_macro(cx.sess(), item.span)
+        if !item.span.in_external_macro(cx.sess().source_map())
             && let VisibilityKind::Restricted { path, shorthand, .. } = &item.vis.kind
         {
             if **path == kw::SelfLower && !is_from_proc_macro(cx, item.vis.span) {
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index 2eb09bac8d8..798f4575c2e 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -362,18 +362,21 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 defaultness: ld,
                 sig: lf,
                 generics: lg,
+                contract: lc,
                 body: lb,
             }),
             Fn(box ast::Fn {
                 defaultness: rd,
                 sig: rf,
                 generics: rg,
+                contract: rc,
                 body: rb,
             }),
         ) => {
             eq_defaultness(*ld, *rd)
                 && eq_fn_sig(lf, rf)
                 && eq_generics(lg, rg)
+                && eq_opt_fn_contract(lc, rc)
                 && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (Mod(lu, lmk), Mod(ru, rmk)) => {
@@ -497,18 +500,21 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
                 defaultness: ld,
                 sig: lf,
                 generics: lg,
+                contract: lc,
                 body: lb,
             }),
             Fn(box ast::Fn {
                 defaultness: rd,
                 sig: rf,
                 generics: rg,
+                contract: rc,
                 body: rb,
             }),
         ) => {
             eq_defaultness(*ld, *rd)
                 && eq_fn_sig(lf, rf)
                 && eq_generics(lg, rg)
+                && eq_opt_fn_contract(lc, rc)
                 && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (
@@ -559,18 +565,21 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
                 defaultness: ld,
                 sig: lf,
                 generics: lg,
+                contract: lc,
                 body: lb,
             }),
             Fn(box ast::Fn {
                 defaultness: rd,
                 sig: rf,
                 generics: rg,
+                contract: rc,
                 body: rb,
             }),
         ) => {
             eq_defaultness(*ld, *rd)
                 && eq_fn_sig(lf, rf)
                 && eq_generics(lg, rg)
+                && eq_opt_fn_contract(lc, rc)
                 && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (
@@ -653,6 +662,17 @@ pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool {
         && eq_ext(&l.ext, &r.ext)
 }
 
+pub fn eq_opt_fn_contract(l: &Option<P<FnContract>>, r: &Option<P<FnContract>>) -> bool {
+    match (l, r) {
+        (Some(l), Some(r)) => {
+            eq_expr_opt(l.requires.as_ref(), r.requires.as_ref())
+            && eq_expr_opt(l.ensures.as_ref(), r.ensures.as_ref())
+        }
+        (None, None) => true,
+        (Some(_), None) | (None, Some(_)) => false,
+    }
+}
+
 pub fn eq_generics(l: &Generics, r: &Generics) -> bool {
     over(&l.params, &r.params, eq_generic_param)
         && over(&l.where_clause.predicates, &r.where_clause.predicates, |l, r| {
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index d0eb5318e64..4bbf28115a6 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -10,7 +10,7 @@ use rustc_hir::{
     AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField,
     ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName,
     Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr,
-    TraitBoundModifiers, Ty, TyKind,
+    TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind,
 };
 use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::LateContext;
@@ -1102,6 +1102,22 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
         }
     }
 
+    pub fn hash_ty_pat(&mut self, pat: &TyPat<'_>) {
+        std::mem::discriminant(&pat.kind).hash(&mut self.s);
+        match pat.kind {
+            TyPatKind::Range(s, e, i) => {
+                if let Some(s) = s {
+                    self.hash_const_arg(s);
+                }
+                if let Some(e) = e {
+                    self.hash_const_arg(e);
+                }
+                std::mem::discriminant(&i).hash(&mut self.s);
+            },
+            TyPatKind::Err(_) => {},
+        }
+    }
+
     pub fn hash_pat(&mut self, pat: &Pat<'_>) {
         std::mem::discriminant(&pat.kind).hash(&mut self.s);
         match pat.kind {
@@ -1247,7 +1263,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
             },
             TyKind::Pat(ty, pat) => {
                 self.hash_ty(ty);
-                self.hash_pat(pat);
+                self.hash_ty_pat(pat);
             },
             TyKind::Ptr(mut_ty) => {
                 self.hash_ty(mut_ty.ty);
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 287bdc9a6fd..5a3a3d0cedc 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
@@ -116,6 +116,7 @@ fn check_rvalue<'tcx>(
         Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
         Rvalue::Repeat(operand, _)
         | Rvalue::Use(operand)
+        | Rvalue::WrapUnsafeBinder(operand, _)
         | Rvalue::Cast(
             CastKind::PointerWithExposedProvenance
             | CastKind::IntToInt
@@ -178,7 +179,7 @@ fn check_rvalue<'tcx>(
                 ))
             }
         },
-        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks, _)
+        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks, _)
         | Rvalue::ShallowInitBox(_, _) => Ok(()),
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(body, tcx);
@@ -289,7 +290,8 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B
             | ProjectionElem::Downcast(..)
             | ProjectionElem::Subslice { .. }
             | ProjectionElem::Subtype(_)
-            | ProjectionElem::Index(_) => {},
+            | ProjectionElem::Index(_)
+            | ProjectionElem::UnwrapUnsafeBinder(_) => {},
         }
     }
 
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index c548f262a92..e4092bcd105 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -197,7 +197,7 @@ pub fn main() {
     });
 
     exit(rustc_driver::catch_with_exit_code(move || {
-        let mut orig_args = rustc_driver::args::raw_args(&early_dcx)?;
+        let mut orig_args = rustc_driver::args::raw_args(&early_dcx);
 
         let has_sysroot_arg = |args: &mut [String]| -> bool {
             if has_arg(args, "--sysroot") {
@@ -239,7 +239,7 @@ pub fn main() {
             pass_sysroot_env_if_given(&mut args, sys_root_env);
 
             rustc_driver::run_compiler(&args, &mut DefaultCallbacks);
-            return Ok(());
+            return;
         }
 
         if orig_args.iter().any(|a| a == "--version" || a == "-V") {
@@ -301,7 +301,6 @@ pub fn main() {
         } else {
             rustc_driver::run_compiler(&args, &mut RustcCallbacks { clippy_args_var });
         }
-        Ok(())
     }))
 }
 
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs
index 71496444660..a7ac875d0a3 100644
--- a/src/tools/compiletest/src/directive-list.rs
+++ b/src/tools/compiletest/src/directive-list.rs
@@ -39,6 +39,10 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "ignore-android",
     "ignore-apple",
     "ignore-arm",
+    "ignore-arm-unknown-linux-gnueabi",
+    "ignore-arm-unknown-linux-gnueabihf",
+    "ignore-arm-unknown-linux-musleabi",
+    "ignore-arm-unknown-linux-musleabihf",
     "ignore-avr",
     "ignore-beta",
     "ignore-cdb",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 8c96554738e..452a2e9a9d5 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -882,14 +882,6 @@ fn iter_header(
         }
         let ln = ln.trim();
 
-        // Assume that any directives will be found before the first module or function. This
-        // doesn't seem to be an optimization with a warm page cache. Maybe with a cold one.
-        // FIXME(jieyouxu): this will cause `//@` directives in the rest of the test file to
-        // not be checked.
-        if ln.starts_with("fn") || ln.starts_with("mod") {
-            return;
-        }
-
         let Some(directive_line) = line_directive(line_number, comment, ln) else {
             continue;
         };
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index ca48abda5fc..0e2da2b02ca 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1417,9 +1417,7 @@ impl<'test> TestCx<'test> {
     }
 
     fn is_rustdoc(&self) -> bool {
-        self.config.src_base.ends_with("rustdoc-ui")
-            || self.config.src_base.ends_with("rustdoc-js")
-            || self.config.src_base.ends_with("rustdoc-json")
+        matches!(self.config.suite.as_str(), "rustdoc-ui" | "rustdoc-js" | "rustdoc-json")
     }
 
     fn get_mir_dump_dir(&self) -> PathBuf {
diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs
index 31fdb0a5d13..bf7eb2e109a 100644
--- a/src/tools/compiletest/src/runtest/rustdoc_json.rs
+++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs
@@ -16,13 +16,12 @@ impl TestCx<'_> {
             self.fatal_proc_rec("rustdoc failed!", &proc_res);
         }
 
-        let root = self.config.find_rust_src_root().unwrap();
         let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap());
         json_out.set_extension("json");
         let res = self.run_command_to_procres(
             Command::new(self.config.jsondocck_path.as_ref().unwrap())
                 .arg("--doc-dir")
-                .arg(root.join(&out_dir))
+                .arg(&out_dir)
                 .arg("--template")
                 .arg(&self.testpaths.file),
         );
diff --git a/src/tools/features-status-dump/Cargo.toml b/src/tools/features-status-dump/Cargo.toml
new file mode 100644
index 00000000000..35be71a46e5
--- /dev/null
+++ b/src/tools/features-status-dump/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "features-status-dump"
+version = "0.1.0"
+license = "MIT OR Apache-2.0"
+edition = "2021"
+
+[dependencies]
+anyhow = { version = "1", features = ["backtrace"] }
+clap = { version = "4", features = ["derive"] }
+serde = { version = "1.0.125", features = [ "derive" ] }
+serde_json = "1.0.59"
+tidy = { path = "../tidy", features = ["build-metrics"] }
diff --git a/src/tools/features-status-dump/src/main.rs b/src/tools/features-status-dump/src/main.rs
new file mode 100644
index 00000000000..1ce98d1506d
--- /dev/null
+++ b/src/tools/features-status-dump/src/main.rs
@@ -0,0 +1,53 @@
+use std::collections::HashMap;
+use std::fs::File;
+use std::io::BufWriter;
+use std::path::PathBuf;
+
+use anyhow::{Context, Result};
+use clap::Parser;
+use tidy::features::{Feature, collect_lang_features, collect_lib_features};
+
+#[derive(Debug, Parser)]
+struct Cli {
+    /// Path to `library/` directory.
+    #[arg(long)]
+    library_path: PathBuf,
+    /// Path to `compiler/` directory.
+    #[arg(long)]
+    compiler_path: PathBuf,
+    /// Path to `output/` directory.
+    #[arg(long)]
+    output_path: PathBuf,
+}
+
+#[derive(Debug, serde::Serialize)]
+struct FeaturesStatus {
+    lang_features_status: HashMap<String, Feature>,
+    lib_features_status: HashMap<String, Feature>,
+}
+
+fn main() -> Result<()> {
+    let Cli { compiler_path, library_path, output_path } = Cli::parse();
+
+    let lang_features_status = collect_lang_features(&compiler_path, &mut false);
+    let lib_features_status = collect_lib_features(&library_path)
+        .into_iter()
+        .filter(|&(ref name, _)| !lang_features_status.contains_key(name))
+        .collect();
+    let features_status = FeaturesStatus { lang_features_status, lib_features_status };
+
+    let output_dir = output_path.parent().with_context(|| {
+        format!("failed to get parent dir of output path `{}`", output_path.display())
+    })?;
+    std::fs::create_dir_all(output_dir).with_context(|| {
+        format!("failed to create output directory at `{}`", output_dir.display())
+    })?;
+
+    let output_file = File::create(&output_path).with_context(|| {
+        format!("failed to create file at given output path `{}`", output_path.display())
+    })?;
+    let writer = BufWriter::new(output_file);
+    serde_json::to_writer_pretty(writer, &features_status)
+        .context("failed to write json output")?;
+    Ok(())
+}
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 363b96fdff1..57a757f9085 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -351,7 +351,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
 dependencies = [
  "cfg-if",
  "libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.13.3+wasi-0.2.2",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -529,12 +541,12 @@ dependencies = [
  "chrono-tz",
  "colored",
  "directories",
- "getrandom",
+ "getrandom 0.3.1",
  "libc",
  "libffi",
  "libloading",
  "measureme",
- "rand",
+ "rand 0.9.0",
  "regex",
  "rustc_version",
  "smallvec",
@@ -662,7 +674,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
 dependencies = [
  "phf_shared",
- "rand",
+ "rand 0.8.5",
 ]
 
 [[package]]
@@ -692,7 +704,7 @@ version = "0.2.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
 dependencies = [
- "zerocopy",
+ "zerocopy 0.7.35",
 ]
 
 [[package]]
@@ -729,19 +741,28 @@ version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 dependencies = [
- "libc",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
+dependencies = [
  "rand_chacha",
- "rand_core",
+ "rand_core 0.9.0",
+ "zerocopy 0.8.14",
 ]
 
 [[package]]
 name = "rand_chacha"
-version = "0.3.1"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
 dependencies = [
  "ppv-lite86",
- "rand_core",
+ "rand_core 0.9.0",
 ]
 
 [[package]]
@@ -749,8 +770,15 @@ name = "rand_core"
 version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+
+[[package]]
+name = "rand_core"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
 dependencies = [
- "getrandom",
+ "getrandom 0.3.1",
+ "zerocopy 0.8.14",
 ]
 
 [[package]]
@@ -768,7 +796,7 @@ version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
 dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
  "libredox",
  "thiserror",
 ]
@@ -1051,9 +1079,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
 
 [[package]]
 name = "ui_test"
-version = "0.26.5"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32ee4c40e5a5f9fa6864ff976473e5d6a6e9884b6ce68b40690d9f87e1994c83"
+checksum = "7484683d60d50ca1d1b6433c3dbf6c5ad71d20387acdcfb16fe79573f3fba576"
 dependencies = [
  "annotate-snippets",
  "anyhow",
@@ -1106,6 +1134,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
+name = "wasi"
+version = "0.13.3+wasi-0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
+[[package]]
 name = "windows-sys"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1245,13 +1282,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
+name = "wit-bindgen-rt"
+version = "0.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
 name = "zerocopy"
 version = "0.7.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
 dependencies = [
  "byteorder",
- "zerocopy-derive",
+ "zerocopy-derive 0.7.35",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.8.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468"
+dependencies = [
+ "zerocopy-derive 0.8.14",
 ]
 
 [[package]]
@@ -1264,3 +1319,14 @@ dependencies = [
  "quote",
  "syn",
 ]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index 6e8e270985e..de80722fc3d 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -18,8 +18,8 @@ test = false    # we have no unit tests
 doctest = false # and no doc tests
 
 [dependencies]
-getrandom = { version = "0.2", features = ["std"] }
-rand = "0.8"
+getrandom = { version = "0.3", features = ["std"] }
+rand = "0.9"
 smallvec = { version = "1.7", features = ["drain_filter"] }
 aes = { version = "0.8.3", features = ["hazmat"] }
 measureme = "11"
@@ -47,8 +47,8 @@ windows-sys = { version = "0.52", features = [
 ] }
 
 [dev-dependencies]
+ui_test = "0.28.0"
 colored = "2"
-ui_test = "0.26.5"
 rustc_version = "0.4"
 regex = "1.5.5"
 tempfile = "3"
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index fb3fc621565..5583030b490 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -14,9 +14,7 @@ function endgroup {
 begingroup "Building Miri"
 
 # Global configuration
-# We are getting some odd linker warnings on macOS, make sure they do not fail the build.
-# (See <https://github.com/rust-lang/rust/issues/136086>.)
-export RUSTFLAGS="-D warnings -A linker-messages"
+export RUSTFLAGS="-D warnings"
 export CARGO_INCREMENTAL=0
 export CARGO_EXTRA_FLAGS="--locked"
 
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 0d405f532fc..6e84524c8aa 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-2f0ad2a71e4a4528bb80bcb24bf8fa4e50cb87c2
+6dd75f0d6802f56564f5f9c947a85ded286d3986
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index 3d0fc5590eb..a4f2a117b18 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -217,7 +217,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // We have to pick a fresh address.
             // Leave some space to the previous allocation, to give it some chance to be less aligned.
             // We ensure that `(global_state.next_base_addr + slack) % 16` is uniformly distributed.
-            let slack = rng.gen_range(0..16);
+            let slack = rng.random_range(0..16);
             // From next_base_addr + slack, round up to adjust for alignment.
             let base_addr = global_state
                 .next_base_addr
diff --git a/src/tools/miri/src/alloc_addresses/reuse_pool.rs b/src/tools/miri/src/alloc_addresses/reuse_pool.rs
index b0c7ee7dff5..c0d24a9fbbc 100644
--- a/src/tools/miri/src/alloc_addresses/reuse_pool.rs
+++ b/src/tools/miri/src/alloc_addresses/reuse_pool.rs
@@ -58,7 +58,7 @@ impl ReusePool {
         // We don't remember stack addresses: there's a lot of them (so the perf impact is big),
         // and we only want to reuse stack slots within the same thread or else we'll add a lot of
         // undesired synchronization.
-        if kind == MemoryKind::Stack || !rng.gen_bool(self.address_reuse_rate) {
+        if kind == MemoryKind::Stack || !rng.random_bool(self.address_reuse_rate) {
             return;
         }
         let clock = clock();
@@ -88,10 +88,10 @@ impl ReusePool {
         thread: ThreadId,
     ) -> Option<(u64, Option<VClock>)> {
         // Determine whether we'll even attempt a reuse. As above, we don't do reuse for stack addresses.
-        if kind == MemoryKind::Stack || !rng.gen_bool(self.address_reuse_rate) {
+        if kind == MemoryKind::Stack || !rng.random_bool(self.address_reuse_rate) {
             return None;
         }
-        let cross_thread_reuse = rng.gen_bool(self.address_reuse_cross_thread_rate);
+        let cross_thread_reuse = rng.random_bool(self.address_reuse_cross_thread_rate);
         // Determine the pool to take this from.
         let subpool = self.subpool(align);
         // Let's see if we can find something of the right size. We want to find the full range of
@@ -118,7 +118,7 @@ impl ReusePool {
             return None;
         }
         // Pick a random element with the desired size.
-        let idx = rng.gen_range(begin..end);
+        let idx = rng.random_range(begin..end);
         // Remove it from the pool and return.
         let (chosen_addr, chosen_size, chosen_thread, clock) = subpool.remove(idx);
         debug_assert!(chosen_size >= size && chosen_addr % align.bytes() == 0);
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 988a0be6327..685f5670ab4 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -379,10 +379,8 @@ fn run_compiler_and_exit(
     callbacks: &mut (dyn rustc_driver::Callbacks + Send),
 ) -> ! {
     // Invoke compiler, and handle return code.
-    let exit_code = rustc_driver::catch_with_exit_code(move || {
-        rustc_driver::run_compiler(args, callbacks);
-        Ok(())
-    });
+    let exit_code =
+        rustc_driver::catch_with_exit_code(move || rustc_driver::run_compiler(args, callbacks));
     std::process::exit(exit_code)
 }
 
@@ -461,7 +459,7 @@ fn main() {
     // (`install_ice_hook` might change `RUST_BACKTRACE`.)
     let env_snapshot = env::vars_os().collect::<Vec<_>>();
 
-    let args = rustc_driver::args::raw_args(&early_dcx)
+    let args = rustc_driver::catch_fatal_errors(|| rustc_driver::args::raw_args(&early_dcx))
         .unwrap_or_else(|_| std::process::exit(rustc_driver::EXIT_FAILURE));
 
     // Install the ctrlc handler that sets `rustc_const_eval::CTRL_C_RECEIVED`, even if
@@ -723,8 +721,8 @@ fn main() {
 
     // Ensure we have parallelism for many-seeds mode.
     if many_seeds.is_some() && !rustc_args.iter().any(|arg| arg.starts_with("-Zthreads=")) {
-        // Clamp to 8 threads; things get a lot less efficient beyond that due to lock contention.
-        let threads = std::thread::available_parallelism().map_or(1, |n| n.get()).min(8);
+        // Clamp to 10 threads; things get a lot less efficient beyond that due to lock contention.
+        let threads = std::thread::available_parallelism().map_or(1, |n| n.get()).min(10);
         rustc_args.push(format!("-Zthreads={threads}"));
     }
     let many_seeds =
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index bcc8668dbc1..18a5a0612bb 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -865,7 +865,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let this = self.eval_context_mut();
         let new_perm = NewPermission::from_ref_ty(val.layout.ty, kind, this);
         let cause = match kind {
-            RetagKind::TwoPhase { .. } => RetagCause::TwoPhase,
+            RetagKind::TwoPhase => RetagCause::TwoPhase,
             RetagKind::FnEntry => unreachable!(),
             RetagKind::Raw | RetagKind::Default => RetagCause::Normal,
         };
@@ -880,7 +880,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let this = self.eval_context_mut();
         let retag_fields = this.machine.borrow_tracker.as_mut().unwrap().get_mut().retag_fields;
         let retag_cause = match kind {
-            RetagKind::TwoPhase { .. } => unreachable!(), // can only happen in `retag_ptr_value`
+            RetagKind::TwoPhase => unreachable!(), // can only happen in `retag_ptr_value`
             RetagKind::FnEntry => RetagCause::FnEntry,
             RetagKind::Default | RetagKind::Raw => RetagCause::Normal,
         };
@@ -904,10 +904,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 new_perm: NewPermission,
             ) -> InterpResult<'tcx> {
                 let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?;
-                let val = self.ecx.sb_retag_reference(&val, new_perm, RetagInfo {
-                    cause: self.retag_cause,
-                    in_field: self.in_field,
-                })?;
+                let val = self.ecx.sb_retag_reference(
+                    &val,
+                    new_perm,
+                    RetagInfo { cause: self.retag_cause, in_field: self.in_field },
+                )?;
                 self.ecx.write_immediate(*val, place)?;
                 interp_ok(())
             }
@@ -996,10 +997,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             access: Some(AccessKind::Write),
             protector: Some(ProtectorKind::StrongProtector),
         };
-        this.sb_retag_place(place, new_perm, RetagInfo {
-            cause: RetagCause::InPlaceFnPassing,
-            in_field: false,
-        })
+        this.sb_retag_place(
+            place,
+            new_perm,
+            RetagInfo { cause: RetagCause::InPlaceFnPassing, in_field: false },
+        )
     }
 
     /// Mark the given tag as exposed. It was found on a pointer with the given AllocId.
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
index 5d7c3d8c219..5c12ce39d10 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
@@ -379,14 +379,18 @@ pub mod diagnostics {
     use super::*;
     impl fmt::Display for PermissionPriv {
         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            write!(f, "{}", match self {
-                ReservedFrz { conflicted: false } => "Reserved",
-                ReservedFrz { conflicted: true } => "Reserved (conflicted)",
-                ReservedIM => "Reserved (interior mutable)",
-                Active => "Active",
-                Frozen => "Frozen",
-                Disabled => "Disabled",
-            })
+            write!(
+                f,
+                "{}",
+                match self {
+                    ReservedFrz { conflicted: false } => "Reserved",
+                    ReservedFrz { conflicted: true } => "Reserved (conflicted)",
+                    ReservedIM => "Reserved (interior mutable)",
+                    Active => "Active",
+                    Frozen => "Frozen",
+                    Disabled => "Disabled",
+                }
+            )
         }
     }
 
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
index fd69278f20a..3389b1c602c 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
@@ -581,15 +581,18 @@ impl Tree {
             let mut debug_info = NodeDebugInfo::new(root_tag, root_default_perm, span);
             // name the root so that all allocations contain one named pointer
             debug_info.add_name("root of the allocation");
-            nodes.insert(root_idx, Node {
-                tag: root_tag,
-                parent: None,
-                children: SmallVec::default(),
-                default_initial_perm: root_default_perm,
-                // The root may never be skipped, all accesses will be local.
-                default_initial_idempotent_foreign_access: IdempotentForeignAccess::None,
-                debug_info,
-            });
+            nodes.insert(
+                root_idx,
+                Node {
+                    tag: root_tag,
+                    parent: None,
+                    children: SmallVec::default(),
+                    default_initial_perm: root_default_perm,
+                    // The root may never be skipped, all accesses will be local.
+                    default_initial_idempotent_foreign_access: IdempotentForeignAccess::None,
+                    debug_info,
+                },
+            );
             nodes
         };
         let rperms = {
@@ -624,14 +627,17 @@ impl<'tcx> Tree {
         let parent_idx = self.tag_mapping.get(&parent_tag).unwrap();
         let strongest_idempotent = default_initial_perm.strongest_idempotent_foreign_access(prot);
         // Create the node
-        self.nodes.insert(idx, Node {
-            tag: new_tag,
-            parent: Some(parent_idx),
-            children: SmallVec::default(),
-            default_initial_perm,
-            default_initial_idempotent_foreign_access: strongest_idempotent,
-            debug_info: NodeDebugInfo::new(new_tag, default_initial_perm, span),
-        });
+        self.nodes.insert(
+            idx,
+            Node {
+                tag: new_tag,
+                parent: Some(parent_idx),
+                children: SmallVec::default(),
+                default_initial_perm,
+                default_initial_idempotent_foreign_access: strongest_idempotent,
+                debug_info: NodeDebugInfo::new(new_tag, default_initial_perm, span),
+            },
+        );
         // Register new_tag as a child of parent_tag
         self.nodes.get_mut(parent_idx).unwrap().children.push(idx);
         // Initialize perms
diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs
index 4cdc9348dc9..b1ca434361b 100644
--- a/src/tools/miri/src/concurrency/data_race.rs
+++ b/src/tools/miri/src/concurrency/data_race.rs
@@ -830,7 +830,7 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
         let success_rate = 1.0 - this.machine.cmpxchg_weak_failure_rate;
         let cmpxchg_success = eq.to_scalar().to_bool()?
             && if can_fail_spuriously {
-                this.machine.rng.get_mut().gen_bool(success_rate)
+                this.machine.rng.get_mut().random_bool(success_rate)
             } else {
                 true
             };
diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs
index 14c72e9398a..268268848ed 100644
--- a/src/tools/miri/src/concurrency/sync.rs
+++ b/src/tools/miri/src/concurrency/sync.rs
@@ -128,7 +128,7 @@ struct Condvar {
 /// The futex state.
 #[derive(Default, Debug)]
 struct Futex {
-    waiters: VecDeque<FutexWaiter>,
+    waiters: Vec<FutexWaiter>,
     /// Tracks the happens-before relationship
     /// between a futex-wake and a futex-wait
     /// during a non-spurious wake event.
@@ -140,6 +140,12 @@ struct Futex {
 #[derive(Default, Clone)]
 pub struct FutexRef(Rc<RefCell<Futex>>);
 
+impl FutexRef {
+    pub fn waiters(&self) -> usize {
+        self.0.borrow().waiters.len()
+    }
+}
+
 impl VisitProvenance for FutexRef {
     fn visit_provenance(&self, _visit: &mut VisitWith<'_>) {
         // No provenance in `Futex`.
@@ -728,25 +734,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         interp_ok(true)
     }
 
-    /// Wait for the futex to be signaled, or a timeout.
-    /// On a signal, `retval_succ` is written to `dest`.
-    /// On a timeout, `retval_timeout` is written to `dest` and `errno_timeout` is set as the last error.
+    /// Wait for the futex to be signaled, or a timeout. Once the thread is
+    /// unblocked, `callback` is called with the unblock reason.
     fn futex_wait(
         &mut self,
         futex_ref: FutexRef,
         bitset: u32,
         timeout: Option<(TimeoutClock, TimeoutAnchor, Duration)>,
-        retval_succ: Scalar,
-        retval_timeout: Scalar,
-        dest: MPlaceTy<'tcx>,
-        errno_timeout: IoError,
+        callback: DynUnblockCallback<'tcx>,
     ) {
         let this = self.eval_context_mut();
         let thread = this.active_thread();
         let mut futex = futex_ref.0.borrow_mut();
         let waiters = &mut futex.waiters;
         assert!(waiters.iter().all(|waiter| waiter.thread != thread), "thread is already waiting");
-        waiters.push_back(FutexWaiter { thread, bitset });
+        waiters.push(FutexWaiter { thread, bitset });
         drop(futex);
 
         this.block_thread(
@@ -755,10 +757,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             callback!(
                 @capture<'tcx> {
                     futex_ref: FutexRef,
-                    retval_succ: Scalar,
-                    retval_timeout: Scalar,
-                    dest: MPlaceTy<'tcx>,
-                    errno_timeout: IoError,
+                    callback: DynUnblockCallback<'tcx>,
                 }
                 |this, unblock: UnblockKind| {
                     match unblock {
@@ -768,29 +767,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                             if let Some(data_race) = &this.machine.data_race {
                                 data_race.acquire_clock(&futex.clock, &this.machine.threads);
                             }
-                            // Write the return value.
-                            this.write_scalar(retval_succ, &dest)?;
-                            interp_ok(())
                         },
                         UnblockKind::TimedOut => {
                             // Remove the waiter from the futex.
                             let thread = this.active_thread();
                             let mut futex = futex_ref.0.borrow_mut();
                             futex.waiters.retain(|waiter| waiter.thread != thread);
-                            // Set errno and write return value.
-                            this.set_last_error(errno_timeout)?;
-                            this.write_scalar(retval_timeout, &dest)?;
-                            interp_ok(())
                         },
                     }
+
+                    callback.call(this, unblock)
                 }
             ),
         );
     }
 
-    /// Wake up the first thread in the queue that matches any of the bits in the bitset.
-    /// Returns whether anything was woken.
-    fn futex_wake(&mut self, futex_ref: &FutexRef, bitset: u32) -> InterpResult<'tcx, bool> {
+    /// Wake up `count` of the threads in the queue that match any of the bits
+    /// in the bitset. Returns how many threads were woken.
+    fn futex_wake(
+        &mut self,
+        futex_ref: &FutexRef,
+        bitset: u32,
+        count: usize,
+    ) -> InterpResult<'tcx, usize> {
         let this = self.eval_context_mut();
         let mut futex = futex_ref.0.borrow_mut();
         let data_race = &this.machine.data_race;
@@ -800,13 +799,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             data_race.release_clock(&this.machine.threads, |clock| futex.clock.clone_from(clock));
         }
 
-        // Wake up the first thread in the queue that matches any of the bits in the bitset.
-        let Some(i) = futex.waiters.iter().position(|w| w.bitset & bitset != 0) else {
-            return interp_ok(false);
-        };
-        let waiter = futex.waiters.remove(i).unwrap();
+        // Remove `count` of the threads in the queue that match any of the bits in the bitset.
+        // We collect all of them before unblocking because the unblock callback may access the
+        // futex state to retrieve the remaining number of waiters on macOS.
+        let waiters: Vec<_> =
+            futex.waiters.extract_if(.., |w| w.bitset & bitset != 0).take(count).collect();
         drop(futex);
-        this.unblock_thread(waiter.thread, BlockReason::Futex)?;
-        interp_ok(true)
+
+        let woken = waiters.len();
+        for waiter in waiters {
+            this.unblock_thread(waiter.thread, BlockReason::Futex)?;
+        }
+
+        interp_ok(woken)
     }
 }
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 6d22dd8d68d..a8a2491304d 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -1138,7 +1138,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         use rand::Rng as _;
 
         let this = self.eval_context_mut();
-        if this.machine.rng.get_mut().gen_bool(this.machine.preemption_rate) {
+        if this.machine.rng.get_mut().random_bool(this.machine.preemption_rate) {
             this.yield_active_thread();
         }
     }
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index c8f04e25207..36b15dbf623 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -558,15 +558,15 @@ where
 
                 match chars.next() {
                     Some('"') => {
-                        cmd.extend(iter::repeat('\\').take(nslashes * 2 + 1));
+                        cmd.extend(iter::repeat_n('\\', nslashes * 2 + 1));
                         cmd.push('"');
                     }
                     Some(c) => {
-                        cmd.extend(iter::repeat('\\').take(nslashes));
+                        cmd.extend(iter::repeat_n('\\', nslashes));
                         cmd.push(c);
                     }
                     None => {
-                        cmd.extend(iter::repeat('\\').take(nslashes * 2));
+                        cmd.extend(iter::repeat_n('\\', nslashes * 2));
                         break;
                     }
                 }
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index c5538351d7d..a26f12cdfb1 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -421,7 +421,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         if this.machine.communicate() {
             // Fill the buffer using the host's rng.
-            getrandom::getrandom(&mut data)
+            getrandom::fill(&mut data)
                 .map_err(|err| err_unsup_format!("host getrandom failed: {}", err))?;
         } else {
             let rng = this.machine.rng.get_mut();
@@ -678,6 +678,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         )
     }
 
+    /// Helper function used inside shims of foreign functions to check that the target OS
+    /// is one of `target_oses`. It returns an error containing the `name` of the foreign function
+    /// in a message if this is not the case.
+    fn check_target_os(&self, target_oses: &[&str], name: Symbol) -> InterpResult<'tcx> {
+        let target_os = self.eval_context_ref().tcx.sess.target.os.as_ref();
+        if !target_oses.contains(&target_os) {
+            throw_unsup_format!("`{name}` is not supported on {target_os}");
+        }
+        interp_ok(())
+    }
+
     /// Helper function used inside the shims of foreign functions to assert that the target OS
     /// is part of the UNIX family. It panics showing a message with the `name` of the foreign function
     /// if this is not the case.
@@ -991,6 +1002,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         check_arg_count(args)
     }
 
+    /// Check shim for variadic function.
+    /// Returns a tuple that consisting of an array of fixed args, and a slice of varargs.
+    fn check_shim_variadic<'a, const N: usize>(
+        &mut self,
+        abi: &FnAbi<'tcx, Ty<'tcx>>,
+        exp_abi: Conv,
+        link_name: Symbol,
+        args: &'a [OpTy<'tcx>],
+    ) -> InterpResult<'tcx, (&'a [OpTy<'tcx>; N], &'a [OpTy<'tcx>])>
+    where
+        &'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>,
+    {
+        self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?;
+        check_vargarg_fixed_arg_count(link_name, abi, args)
+    }
+
     /// Mark a machine allocation that was just created as immutable.
     fn mark_immutable(&mut self, mplace: &MPlaceTy<'tcx>) {
         let this = self.eval_context_mut();
@@ -1184,8 +1211,10 @@ where
     throw_ub_format!("incorrect number of arguments: got {}, expected {}", args.len(), N)
 }
 
-/// Check that the number of args is at least the minumim what we expect.
-pub fn check_min_arg_count<'a, 'tcx, const N: usize>(
+/// Check that the number of varargs is at least the minimum what we expect.
+/// Fixed args should not be included.
+/// Use `check_vararg_fixed_arg_count` to extract the varargs slice from full function arguments.
+pub fn check_min_vararg_count<'a, 'tcx, const N: usize>(
     name: &'a str,
     args: &'a [OpTy<'tcx>],
 ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> {
@@ -1193,7 +1222,35 @@ pub fn check_min_arg_count<'a, 'tcx, const N: usize>(
         return interp_ok(ops);
     }
     throw_ub_format!(
-        "incorrect number of arguments for `{name}`: got {}, expected at least {}",
+        "not enough variadic arguments for `{name}`: got {}, expected at least {}",
+        args.len(),
+        N
+    )
+}
+
+/// Check the number of fixed args of a vararg function.
+/// Returns a tuple that consisting of an array of fixed args, and a slice of varargs.
+fn check_vargarg_fixed_arg_count<'a, 'tcx, const N: usize>(
+    link_name: Symbol,
+    abi: &FnAbi<'tcx, Ty<'tcx>>,
+    args: &'a [OpTy<'tcx>],
+) -> InterpResult<'tcx, (&'a [OpTy<'tcx>; N], &'a [OpTy<'tcx>])> {
+    if !abi.c_variadic {
+        throw_ub_format!("calling a variadic function with a non-variadic caller-side signature");
+    }
+    if abi.fixed_count != u32::try_from(N).unwrap() {
+        throw_ub_format!(
+            "incorrect number of fixed arguments for variadic function `{}`: got {}, expected {N}",
+            link_name.as_str(),
+            abi.fixed_count
+        )
+    }
+    if let Some(args) = args.split_first_chunk() {
+        return interp_ok(args);
+    }
+    throw_ub_format!(
+        "incorrect number of arguments for `{}`: got {}, expected at least {}",
+        link_name.as_str(),
         args.len(),
         N
     )
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index 9eebbc5d363..bce78adcaea 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -141,7 +141,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // FIXME: should we check for validity here? It's tricky because we do not have a
                 // place. Codegen does not seem to set any attributes like `noundef` for intrinsic
                 // calls, so we don't *have* to do anything.
-                let branch: bool = this.machine.rng.get_mut().gen();
+                let branch: bool = this.machine.rng.get_mut().random();
                 this.write_scalar(Scalar::from_bool(branch), dest)?;
             }
 
@@ -289,7 +289,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let a = this.read_scalar(a)?.to_f32()?;
                 let b = this.read_scalar(b)?.to_f32()?;
                 let c = this.read_scalar(c)?.to_f32()?;
-                let fuse: bool = this.machine.rng.get_mut().gen();
+                let fuse: bool = this.machine.rng.get_mut().random();
                 let res = if fuse {
                     // FIXME: Using host floats, to work around https://github.com/rust-lang/rustc_apfloat/issues/11
                     a.to_host().mul_add(b.to_host(), c.to_host()).to_soft()
@@ -304,7 +304,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let a = this.read_scalar(a)?.to_f64()?;
                 let b = this.read_scalar(b)?.to_f64()?;
                 let c = this.read_scalar(c)?.to_f64()?;
-                let fuse: bool = this.machine.rng.get_mut().gen();
+                let fuse: bool = this.machine.rng.get_mut().random();
                 let res = if fuse {
                     // FIXME: Using host floats, to work around https://github.com/rust-lang/rustc_apfloat/issues/11
                     a.to_host().mul_add(b.to_host(), c.to_host()).to_soft()
diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs
index 63a61dcd148..45e316b190a 100644
--- a/src/tools/miri/src/intrinsics/simd.rs
+++ b/src/tools/miri/src/intrinsics/simd.rs
@@ -304,7 +304,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     let c = this.read_scalar(&this.project_index(&c, i)?)?;
                     let dest = this.project_index(&dest, i)?;
 
-                    let fuse: bool = intrinsic_name == "fma" || this.machine.rng.get_mut().gen();
+                    let fuse: bool = intrinsic_name == "fma" || this.machine.rng.get_mut().random();
 
                     // Works for f32 and f64.
                     // FIXME: using host floats to work around https://github.com/rust-lang/miri/issues/2468.
@@ -639,8 +639,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let (right, right_len) = this.project_to_simd(right)?;
                 let (dest, dest_len) = this.project_to_simd(dest)?;
 
-                let index =
-                    generic_args[2].expect_const().to_value().valtree.unwrap_branch();
+                let index = generic_args[2].expect_const().to_value().valtree.unwrap_branch();
                 let index_len = index.len();
 
                 assert_eq!(left_len, right_len);
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 3ec35763a7d..45054c37c40 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -15,6 +15,8 @@
 #![feature(unqualified_local_imports)]
 #![feature(derive_coerce_pointee)]
 #![feature(arbitrary_self_types)]
+#![feature(unsigned_is_multiple_of)]
+#![feature(extract_if)]
 // Configure clippy and other lints
 #![allow(
     clippy::collapsible_else_if,
@@ -36,6 +38,7 @@
     clippy::needless_question_mark,
     clippy::needless_lifetimes,
     clippy::too_long_first_doc_paragraph,
+    // We don't use translatable diagnostics
     rustc::diagnostic_outside_of_impl,
     // We are not implementing queries here so it's fine
     rustc::potential_query_instability,
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 3727b5f4cae..6bd1076a8a8 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1112,10 +1112,13 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         // Call the lang item.
         let panic = ecx.tcx.lang_items().get(reason.lang_item()).unwrap();
         let panic = ty::Instance::mono(ecx.tcx.tcx, panic);
-        ecx.call_function(panic, ExternAbi::Rust, &[], None, StackPopCleanup::Goto {
-            ret: None,
-            unwind: mir::UnwindAction::Unreachable,
-        })?;
+        ecx.call_function(
+            panic,
+            ExternAbi::Rust,
+            &[],
+            None,
+            StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
+        )?;
         interp_ok(())
     }
 
@@ -1148,6 +1151,11 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
     }
 
     #[inline(always)]
+    fn contract_checks(ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool> {
+        interp_ok(ecx.tcx.sess.contract_checks())
+    }
+
+    #[inline(always)]
     fn thread_local_static_pointer(
         ecx: &mut MiriInterpCx<'tcx>,
         def_id: DefId,
@@ -1501,7 +1509,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
             catch_unwind: None,
             timing,
             is_user_relevant: ecx.machine.is_user_relevant(&frame),
-            salt: ecx.machine.rng.borrow_mut().gen::<usize>() % ADDRS_PER_ANON_GLOBAL,
+            salt: ecx.machine.rng.borrow_mut().random_range(0..ADDRS_PER_ANON_GLOBAL),
             data_race: ecx.machine.data_race.as_ref().map(|_| data_race::FrameState::default()),
         };
 
@@ -1716,7 +1724,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         if unique {
             CTFE_ALLOC_SALT
         } else {
-            ecx.machine.rng.borrow_mut().gen::<usize>() % ADDRS_PER_ANON_GLOBAL
+            ecx.machine.rng.borrow_mut().random_range(0..ADDRS_PER_ANON_GLOBAL)
         }
     }
 
diff --git a/src/tools/miri/src/math.rs b/src/tools/miri/src/math.rs
index ed3d2d55678..7117f722fee 100644
--- a/src/tools/miri/src/math.rs
+++ b/src/tools/miri/src/math.rs
@@ -1,9 +1,12 @@
 use rand::Rng as _;
-use rand::distributions::Distribution as _;
 use rustc_apfloat::Float as _;
 use rustc_apfloat::ieee::IeeeFloat;
 
-/// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale).
+/// Disturbes a floating-point result by a relative error in the range (-2^scale, 2^scale).
+///
+/// For a 2^N ULP error, you can use an `err_scale` of `-(F::PRECISION - 1 - N)`.
+/// In other words, a 1 ULP (absolute) error is the same as a `2^-(F::PRECISION-1)` relative error.
+/// (Subtracting 1 compensates for the integer bit.)
 pub(crate) fn apply_random_float_error<F: rustc_apfloat::Float>(
     ecx: &mut crate::MiriInterpCx<'_>,
     val: F,
@@ -11,12 +14,15 @@ pub(crate) fn apply_random_float_error<F: rustc_apfloat::Float>(
 ) -> F {
     let rng = ecx.machine.rng.get_mut();
     // Generate a random integer in the range [0, 2^PREC).
-    let dist = rand::distributions::Uniform::new(0, 1 << F::PRECISION);
-    let err = F::from_u128(dist.sample(rng))
-        .value
-        .scalbn(err_scale.strict_sub(F::PRECISION.try_into().unwrap()));
+    // (When read as binary, the position of the first `1` determines the exponent,
+    // and the remaining bits fill the mantissa. `PREC` is one plus the size of the mantissa,
+    // so this all works out.)
+    let r = F::from_u128(rng.random_range(0..(1 << F::PRECISION))).value;
+    // Multiply this with 2^(scale - PREC). The result is between 0 and
+    // 2^PREC * 2^(scale - PREC) = 2^scale.
+    let err = r.scalbn(err_scale.strict_sub(F::PRECISION.try_into().unwrap()));
     // give it a random sign
-    let err = if rng.gen::<bool>() { -err } else { err };
+    let err = if rng.random() { -err } else { err };
     // multiple the value with (1+err)
     (val * (F::from_u128(1).value + err).value).value
 }
diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs
index 43c628d66d5..c588b6fc7f1 100644
--- a/src/tools/miri/src/operator.rs
+++ b/src/tools/miri/src/operator.rs
@@ -108,7 +108,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         // Pick one of the NaNs.
         let nan = nans.choose(&mut *rand).unwrap();
         // Non-deterministically flip the sign.
-        if rand.gen() {
+        if rand.random() {
             // This will properly flip even for NaN.
             -nan
         } else {
@@ -120,6 +120,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let this = self.eval_context_ref();
         // Return one side non-deterministically.
         let mut rand = this.machine.rng.borrow_mut();
-        if rand.gen() { a } else { b }
+        if rand.random() { a } else { b }
     }
 }
diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs
index 0fda13e0616..323b95d5f5f 100644
--- a/src/tools/miri/src/shims/alloc.rs
+++ b/src/tools/miri/src/shims/alloc.rs
@@ -81,7 +81,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn malloc(&mut self, size: u64, init: AllocInit) -> InterpResult<'tcx, Pointer> {
         let this = self.eval_context_mut();
         let align = this.malloc_align(size);
-        let ptr = this.allocate_ptr(Size::from_bytes(size), align, MiriMemoryKind::C.into(), init)?;
+        let ptr =
+            this.allocate_ptr(Size::from_bytes(size), align, MiriMemoryKind::C.into(), init)?;
         interp_ok(ptr.into())
     }
 
@@ -92,7 +93,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         size: &OpTy<'tcx>,
     ) -> InterpResult<'tcx, Scalar> {
         let this = self.eval_context_mut();
-        let memptr = this.deref_pointer(memptr)?;
+        let memptr = this.deref_pointer_as(memptr, this.machine.layouts.mut_raw_ptr)?;
         let align = this.read_target_usize(align)?;
         let size = this.read_target_usize(size)?;
 
@@ -105,7 +106,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 Size::from_bytes(size),
                 Align::from_bytes(align).unwrap(),
                 MiriMemoryKind::C.into(),
-                AllocInit::Uninit
+                AllocInit::Uninit,
             )?;
             this.write_pointer(ptr, &memptr)?;
             interp_ok(Scalar::from_i32(0))
@@ -138,7 +139,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     Size::from_bytes(new_size),
                     new_align,
                     MiriMemoryKind::C.into(),
-                    AllocInit::Uninit
+                    AllocInit::Uninit,
                 )?;
                 interp_ok(new_ptr.into())
             }
@@ -179,7 +180,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     Size::from_bytes(size),
                     Align::from_bytes(align).unwrap(),
                     MiriMemoryKind::C.into(),
-                    AllocInit::Uninit
+                    AllocInit::Uninit,
                 )?;
                 interp_ok(ptr.into())
             }
diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs
index 1622ef280d2..7e667e70a17 100644
--- a/src/tools/miri/src/shims/backtrace.rs
+++ b/src/tools/miri/src/shims/backtrace.rs
@@ -4,7 +4,6 @@ use rustc_middle::ty::{self, Instance, Ty};
 use rustc_span::{BytePos, Loc, Symbol, hygiene};
 use rustc_target::callconv::{Conv, FnAbi};
 
-use crate::helpers::check_min_arg_count;
 use crate::*;
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
@@ -34,13 +33,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         abi: &FnAbi<'tcx, Ty<'tcx>>,
         link_name: Symbol,
         args: &[OpTy<'tcx>],
-        dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
-        let tcx = this.tcx;
+        let ptr_ty = this.machine.layouts.mut_raw_ptr.ty;
+        let ptr_layout = this.layout_of(ptr_ty)?;
+
+        let [flags, buf] = this.check_shim(abi, Conv::Rust, link_name, args)?;
 
-        let [flags] = check_min_arg_count("miri_get_backtrace", args)?;
         let flags = this.read_scalar(flags)?.to_u64()?;
+        let buf_place = this.deref_pointer_as(buf, ptr_layout)?;
 
         let mut data = Vec::new();
         for frame in this.active_thread_stack().iter().rev() {
@@ -63,44 +64,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             })
             .collect();
 
-        let len: u64 = ptrs.len().try_into().unwrap();
-
-        let ptr_ty = this.machine.layouts.mut_raw_ptr.ty;
-        let array_layout = this.layout_of(Ty::new_array(tcx.tcx, ptr_ty, len)).unwrap();
-
         match flags {
-            // storage for pointers is allocated by miri
-            // deallocating the slice is undefined behavior with a custom global allocator
             0 => {
-                let [_flags] = this.check_shim(abi, Conv::Rust, link_name, args)?;
-
-                let alloc = this.allocate(array_layout, MiriMemoryKind::Rust.into())?;
-
-                // Write pointers into array
-                for (i, ptr) in ptrs.into_iter().enumerate() {
-                    let place = this.project_index(&alloc, i as u64)?;
-
-                    this.write_pointer(ptr, &place)?;
-                }
-
-                this.write_immediate(Immediate::new_slice(alloc.ptr(), len, this), dest)?;
+                throw_unsup_format!("miri_get_backtrace: v0 is not supported any more");
             }
-            // storage for pointers is allocated by the caller
-            1 => {
-                let [_flags, buf] = this.check_shim(abi, Conv::Rust, link_name, args)?;
-
-                let buf_place = this.deref_pointer(buf)?;
-
-                let ptr_layout = this.layout_of(ptr_ty)?;
-
+            1 =>
                 for (i, ptr) in ptrs.into_iter().enumerate() {
                     let offset = ptr_layout.size.checked_mul(i.try_into().unwrap(), this).unwrap();
 
                     let op_place = buf_place.offset(offset, ptr_layout, this)?;
 
                     this.write_pointer(ptr, &op_place)?;
-                }
-            }
+                },
             _ => throw_unsup_format!("unknown `miri_get_backtrace` flags {}", flags),
         };
 
diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs
index f0aebfe1693..20dd3c8db2a 100644
--- a/src/tools/miri/src/shims/extern_static.rs
+++ b/src/tools/miri/src/shims/extern_static.rs
@@ -60,10 +60,10 @@ impl<'tcx> MiriMachine<'tcx> {
 
         match ecx.tcx.sess.target.os.as_ref() {
             "linux" => {
-                Self::null_ptr_extern_statics(ecx, &[
-                    "__cxa_thread_atexit_impl",
-                    "__clock_gettime64",
-                ])?;
+                Self::null_ptr_extern_statics(
+                    ecx,
+                    &["__cxa_thread_atexit_impl", "__clock_gettime64"],
+                )?;
                 Self::weak_symbol_extern_statics(ecx, &["getrandom", "statx"])?;
             }
             "freebsd" => {
diff --git a/src/tools/miri/src/shims/files.rs b/src/tools/miri/src/shims/files.rs
index 73425eee515..6b4f4cdc922 100644
--- a/src/tools/miri/src/shims/files.rs
+++ b/src/tools/miri/src/shims/files.rs
@@ -1,6 +1,6 @@
 use std::any::Any;
 use std::collections::BTreeMap;
-use std::io::{IsTerminal, Read, SeekFrom, Write};
+use std::io::{IsTerminal, SeekFrom, Write};
 use std::marker::CoercePointee;
 use std::ops::Deref;
 use std::rc::{Rc, Weak};
@@ -140,8 +140,8 @@ pub trait FileDescription: std::fmt::Debug + FileDescriptionExt {
         _communicate_allowed: bool,
         _ptr: Pointer,
         _len: usize,
-        _dest: &MPlaceTy<'tcx>,
         _ecx: &mut MiriInterpCx<'tcx>,
+        _finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         throw_unsup_format!("cannot read from {}", self.name());
     }
@@ -154,8 +154,8 @@ pub trait FileDescription: std::fmt::Debug + FileDescriptionExt {
         _communicate_allowed: bool,
         _ptr: Pointer,
         _len: usize,
-        _dest: &MPlaceTy<'tcx>,
         _ecx: &mut MiriInterpCx<'tcx>,
+        _finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         throw_unsup_format!("cannot write to {}", self.name());
     }
@@ -207,19 +207,16 @@ impl FileDescription for io::Stdin {
         communicate_allowed: bool,
         ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
-        let mut bytes = vec![0; len];
         if !communicate_allowed {
             // We want isolation mode to be deterministic, so we have to disallow all reads, even stdin.
             helpers::isolation_abort_error("`read` from stdin")?;
         }
-        let result = Read::read(&mut &*self, &mut bytes);
-        match result {
-            Ok(read_size) => ecx.return_read_success(ptr, &bytes, read_size, dest),
-            Err(e) => ecx.set_last_error_and_return(e, dest),
-        }
+
+        let result = ecx.read_from_host(&*self, len, ptr)?;
+        finish.call(ecx, result)
     }
 
     fn is_tty(&self, communicate_allowed: bool) -> bool {
@@ -237,22 +234,19 @@ impl FileDescription for io::Stdout {
         _communicate_allowed: bool,
         ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
-        let bytes = ecx.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?;
-        // We allow writing to stderr even with isolation enabled.
-        let result = Write::write(&mut &*self, bytes);
+        // We allow writing to stdout even with isolation enabled.
+        let result = ecx.write_to_host(&*self, len, ptr)?;
         // Stdout is buffered, flush to make sure it appears on the
         // screen.  This is the write() syscall of the interpreted
         // program, we want it to correspond to a write() syscall on
         // the host -- there is no good in adding extra buffering
         // here.
         io::stdout().flush().unwrap();
-        match result {
-            Ok(write_size) => ecx.return_write_success(write_size, dest),
-            Err(e) => ecx.set_last_error_and_return(e, dest),
-        }
+
+        finish.call(ecx, result)
     }
 
     fn is_tty(&self, communicate_allowed: bool) -> bool {
@@ -270,17 +264,13 @@ impl FileDescription for io::Stderr {
         _communicate_allowed: bool,
         ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
-        let bytes = ecx.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?;
         // We allow writing to stderr even with isolation enabled.
+        let result = ecx.write_to_host(&*self, len, ptr)?;
         // No need to flush, stderr is not buffered.
-        let result = Write::write(&mut &*self, bytes);
-        match result {
-            Ok(write_size) => ecx.return_write_success(write_size, dest),
-            Err(e) => ecx.set_last_error_and_return(e, dest),
-        }
+        finish.call(ecx, result)
     }
 
     fn is_tty(&self, communicate_allowed: bool) -> bool {
@@ -302,11 +292,11 @@ impl FileDescription for NullOutput {
         _communicate_allowed: bool,
         _ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         // We just don't write anything, but report to the user that we did.
-        ecx.return_write_success(len, dest)
+        finish.call(ecx, Ok(len))
     }
 }
 
@@ -405,40 +395,41 @@ impl FdTable {
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
 pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
-    /// Helper to implement `FileDescription::read`:
-    /// This is only used when `read` is successful.
-    /// `actual_read_size` should be the return value of some underlying `read` call that used
-    /// `bytes` as its output buffer.
-    /// The length of `bytes` must not exceed either the host's or the target's `isize`.
-    /// `bytes` is written to `buf` and the size is written to `dest`.
-    fn return_read_success(
+    /// Read data from a host `Read` type, store the result into machine memory,
+    /// and return whether that worked.
+    fn read_from_host(
         &mut self,
-        buf: Pointer,
-        bytes: &[u8],
-        actual_read_size: usize,
-        dest: &MPlaceTy<'tcx>,
-    ) -> InterpResult<'tcx> {
+        mut file: impl io::Read,
+        len: usize,
+        ptr: Pointer,
+    ) -> InterpResult<'tcx, Result<usize, IoError>> {
         let this = self.eval_context_mut();
-        // If reading to `bytes` did not fail, we write those bytes to the buffer.
-        // Crucially, if fewer than `bytes.len()` bytes were read, only write
-        // that much into the output buffer!
-        this.write_bytes_ptr(buf, bytes[..actual_read_size].iter().copied())?;
 
-        // The actual read size is always less than what got originally requested so this cannot fail.
-        this.write_int(u64::try_from(actual_read_size).unwrap(), dest)?;
-        interp_ok(())
+        let mut bytes = vec![0; len];
+        let result = file.read(&mut bytes);
+        match result {
+            Ok(read_size) => {
+                // If reading to `bytes` did not fail, we write those bytes to the buffer.
+                // Crucially, if fewer than `bytes.len()` bytes were read, only write
+                // that much into the output buffer!
+                this.write_bytes_ptr(ptr, bytes[..read_size].iter().copied())?;
+                interp_ok(Ok(read_size))
+            }
+            Err(e) => interp_ok(Err(IoError::HostError(e))),
+        }
     }
 
-    /// Helper to implement `FileDescription::write`:
-    /// This function is only used when `write` is successful, and writes `actual_write_size` to `dest`
-    fn return_write_success(
+    /// Write data to a host `Write` type, withthe bytes taken from machine memory.
+    fn write_to_host(
         &mut self,
-        actual_write_size: usize,
-        dest: &MPlaceTy<'tcx>,
-    ) -> InterpResult<'tcx> {
+        mut file: impl io::Write,
+        len: usize,
+        ptr: Pointer,
+    ) -> InterpResult<'tcx, Result<usize, IoError>> {
         let this = self.eval_context_mut();
-        // The actual write size is always less than what got originally requested so this cannot fail.
-        this.write_int(u64::try_from(actual_write_size).unwrap(), dest)?;
-        interp_ok(())
+
+        let bytes = this.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?;
+        let result = file.write(bytes);
+        interp_ok(result.map_err(IoError::HostError))
     }
 }
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 1ce0c209de9..97bfb04f1f4 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -357,7 +357,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Obtains a Miri backtrace. See the README for details.
             "miri_get_backtrace" => {
                 // `check_shim` happens inside `handle_miri_get_backtrace`.
-                this.handle_miri_get_backtrace(abi, link_name, args, dest)?;
+                this.handle_miri_get_backtrace(abi, link_name, args)?;
             }
             // Resolves a Miri backtrace frame. See the README for details.
             "miri_resolve_frame" => {
@@ -509,7 +509,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                         Size::from_bytes(size),
                         Align::from_bytes(align).unwrap(),
                         memory_kind.into(),
-                        AllocInit::Uninit
+                        AllocInit::Uninit,
                     )?;
 
                     ecx.write_pointer(ptr, dest)
@@ -538,7 +538,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                         Size::from_bytes(size),
                         Align::from_bytes(align).unwrap(),
                         MiriMemoryKind::Rust.into(),
-                        AllocInit::Zero
+                        AllocInit::Zero,
                     )?;
                     this.write_pointer(ptr, dest)
                 });
@@ -599,7 +599,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                         Size::from_bytes(new_size),
                         align,
                         MiriMemoryKind::Rust.into(),
-                        AllocInit::Uninit
+                        AllocInit::Uninit,
                     )?;
                     this.write_pointer(new_ptr, dest)
                 });
@@ -861,7 +861,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "lgammaf_r" => {
                 let [x, signp] = this.check_shim(abi, Conv::C, link_name, args)?;
                 let x = this.read_scalar(x)?.to_f32()?;
-                let signp = this.deref_pointer(signp)?;
+                let signp = this.deref_pointer_as(signp, this.machine.layouts.i32)?;
 
                 // Using host floats (but it's fine, these operations do not have guaranteed precision).
                 let (res, sign) = x.to_host().ln_gamma();
@@ -872,7 +872,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "lgamma_r" => {
                 let [x, signp] = this.check_shim(abi, Conv::C, link_name, args)?;
                 let x = this.read_scalar(x)?.to_f64()?;
-                let signp = this.deref_pointer(signp)?;
+                let signp = this.deref_pointer_as(signp, this.machine.layouts.i32)?;
 
                 // Using host floats (but it's fine, these operations do not have guaranteed precision).
                 let (res, sign) = x.to_host().ln_gamma();
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index 93479540009..83f331bb173 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -247,10 +247,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Call the lang item associated with this message.
                 let fn_item = this.tcx.require_lang_item(msg.panic_function(), None);
                 let instance = ty::Instance::mono(this.tcx.tcx, fn_item);
-                this.call_function(instance, ExternAbi::Rust, &[], None, StackPopCleanup::Goto {
-                    ret: None,
-                    unwind,
-                })?;
+                this.call_function(
+                    instance,
+                    ExternAbi::Rust,
+                    &[],
+                    None,
+                    StackPopCleanup::Goto { ret: None, unwind },
+                )?;
             }
         }
         interp_ok(())
diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs
index d6c77d9c4d9..64b3ce6b4e4 100644
--- a/src/tools/miri/src/shims/time.rs
+++ b/src/tools/miri/src/shims/time.rs
@@ -132,16 +132,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         this.assert_target_os_is_unix("localtime_r");
         this.check_no_isolation("`localtime_r`")?;
 
-        let timep = this.deref_pointer(timep)?;
+        let time_layout = this.libc_ty_layout("time_t");
+        let timep = this.deref_pointer_as(timep, time_layout)?;
         let result = this.deref_pointer_as(result_op, this.libc_ty_layout("tm"))?;
 
         // The input "represents the number of seconds elapsed since the Epoch,
         // 1970-01-01 00:00:00 +0000 (UTC)".
-        let sec_since_epoch: i64 = this
-            .read_scalar(&timep)?
-            .to_int(this.libc_ty_layout("time_t").size)?
-            .try_into()
-            .unwrap();
+        let sec_since_epoch: i64 =
+            this.read_scalar(&timep)?.to_int(time_layout.size)?.try_into().unwrap();
         let dt_utc: DateTime<Utc> =
             DateTime::from_timestamp(sec_since_epoch, 0).expect("Invalid timestamp");
 
@@ -254,7 +252,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let qpc = i64::try_from(duration.as_nanos()).map_err(|_| {
             err_unsup_format!("programs running longer than 2^63 nanoseconds are not supported")
         })?;
-        this.write_scalar(Scalar::from_i64(qpc), &this.deref_pointer(lpPerformanceCount_op)?)?;
+        this.write_scalar(
+            Scalar::from_i64(qpc),
+            &this.deref_pointer_as(lpPerformanceCount_op, this.machine.layouts.i64)?,
+        )?;
         interp_ok(Scalar::from_i32(-1)) // return non-zero on success
     }
 
diff --git a/src/tools/miri/src/shims/unix/android/thread.rs b/src/tools/miri/src/shims/unix/android/thread.rs
index 8d5d4a52b6e..c7e2c4d507b 100644
--- a/src/tools/miri/src/shims/unix/android/thread.rs
+++ b/src/tools/miri/src/shims/unix/android/thread.rs
@@ -3,7 +3,7 @@ use rustc_middle::ty::Ty;
 use rustc_span::Symbol;
 use rustc_target::callconv::{Conv, FnAbi};
 
-use crate::helpers::check_min_arg_count;
+use crate::helpers::check_min_vararg_count;
 use crate::shims::unix::thread::{EvalContextExt as _, ThreadNameResult};
 use crate::*;
 
@@ -16,18 +16,15 @@ pub fn prctl<'tcx>(
     args: &[OpTy<'tcx>],
     dest: &MPlaceTy<'tcx>,
 ) -> InterpResult<'tcx> {
-    // We do not use `check_shim` here because `prctl` is variadic. The argument
-    // count is checked bellow.
-    ecx.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;
+    let ([op], varargs) = ecx.check_shim_variadic(abi, Conv::C, link_name, args)?;
 
     // FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch.
     let pr_set_name = 15;
     let pr_get_name = 16;
 
-    let [op] = check_min_arg_count("prctl", args)?;
     let res = match ecx.read_scalar(op)?.to_i32()? {
         op if op == pr_set_name => {
-            let [_, name] = check_min_arg_count("prctl(PR_SET_NAME, ...)", args)?;
+            let [name] = check_min_vararg_count("prctl(PR_SET_NAME, ...)", varargs)?;
             let name = ecx.read_scalar(name)?;
             let thread = ecx.pthread_self()?;
             // The Linux kernel silently truncates long names.
@@ -38,7 +35,7 @@ pub fn prctl<'tcx>(
             Scalar::from_u32(0)
         }
         op if op == pr_get_name => {
-            let [_, name] = check_min_arg_count("prctl(PR_GET_NAME, ...)", args)?;
+            let [name] = check_min_vararg_count("prctl(PR_GET_NAME, ...)", varargs)?;
             let name = ecx.read_scalar(name)?;
             let thread = ecx.pthread_self()?;
             let len = Scalar::from_target_usize(TASK_COMM_LEN as u64, ecx);
diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs
index 0b59490308b..3f85b9ae9bd 100644
--- a/src/tools/miri/src/shims/unix/fd.rs
+++ b/src/tools/miri/src/shims/unix/fd.rs
@@ -6,7 +6,7 @@ use std::io::ErrorKind;
 
 use rustc_abi::Size;
 
-use crate::helpers::check_min_arg_count;
+use crate::helpers::check_min_vararg_count;
 use crate::shims::files::FileDescription;
 use crate::shims::unix::linux_like::epoll::EpollReadyEvents;
 use crate::shims::unix::*;
@@ -30,8 +30,8 @@ pub trait UnixFileDescription: FileDescription {
         _offset: u64,
         _ptr: Pointer,
         _len: usize,
-        _dest: &MPlaceTy<'tcx>,
         _ecx: &mut MiriInterpCx<'tcx>,
+        _finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         throw_unsup_format!("cannot pread from {}", self.name());
     }
@@ -46,8 +46,8 @@ pub trait UnixFileDescription: FileDescription {
         _ptr: Pointer,
         _len: usize,
         _offset: u64,
-        _dest: &MPlaceTy<'tcx>,
         _ecx: &mut MiriInterpCx<'tcx>,
+        _finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         throw_unsup_format!("cannot pwrite to {}", self.name());
     }
@@ -127,11 +127,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         interp_ok(Scalar::from_i32(this.try_unwrap_io_result(result)?))
     }
 
-    fn fcntl(&mut self, args: &[OpTy<'tcx>]) -> InterpResult<'tcx, Scalar> {
+    fn fcntl(
+        &mut self,
+        fd_num: &OpTy<'tcx>,
+        cmd: &OpTy<'tcx>,
+        varargs: &[OpTy<'tcx>],
+    ) -> InterpResult<'tcx, Scalar> {
         let this = self.eval_context_mut();
 
-        let [fd_num, cmd] = check_min_arg_count("fcntl", args)?;
-
         let fd_num = this.read_scalar(fd_num)?.to_i32()?;
         let cmd = this.read_scalar(cmd)?.to_i32()?;
 
@@ -163,7 +166,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     "fcntl(fd, F_DUPFD_CLOEXEC, ...)"
                 };
 
-                let [_, _, start] = check_min_arg_count(cmd_name, args)?;
+                let [start] = check_min_vararg_count(cmd_name, varargs)?;
                 let start = this.read_scalar(start)?.to_i32()?;
 
                 if let Some(fd) = this.machine.fds.get(fd_num) {
@@ -233,7 +236,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let count = usize::try_from(count).unwrap(); // now it fits in a `usize`
         let communicate = this.machine.communicate();
 
-        // We temporarily dup the FD to be able to retain mutable access to `this`.
+        // Get the FD.
         let Some(fd) = this.machine.fds.get(fd_num) else {
             trace!("read: FD not found");
             return this.set_last_error_and_return(LibcError("EBADF"), dest);
@@ -244,13 +247,33 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         // because it was a target's `usize`. Also we are sure that its smaller than
         // `usize::MAX` because it is bounded by the host's `isize`.
 
+        let finish = {
+            let dest = dest.clone();
+            callback!(
+                @capture<'tcx> {
+                    count: usize,
+                    dest: MPlaceTy<'tcx>,
+                }
+                |this, result: Result<usize, IoError>| {
+                    match result {
+                        Ok(read_size) => {
+                            assert!(read_size <= count);
+                            // This must fit since `count` fits.
+                            this.write_int(u64::try_from(read_size).unwrap(), &dest)
+                        }
+                        Err(e) => {
+                            this.set_last_error_and_return(e, &dest)
+                        }
+                }}
+            )
+        };
         match offset {
-            None => fd.read(communicate, buf, count, dest, this)?,
+            None => fd.read(communicate, buf, count, this, finish)?,
             Some(offset) => {
                 let Ok(offset) = u64::try_from(offset) else {
                     return this.set_last_error_and_return(LibcError("EINVAL"), dest);
                 };
-                fd.as_unix().pread(communicate, offset, buf, count, dest, this)?
+                fd.as_unix().pread(communicate, offset, buf, count, this, finish)?
             }
         };
         interp_ok(())
@@ -284,13 +307,33 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             return this.set_last_error_and_return(LibcError("EBADF"), dest);
         };
 
+        let finish = {
+            let dest = dest.clone();
+            callback!(
+                @capture<'tcx> {
+                    count: usize,
+                    dest: MPlaceTy<'tcx>,
+                }
+                |this, result: Result<usize, IoError>| {
+                    match result {
+                        Ok(write_size) => {
+                            assert!(write_size <= count);
+                            // This must fit since `count` fits.
+                            this.write_int(u64::try_from(write_size).unwrap(), &dest)
+                        }
+                        Err(e) => {
+                            this.set_last_error_and_return(e, &dest)
+                        }
+                }}
+            )
+        };
         match offset {
-            None => fd.write(communicate, buf, count, dest, this)?,
+            None => fd.write(communicate, buf, count, this, finish)?,
             Some(offset) => {
                 let Ok(offset) = u64::try_from(offset) else {
                     return this.set_last_error_and_return(LibcError("EINVAL"), dest);
                 };
-                fd.as_unix().pwrite(communicate, buf, count, offset, dest, this)?
+                fd.as_unix().pwrite(communicate, buf, count, offset, this, finish)?
             }
         };
         interp_ok(())
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 3353cf2cc59..d459ec7cb77 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -205,10 +205,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(result, dest)?;
             }
             "fcntl" => {
-                // `fcntl` is variadic. The argument count is checked based on the first argument
-                // in `this.fcntl()`, so we do not use `check_shim` here.
-                this.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;
-                let result = this.fcntl(args)?;
+                let ([fd_num, cmd], varargs) =
+                    this.check_shim_variadic(abi, Conv::C, link_name, args)?;
+                let result = this.fcntl(fd_num, cmd, varargs)?;
                 this.write_scalar(result, dest)?;
             }
             "dup" => {
@@ -236,8 +235,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "open" | "open64" => {
                 // `open` is variadic, the third argument is only present when the second argument
                 // has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set
-                this.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;
-                let result = this.open(args)?;
+                let ([path_raw, flag], varargs) =
+                    this.check_shim_variadic(abi, Conv::C, link_name, args)?;
+                let result = this.open(path_raw, flag, varargs)?;
                 this.write_scalar(result, dest)?;
             }
             "unlink" => {
@@ -354,10 +354,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "pipe2" => {
                 // Currently this function does not exist on all Unixes, e.g. on macOS.
-                if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "solaris" | "illumos")
-                {
-                    throw_unsup_format!("`pipe2` is not supported on {}", this.tcx.sess.target.os);
-                }
+                this.check_target_os(&["linux", "freebsd", "solaris", "illumos"], link_name)?;
                 let [pipefd, flags] = this.check_shim(abi, Conv::C, link_name, args)?;
                 let result = this.pipe2(pipefd, Some(flags))?;
                 this.write_scalar(result, dest)?;
@@ -402,12 +399,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             "reallocarray" => {
                 // Currently this function does not exist on all Unixes, e.g. on macOS.
-                if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "android") {
-                    throw_unsup_format!(
-                        "`reallocarray` is not supported on {}",
-                        this.tcx.sess.target.os
-                    );
-                }
+                this.check_target_os(&["linux", "freebsd", "android"], link_name)?;
                 let [ptr, nmemb, size] = this.check_shim(abi, Conv::C, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let nmemb = this.read_target_usize(nmemb)?;
@@ -656,13 +648,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "sched_getaffinity" => {
                 // Currently this function does not exist on all Unixes, e.g. on macOS.
-                if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "android") {
-                    throw_unsup_format!(
-                        "`sched_getaffinity` is not supported on {}",
-                        this.tcx.sess.target.os
-                    );
-                }
-
+                this.check_target_os(&["linux", "freebsd", "android"], link_name)?;
                 let [pid, cpusetsize, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
                 let pid = this.read_scalar(pid)?.to_u32()?;
                 let cpusetsize = this.read_target_usize(cpusetsize)?;
@@ -699,13 +685,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "sched_setaffinity" => {
                 // Currently this function does not exist on all Unixes, e.g. on macOS.
-                if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "android") {
-                    throw_unsup_format!(
-                        "`sched_setaffinity` is not supported on {}",
-                        this.tcx.sess.target.os
-                    );
-                }
-
+                this.check_target_os(&["linux", "freebsd", "android"], link_name)?;
                 let [pid, cpusetsize, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
                 let pid = this.read_scalar(pid)?.to_u32()?;
                 let cpusetsize = this.read_target_usize(cpusetsize)?;
@@ -761,16 +741,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "getentropy" => {
                 // This function is non-standard but exists with the same signature and behavior on
                 // Linux, macOS, FreeBSD and Solaris/Illumos.
-                if !matches!(
-                    &*this.tcx.sess.target.os,
-                    "linux" | "macos" | "freebsd" | "illumos" | "solaris" | "android"
-                ) {
-                    throw_unsup_format!(
-                        "`getentropy` is not supported on {}",
-                        this.tcx.sess.target.os
-                    );
-                }
-
+                this.check_target_os(
+                    &["linux", "macos", "freebsd", "illumos", "solaris", "android"],
+                    link_name,
+                )?;
                 let [buf, bufsize] = this.check_shim(abi, Conv::C, link_name, args)?;
                 let buf = this.read_pointer(buf)?;
                 let bufsize = this.read_target_usize(bufsize)?;
@@ -797,15 +771,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "getrandom" => {
                 // This function is non-standard but exists with the same signature and behavior on
                 // Linux, FreeBSD and Solaris/Illumos.
-                if !matches!(
-                    &*this.tcx.sess.target.os,
-                    "linux" | "freebsd" | "illumos" | "solaris" | "android"
-                ) {
-                    throw_unsup_format!(
-                        "`getrandom` is not supported on {}",
-                        this.tcx.sess.target.os
-                    );
-                }
+                this.check_target_os(
+                    &["linux", "freebsd", "illumos", "solaris", "android"],
+                    link_name,
+                )?;
                 let [ptr, len, flags] = this.check_shim(abi, Conv::C, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let len = this.read_target_usize(len)?;
@@ -817,12 +786,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "arc4random_buf" => {
                 // This function is non-standard but exists with the same signature and
                 // same behavior (eg never fails) on FreeBSD and Solaris/Illumos.
-                if !matches!(&*this.tcx.sess.target.os, "freebsd" | "illumos" | "solaris") {
-                    throw_unsup_format!(
-                        "`arc4random_buf` is not supported on {}",
-                        this.tcx.sess.target.os
-                    );
-                }
+                this.check_target_os(&["freebsd", "illumos", "solaris"], link_name)?;
                 let [ptr, len] = this.check_shim(abi, Conv::C, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let len = this.read_target_usize(len)?;
@@ -842,15 +806,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // For arm32 they did something custom, but similar enough that the same
                 // `_Unwind_RaiseException` impl in miri should work:
                 // https://github.com/ARM-software/abi-aa/blob/main/ehabi32/ehabi32.rst
-                if !matches!(
-                    &*this.tcx.sess.target.os,
-                    "linux" | "freebsd" | "illumos" | "solaris" | "android" | "macos"
-                ) {
-                    throw_unsup_format!(
-                        "`_Unwind_RaiseException` is not supported on {}",
-                        this.tcx.sess.target.os
-                    );
-                }
+                this.check_target_os(
+                    &["linux", "freebsd", "illumos", "solaris", "android", "macos"],
+                    link_name,
+                )?;
                 // This function looks and behaves excatly like miri_start_unwind.
                 let [payload] = this.check_shim(abi, Conv::C, link_name, args)?;
                 this.handle_miri_start_unwind(payload)?;
@@ -866,8 +825,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // These shims are enabled only when the caller is in the standard library.
             "pthread_attr_getguardsize" if this.frame_in_std() => {
                 let [_attr, guard_size] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let guard_size = this.deref_pointer(guard_size)?;
                 let guard_size_layout = this.libc_ty_layout("size_t");
+                let guard_size = this.deref_pointer_as(guard_size, guard_size_layout)?;
                 this.write_scalar(
                     Scalar::from_uint(this.machine.page_size, guard_size_layout.size),
                     &guard_size,
@@ -893,8 +852,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     this.check_shim(abi, Conv::C, link_name, args)?;
                 let _attr_place =
                     this.deref_pointer_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?;
-                let addr_place = this.deref_pointer(addr_place)?;
-                let size_place = this.deref_pointer(size_place)?;
+                let addr_place = this.deref_pointer_as(addr_place, this.machine.layouts.usize)?;
+                let size_place = this.deref_pointer_as(size_place, this.machine.layouts.usize)?;
 
                 this.write_scalar(
                     Scalar::from_uint(this.machine.stack_addr, this.pointer_size()),
@@ -928,7 +887,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let pwd = this.deref_pointer_as(pwd, this.libc_ty_layout("passwd"))?;
                 let buf = this.read_pointer(buf)?;
                 let buflen = this.read_target_usize(buflen)?;
-                let result = this.deref_pointer(result)?;
+                let result = this.deref_pointer_as(result, this.machine.layouts.mut_raw_ptr)?;
 
                 // Must be for "us".
                 if uid != UID {
diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
index 03dbd931329..08d06fe5d4c 100644
--- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
@@ -60,17 +60,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // since freebsd 12 the former form can be expected.
             "stat" | "stat@FBSD_1.0" => {
                 let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let result = this.macos_fbsd_solaris_stat(path, buf)?;
+                let result = this.macos_fbsd_solarish_stat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "lstat" | "lstat@FBSD_1.0" => {
                 let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let result = this.macos_fbsd_solaris_lstat(path, buf)?;
+                let result = this.macos_fbsd_solarish_lstat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "fstat" | "fstat@FBSD_1.0" => {
                 let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let result = this.macos_fbsd_solaris_fstat(fd, buf)?;
+                let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "readdir_r" | "readdir_r@FBSD_1.0" => {
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index cafce62cfed..c7399b00d3f 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -13,7 +13,7 @@ use rustc_abi::Size;
 use rustc_data_structures::fx::FxHashMap;
 
 use self::shims::time::system_time_to_duration;
-use crate::helpers::check_min_arg_count;
+use crate::helpers::check_min_vararg_count;
 use crate::shims::files::{EvalContextExt as _, FileDescription, FileDescriptionRef};
 use crate::shims::os_str::bytes_to_os_str;
 use crate::shims::unix::fd::{FlockOp, UnixFileDescription};
@@ -35,16 +35,13 @@ impl FileDescription for FileHandle {
         communicate_allowed: bool,
         ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         assert!(communicate_allowed, "isolation should have prevented even opening a file");
-        let mut bytes = vec![0; len];
-        let result = (&mut &self.file).read(&mut bytes);
-        match result {
-            Ok(read_size) => ecx.return_read_success(ptr, &bytes, read_size, dest),
-            Err(e) => ecx.set_last_error_and_return(e, dest),
-        }
+
+        let result = ecx.read_from_host(&self.file, len, ptr)?;
+        finish.call(ecx, result)
     }
 
     fn write<'tcx>(
@@ -52,16 +49,13 @@ impl FileDescription for FileHandle {
         communicate_allowed: bool,
         ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         assert!(communicate_allowed, "isolation should have prevented even opening a file");
-        let bytes = ecx.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?;
-        let result = (&mut &self.file).write(bytes);
-        match result {
-            Ok(write_size) => ecx.return_write_success(write_size, dest),
-            Err(e) => ecx.set_last_error_and_return(e, dest),
-        }
+
+        let result = ecx.write_to_host(&self.file, len, ptr)?;
+        finish.call(ecx, result)
     }
 
     fn seek<'tcx>(
@@ -119,8 +113,8 @@ impl UnixFileDescription for FileHandle {
         offset: u64,
         ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         assert!(communicate_allowed, "isolation should have prevented even opening a file");
         let mut bytes = vec![0; len];
@@ -137,11 +131,17 @@ impl UnixFileDescription for FileHandle {
                 .expect("failed to restore file position, this shouldn't be possible");
             res
         };
-        let result = f();
-        match result {
-            Ok(read_size) => ecx.return_read_success(ptr, &bytes, read_size, dest),
-            Err(e) => ecx.set_last_error_and_return(e, dest),
-        }
+        let result = match f() {
+            Ok(read_size) => {
+                // If reading to `bytes` did not fail, we write those bytes to the buffer.
+                // Crucially, if fewer than `bytes.len()` bytes were read, only write
+                // that much into the output buffer!
+                ecx.write_bytes_ptr(ptr, bytes[..read_size].iter().copied())?;
+                Ok(read_size)
+            }
+            Err(e) => Err(IoError::HostError(e)),
+        };
+        finish.call(ecx, result)
     }
 
     fn pwrite<'tcx>(
@@ -150,8 +150,8 @@ impl UnixFileDescription for FileHandle {
         ptr: Pointer,
         len: usize,
         offset: u64,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         assert!(communicate_allowed, "isolation should have prevented even opening a file");
         // Emulates pwrite using seek + write + seek to restore cursor position.
@@ -169,10 +169,7 @@ impl UnixFileDescription for FileHandle {
             res
         };
         let result = f();
-        match result {
-            Ok(write_size) => ecx.return_write_success(write_size, dest),
-            Err(e) => ecx.set_last_error_and_return(e, dest),
-        }
+        finish.call(ecx, result.map_err(IoError::HostError))
     }
 
     fn flock<'tcx>(
@@ -273,7 +270,7 @@ impl UnixFileDescription for FileHandle {
 
 impl<'tcx> EvalContextExtPrivate<'tcx> for crate::MiriInterpCx<'tcx> {}
 trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> {
-    fn macos_fbsd_solaris_write_buf(
+    fn macos_fbsd_solarish_write_stat_buf(
         &mut self,
         metadata: FileMetadata,
         buf_op: &OpTy<'tcx>,
@@ -321,9 +318,9 @@ trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> {
         }
 
         if matches!(&*this.tcx.sess.target.os, "solaris" | "illumos") {
-            // FIXME: write st_fstype field once libc is updated.
-            // https://github.com/rust-lang/libc/pull/4145
-            //this.write_int_fields_named(&[("st_fstype", 0)], &buf)?;
+            let st_fstype = this.project_field_named(&buf, "st_fstype")?;
+            // This is an array; write 0 into first element so that it encodes the empty string.
+            this.write_int(0, &this.project_index(&st_fstype, 0)?)?;
         }
 
         interp_ok(0)
@@ -452,9 +449,12 @@ fn maybe_sync_file(
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
 pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
-    fn open(&mut self, args: &[OpTy<'tcx>]) -> InterpResult<'tcx, Scalar> {
-        let [path_raw, flag] = check_min_arg_count("open", args)?;
-
+    fn open(
+        &mut self,
+        path_raw: &OpTy<'tcx>,
+        flag: &OpTy<'tcx>,
+        varargs: &[OpTy<'tcx>],
+    ) -> InterpResult<'tcx, Scalar> {
         let this = self.eval_context_mut();
 
         let path_raw = this.read_pointer(path_raw)?;
@@ -507,7 +507,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Get the mode.  On macOS, the argument type `mode_t` is actually `u16`, but
             // C integer promotion rules mean that on the ABI level, it gets passed as `u32`
             // (see https://github.com/rust-lang/rust/issues/71915).
-            let [_, _, mode] = check_min_arg_count("open(pathname, O_CREAT, ...)", args)?;
+            let [mode] = check_min_vararg_count("open(pathname, O_CREAT, ...)", varargs)?;
             let mode = this.read_scalar(mode)?.to_u32()?;
 
             #[cfg(unix)]
@@ -668,7 +668,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         interp_ok(Scalar::from_i32(this.try_unwrap_io_result(result)?))
     }
 
-    fn macos_fbsd_solaris_stat(
+    fn macos_fbsd_solarish_stat(
         &mut self,
         path_op: &OpTy<'tcx>,
         buf_op: &OpTy<'tcx>,
@@ -694,11 +694,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             Err(err) => return this.set_last_error_and_return_i32(err),
         };
 
-        interp_ok(Scalar::from_i32(this.macos_fbsd_solaris_write_buf(metadata, buf_op)?))
+        interp_ok(Scalar::from_i32(this.macos_fbsd_solarish_write_stat_buf(metadata, buf_op)?))
     }
 
     // `lstat` is used to get symlink metadata.
-    fn macos_fbsd_solaris_lstat(
+    fn macos_fbsd_solarish_lstat(
         &mut self,
         path_op: &OpTy<'tcx>,
         buf_op: &OpTy<'tcx>,
@@ -726,10 +726,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             Err(err) => return this.set_last_error_and_return_i32(err),
         };
 
-        interp_ok(Scalar::from_i32(this.macos_fbsd_solaris_write_buf(metadata, buf_op)?))
+        interp_ok(Scalar::from_i32(this.macos_fbsd_solarish_write_stat_buf(metadata, buf_op)?))
     }
 
-    fn macos_fbsd_solaris_fstat(
+    fn macos_fbsd_solarish_fstat(
         &mut self,
         fd_op: &OpTy<'tcx>,
         buf_op: &OpTy<'tcx>,
@@ -756,7 +756,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             Ok(metadata) => metadata,
             Err(err) => return this.set_last_error_and_return_i32(err),
         };
-        interp_ok(Scalar::from_i32(this.macos_fbsd_solaris_write_buf(metadata, buf_op)?))
+        interp_ok(Scalar::from_i32(this.macos_fbsd_solarish_write_stat_buf(metadata, buf_op)?))
     }
 
     fn linux_statx(
@@ -1109,7 +1109,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     Size::from_bytes(size),
                     dirent_layout.align.abi,
                     MiriMemoryKind::Runtime.into(),
-                    AllocInit::Uninit
+                    AllocInit::Uninit,
                 )?;
                 let entry: Pointer = entry.into();
 
@@ -1169,6 +1169,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         }
 
         let dirp = this.read_target_usize(dirp_op)?;
+        let result_place = this.deref_pointer_as(result_op, this.machine.layouts.mut_raw_ptr)?;
 
         // Reject if isolation is enabled.
         if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
@@ -1254,15 +1255,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     }
                     _ => unreachable!(),
                 }
-
-                let result_place = this.deref_pointer(result_op)?;
                 this.write_scalar(this.read_scalar(entry_op)?, &result_place)?;
 
                 Scalar::from_i32(0)
             }
             None => {
                 // end of stream: return 0, assign *result=NULL
-                this.write_null(&this.deref_pointer(result_op)?)?;
+                this.write_null(&result_place)?;
                 Scalar::from_i32(0)
             }
             Some(Err(e)) => {
@@ -1548,7 +1547,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         }
     }
     fn mkstemp(&mut self, template_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
-        use rand::seq::SliceRandom;
+        use rand::seq::IndexedRandom;
 
         // POSIX defines the template string.
         const TEMPFILE_TEMPLATE_STR: &str = "XXXXXX";
diff --git a/src/tools/miri/src/shims/unix/linux/mem.rs b/src/tools/miri/src/shims/unix/linux/mem.rs
index 6418d749d3d..8e5a3021b1c 100644
--- a/src/tools/miri/src/shims/unix/linux/mem.rs
+++ b/src/tools/miri/src/shims/unix/linux/mem.rs
@@ -49,7 +49,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             Size::from_bytes(new_size),
             align,
             MiriMemoryKind::Mmap.into(),
-            AllocInit::Zero
+            AllocInit::Zero,
         )?;
 
         interp_ok(Scalar::from_pointer(ptr, this))
diff --git a/src/tools/miri/src/shims/unix/linux_like/eventfd.rs b/src/tools/miri/src/shims/unix/linux_like/eventfd.rs
index 4b76bbb2b4d..936d436bd82 100644
--- a/src/tools/miri/src/shims/unix/linux_like/eventfd.rs
+++ b/src/tools/miri/src/shims/unix/linux_like/eventfd.rs
@@ -51,20 +51,20 @@ impl FileDescription for EventFd {
         _communicate_allowed: bool,
         ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         // We're treating the buffer as a `u64`.
         let ty = ecx.machine.layouts.u64;
         // Check the size of slice, and return error only if the size of the slice < 8.
         if len < ty.size.bytes_usize() {
-            return ecx.set_last_error_and_return(ErrorKind::InvalidInput, dest);
+            return finish.call(ecx, Err(ErrorKind::InvalidInput.into()));
         }
 
         // Turn the pointer into a place at the right type.
         let buf_place = ecx.ptr_to_mplace_unaligned(ptr, ty);
 
-        eventfd_read(buf_place, dest, self, ecx)
+        eventfd_read(buf_place, self, ecx, finish)
     }
 
     /// A write call adds the 8-byte integer value supplied in
@@ -84,20 +84,20 @@ impl FileDescription for EventFd {
         _communicate_allowed: bool,
         ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
         // We're treating the buffer as a `u64`.
         let ty = ecx.machine.layouts.u64;
         // Check the size of slice, and return error only if the size of the slice < 8.
         if len < ty.layout.size.bytes_usize() {
-            return ecx.set_last_error_and_return(ErrorKind::InvalidInput, dest);
+            return finish.call(ecx, Err(ErrorKind::InvalidInput.into()));
         }
 
         // Turn the pointer into a place at the right type.
         let buf_place = ecx.ptr_to_mplace_unaligned(ptr, ty);
 
-        eventfd_write(buf_place, dest, self, ecx)
+        eventfd_write(buf_place, self, ecx, finish)
     }
 
     fn as_unix(&self) -> &dyn UnixFileDescription {
@@ -183,15 +183,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 /// else just add the user-supplied value to current counter.
 fn eventfd_write<'tcx>(
     buf_place: MPlaceTy<'tcx>,
-    dest: &MPlaceTy<'tcx>,
     eventfd: FileDescriptionRef<EventFd>,
     ecx: &mut MiriInterpCx<'tcx>,
+    finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
 ) -> InterpResult<'tcx> {
     // Figure out which value we should add.
     let num = ecx.read_scalar(&buf_place)?.to_u64()?;
     // u64::MAX as input is invalid because the maximum value of counter is u64::MAX - 1.
     if num == u64::MAX {
-        return ecx.set_last_error_and_return(ErrorKind::InvalidInput, dest);
+        return finish.call(ecx, Err(ErrorKind::InvalidInput.into()));
     }
 
     match eventfd.counter.get().checked_add(num) {
@@ -219,16 +219,14 @@ fn eventfd_write<'tcx>(
             ecx.check_and_update_readiness(eventfd)?;
 
             // Return how many bytes we consumed from the user-provided buffer.
-            return ecx.write_int(buf_place.layout.size.bytes(), dest);
+            return finish.call(ecx, Ok(buf_place.layout.size.bytes_usize()));
         }
         None | Some(u64::MAX) => {
             // We can't update the state, so we have to block.
             if eventfd.is_nonblock {
-                return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest);
+                return finish.call(ecx, Err(ErrorKind::WouldBlock.into()));
             }
 
-            let dest = dest.clone();
-
             eventfd.blocked_write_tid.borrow_mut().push(ecx.active_thread());
 
             let weak_eventfd = FileDescriptionRef::downgrade(&eventfd);
@@ -239,7 +237,7 @@ fn eventfd_write<'tcx>(
                     @capture<'tcx> {
                         num: u64,
                         buf_place: MPlaceTy<'tcx>,
-                        dest: MPlaceTy<'tcx>,
+                        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
                         weak_eventfd: WeakFileDescriptionRef<EventFd>,
                     }
                     |this, unblock: UnblockKind| {
@@ -247,7 +245,7 @@ fn eventfd_write<'tcx>(
                         // When we get unblocked, try again. We know the ref is still valid,
                         // otherwise there couldn't be a `write` that unblocks us.
                         let eventfd_ref = weak_eventfd.upgrade().unwrap();
-                        eventfd_write(buf_place, &dest, eventfd_ref, this)
+                        eventfd_write(buf_place, eventfd_ref, this, finish)
                     }
                 ),
             );
@@ -260,9 +258,9 @@ fn eventfd_write<'tcx>(
 /// else just return the current counter value to the caller and set the counter to 0.
 fn eventfd_read<'tcx>(
     buf_place: MPlaceTy<'tcx>,
-    dest: &MPlaceTy<'tcx>,
     eventfd: FileDescriptionRef<EventFd>,
     ecx: &mut MiriInterpCx<'tcx>,
+    finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
 ) -> InterpResult<'tcx> {
     // Set counter to 0, get old value.
     let counter = eventfd.counter.replace(0);
@@ -270,9 +268,8 @@ fn eventfd_read<'tcx>(
     // Block when counter == 0.
     if counter == 0 {
         if eventfd.is_nonblock {
-            return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest);
+            return finish.call(ecx, Err(ErrorKind::WouldBlock.into()));
         }
-        let dest = dest.clone();
 
         eventfd.blocked_read_tid.borrow_mut().push(ecx.active_thread());
 
@@ -283,7 +280,7 @@ fn eventfd_read<'tcx>(
             callback!(
                 @capture<'tcx> {
                     buf_place: MPlaceTy<'tcx>,
-                    dest: MPlaceTy<'tcx>,
+                    finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
                     weak_eventfd: WeakFileDescriptionRef<EventFd>,
                 }
                 |this, unblock: UnblockKind| {
@@ -291,7 +288,7 @@ fn eventfd_read<'tcx>(
                     // When we get unblocked, try again. We know the ref is still valid,
                     // otherwise there couldn't be a `write` that unblocks us.
                     let eventfd_ref = weak_eventfd.upgrade().unwrap();
-                    eventfd_read(buf_place, &dest, eventfd_ref, this)
+                    eventfd_read(buf_place, eventfd_ref, this, finish)
                 }
             ),
         );
@@ -317,7 +314,7 @@ fn eventfd_read<'tcx>(
         ecx.check_and_update_readiness(eventfd)?;
 
         // Tell userspace how many bytes we put into the buffer.
-        return ecx.write_int(buf_place.layout.size.bytes(), dest);
+        return finish.call(ecx, Ok(buf_place.layout.size.bytes_usize()));
     }
     interp_ok(())
 }
diff --git a/src/tools/miri/src/shims/unix/linux_like/sync.rs b/src/tools/miri/src/shims/unix/linux_like/sync.rs
index 51124fb2a00..280bee4800f 100644
--- a/src/tools/miri/src/shims/unix/linux_like/sync.rs
+++ b/src/tools/miri/src/shims/unix/linux_like/sync.rs
@@ -1,5 +1,5 @@
 use crate::concurrency::sync::FutexRef;
-use crate::helpers::check_min_arg_count;
+use crate::helpers::check_min_vararg_count;
 use crate::*;
 
 struct LinuxFutex {
@@ -10,7 +10,7 @@ struct LinuxFutex {
 /// `args` is the arguments *including* the syscall number.
 pub fn futex<'tcx>(
     ecx: &mut MiriInterpCx<'tcx>,
-    args: &[OpTy<'tcx>],
+    varargs: &[OpTy<'tcx>],
     dest: &MPlaceTy<'tcx>,
 ) -> InterpResult<'tcx> {
     // The amount of arguments used depends on the type of futex operation.
@@ -21,7 +21,7 @@ pub fn futex<'tcx>(
     // may or may not be left out from the `syscall()` call.
     // Therefore we don't use `check_arg_count` here, but only check for the
     // number of arguments to fall within a range.
-    let [_, addr, op, val] = check_min_arg_count("`syscall(SYS_futex, ...)`", args)?;
+    let [addr, op, val] = check_min_vararg_count("`syscall(SYS_futex, ...)`", varargs)?;
 
     // The first three arguments (after the syscall number itself) are the same to all futex operations:
     //     (int *addr, int op, int val).
@@ -55,14 +55,16 @@ pub fn futex<'tcx>(
             let wait_bitset = op & !futex_realtime == futex_wait_bitset;
 
             let (timeout, bitset) = if wait_bitset {
-                let [_, _, _, _, timeout, uaddr2, bitset] =
-                    check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT_BITSET, ...)`", args)?;
+                let [_, _, _, timeout, uaddr2, bitset] = check_min_vararg_count(
+                    "`syscall(SYS_futex, FUTEX_WAIT_BITSET, ...)`",
+                    varargs,
+                )?;
                 let _timeout = ecx.read_pointer(timeout)?;
                 let _uaddr2 = ecx.read_pointer(uaddr2)?;
                 (timeout, ecx.read_scalar(bitset)?.to_u32()?)
             } else {
-                let [_, _, _, _, timeout] =
-                    check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT, ...)`", args)?;
+                let [_, _, _, timeout] =
+                    check_min_vararg_count("`syscall(SYS_futex, FUTEX_WAIT, ...)`", varargs)?;
                 (timeout, u32::MAX)
             };
 
@@ -156,14 +158,24 @@ pub fn futex<'tcx>(
                     .futex
                     .clone();
 
+                let dest = dest.clone();
                 ecx.futex_wait(
                     futex_ref,
                     bitset,
                     timeout,
-                    Scalar::from_target_isize(0, ecx), // retval_succ
-                    Scalar::from_target_isize(-1, ecx), // retval_timeout
-                    dest.clone(),
-                    LibcError("ETIMEDOUT"), // errno_timeout
+                    callback!(
+                        @capture<'tcx> {
+                            dest: MPlaceTy<'tcx>,
+                        }
+                        |ecx, unblock: UnblockKind| match unblock {
+                            UnblockKind::Ready => {
+                                ecx.write_int(0, &dest)
+                            }
+                            UnblockKind::TimedOut => {
+                                ecx.set_last_error_and_return(LibcError("ETIMEDOUT"), &dest)
+                            }
+                        }
+                    ),
                 );
             } else {
                 // The futex value doesn't match the expected value, so we return failure
@@ -190,8 +202,10 @@ pub fn futex<'tcx>(
             let futex_ref = futex_ref.futex.clone();
 
             let bitset = if op == futex_wake_bitset {
-                let [_, _, _, _, timeout, uaddr2, bitset] =
-                    check_min_arg_count("`syscall(SYS_futex, FUTEX_WAKE_BITSET, ...)`", args)?;
+                let [_, _, _, timeout, uaddr2, bitset] = check_min_vararg_count(
+                    "`syscall(SYS_futex, FUTEX_WAKE_BITSET, ...)`",
+                    varargs,
+                )?;
                 let _timeout = ecx.read_pointer(timeout)?;
                 let _uaddr2 = ecx.read_pointer(uaddr2)?;
                 ecx.read_scalar(bitset)?.to_u32()?
@@ -205,16 +219,8 @@ pub fn futex<'tcx>(
             // will see the latest value on addr which could be changed by our caller
             // before doing the syscall.
             ecx.atomic_fence(AtomicFenceOrd::SeqCst)?;
-            let mut n = 0;
-            #[expect(clippy::arithmetic_side_effects)]
-            for _ in 0..val {
-                if ecx.futex_wake(&futex_ref, bitset)? {
-                    n += 1;
-                } else {
-                    break;
-                }
-            }
-            ecx.write_scalar(Scalar::from_target_isize(n, ecx), dest)?;
+            let woken = ecx.futex_wake(&futex_ref, bitset, val.try_into().unwrap())?;
+            ecx.write_scalar(Scalar::from_target_isize(woken.try_into().unwrap(), ecx), dest)?;
         }
         op => throw_unsup_format!("Miri does not support `futex` syscall with op={}", op),
     }
diff --git a/src/tools/miri/src/shims/unix/linux_like/syscall.rs b/src/tools/miri/src/shims/unix/linux_like/syscall.rs
index 5fb262e176f..22c6dc97507 100644
--- a/src/tools/miri/src/shims/unix/linux_like/syscall.rs
+++ b/src/tools/miri/src/shims/unix/linux_like/syscall.rs
@@ -2,7 +2,7 @@ use rustc_middle::ty::Ty;
 use rustc_span::Symbol;
 use rustc_target::callconv::{Conv, FnAbi};
 
-use crate::helpers::check_min_arg_count;
+use crate::helpers::check_min_vararg_count;
 use crate::shims::unix::linux_like::eventfd::EvalContextExt as _;
 use crate::shims::unix::linux_like::sync::futex;
 use crate::*;
@@ -14,9 +14,7 @@ pub fn syscall<'tcx>(
     args: &[OpTy<'tcx>],
     dest: &MPlaceTy<'tcx>,
 ) -> InterpResult<'tcx> {
-    // We do not use `check_shim` here because `syscall` is variadic. The argument
-    // count is checked bellow.
-    ecx.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;
+    let ([op], varargs) = ecx.check_shim_variadic(abi, Conv::C, link_name, args)?;
     // The syscall variadic function is legal to call with more arguments than needed,
     // extra arguments are simply ignored. The important check is that when we use an
     // argument, we have to also check all arguments *before* it to ensure that they
@@ -26,14 +24,13 @@ pub fn syscall<'tcx>(
     let sys_futex = ecx.eval_libc("SYS_futex").to_target_usize(ecx)?;
     let sys_eventfd2 = ecx.eval_libc("SYS_eventfd2").to_target_usize(ecx)?;
 
-    let [op] = check_min_arg_count("syscall", args)?;
     match ecx.read_target_usize(op)? {
         // `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`
         // is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
         num if num == sys_getrandom => {
             // Used by getrandom 0.1
             // The first argument is the syscall id, so skip over it.
-            let [_, ptr, len, flags] = check_min_arg_count("syscall(SYS_getrandom, ...)", args)?;
+            let [ptr, len, flags] = check_min_vararg_count("syscall(SYS_getrandom, ...)", varargs)?;
 
             let ptr = ecx.read_pointer(ptr)?;
             let len = ecx.read_target_usize(len)?;
@@ -47,10 +44,10 @@ pub fn syscall<'tcx>(
         }
         // `futex` is used by some synchronization primitives.
         num if num == sys_futex => {
-            futex(ecx, args, dest)?;
+            futex(ecx, varargs, dest)?;
         }
         num if num == sys_eventfd2 => {
-            let [_, initval, flags] = check_min_arg_count("syscall(SYS_evetfd2, ...)", args)?;
+            let [initval, flags] = check_min_vararg_count("syscall(SYS_evetfd2, ...)", varargs)?;
 
             let result = ecx.eventfd(initval, flags)?;
             ecx.write_int(result.to_i32()?, dest)?;
diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
index 85c963774a1..918fd8dd52d 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -2,13 +2,20 @@ use rustc_middle::ty::Ty;
 use rustc_span::Symbol;
 use rustc_target::callconv::{Conv, FnAbi};
 
-use super::sync::EvalContextExt as _;
-use crate::helpers::check_min_arg_count;
+use super::sync::{EvalContextExt as _, MacOsFutexTimeout};
 use crate::shims::unix::*;
 use crate::*;
 
-pub fn is_dyn_sym(_name: &str) -> bool {
-    false
+pub fn is_dyn_sym(name: &str) -> bool {
+    match name {
+        // These only became available with macOS 11.0, so std looks them up dynamically.
+        "os_sync_wait_on_address"
+        | "os_sync_wait_on_address_with_deadline"
+        | "os_sync_wait_on_address_with_timeout"
+        | "os_sync_wake_by_address_any"
+        | "os_sync_wake_by_address_all" => true,
+        _ => false,
+    }
 }
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
@@ -40,17 +47,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "stat" | "stat64" | "stat$INODE64" => {
                 let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let result = this.macos_fbsd_solaris_stat(path, buf)?;
+                let result = this.macos_fbsd_solarish_stat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "lstat" | "lstat64" | "lstat$INODE64" => {
                 let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let result = this.macos_fbsd_solaris_lstat(path, buf)?;
+                let result = this.macos_fbsd_solarish_lstat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "fstat" | "fstat64" | "fstat$INODE64" => {
                 let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let result = this.macos_fbsd_solaris_fstat(fd, buf)?;
+                let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "opendir$INODE64" => {
@@ -69,10 +76,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(result, dest)?;
             }
             "ioctl" => {
-                // `ioctl` is variadic. The argument count is checked based on the first argument
-                // in `this.ioctl()`, so we do not use `check_shim` here.
-                this.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;
-                let result = this.ioctl(args)?;
+                let ([fd_num, cmd], varargs) =
+                    this.check_shim_variadic(abi, Conv::C, link_name, args)?;
+                let result = this.ioctl(fd_num, cmd, varargs)?;
                 this.write_scalar(result, dest)?;
             }
 
@@ -216,6 +222,58 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(res, dest)?;
             }
 
+            // Futex primitives
+            "os_sync_wait_on_address" => {
+                let [addr_op, value_op, size_op, flags_op] =
+                    this.check_shim(abi, Conv::C, link_name, args)?;
+                this.os_sync_wait_on_address(
+                    addr_op,
+                    value_op,
+                    size_op,
+                    flags_op,
+                    MacOsFutexTimeout::None,
+                    dest,
+                )?;
+            }
+            "os_sync_wait_on_address_with_deadline" => {
+                let [addr_op, value_op, size_op, flags_op, clock_op, timeout_op] =
+                    this.check_shim(abi, Conv::C, link_name, args)?;
+                this.os_sync_wait_on_address(
+                    addr_op,
+                    value_op,
+                    size_op,
+                    flags_op,
+                    MacOsFutexTimeout::Absolute { clock_op, timeout_op },
+                    dest,
+                )?;
+            }
+            "os_sync_wait_on_address_with_timeout" => {
+                let [addr_op, value_op, size_op, flags_op, clock_op, timeout_op] =
+                    this.check_shim(abi, Conv::C, link_name, args)?;
+                this.os_sync_wait_on_address(
+                    addr_op,
+                    value_op,
+                    size_op,
+                    flags_op,
+                    MacOsFutexTimeout::Relative { clock_op, timeout_op },
+                    dest,
+                )?;
+            }
+            "os_sync_wake_by_address_any" => {
+                let [addr_op, size_op, flags_op] =
+                    this.check_shim(abi, Conv::C, link_name, args)?;
+                this.os_sync_wake_by_address(
+                    addr_op, size_op, flags_op, /* all */ false, dest,
+                )?;
+            }
+            "os_sync_wake_by_address_all" => {
+                let [addr_op, size_op, flags_op] =
+                    this.check_shim(abi, Conv::C, link_name, args)?;
+                this.os_sync_wake_by_address(
+                    addr_op, size_op, flags_op, /* all */ true, dest,
+                )?;
+            }
+
             "os_unfair_lock_lock" => {
                 let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?;
                 this.os_unfair_lock_lock(lock_op)?;
@@ -243,12 +301,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         interp_ok(EmulateItemResult::NeedsReturn)
     }
 
-    fn ioctl(&mut self, args: &[OpTy<'tcx>]) -> InterpResult<'tcx, Scalar> {
+    fn ioctl(
+        &mut self,
+        fd_num: &OpTy<'tcx>,
+        cmd: &OpTy<'tcx>,
+        _varargs: &[OpTy<'tcx>],
+    ) -> InterpResult<'tcx, Scalar> {
         let this = self.eval_context_mut();
 
         let fioclex = this.eval_libc_u64("FIOCLEX");
 
-        let [fd_num, cmd] = check_min_arg_count("ioctl", args)?;
         let fd_num = this.read_scalar(fd_num)?.to_i32()?;
         let cmd = this.read_scalar(cmd)?.to_u64()?;
 
diff --git a/src/tools/miri/src/shims/unix/macos/sync.rs b/src/tools/miri/src/shims/unix/macos/sync.rs
index 330c64f06a3..6ba52f2f57e 100644
--- a/src/tools/miri/src/shims/unix/macos/sync.rs
+++ b/src/tools/miri/src/shims/unix/macos/sync.rs
@@ -10,8 +10,12 @@
 //! and we do not detect copying of the lock, but macOS doesn't guarantee anything
 //! in that case either.
 
+use std::cell::Cell;
+use std::time::Duration;
+
 use rustc_abi::Size;
 
+use crate::concurrency::sync::FutexRef;
 use crate::*;
 
 #[derive(Clone)]
@@ -20,6 +24,26 @@ enum MacOsUnfairLock {
     Active { mutex_ref: MutexRef },
 }
 
+pub enum MacOsFutexTimeout<'a, 'tcx> {
+    None,
+    Relative { clock_op: &'a OpTy<'tcx>, timeout_op: &'a OpTy<'tcx> },
+    Absolute { clock_op: &'a OpTy<'tcx>, timeout_op: &'a OpTy<'tcx> },
+}
+
+/// Metadata for a macOS futex.
+///
+/// Since macOS 11.0, Apple has exposed the previously private futex API consisting
+/// of `os_sync_wait_on_address` (and friends) and `os_sync_wake_by_address_{any, all}`.
+/// These work with different value sizes and flags, which are validated to be consistent.
+/// This structure keeps track of both the futex queue and these values.
+struct MacOsFutex {
+    futex: FutexRef,
+    /// The size in bytes of the atomic primitive underlying this futex.
+    size: Cell<u64>,
+    /// Whether the futex is shared across process boundaries.
+    shared: Cell<bool>,
+}
+
 impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {}
 trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn os_unfair_lock_get_data<'a>(
@@ -30,7 +54,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
         'tcx: 'a,
     {
         let this = self.eval_context_mut();
-        let lock = this.deref_pointer(lock_ptr)?;
+        let lock = this.deref_pointer_as(lock_ptr, this.libc_ty_layout("os_unfair_lock_s"))?;
         this.lazy_sync_get_data(
             &lock,
             Size::ZERO, // offset for init tracking
@@ -54,6 +78,198 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
 pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
+    /// Implements [`os_sync_wait_on_address`], [`os_sync_wait_on_address_with_deadline`]
+    /// and [`os_sync_wait_on_address_with_timeout`].
+    ///
+    /// [`os_sync_wait_on_address`]: https://developer.apple.com/documentation/os/os_sync_wait_on_address?language=objc
+    /// [`os_sync_wait_on_address_with_deadline`]: https://developer.apple.com/documentation/os/os_sync_wait_on_address_with_deadline?language=objc
+    /// [`os_sync_wait_on_address_with_timeout`]: https://developer.apple.com/documentation/os/os_sync_wait_on_address_with_timeout?language=objc
+    fn os_sync_wait_on_address(
+        &mut self,
+        addr_op: &OpTy<'tcx>,
+        value_op: &OpTy<'tcx>,
+        size_op: &OpTy<'tcx>,
+        flags_op: &OpTy<'tcx>,
+        timeout: MacOsFutexTimeout<'_, 'tcx>,
+        dest: &MPlaceTy<'tcx>,
+    ) -> InterpResult<'tcx> {
+        let this = self.eval_context_mut();
+        let none = this.eval_libc_u32("OS_SYNC_WAIT_ON_ADDRESS_NONE");
+        let shared = this.eval_libc_u32("OS_SYNC_WAIT_ON_ADDRESS_SHARED");
+        let absolute_clock = this.eval_libc_u32("OS_CLOCK_MACH_ABSOLUTE_TIME");
+
+        let ptr = this.read_pointer(addr_op)?;
+        let value = this.read_scalar(value_op)?.to_u64()?;
+        let size = this.read_target_usize(size_op)?;
+        let flags = this.read_scalar(flags_op)?.to_u32()?;
+
+        let clock_timeout = match timeout {
+            MacOsFutexTimeout::None => None,
+            MacOsFutexTimeout::Relative { clock_op, timeout_op } => {
+                let clock = this.read_scalar(clock_op)?.to_u32()?;
+                let timeout = this.read_scalar(timeout_op)?.to_u64()?;
+                Some((clock, TimeoutAnchor::Relative, timeout))
+            }
+            MacOsFutexTimeout::Absolute { clock_op, timeout_op } => {
+                let clock = this.read_scalar(clock_op)?.to_u32()?;
+                let timeout = this.read_scalar(timeout_op)?.to_u64()?;
+                Some((clock, TimeoutAnchor::Absolute, timeout))
+            }
+        };
+
+        // Perform validation of the arguments.
+        let addr = ptr.addr().bytes();
+        if addr == 0
+            || !matches!(size, 4 | 8)
+            || !addr.is_multiple_of(size)
+            || (flags != none && flags != shared)
+            || clock_timeout
+                .is_some_and(|(clock, _, timeout)| clock != absolute_clock || timeout == 0)
+        {
+            this.set_last_error_and_return(LibcError("EINVAL"), dest)?;
+            return interp_ok(());
+        }
+
+        let is_shared = flags == shared;
+        let timeout = clock_timeout.map(|(_, anchor, timeout)| {
+            // The only clock that is currenlty supported is the monotonic clock.
+            // While the deadline argument of `os_sync_wait_on_address_with_deadline`
+            // is actually not in nanoseconds but in the units of `mach_current_time`,
+            // the two are equivalent in miri.
+            (TimeoutClock::Monotonic, anchor, Duration::from_nanos(timeout))
+        });
+
+        // See the Linux futex implementation for why this fence exists.
+        this.atomic_fence(AtomicFenceOrd::SeqCst)?;
+
+        let layout = this.machine.layouts.uint(Size::from_bytes(size)).unwrap();
+        let futex_val = this
+            .read_scalar_atomic(&this.ptr_to_mplace(ptr, layout), AtomicReadOrd::Acquire)?
+            .to_bits(Size::from_bytes(size))?;
+
+        let futex = this
+            .get_sync_or_init(ptr, |_| {
+                MacOsFutex {
+                    futex: Default::default(),
+                    size: Cell::new(size),
+                    shared: Cell::new(is_shared),
+                }
+            })
+            .unwrap();
+
+        // Detect mismatches between the flags and sizes used on this address
+        // by comparing it with the parameters used by the other waiters in
+        // the current list. If the list is currently empty, update those
+        // parameters.
+        if futex.futex.waiters() == 0 {
+            futex.size.set(size);
+            futex.shared.set(is_shared);
+        } else if futex.size.get() != size || futex.shared.get() != is_shared {
+            this.set_last_error_and_return(LibcError("EINVAL"), dest)?;
+            return interp_ok(());
+        }
+
+        if futex_val == value.into() {
+            // If the values are the same, we have to block.
+            let futex_ref = futex.futex.clone();
+            let dest = dest.clone();
+            this.futex_wait(
+                futex_ref.clone(),
+                u32::MAX, // bitset
+                timeout,
+                callback!(
+                    @capture<'tcx> {
+                        dest: MPlaceTy<'tcx>,
+                        futex_ref: FutexRef,
+                    }
+                    |this, unblock: UnblockKind| {
+                        match unblock {
+                            UnblockKind::Ready => {
+                                let remaining = futex_ref.waiters().try_into().unwrap();
+                                this.write_scalar(Scalar::from_i32(remaining), &dest)
+                            }
+                            UnblockKind::TimedOut => {
+                                this.set_last_error_and_return(LibcError("ETIMEDOUT"), &dest)
+                            }
+                        }
+                    }
+                ),
+            );
+        } else {
+            // else retrieve the current number of waiters.
+            let waiters = futex.futex.waiters().try_into().unwrap();
+            this.write_scalar(Scalar::from_i32(waiters), dest)?;
+        }
+
+        interp_ok(())
+    }
+
+    /// Implements [`os_sync_wake_by_address_all`] and [`os_sync_wake_by_address_any`].
+    ///
+    /// [`os_sync_wake_by_address_all`]: https://developer.apple.com/documentation/os/os_sync_wake_by_address_all?language=objc
+    /// [`os_sync_wake_by_address_any`]: https://developer.apple.com/documentation/os/os_sync_wake_by_address_any?language=objc
+    fn os_sync_wake_by_address(
+        &mut self,
+        addr_op: &OpTy<'tcx>,
+        size_op: &OpTy<'tcx>,
+        flags_op: &OpTy<'tcx>,
+        all: bool,
+        dest: &MPlaceTy<'tcx>,
+    ) -> InterpResult<'tcx> {
+        let this = self.eval_context_mut();
+        let none = this.eval_libc_u32("OS_SYNC_WAKE_BY_ADDRESS_NONE");
+        let shared = this.eval_libc_u32("OS_SYNC_WAKE_BY_ADDRESS_SHARED");
+
+        let ptr = this.read_pointer(addr_op)?;
+        let size = this.read_target_usize(size_op)?;
+        let flags = this.read_scalar(flags_op)?.to_u32()?;
+
+        // Perform validation of the arguments.
+        let addr = ptr.addr().bytes();
+        if addr == 0 || !matches!(size, 4 | 8) || (flags != none && flags != shared) {
+            this.set_last_error_and_return(LibcError("EINVAL"), dest)?;
+            return interp_ok(());
+        }
+
+        let is_shared = flags == shared;
+
+        let Some(futex) = this.get_sync_or_init(ptr, |_| {
+            MacOsFutex {
+                futex: Default::default(),
+                size: Cell::new(size),
+                shared: Cell::new(is_shared),
+            }
+        }) else {
+            // No AllocId, or no live allocation at that AllocId. Return an
+            // error code. (That seems nicer than silently doing something
+            // non-intuitive.) This means that if an address gets reused by a
+            // new allocation, we'll use an independent futex queue for this...
+            // that seems acceptable.
+            this.set_last_error_and_return(LibcError("ENOENT"), dest)?;
+            return interp_ok(());
+        };
+
+        if futex.futex.waiters() == 0 {
+            this.set_last_error_and_return(LibcError("ENOENT"), dest)?;
+            return interp_ok(());
+        // If there are waiters in the queue, they have all used the parameters
+        // stored in `futex` (we check this in `os_sync_wait_on_address` above).
+        // Detect mismatches between "our" parameters and the parameters used by
+        // the waiters and return an error in that case.
+        } else if futex.size.get() != size || futex.shared.get() != is_shared {
+            this.set_last_error_and_return(LibcError("EINVAL"), dest)?;
+            return interp_ok(());
+        }
+
+        let futex_ref = futex.futex.clone();
+
+        // See the Linux futex implementation for why this fence exists.
+        this.atomic_fence(AtomicFenceOrd::SeqCst)?;
+        this.futex_wake(&futex_ref, u32::MAX, if all { usize::MAX } else { 1 })?;
+        this.write_scalar(Scalar::from_i32(0), dest)?;
+        interp_ok(())
+    }
+
     fn os_unfair_lock_lock(&mut self, lock_op: &OpTy<'tcx>) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
diff --git a/src/tools/miri/src/shims/unix/mem.rs b/src/tools/miri/src/shims/unix/mem.rs
index 2d5d3a6471a..aefeee6f7a3 100644
--- a/src/tools/miri/src/shims/unix/mem.rs
+++ b/src/tools/miri/src/shims/unix/mem.rs
@@ -116,7 +116,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             align,
             MiriMemoryKind::Mmap.into(),
             // mmap guarantees new mappings are zero-init.
-            AllocInit::Zero
+            AllocInit::Zero,
         )?;
 
         interp_ok(Scalar::from_pointer(ptr, this))
diff --git a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
index f94783a3907..21d4f41f485 100644
--- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
@@ -87,17 +87,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // File related shims
             "stat" | "stat64" => {
                 let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let result = this.macos_fbsd_solaris_stat(path, buf)?;
+                let result = this.macos_fbsd_solarish_stat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "lstat" | "lstat64" => {
                 let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let result = this.macos_fbsd_solaris_lstat(path, buf)?;
+                let result = this.macos_fbsd_solarish_lstat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "fstat" | "fstat64" => {
                 let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let result = this.macos_fbsd_solaris_fstat(fd, buf)?;
+                let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "readdir" => {
@@ -163,7 +163,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     throw_unsup_format!("pset_info is only supported with list==NULL");
                 }
 
-                let cpus = this.deref_pointer(cpus)?;
+                let cpus = this.deref_pointer_as(cpus, this.machine.layouts.u32)?;
                 this.write_scalar(Scalar::from_u32(this.machine.num_cpus), &cpus)?;
                 this.write_null(dest)?;
             }
diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs
index 5b0a9398b4b..9f1fabfbf64 100644
--- a/src/tools/miri/src/shims/unix/sync.rs
+++ b/src/tools/miri/src/shims/unix/sync.rs
@@ -170,7 +170,7 @@ fn mutex_create<'tcx>(
     mutex_ptr: &OpTy<'tcx>,
     kind: MutexKind,
 ) -> InterpResult<'tcx, PthreadMutex> {
-    let mutex = ecx.deref_pointer(mutex_ptr)?;
+    let mutex = ecx.deref_pointer_as(mutex_ptr, ecx.libc_ty_layout("pthread_mutex_t"))?;
     let id = ecx.machine.sync.mutex_create();
     let data = PthreadMutex { mutex_ref: id, kind };
     ecx.lazy_sync_init(&mutex, mutex_init_offset(ecx)?, data.clone())?;
@@ -186,7 +186,7 @@ fn mutex_get_data<'tcx, 'a>(
 where
     'tcx: 'a,
 {
-    let mutex = ecx.deref_pointer(mutex_ptr)?;
+    let mutex = ecx.deref_pointer_as(mutex_ptr, ecx.libc_ty_layout("pthread_mutex_t"))?;
     ecx.lazy_sync_get_data(
         &mutex,
         mutex_init_offset(ecx)?,
@@ -265,7 +265,7 @@ fn rwlock_get_data<'tcx, 'a>(
 where
     'tcx: 'a,
 {
-    let rwlock = ecx.deref_pointer(rwlock_ptr)?;
+    let rwlock = ecx.deref_pointer_as(rwlock_ptr, ecx.libc_ty_layout("pthread_rwlock_t"))?;
     ecx.lazy_sync_get_data(
         &rwlock,
         rwlock_init_offset(ecx)?,
@@ -383,7 +383,7 @@ fn cond_create<'tcx>(
     cond_ptr: &OpTy<'tcx>,
     clock: ClockId,
 ) -> InterpResult<'tcx, PthreadCondvar> {
-    let cond = ecx.deref_pointer(cond_ptr)?;
+    let cond = ecx.deref_pointer_as(cond_ptr, ecx.libc_ty_layout("pthread_cond_t"))?;
     let id = ecx.machine.sync.condvar_create();
     let data = PthreadCondvar { id, clock };
     ecx.lazy_sync_init(&cond, cond_init_offset(ecx)?, data)?;
@@ -397,7 +397,7 @@ fn cond_get_data<'tcx, 'a>(
 where
     'tcx: 'a,
 {
-    let cond = ecx.deref_pointer(cond_ptr)?;
+    let cond = ecx.deref_pointer_as(cond_ptr, ecx.libc_ty_layout("pthread_cond_t"))?;
     ecx.lazy_sync_get_data(
         &cond,
         cond_init_offset(ecx)?,
@@ -760,7 +760,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let this = self.eval_context_mut();
 
         let clock_id = condattr_get_clock_id(this, attr_op)?;
-        this.write_scalar(Scalar::from_i32(clock_id), &this.deref_pointer(clk_id_op)?)?;
+        this.write_scalar(
+            Scalar::from_i32(clock_id),
+            &this.deref_pointer_as(clk_id_op, this.libc_ty_layout("clockid_t"))?,
+        )?;
 
         interp_ok(())
     }
diff --git a/src/tools/miri/src/shims/unix/unnamed_socket.rs b/src/tools/miri/src/shims/unix/unnamed_socket.rs
index 08515b815a9..e183bfdf0e1 100644
--- a/src/tools/miri/src/shims/unix/unnamed_socket.rs
+++ b/src/tools/miri/src/shims/unix/unnamed_socket.rs
@@ -5,9 +5,7 @@
 use std::cell::{Cell, OnceCell, RefCell};
 use std::collections::VecDeque;
 use std::io;
-use std::io::{ErrorKind, Read};
-
-use rustc_abi::Size;
+use std::io::ErrorKind;
 
 use crate::concurrency::VClock;
 use crate::shims::files::{
@@ -92,10 +90,10 @@ impl FileDescription for AnonSocket {
         _communicate_allowed: bool,
         ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
-        anonsocket_read(self, len, ptr, dest, ecx)
+        anonsocket_read(self, ptr, len, ecx, finish)
     }
 
     fn write<'tcx>(
@@ -103,10 +101,10 @@ impl FileDescription for AnonSocket {
         _communicate_allowed: bool,
         ptr: Pointer,
         len: usize,
-        dest: &MPlaceTy<'tcx>,
         ecx: &mut MiriInterpCx<'tcx>,
+        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
     ) -> InterpResult<'tcx> {
-        anonsocket_write(self, ptr, len, dest, ecx)
+        anonsocket_write(self, ptr, len, ecx, finish)
     }
 
     fn as_unix(&self) -> &dyn UnixFileDescription {
@@ -119,25 +117,25 @@ fn anonsocket_write<'tcx>(
     self_ref: FileDescriptionRef<AnonSocket>,
     ptr: Pointer,
     len: usize,
-    dest: &MPlaceTy<'tcx>,
     ecx: &mut MiriInterpCx<'tcx>,
+    finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
 ) -> InterpResult<'tcx> {
     // Always succeed on write size 0.
     // ("If count is zero and fd refers to a file other than a regular file, the results are not specified.")
     if len == 0 {
-        return ecx.return_write_success(0, dest);
+        return finish.call(ecx, Ok(0));
     }
 
     // We are writing to our peer's readbuf.
     let Some(peer_fd) = self_ref.peer_fd().upgrade() else {
         // If the upgrade from Weak to Rc fails, it indicates that all read ends have been
         // closed. It is an error to write even if there would be space.
-        return ecx.set_last_error_and_return(ErrorKind::BrokenPipe, dest);
+        return finish.call(ecx, Err(ErrorKind::BrokenPipe.into()));
     };
 
     let Some(writebuf) = &peer_fd.readbuf else {
         // Writing to the read end of a pipe.
-        return ecx.set_last_error_and_return(IoError::LibcError("EBADF"), dest);
+        return finish.call(ecx, Err(IoError::LibcError("EBADF")));
     };
 
     // Let's see if we can write.
@@ -145,13 +143,12 @@ fn anonsocket_write<'tcx>(
     if available_space == 0 {
         if self_ref.is_nonblock {
             // Non-blocking socketpair with a full buffer.
-            return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest);
+            return finish.call(ecx, Err(ErrorKind::WouldBlock.into()));
         } else {
             self_ref.blocked_write_tid.borrow_mut().push(ecx.active_thread());
             // Blocking socketpair with a full buffer.
             // Block the current thread; only keep a weak ref for this.
             let weak_self_ref = FileDescriptionRef::downgrade(&self_ref);
-            let dest = dest.clone();
             ecx.block_thread(
                 BlockReason::UnnamedSocket,
                 None,
@@ -160,14 +157,14 @@ fn anonsocket_write<'tcx>(
                         weak_self_ref: WeakFileDescriptionRef<AnonSocket>,
                         ptr: Pointer,
                         len: usize,
-                        dest: MPlaceTy<'tcx>,
+                        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
                     }
                     |this, unblock: UnblockKind| {
                         assert_eq!(unblock, UnblockKind::Ready);
                         // If we got unblocked, then our peer successfully upgraded its weak
                         // ref to us. That means we can also upgrade our weak ref.
                         let self_ref = weak_self_ref.upgrade().unwrap();
-                        anonsocket_write(self_ref, ptr, len, &dest, this)
+                        anonsocket_write(self_ref, ptr, len, this, finish)
                     }
                 ),
             );
@@ -180,9 +177,9 @@ fn anonsocket_write<'tcx>(
             writebuf.clock.join(clock);
         });
         // Do full write / partial write based on the space available.
-        let actual_write_size = len.min(available_space);
-        let bytes = ecx.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?;
-        writebuf.buf.extend(&bytes[..actual_write_size]);
+        let write_size = len.min(available_space);
+        let actual_write_size = ecx.write_to_host(&mut writebuf.buf, write_size, ptr)?.unwrap();
+        assert_eq!(actual_write_size, write_size);
 
         // Need to stop accessing peer_fd so that it can be notified.
         drop(writebuf);
@@ -197,7 +194,7 @@ fn anonsocket_write<'tcx>(
         // The kernel does this even if the fd was already readable before, so we follow suit.
         ecx.check_and_update_readiness(peer_fd)?;
 
-        return ecx.return_write_success(actual_write_size, dest);
+        return finish.call(ecx, Ok(write_size));
     }
     interp_ok(())
 }
@@ -205,14 +202,14 @@ fn anonsocket_write<'tcx>(
 /// Read from AnonSocket and return the number of bytes read.
 fn anonsocket_read<'tcx>(
     self_ref: FileDescriptionRef<AnonSocket>,
-    len: usize,
     ptr: Pointer,
-    dest: &MPlaceTy<'tcx>,
+    len: usize,
     ecx: &mut MiriInterpCx<'tcx>,
+    finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
 ) -> InterpResult<'tcx> {
     // Always succeed on read size 0.
     if len == 0 {
-        return ecx.return_read_success(ptr, &[], 0, dest);
+        return finish.call(ecx, Ok(0));
     }
 
     let Some(readbuf) = &self_ref.readbuf else {
@@ -225,43 +222,41 @@ fn anonsocket_read<'tcx>(
         if self_ref.peer_fd().upgrade().is_none() {
             // Socketpair with no peer and empty buffer.
             // 0 bytes successfully read indicates end-of-file.
-            return ecx.return_read_success(ptr, &[], 0, dest);
+            return finish.call(ecx, Ok(0));
         } else if self_ref.is_nonblock {
             // Non-blocking socketpair with writer and empty buffer.
             // https://linux.die.net/man/2/read
             // EAGAIN or EWOULDBLOCK can be returned for socket,
             // POSIX.1-2001 allows either error to be returned for this case.
             // Since there is no ErrorKind for EAGAIN, WouldBlock is used.
-            return ecx.set_last_error_and_return(ErrorKind::WouldBlock, dest);
+            return finish.call(ecx, Err(ErrorKind::WouldBlock.into()));
         } else {
             self_ref.blocked_read_tid.borrow_mut().push(ecx.active_thread());
             // Blocking socketpair with writer and empty buffer.
             // Block the current thread; only keep a weak ref for this.
             let weak_self_ref = FileDescriptionRef::downgrade(&self_ref);
-            let dest = dest.clone();
             ecx.block_thread(
                 BlockReason::UnnamedSocket,
                 None,
                 callback!(
                     @capture<'tcx> {
                         weak_self_ref: WeakFileDescriptionRef<AnonSocket>,
-                        len: usize,
                         ptr: Pointer,
-                        dest: MPlaceTy<'tcx>,
+                        len: usize,
+                        finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
                     }
                     |this, unblock: UnblockKind| {
                         assert_eq!(unblock, UnblockKind::Ready);
                         // If we got unblocked, then our peer successfully upgraded its weak
                         // ref to us. That means we can also upgrade our weak ref.
                         let self_ref = weak_self_ref.upgrade().unwrap();
-                        anonsocket_read(self_ref, len, ptr, &dest, this)
+                        anonsocket_read(self_ref, ptr, len, this, finish)
                     }
                 ),
             );
         }
     } else {
         // There's data to be read!
-        let mut bytes = vec![0; len];
         let mut readbuf = readbuf.borrow_mut();
         // Synchronize with all previous writes to this buffer.
         // FIXME: this over-synchronizes; a more precise approach would be to
@@ -270,7 +265,7 @@ fn anonsocket_read<'tcx>(
 
         // Do full read / partial read based on the space available.
         // Conveniently, `read` exists on `VecDeque` and has exactly the desired behavior.
-        let actual_read_size = readbuf.buf.read(&mut bytes[..]).unwrap();
+        let read_size = ecx.read_from_host(&mut readbuf.buf, len, ptr)?.unwrap();
 
         // Need to drop before others can access the readbuf again.
         drop(readbuf);
@@ -293,7 +288,7 @@ fn anonsocket_read<'tcx>(
             ecx.check_and_update_readiness(peer_fd)?;
         };
 
-        return ecx.return_read_success(ptr, &bytes, actual_read_size, dest);
+        return finish.call(ecx, Ok(read_size));
     }
     interp_ok(())
 }
@@ -362,7 +357,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let domain = this.read_scalar(domain)?.to_i32()?;
         let mut flags = this.read_scalar(type_)?.to_i32()?;
         let protocol = this.read_scalar(protocol)?.to_i32()?;
-        let sv = this.deref_pointer(sv)?;
+        // This is really a pointer to `[i32; 2]` but we use a ptr-to-first-element representation.
+        let sv = this.deref_pointer_as(sv, this.machine.layouts.i32)?;
 
         let mut is_sock_nonblock = false;
 
diff --git a/src/tools/miri/src/shims/windows/env.rs b/src/tools/miri/src/shims/windows/env.rs
index 72c1fb58023..1b2ccd99ef9 100644
--- a/src/tools/miri/src/shims/windows/env.rs
+++ b/src/tools/miri/src/shims/windows/env.rs
@@ -218,7 +218,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         let token = this.read_target_isize(token)?;
         let buf = this.read_pointer(buf)?;
-        let size = this.deref_pointer(size)?;
+        let size = this.deref_pointer_as(size, this.machine.layouts.u32)?;
 
         if token != -4 {
             throw_unsup_format!(
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index 4462d025bea..fae6170a9e7 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -266,7 +266,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     Size::from_bytes(size),
                     Align::from_bytes(align).unwrap(),
                     MiriMemoryKind::WinHeap.into(),
-                    init
+                    init,
                 )?;
                 this.write_pointer(ptr, dest)?;
             }
@@ -299,7 +299,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     Size::from_bytes(size),
                     Align::from_bytes(align).unwrap(),
                     MiriMemoryKind::WinHeap.into(),
-                    AllocInit::Uninit
+                    AllocInit::Uninit,
                 )?;
                 this.write_pointer(new_ptr, dest)?;
             }
@@ -335,7 +335,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Initialize with `0`.
                 this.write_bytes_ptr(
                     system_info.ptr(),
-                    iter::repeat(0u8).take(system_info.layout.size.bytes_usize()),
+                    iter::repeat_n(0u8, system_info.layout.size.bytes_usize()),
                 )?;
                 // Set selected fields.
                 this.write_int_fields_named(
@@ -523,7 +523,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let [handle, name_ptr] = this.check_shim(abi, sys_conv, link_name, args)?;
 
                 let handle = this.read_scalar(handle)?;
-                let name_ptr = this.deref_pointer(name_ptr)?; // the pointer where we should store the ptr to the name
+                let name_ptr = this.deref_pointer_as(name_ptr, this.machine.layouts.mut_raw_ptr)?; // the pointer where we should store the ptr to the name
 
                 let thread = match Handle::try_from_scalar(handle, this)? {
                     Ok(Handle::Thread(thread)) => Ok(thread),
@@ -725,7 +725,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "GetConsoleMode" if this.frame_in_std() => {
                 let [console, mode] = this.check_shim(abi, sys_conv, link_name, args)?;
                 this.read_target_isize(console)?;
-                this.deref_pointer(mode)?;
+                this.deref_pointer_as(mode, this.machine.layouts.u32)?;
                 // Indicate an error.
                 this.write_null(dest)?;
             }
diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs
index 4001201bf67..8d5ea7db9e4 100644
--- a/src/tools/miri/src/shims/windows/sync.rs
+++ b/src/tools/miri/src/shims/windows/sync.rs
@@ -29,7 +29,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
     {
         let this = self.eval_context_mut();
 
-        let init_once = this.deref_pointer(init_once_ptr)?;
+        let init_once =
+            this.deref_pointer_as(init_once_ptr, this.windows_ty_layout("INIT_ONCE"))?;
         let init_offset = Size::ZERO;
 
         this.lazy_sync_get_data(
@@ -85,7 +86,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         let id = this.init_once_get_data(init_once_op)?.id;
         let flags = this.read_scalar(flags_op)?.to_u32()?;
-        let pending_place = this.deref_pointer(pending_op)?;
+        // PBOOL is int*
+        let pending_place = this.deref_pointer_as(pending_op, this.machine.layouts.i32)?;
         let context = this.read_pointer(context_op)?;
 
         if flags != 0 {
@@ -210,14 +212,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 .futex
                 .clone();
 
+            let dest = dest.clone();
             this.futex_wait(
                 futex_ref,
                 u32::MAX, // bitset
                 timeout,
-                Scalar::from_i32(1), // retval_succ
-                Scalar::from_i32(0), // retval_timeout
-                dest.clone(),
-                IoError::WindowsError("ERROR_TIMEOUT"), // errno_timeout
+                callback!(
+                    @capture<'tcx> {
+                        dest: MPlaceTy<'tcx>
+                    }
+                    |this, unblock: UnblockKind| {
+                        match unblock {
+                            UnblockKind::Ready => {
+                                this.write_int(1, &dest)
+                            }
+                            UnblockKind::TimedOut => {
+                                this.set_last_error(IoError::WindowsError("ERROR_TIMEOUT"))?;
+                                this.write_int(0, &dest)
+                            }
+                        }
+                    }
+                ),
             );
         }
 
@@ -242,7 +257,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         };
         let futex_ref = futex_ref.futex.clone();
 
-        this.futex_wake(&futex_ref, u32::MAX)?;
+        this.futex_wake(&futex_ref, u32::MAX, 1)?;
 
         interp_ok(())
     }
@@ -262,7 +277,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         };
         let futex_ref = futex_ref.futex.clone();
 
-        while this.futex_wake(&futex_ref, u32::MAX)? {}
+        this.futex_wake(&futex_ref, u32::MAX, usize::MAX)?;
 
         interp_ok(())
     }
diff --git a/src/tools/miri/src/shims/windows/thread.rs b/src/tools/miri/src/shims/windows/thread.rs
index efc1c2286bc..5db55404422 100644
--- a/src/tools/miri/src/shims/windows/thread.rs
+++ b/src/tools/miri/src/shims/windows/thread.rs
@@ -29,7 +29,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let thread = if this.ptr_is_null(this.read_pointer(thread_op)?)? {
             None
         } else {
-            let thread_info_place = this.deref_pointer(thread_op)?;
+            let thread_info_place = this.deref_pointer_as(thread_op, this.machine.layouts.u32)?;
             Some(thread_info_place)
         };
 
diff --git a/src/tools/miri/test_dependencies/Cargo.lock b/src/tools/miri/test_dependencies/Cargo.lock
index 0a5e9f62dd9..af92f9d0dec 100644
--- a/src/tools/miri/test_dependencies/Cargo.lock
+++ b/src/tools/miri/test_dependencies/Cargo.lock
@@ -106,6 +106,18 @@ dependencies = [
 ]
 
 [[package]]
+name = "getrandom"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.13.3+wasi-0.2.2",
+ "windows-targets",
+]
+
+[[package]]
 name = "gimli"
 version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -178,6 +190,7 @@ dependencies = [
  "cfg-if",
  "getrandom 0.1.16",
  "getrandom 0.2.15",
+ "getrandom 0.3.1",
  "libc",
  "num_cpus",
  "page_size",
@@ -360,6 +373,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
+name = "wasi"
+version = "0.13.3+wasi-0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
+[[package]]
 name = "wasm-bindgen"
 version = "0.2.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -507,3 +529,12 @@ name = "windows_x86_64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "wit-bindgen-rt"
+version = "0.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
+dependencies = [
+ "bitflags",
+]
diff --git a/src/tools/miri/test_dependencies/Cargo.toml b/src/tools/miri/test_dependencies/Cargo.toml
index e7eff46afca..78dddaf11df 100644
--- a/src/tools/miri/test_dependencies/Cargo.toml
+++ b/src/tools/miri/test_dependencies/Cargo.toml
@@ -8,13 +8,14 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
-# all dependencies (and their transitive ones) listed here can be used in `tests/`.
+# all dependencies (and their transitive ones) listed here can be used in `tests/*-dep`.
 libc = "0.2"
 num_cpus = "1.10.1"
 cfg-if = "1"
 
 getrandom_01 = { package = "getrandom", version = "0.1" }
 getrandom_02 = { package = "getrandom", version = "0.2", features = ["js"] }
+getrandom_03 = { package = "getrandom", version = "0.3" }
 
 [target.'cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))'.dependencies]
 tempfile = "3"
diff --git a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs
index 4b6f344a78e..457f32e5544 100644
--- a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs
+++ b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs
@@ -8,5 +8,5 @@ fn main() {
 fn test_file_open_missing_needed_mode() {
     let name = b"missing_arg.txt\0";
     let name_ptr = name.as_ptr().cast::<libc::c_char>();
-    let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; //~ ERROR: Undefined Behavior: incorrect number of arguments for `open(pathname, O_CREAT, ...)`: got 2, expected at least 3
+    let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; //~ ERROR: Undefined Behavior: not enough variadic arguments
 }
diff --git a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr
index ca9e3c6c4be..f48b75460d4 100644
--- a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr
+++ b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: incorrect number of arguments for `open(pathname, O_CREAT, ...)`: got 2, expected at least 3
+error: Undefined Behavior: not enough variadic arguments for `open(pathname, O_CREAT, ...)`: got 0, expected at least 1
   --> tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs:LL:CC
    |
-LL | ... { libc::open(name_ptr, libc::O_CREAT) };
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of arguments for `open(pathname, O_CREAT, ...)`: got 2, expected at least 3
+LL |     let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) };
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not enough variadic arguments for `open(pathname, O_CREAT, ...)`: got 0, expected at least 1
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/intrinsics/disjoint_bitor.rs b/src/tools/miri/tests/fail/intrinsics/disjoint_bitor.rs
new file mode 100644
index 00000000000..a7127143330
--- /dev/null
+++ b/src/tools/miri/tests/fail/intrinsics/disjoint_bitor.rs
@@ -0,0 +1,5 @@
+#![feature(core_intrinsics)]
+fn main() {
+    // one bit in common
+    unsafe { std::intrinsics::disjoint_bitor(0b01101001_u8, 0b10001110) }; //~ ERROR: Undefined Behavior
+}
diff --git a/src/tools/miri/tests/fail/intrinsics/disjoint_bitor.stderr b/src/tools/miri/tests/fail/intrinsics/disjoint_bitor.stderr
new file mode 100644
index 00000000000..82502953118
--- /dev/null
+++ b/src/tools/miri/tests/fail/intrinsics/disjoint_bitor.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: `assume` called with `false`
+  --> tests/fail/intrinsics/disjoint_bitor.rs:LL:CC
+   |
+LL |     unsafe { std::intrinsics::disjoint_bitor(0b01101001_u8, 0b10001110) };
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `assume` called with `false`
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/intrinsics/disjoint_bitor.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.rs b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.rs
new file mode 100644
index 00000000000..5a997ad8ec4
--- /dev/null
+++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.rs
@@ -0,0 +1,5 @@
+fn main() {
+    unsafe {
+        (&1_u8 as *const u8).offset_from(&2_u8); //~ERROR: not both derived from the same allocation
+    }
+}
diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr
new file mode 100644
index 00000000000..34d7c6a8021
--- /dev/null
+++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_allocs.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
+  --> tests/fail/intrinsics/ptr_offset_from_different_allocs.rs:LL:CC
+   |
+LL |         (&1_u8 as *const u8).offset_from(&2_u8);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/intrinsics/ptr_offset_from_different_allocs.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs
index 0acda559d3a..0d34e711ca7 100644
--- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs
+++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.rs
@@ -15,6 +15,6 @@ fn main() {
         let _ = p1.byte_offset_from(p1);
 
         // UB because different pointers.
-        let _ = p1.byte_offset_from(p2); //~ERROR: no provenance
+        let _ = p1.byte_offset_from(p2); //~ERROR: not both derived from the same allocation
     }
 }
diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr
index 7ef66390fcd..897945d6d5d 100644
--- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_different_ints.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: out-of-bounds `offset_from` origin: expected a pointer to the end of 1 byte of memory, but got 0xb[noalloc] which is a dangling pointer (it has no provenance)
+error: Undefined Behavior: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
   --> tests/fail/intrinsics/ptr_offset_from_different_ints.rs:LL:CC
    |
 LL |         let _ = p1.byte_offset_from(p2);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to the end of 1 byte of memory, but got 0xb[noalloc] which is a dangling pointer (it has no provenance)
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.rs b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.rs
new file mode 100644
index 00000000000..06f6b7a0117
--- /dev/null
+++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.rs
@@ -0,0 +1,7 @@
+fn main() {
+    let mem = [0u8; 1];
+    let ptr = mem.as_ptr();
+    unsafe {
+        ptr.wrapping_add(4).offset_from(ptr); //~ERROR: the memory range between them is not in-bounds of an allocation
+    }
+}
diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr
new file mode 100644
index 00000000000..67df633bef5
--- /dev/null
+++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_oob.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation
+  --> tests/fail/intrinsics/ptr_offset_from_oob.rs:LL:CC
+   |
+LL |         ptr.wrapping_add(4).offset_from(ptr);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/intrinsics/ptr_offset_from_oob.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-decl.rs b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-decl.rs
index a20539ee7c7..c557c35c9de 100644
--- a/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-decl.rs
+++ b/src/tools/miri/tests/fail/shims/backtrace/bad-backtrace-decl.rs
@@ -1,10 +1,13 @@
 extern "Rust" {
-    fn miri_get_backtrace(flags: u64) -> Box<[*mut ()]>;
+    fn miri_backtrace_size(flags: u64) -> usize;
+    fn miri_get_backtrace(flags: u64, buf: *mut *mut ());
     fn miri_resolve_frame(ptr: *mut (), flags: u64);
 }
 
 fn main() {
-    let frames = unsafe { miri_get_backtrace(0) };
+    let size = unsafe { miri_backtrace_size(0) };
+    let mut frames = vec![std::ptr::null_mut(); size];
+    unsafe { miri_get_backtrace(1, frames.as_mut_ptr()) };
     for frame in frames.iter() {
         unsafe {
             miri_resolve_frame(*frame, 0); //~ ERROR: Undefined Behavior: bad declaration of miri_resolve_frame - should return a struct with 5 fields
diff --git a/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.rs b/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.rs
new file mode 100644
index 00000000000..b920e6795f9
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.rs
@@ -0,0 +1,17 @@
+//@ignore-target: windows # File handling is not implemented yet
+//@compile-flags: -Zmiri-disable-isolation
+use std::ffi::{CString, OsStr, c_char, c_int};
+use std::os::unix::ffi::OsStrExt;
+
+// Declare a variadic function as non-variadic.
+extern "C" {
+    fn open(path: *const c_char, oflag: c_int) -> c_int;
+}
+
+fn main() {
+    let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed");
+    let _fd = unsafe {
+        open(c_path.as_ptr(), /* value does not matter */ 0)
+        //~^ ERROR: calling a variadic function with a non-variadic caller-side signature
+    };
+}
diff --git a/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr b/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr
new file mode 100644
index 00000000000..43813af9a3c
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/non_vararg_signature_mismatch.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: calling a variadic function with a non-variadic caller-side signature
+  --> tests/fail/shims/non_vararg_signature_mismatch.rs:LL:CC
+   |
+LL |         open(c_path.as_ptr(), /* value does not matter */ 0)
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling a variadic function with a non-variadic caller-side signature
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/shims/non_vararg_signature_mismatch.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs
new file mode 100644
index 00000000000..e9cb69418d2
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs
@@ -0,0 +1,16 @@
+//@ignore-target: windows # File handling is not implemented yet
+//@compile-flags: -Zmiri-disable-isolation
+use std::ffi::{CString, OsStr, c_char, c_int};
+use std::os::unix::ffi::OsStrExt;
+
+extern "C" {
+    fn open(path: *const c_char, ...) -> c_int;
+}
+
+fn main() {
+    let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed");
+    let _fd = unsafe {
+        open(c_path.as_ptr(), /* value does not matter */ 0)
+        //~^ ERROR: incorrect number of fixed arguments for variadic function
+    };
+}
diff --git a/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr
new file mode 100644
index 00000000000..12e464813cf
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: incorrect number of fixed arguments for variadic function `open`: got 1, expected 2
+  --> tests/fail/shims/wrong_fixed_arg_count.rs:LL:CC
+   |
+LL |         open(c_path.as_ptr(), /* value does not matter */ 0)
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of fixed arguments for variadic function `open`: got 1, expected 2
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/shims/wrong_fixed_arg_count.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/pass-dep/concurrency/apple-futex.rs b/src/tools/miri/tests/pass-dep/concurrency/apple-futex.rs
new file mode 100644
index 00000000000..becb90eb923
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/concurrency/apple-futex.rs
@@ -0,0 +1,276 @@
+//@only-target: darwin
+//@compile-flags: -Zmiri-preemption-rate=0
+
+use std::time::{Duration, Instant};
+use std::{io, ptr, thread};
+
+fn wake_nobody() {
+    let futex = 0;
+
+    // Wake 1 waiter. Expect ENOENT as nobody is waiting.
+    unsafe {
+        assert_eq!(
+            libc::os_sync_wake_by_address_any(
+                ptr::from_ref(&futex).cast_mut().cast(),
+                size_of::<i32>(),
+                libc::OS_SYNC_WAKE_BY_ADDRESS_NONE
+            ),
+            -1
+        );
+        assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ENOENT);
+    }
+}
+
+fn wake_dangling() {
+    let futex = Box::new(0);
+    let ptr = ptr::from_ref(&futex).cast_mut().cast();
+    drop(futex);
+
+    // Expect error since this is now "unmapped" memory.
+    unsafe {
+        assert_eq!(
+            libc::os_sync_wake_by_address_any(
+                ptr,
+                size_of::<i32>(),
+                libc::OS_SYNC_WAKE_BY_ADDRESS_NONE
+            ),
+            -1
+        );
+        assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ENOENT);
+    }
+}
+
+fn wait_wrong_val() {
+    let futex: i32 = 123;
+
+    // Only wait if the futex value is 456.
+    unsafe {
+        assert_eq!(
+            libc::os_sync_wait_on_address(
+                ptr::from_ref(&futex).cast_mut().cast(),
+                456,
+                size_of::<i32>(),
+                libc::OS_SYNC_WAIT_ON_ADDRESS_NONE
+            ),
+            0,
+        );
+    }
+}
+
+fn wait_timeout() {
+    let start = Instant::now();
+
+    let futex: i32 = 123;
+
+    // Wait for 200ms, with nobody waking us up early.
+    unsafe {
+        assert_eq!(
+            libc::os_sync_wait_on_address_with_timeout(
+                ptr::from_ref(&futex).cast_mut().cast(),
+                123,
+                size_of::<i32>(),
+                libc::OS_SYNC_WAIT_ON_ADDRESS_NONE,
+                libc::OS_CLOCK_MACH_ABSOLUTE_TIME,
+                200_000_000,
+            ),
+            -1,
+        );
+        assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
+    }
+
+    assert!((200..1000).contains(&start.elapsed().as_millis()));
+}
+
+fn wait_absolute_timeout() {
+    let start = Instant::now();
+
+    // Get the current monotonic timestamp.
+    #[allow(deprecated)]
+    let mut deadline = unsafe { libc::mach_absolute_time() };
+
+    // Add 200ms.
+    // What we should be doing here is call `mach_timebase_info` to determine the
+    // unit used for `deadline`, but we know what Miri returns for that function:
+    // the unit is nanoseconds.
+    deadline += 200_000_000;
+
+    let futex: i32 = 123;
+
+    // Wait for 200ms from now, with nobody waking us up early.
+    unsafe {
+        assert_eq!(
+            libc::os_sync_wait_on_address_with_deadline(
+                ptr::from_ref(&futex).cast_mut().cast(),
+                123,
+                size_of::<i32>(),
+                libc::OS_SYNC_WAIT_ON_ADDRESS_NONE,
+                libc::OS_CLOCK_MACH_ABSOLUTE_TIME,
+                deadline,
+            ),
+            -1,
+        );
+        assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
+    }
+
+    assert!((200..1000).contains(&start.elapsed().as_millis()));
+}
+
+fn wait_wake() {
+    let start = Instant::now();
+
+    static mut FUTEX: i32 = 0;
+
+    let t = thread::spawn(move || {
+        thread::sleep(Duration::from_millis(200));
+        unsafe {
+            assert_eq!(
+                libc::os_sync_wake_by_address_any(
+                    (&raw const FUTEX).cast_mut().cast(),
+                    size_of::<i32>(),
+                    libc::OS_SYNC_WAKE_BY_ADDRESS_NONE,
+                ),
+                0,
+            );
+        }
+    });
+
+    unsafe {
+        assert_eq!(
+            libc::os_sync_wait_on_address(
+                (&raw const FUTEX).cast_mut().cast(),
+                0,
+                size_of::<i32>(),
+                libc::OS_SYNC_WAIT_ON_ADDRESS_NONE,
+            ),
+            0,
+        );
+    }
+
+    // When running this in stress-gc mode, things can take quite long.
+    // So the timeout is 3000 ms.
+    assert!((200..3000).contains(&start.elapsed().as_millis()));
+    t.join().unwrap();
+}
+
+fn wait_wake_multiple() {
+    let val = 0i32;
+    let futex = &val;
+
+    thread::scope(|s| {
+        // Spawn some threads and make them wait on the futex.
+        for i in 0..4 {
+            s.spawn(move || unsafe {
+                assert_eq!(
+                    libc::os_sync_wait_on_address(
+                        ptr::from_ref(futex).cast_mut().cast(),
+                        0,
+                        size_of::<i32>(),
+                        libc::OS_SYNC_WAIT_ON_ADDRESS_NONE,
+                    ),
+                    // The last two threads will be woken at the same time,
+                    // but for the first two threads the remaining number
+                    // of waiters should be strictly decreasing.
+                    if i < 2 { 3 - i } else { 0 },
+                );
+            });
+
+            thread::yield_now();
+        }
+
+        // Wake the threads up again.
+        unsafe {
+            assert_eq!(
+                libc::os_sync_wake_by_address_any(
+                    ptr::from_ref(futex).cast_mut().cast(),
+                    size_of::<i32>(),
+                    libc::OS_SYNC_WAKE_BY_ADDRESS_NONE,
+                ),
+                0
+            );
+
+            assert_eq!(
+                libc::os_sync_wake_by_address_any(
+                    ptr::from_ref(futex).cast_mut().cast(),
+                    size_of::<i32>(),
+                    libc::OS_SYNC_WAKE_BY_ADDRESS_NONE,
+                ),
+                0
+            );
+
+            // Wake both remaining threads at the same time.
+            assert_eq!(
+                libc::os_sync_wake_by_address_all(
+                    ptr::from_ref(futex).cast_mut().cast(),
+                    size_of::<i32>(),
+                    libc::OS_SYNC_WAKE_BY_ADDRESS_NONE,
+                ),
+                0
+            );
+        }
+    })
+}
+
+fn param_mismatch() {
+    let futex = 0;
+    thread::scope(|s| {
+        s.spawn(|| {
+            unsafe {
+                assert_eq!(
+                    libc::os_sync_wait_on_address_with_timeout(
+                        ptr::from_ref(&futex).cast_mut().cast(),
+                        0,
+                        size_of::<i32>(),
+                        libc::OS_SYNC_WAIT_ON_ADDRESS_NONE,
+                        libc::OS_CLOCK_MACH_ABSOLUTE_TIME,
+                        400_000_000,
+                    ),
+                    -1,
+                );
+                assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
+            }
+        });
+
+        s.spawn(|| {
+            thread::yield_now();
+            unsafe {
+                assert_eq!(
+                    libc::os_sync_wait_on_address(
+                        ptr::from_ref(&futex).cast_mut().cast(),
+                        0,
+                        size_of::<i32>(),
+                        libc::OS_SYNC_WAIT_ON_ADDRESS_SHARED,
+                    ),
+                    -1,
+                );
+                // This call fails because it uses the shared flag whereas the first waiter didn't.
+                assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
+            }
+        });
+
+        thread::yield_now();
+
+        unsafe {
+            assert_eq!(
+                libc::os_sync_wake_by_address_any(
+                    ptr::from_ref(&futex).cast_mut().cast(),
+                    size_of::<i32>(),
+                    libc::OS_SYNC_WAIT_ON_ADDRESS_SHARED,
+                ),
+                -1,
+            );
+            // This call fails because it uses the shared flag whereas the waiter didn't.
+            assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
+        }
+    });
+}
+
+fn main() {
+    wake_nobody();
+    wake_dangling();
+    wait_wrong_val();
+    wait_timeout();
+    wait_absolute_timeout();
+    wait_wake();
+    wait_wake_multiple();
+    param_mismatch();
+}
diff --git a/src/tools/miri/tests/pass-dep/getrandom.rs b/src/tools/miri/tests/pass-dep/getrandom.rs
index a5bc5ec7079..d359730e7f9 100644
--- a/src/tools/miri/tests/pass-dep/getrandom.rs
+++ b/src/tools/miri/tests/pass-dep/getrandom.rs
@@ -3,7 +3,7 @@
 //@revisions: isolation no_isolation
 //@[no_isolation]compile-flags: -Zmiri-disable-isolation
 
-/// Test direct calls of getrandom 0.1 and 0.2.
+/// Test direct calls of getrandom 0.1, 0.2 and 0.3.
 fn main() {
     let mut data = vec![0; 16];
 
@@ -13,4 +13,6 @@ fn main() {
     getrandom_01::getrandom(&mut data).unwrap();
 
     getrandom_02::getrandom(&mut data).unwrap();
+
+    getrandom_03::fill(&mut data).unwrap();
 }
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs
index 23e2122ee50..dc3ab2828fa 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs
@@ -230,10 +230,10 @@ fn test_two_same_fd_in_same_epoll_instance() {
     //Two notification should be received.
     let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
     let expected_value = 5 as u64;
-    check_epoll_wait::<8>(epfd, &[
-        (expected_event, expected_value),
-        (expected_event, expected_value),
-    ]);
+    check_epoll_wait::<8>(
+        epfd,
+        &[(expected_event, expected_value), (expected_event, expected_value)],
+    );
 }
 
 fn test_epoll_eventfd() {
@@ -290,10 +290,10 @@ fn test_epoll_socketpair_both_sides() {
     let expected_value0 = fds[0] as u64;
     let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
     let expected_value1 = fds[1] as u64;
-    check_epoll_wait::<8>(epfd, &[
-        (expected_event0, expected_value0),
-        (expected_event1, expected_value1),
-    ]);
+    check_epoll_wait::<8>(
+        epfd,
+        &[(expected_event0, expected_value0), (expected_event1, expected_value1)],
+    );
 
     // Read from fds[0].
     let mut buf: [u8; 5] = [0; 5];
@@ -453,10 +453,10 @@ fn test_socketpair_read() {
     let expected_value0 = fds[0] as u64;
     let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
     let expected_value1 = fds[1] as u64;
-    check_epoll_wait::<8>(epfd, &[
-        (expected_event0, expected_value0),
-        (expected_event1, expected_value1),
-    ]);
+    check_epoll_wait::<8>(
+        epfd,
+        &[(expected_event0, expected_value0), (expected_event1, expected_value1)],
+    );
 
     // Read 3 bytes from fds[0].
     let mut buf: [u8; 3] = [0; 3];
diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs
index 9b9542b88a9..3bc953c3a5f 100644
--- a/src/tools/miri/tests/ui.rs
+++ b/src/tools/miri/tests/ui.rs
@@ -13,7 +13,7 @@ use ui_test::custom_flags::edition::Edition;
 use ui_test::dependencies::DependencyBuilder;
 use ui_test::per_test_config::TestConfig;
 use ui_test::spanned::Spanned;
-use ui_test::{CommandBuilder, Config, Format, Match, OutputConflictHandling, status_emitter};
+use ui_test::{CommandBuilder, Config, Format, Match, ignore_output_conflict, status_emitter};
 
 #[derive(Copy, Clone, Debug)]
 enum Mode {
@@ -82,9 +82,18 @@ fn build_native_lib() -> PathBuf {
     native_lib_path
 }
 
+struct WithDependencies {
+    bless: bool,
+}
+
 /// Does *not* set any args or env vars, since it is shared between the test runner and
 /// run_dep_mode.
-fn miri_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) -> Config {
+fn miri_config(
+    target: &str,
+    path: &str,
+    mode: Mode,
+    with_dependencies: Option<WithDependencies>,
+) -> Config {
     // Miri is rustc-like, so we create a default builder for rustc and modify it
     let mut program = CommandBuilder::rustc();
     program.program = miri_path();
@@ -119,22 +128,26 @@ fn miri_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) ->
     // keep in sync with `./miri run`
     config.comment_defaults.base().add_custom("edition", Edition("2021".into()));
 
-    if with_dependencies {
-        config.comment_defaults.base().set_custom("dependencies", DependencyBuilder {
-            program: CommandBuilder {
-                // Set the `cargo-miri` binary, which we expect to be in the same folder as the `miri` binary.
-                // (It's a separate crate, so we don't get an env var from cargo.)
-                program: miri_path()
-                    .with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)),
-                // There is no `cargo miri build` so we just use `cargo miri run`.
-                args: ["miri", "run"].into_iter().map(Into::into).collect(),
-                // Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>.
-                envs: vec![("RUSTFLAGS".into(), None)],
-                ..CommandBuilder::cargo()
+    if let Some(WithDependencies { bless }) = with_dependencies {
+        config.comment_defaults.base().set_custom(
+            "dependencies",
+            DependencyBuilder {
+                program: CommandBuilder {
+                    // Set the `cargo-miri` binary, which we expect to be in the same folder as the `miri` binary.
+                    // (It's a separate crate, so we don't get an env var from cargo.)
+                    program: miri_path()
+                        .with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)),
+                    // There is no `cargo miri build` so we just use `cargo miri run`.
+                    args: ["miri", "run"].into_iter().map(Into::into).collect(),
+                    // Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>.
+                    envs: vec![("RUSTFLAGS".into(), None)],
+                    ..CommandBuilder::cargo()
+                },
+                crate_manifest_path: Path::new("test_dependencies").join("Cargo.toml"),
+                build_std: None,
+                bless_lockfile: bless,
             },
-            crate_manifest_path: Path::new("test_dependencies").join("Cargo.toml"),
-            build_std: None,
-        });
+        );
     }
     config
 }
@@ -146,7 +159,20 @@ fn run_tests(
     with_dependencies: bool,
     tmpdir: &Path,
 ) -> Result<()> {
+    // Handle command-line arguments.
+    let mut args = ui_test::Args::test()?;
+    args.bless |= env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0");
+
+    let with_dependencies = with_dependencies.then_some(WithDependencies { bless: args.bless });
+
     let mut config = miri_config(target, path, mode, with_dependencies);
+    config.with_args(&args);
+    config.bless_command = Some("./miri test --bless".into());
+
+    if env::var_os("MIRI_SKIP_UI_CHECKS").is_some() {
+        assert!(!args.bless, "cannot use RUSTC_BLESS and MIRI_SKIP_UI_CHECKS at the same time");
+        config.output_conflict_handling = ignore_output_conflict;
+    }
 
     // Add a test env var to do environment communication tests.
     config.program.envs.push(("MIRI_ENV_VAR_TEST".into(), Some("0".into())));
@@ -182,16 +208,6 @@ fn run_tests(
         config.program.args.push(flag);
     }
 
-    // Handle command-line arguments.
-    let mut args = ui_test::Args::test()?;
-    args.bless |= env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0");
-    config.with_args(&args);
-    config.bless_command = Some("./miri test --bless".into());
-
-    if env::var_os("MIRI_SKIP_UI_CHECKS").is_some() {
-        assert!(!args.bless, "cannot use RUSTC_BLESS and MIRI_SKIP_UI_CHECKS at the same time");
-        config.output_conflict_handling = OutputConflictHandling::Ignore;
-    }
     eprintln!("   Compiler: {}", config.program.display());
     ui_test::run_tests_generic(
         // Only run one test suite. In the future we can add all test suites to one `Vec` and run
@@ -327,7 +343,8 @@ fn main() -> Result<()> {
 }
 
 fn run_dep_mode(target: String, args: impl Iterator<Item = OsString>) -> Result<()> {
-    let mut config = miri_config(&target, "", Mode::RunDep, /* with dependencies */ true);
+    let mut config =
+        miri_config(&target, "", Mode::RunDep, Some(WithDependencies { bless: false }));
     config.comment_defaults.base().custom.remove("edition"); // `./miri` adds an `--edition` in `args`, so don't set it twice
     config.fill_host_and_target()?;
     config.program.args = args.collect();
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 63cc8794cea..34077c5f866 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -114,14 +114,13 @@ fn default_dcx(
         false,
     );
     let emitter = Box::new(
-        HumanEmitter::new(stderr_destination(emit_color), fallback_bundle.clone())
+        HumanEmitter::new(stderr_destination(emit_color), fallback_bundle)
             .sm(Some(source_map.clone())),
     );
 
     let emitter: Box<DynEmitter> = if !show_parse_errors {
         Box::new(SilentEmitter {
-            fallback_bundle,
-            fatal_dcx: DiagCtxt::new(emitter),
+            fatal_emitter: emitter,
             fatal_note: None,
             emit_fatal_diagnostic: false,
         })
@@ -205,16 +204,7 @@ impl ParseSess {
     }
 
     pub(crate) fn set_silent_emitter(&mut self) {
-        // Ideally this invocation wouldn't be necessary and the fallback bundle in
-        // `self.parse_sess.dcx` could be used, but the lock in `DiagCtxt` prevents this.
-        // See `<rustc_errors::SilentEmitter as Translate>::fallback_fluent_bundle`.
-        let fallback_bundle = rustc_errors::fallback_fluent_bundle(
-            rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
-            false,
-        );
-        self.raw_psess
-            .dcx()
-            .make_silent(fallback_bundle, None, false);
+        self.raw_psess.dcx().make_silent(None, false);
     }
 
     pub(crate) fn span_to_filename(&self, span: Span) -> FileName {
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 2f424a482b5..9a4d0891b4a 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -12,11 +12,15 @@ miropt-test-tools = { path = "../miropt-test-tools" }
 walkdir = "2"
 ignore = "0.4.18"
 semver = "1.0"
+serde = { version = "1.0.125", features = ["derive"], optional = true }
 termcolor = "1.1.3"
 rustc-hash = "2.0.0"
 fluent-syntax = "0.11.1"
 similar = "2.5.0"
 
+[features]
+build-metrics = ["dep:serde"]
+
 [[bin]]
 name = "rust-tidy"
 path = "src/main.rs"
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 4f24eb21242..fcd7943e6e0 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -27,6 +27,7 @@ const FEATURE_GROUP_START_PREFIX: &str = "// feature-group-start";
 const FEATURE_GROUP_END_PREFIX: &str = "// feature-group-end";
 
 #[derive(Debug, PartialEq, Clone)]
+#[cfg_attr(feature = "build-metrics", derive(serde::Serialize))]
 pub enum Status {
     Accepted,
     Removed,
@@ -45,6 +46,7 @@ impl fmt::Display for Status {
 }
 
 #[derive(Debug, Clone)]
+#[cfg_attr(feature = "build-metrics", derive(serde::Serialize))]
 pub struct Feature {
     pub level: Status,
     pub since: Option<Version>,
diff --git a/src/tools/tidy/src/features/version.rs b/src/tools/tidy/src/features/version.rs
index 0830c226caf..6a902e80f8e 100644
--- a/src/tools/tidy/src/features/version.rs
+++ b/src/tools/tidy/src/features/version.rs
@@ -8,6 +8,7 @@ mod tests;
 pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[cfg_attr(feature = "build-metrics", derive(serde::Serialize))]
 pub enum Version {
     Explicit { parts: [u32; 3] },
     CurrentPlaceholder,
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 839d23fb9a7..17786ed6d2f 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -3146,7 +3146,6 @@ ui/nll/issue-97997.rs
 ui/nll/issue-98170.rs
 ui/nll/issue-98589-closures-relate-named-regions.rs
 ui/nll/issue-98693.rs
-ui/nll/polonius/issue-46589.rs
 ui/nll/relate_tys/issue-48071.rs
 ui/nll/ty-outlives/issue-53789-1.rs
 ui/nll/ty-outlives/issue-53789-2.rs
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index c650fd0eec6..c708ff7150c 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -48,8 +48,9 @@ const EXCEPTION_PATHS: &[&str] = &[
     // we must use `#[cfg(windows)]` to conditionally compile the
     // correct `VaList` structure for windows.
     "library/core/src/ffi/va_list.rs",
-    // We placed a linkage against Windows libraries here
+    // core::ffi contains platform-specific type and linkage configuration
     "library/core/src/ffi/mod.rs",
+    "library/core/src/ffi/primitives.rs",
     "library/std/src/sys", // Platform-specific code for std lives here.
     "library/std/src/os",  // Platform-specific public interfaces
     // Temporary `std` exceptions
diff --git a/tests/assembly/small_data_threshold.rs b/tests/assembly/small_data_threshold.rs
index d3ba144600e..bed515915b8 100644
--- a/tests/assembly/small_data_threshold.rs
+++ b/tests/assembly/small_data_threshold.rs
@@ -58,35 +58,35 @@ static mut Z: u64 = 0;
 // Currently, only MIPS and RISCV successfully put any objects in the small data
 // sections so the U/V/W/X tests are skipped on Hexagon and M68K
 
-//@ RISCV: .section .sdata
-//@ RISCV-NOT: .section
-//@ RISCV: U:
-//@ RISCV: .section .sbss
-//@ RISCV-NOT: .section
-//@ RISCV: V:
-//@ RISCV: .section .sdata
-//@ RISCV-NOT: .section
-//@ RISCV: W:
-//@ RISCV: .section .sbss
-//@ RISCV-NOT: .section
-//@ RISCV: X:
+// RISCV: .section .sdata
+// RISCV-NOT: .section
+// RISCV: U:
+// RISCV: .section .sbss
+// RISCV-NOT: .section
+// RISCV: V:
+// RISCV: .section .sdata
+// RISCV-NOT: .section
+// RISCV: W:
+// RISCV: .section .sbss
+// RISCV-NOT: .section
+// RISCV: X:
 
-//@ MIPS: .section .sdata
-//@ MIPS-NOT: .section
-//@ MIPS: U:
-//@ MIPS: .section .sbss
-//@ MIPS-NOT: .section
-//@ MIPS: V:
-//@ MIPS: .section .sdata
-//@ MIPS-NOT: .section
-//@ MIPS: W:
-//@ MIPS: .section .sbss
-//@ MIPS-NOT: .section
-//@ MIPS: X:
+// MIPS: .section .sdata
+// MIPS-NOT: .section
+// MIPS: U:
+// MIPS: .section .sbss
+// MIPS-NOT: .section
+// MIPS: V:
+// MIPS: .section .sdata
+// MIPS-NOT: .section
+// MIPS: W:
+// MIPS: .section .sbss
+// MIPS-NOT: .section
+// MIPS: X:
 
-//@ CHECK: .section .data.Y,
-//@ CHECK-NOT: .section
-//@ CHECK: Y:
-//@ CHECK: .section .bss.Z,
-//@ CHECK-NOT: .section
-//@ CHECK: Z:
+// CHECK: .section .data.Y,
+// CHECK-NOT: .section
+// CHECK: Y:
+// CHECK: .section .bss.Z,
+// CHECK-NOT: .section
+// CHECK: Z:
diff --git a/tests/codegen/bigint-helpers.rs b/tests/codegen/bigint-helpers.rs
new file mode 100644
index 00000000000..355cccb8150
--- /dev/null
+++ b/tests/codegen/bigint-helpers.rs
@@ -0,0 +1,13 @@
+//@ compile-flags: -C opt-level=3
+
+#![crate_type = "lib"]
+#![feature(bigint_helper_methods)]
+
+// CHECK-LABEL: @u32_carrying_add
+#[no_mangle]
+pub fn u32_carrying_add(a: u32, b: u32, c: bool) -> (u32, bool) {
+    // CHECK: @llvm.uadd.with.overflow.i32
+    // CHECK: @llvm.uadd.with.overflow.i32
+    // CHECK: or disjoint i1
+    u32::carrying_add(a, b, c)
+}
diff --git a/tests/codegen/debug-column.rs b/tests/codegen/debug-column.rs
index d14a5c29142..2aa0a8a864c 100644
--- a/tests/codegen/debug-column.rs
+++ b/tests/codegen/debug-column.rs
@@ -1,6 +1,6 @@
 // Verify that debuginfo column numbers are 1-based byte offsets.
 //
-//@ ignore-windows
+//@ ignore-msvc
 //@ compile-flags: -C debuginfo=2
 
 #[rustfmt::skip]
diff --git a/tests/codegen/force-no-unwind-tables.rs b/tests/codegen/force-no-unwind-tables.rs
index e823bedac0f..1de5e0858e0 100644
--- a/tests/codegen/force-no-unwind-tables.rs
+++ b/tests/codegen/force-no-unwind-tables.rs
@@ -1,5 +1,5 @@
 //@ compile-flags: -C no-prepopulate-passes -C panic=abort -C force-unwind-tables=n
-//@ ignore-windows
+//@ ignore-windows: unwind tables are required for panics on Windows
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/intrinsics/disjoint_bitor.rs b/tests/codegen/intrinsics/disjoint_bitor.rs
new file mode 100644
index 00000000000..fc45439ee0b
--- /dev/null
+++ b/tests/codegen/intrinsics/disjoint_bitor.rs
@@ -0,0 +1,30 @@
+//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0
+
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::disjoint_bitor;
+
+// CHECK-LABEL: @disjoint_bitor_signed
+#[no_mangle]
+pub unsafe fn disjoint_bitor_signed(x: i32, y: i32) -> i32 {
+    // CHECK: or disjoint i32 %x, %y
+    disjoint_bitor(x, y)
+}
+
+// CHECK-LABEL: @disjoint_bitor_unsigned
+#[no_mangle]
+pub unsafe fn disjoint_bitor_unsigned(x: u64, y: u64) -> u64 {
+    // CHECK: or disjoint i64 %x, %y
+    disjoint_bitor(x, y)
+}
+
+// CHECK-LABEL: @disjoint_bitor_literal
+#[no_mangle]
+pub unsafe fn disjoint_bitor_literal() -> u8 {
+    // This is a separate check because even without any passes,
+    // LLVM will fold so it's not an instruction, which can assert in LLVM.
+
+    // CHECK: store i8 3
+    disjoint_bitor(1, 2)
+}
diff --git a/tests/codegen/issues/issue-136329-optnone-noinline.rs b/tests/codegen/issues/issue-136329-optnone-noinline.rs
new file mode 100644
index 00000000000..57c9e47a499
--- /dev/null
+++ b/tests/codegen/issues/issue-136329-optnone-noinline.rs
@@ -0,0 +1,21 @@
+//! Ensure that `#[optimize(none)]` functions are never inlined
+
+//@ compile-flags: -Copt-level=3
+
+#![feature(optimize_attribute)]
+
+#[optimize(none)]
+pub fn foo() {
+    let _x = 123;
+}
+
+// CHECK-LABEL: define{{.*}}void @bar
+// CHECK: start:
+// CHECK: {{.*}}call {{.*}}void
+// CHECK: ret void
+#[no_mangle]
+pub fn bar() {
+    foo();
+}
+
+fn main() {}
diff --git a/tests/codegen/thread-local.rs b/tests/codegen/thread-local.rs
index 2ee15811cc3..3cd81652f5a 100644
--- a/tests/codegen/thread-local.rs
+++ b/tests/codegen/thread-local.rs
@@ -1,6 +1,6 @@
 //@ compile-flags: -O
 //@ aux-build:thread_local_aux.rs
-//@ ignore-windows FIXME(#84933)
+//@ ignore-windows FIXME(#134939)
 //@ ignore-wasm globals are used instead of thread locals
 //@ ignore-emscripten globals are used instead of thread locals
 //@ ignore-android does not use #[thread_local]
diff --git a/tests/crashes/125810.rs b/tests/crashes/125810.rs
deleted file mode 100644
index 4a152da8ddf..00000000000
--- a/tests/crashes/125810.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: rust-lang/rust#125810
-#![feature(arbitrary_self_types, dispatch_from_dyn)]
-
-use std::ops::{Deref, DispatchFromDyn};
-
-trait Trait<T: Deref<Target = Self> + DispatchFromDyn<T>> {
-    fn MONO_BUF(self: T) -> dyn Trait<T>;
-}
-
-fn main() {}
diff --git a/tests/crashes/132981.rs b/tests/crashes/132981.rs
index 8ff4fa36fd0..916c1559240 100644
--- a/tests/crashes/132981.rs
+++ b/tests/crashes/132981.rs
@@ -2,6 +2,10 @@
 //@compile-flags: -Clink-dead-code=true --crate-type lib
 //@ only-x86_64
 //@ ignore-windows
+// The set of targets this crashes on is really fiddly, because it is deep in our ABI logic. It
+// crashes on x86_64-unknown-linux-gnu, and i686-pc-windows-msvc, but not on
+// x86_64-pc-windows-msvc. If you are trying to fix this crash, don't pay too much attention to the
+// directives.
 
 #![feature(rust_cold_cc)]
 pub extern "rust-cold" fn foo(_: [usize; 3]) {}
diff --git a/tests/crashes/134355.rs b/tests/crashes/134355.rs
deleted file mode 100644
index b662341e6b1..00000000000
--- a/tests/crashes/134355.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ known-bug: #134355
-
-//@compile-flags: --crate-type=lib
-fn digit() -> str {
-    return { i32::MIN };
-}
diff --git a/tests/crashes/135124.rs b/tests/crashes/135124.rs
deleted file mode 100644
index d6655cb46fa..00000000000
--- a/tests/crashes/135124.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: #135124
-trait A  {
-    fn y(&self)
-    {
-        fn call() -> impl Sized {}
-        self.fold(call());
-    }
-    fn fold(&self, &self._) {}
-}
diff --git a/tests/crashes/90110.rs b/tests/crashes/90110.rs
deleted file mode 100644
index a27a1f42b7a..00000000000
--- a/tests/crashes/90110.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-//@ known-bug: #90110
-
-use std::fs::File;
-use std::io::{BufReader, BufRead};
-use std::str::Split;
-use std::path::Path;
-
-pub trait Parser<D>
-where dyn Parser<D>: Sized
-{
-    fn new(split_header: Split<&str>) -> Self where Self: Sized;
-    fn parse_line(&self, split_line: &Split<&str>) -> D;
-}
-
-
-pub struct CsvReader<D> {
-    parser: Box<dyn Parser<D>>,
-
-    reader: BufReader<File>,
-    buf: String,    // Buffer we will read into. Avoids re-allocation on each line.
-    path: String,   // Record this so we can return more informative error messages.
-    line: usize,    // Same motivation for this.
-}
-
-impl<D> CsvReader<D>
-where dyn Parser<D>: Sized
-{
-    fn new<F>(path: &str, make_parser: F) -> CsvReader<D>
-    where F: Fn(Split<char>) -> dyn Parser<D> {
-        let file = match File::open(Path::new(path)) {
-            Err(err) => panic!("Couldn't read {}: {}", path, err),
-            Ok(file) => file,
-        };
-
-        let mut reader = BufReader::new(file);
-
-        let mut buf = String::new();
-
-        let parser = Box::new(match reader.read_line(&mut buf) {
-            Err(err) => panic!("Failed to read the header line from {}: {}", path, err),
-            Ok(_) => {
-                let split_header = buf.split(',');
-                make_parser(split_header)
-            },
-        });
-
-        CsvReader {
-            parser: parser,
-            reader,
-            buf,
-            path: path.to_string(),
-            line: 2,
-        }
-    }
-}
-
-pub fn main() {}
diff --git a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir
index 60c0b8afa53..3f000dcafb0 100644
--- a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir
@@ -19,16 +19,16 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
         scope 2 {
             debug x => _9;
         }
-        scope 5 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) {
+        scope 5 (inlined iter::range::<impl Iterator for std::ops::RangeInclusive<u32>>::next) {
         }
     }
-    scope 3 (inlined RangeInclusive::<u32>::new) {
+    scope 3 (inlined std::ops::RangeInclusive::<u32>::new) {
     }
-    scope 4 (inlined <RangeInclusive<u32> as IntoIterator>::into_iter) {
+    scope 4 (inlined <std::ops::RangeInclusive<u32> as IntoIterator>::into_iter) {
     }
 
     bb0: {
-        _4 = RangeInclusive::<u32> { start: copy _1, end: copy _2, exhausted: const false };
+        _4 = std::ops::RangeInclusive::<u32> { start: copy _1, end: copy _2, exhausted: const false };
         StorageLive(_5);
         _5 = copy _4;
         goto -> bb1;
@@ -37,7 +37,7 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
     bb1: {
         StorageLive(_7);
         _6 = &mut _5;
-        _7 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind unreachable];
+        _7 = <std::ops::RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind unreachable];
     }
 
     bb2: {
diff --git a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir
index 7145da58ce1..23537173627 100644
--- a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir
@@ -19,16 +19,16 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
         scope 2 {
             debug x => _9;
         }
-        scope 5 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) {
+        scope 5 (inlined iter::range::<impl Iterator for std::ops::RangeInclusive<u32>>::next) {
         }
     }
-    scope 3 (inlined RangeInclusive::<u32>::new) {
+    scope 3 (inlined std::ops::RangeInclusive::<u32>::new) {
     }
-    scope 4 (inlined <RangeInclusive<u32> as IntoIterator>::into_iter) {
+    scope 4 (inlined <std::ops::RangeInclusive<u32> as IntoIterator>::into_iter) {
     }
 
     bb0: {
-        _4 = RangeInclusive::<u32> { start: copy _1, end: copy _2, exhausted: const false };
+        _4 = std::ops::RangeInclusive::<u32> { start: copy _1, end: copy _2, exhausted: const false };
         StorageLive(_5);
         _5 = copy _4;
         goto -> bb1;
@@ -37,7 +37,7 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
     bb1: {
         StorageLive(_7);
         _6 = &mut _5;
-        _7 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind: bb8];
+        _7 = <std::ops::RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind: bb8];
     }
 
     bb2: {
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-abort.mir
index 8e038246fa2..13969e5d238 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-abort.mir
@@ -1,13 +1,13 @@
 // MIR for `range_inclusive_iter_next` after PreCodegen
 
-fn range_inclusive_iter_next(_1: &mut RangeInclusive<u32>) -> Option<u32> {
+fn range_inclusive_iter_next(_1: &mut std::ops::RangeInclusive<u32>) -> Option<u32> {
     debug it => _1;
     let mut _0: std::option::Option<u32>;
-    scope 1 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) {
+    scope 1 (inlined iter::range::<impl Iterator for std::ops::RangeInclusive<u32>>::next) {
     }
 
     bb0: {
-        _0 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind unreachable];
+        _0 = <std::ops::RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind unreachable];
     }
 
     bb1: {
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir
index f54d003c662..98cd58284df 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir
@@ -1,13 +1,13 @@
 // MIR for `range_inclusive_iter_next` after PreCodegen
 
-fn range_inclusive_iter_next(_1: &mut RangeInclusive<u32>) -> Option<u32> {
+fn range_inclusive_iter_next(_1: &mut std::ops::RangeInclusive<u32>) -> Option<u32> {
     debug it => _1;
     let mut _0: std::option::Option<u32>;
-    scope 1 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) {
+    scope 1 (inlined iter::range::<impl Iterator for std::ops::RangeInclusive<u32>>::next) {
     }
 
     bb0: {
-        _0 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind continue];
+        _0 = <std::ops::RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
diff --git a/tests/rustdoc-json/primitives/primitive_impls.rs b/tests/rustdoc-json/primitives/primitive_impls.rs
index 77d1d68f8e4..58c222ce4f0 100644
--- a/tests/rustdoc-json/primitives/primitive_impls.rs
+++ b/tests/rustdoc-json/primitives/primitive_impls.rs
@@ -1,4 +1,4 @@
-#![feature(no_core)]
+#![feature(no_core, lang_items)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 #![no_core]
@@ -6,6 +6,9 @@
 
 //@ set impl_i32 = "$.index[*][?(@.docs=='Only core can do this')].id"
 
+#[lang = "sized"]
+trait Sized {}
+
 /// Only core can do this
 impl i32 {
     //@ set identity = "$.index[*][?(@.docs=='Do Nothing')].id"
diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs
index 6b1aa455d98..18ac37280c0 100644
--- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs
+++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs
@@ -2,9 +2,12 @@
 // feature.
 
 #![deny(warnings)]
-#![feature(no_core)]
+#![feature(no_core, lang_items)]
 #![no_core]
 
+#[lang = "sized"]
+trait Sized {}
+
 /// ```{class="}
 /// main;
 /// ```
diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr
index 385b2ccacc1..cc13cc0fe53 100644
--- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr
+++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr
@@ -1,5 +1,5 @@
 error: unclosed quote string `"`
-  --> $DIR/custom_code_classes_in_docs-warning3.rs:8:1
+  --> $DIR/custom_code_classes_in_docs-warning3.rs:11:1
    |
 LL | / /// ```{class="}
 LL | | /// main;
@@ -17,7 +17,7 @@ LL | #![deny(warnings)]
    = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]`
 
 error: unclosed quote string `"`
-  --> $DIR/custom_code_classes_in_docs-warning3.rs:8:1
+  --> $DIR/custom_code_classes_in_docs-warning3.rs:11:1
    |
 LL | / /// ```{class="}
 LL | | /// main;
diff --git a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs
index 5c9e2978e48..6fddaa49fac 100644
--- a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs
+++ b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs
@@ -1,4 +1,4 @@
-//@ ignore-windows
+//@ ignore-windows different error message
 //@ revisions: edition2015 edition2024
 //@[edition2015]edition:2015
 //@[edition2015]check-fail
diff --git a/tests/rustdoc/assoc-consts.rs b/tests/rustdoc/assoc-consts.rs
index cb8e839541c..247b5b180a8 100644
--- a/tests/rustdoc/assoc-consts.rs
+++ b/tests/rustdoc/assoc-consts.rs
@@ -45,7 +45,7 @@ pub fn f(_: &(ToString + 'static)) {}
 
 impl Bar {
     //@ has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \
-    //      "const F: fn(_: &(dyn ToString + 'static))"
+    //      "const F: fn(&(dyn ToString + 'static))"
     pub const F: fn(_: &(ToString + 'static)) = f;
 }
 
diff --git a/tests/rustdoc/cfg_doc_reexport.rs b/tests/rustdoc/cfg_doc_reexport.rs
index f8101e2a958..44ec3663284 100644
--- a/tests/rustdoc/cfg_doc_reexport.rs
+++ b/tests/rustdoc/cfg_doc_reexport.rs
@@ -1,9 +1,12 @@
 #![feature(doc_cfg)]
-#![feature(no_core)]
+#![feature(no_core, lang_items)]
 
 #![crate_name = "foo"]
 #![no_core]
 
+#[lang = "sized"]
+trait Sized {}
+
 //@ has 'foo/index.html'
 //@ has - '//dt/*[@class="stab portability"]' 'foobar'
 //@ has - '//dt/*[@class="stab portability"]' 'bar'
diff --git a/tests/rustdoc/cross-crate-primitive-doc.rs b/tests/rustdoc/cross-crate-primitive-doc.rs
index ca33dedcbae..0ffde5b0f2d 100644
--- a/tests/rustdoc/cross-crate-primitive-doc.rs
+++ b/tests/rustdoc/cross-crate-primitive-doc.rs
@@ -2,9 +2,12 @@
 //@ compile-flags: --extern-html-root-url=primitive_doc=../ -Z unstable-options
 //@ only-linux
 
-#![feature(no_core)]
+#![feature(no_core, lang_items)]
 #![no_core]
 
+#[lang = "sized"]
+trait Sized {}
+
 extern crate primitive_doc;
 
 //@ has 'cross_crate_primitive_doc/fn.foo.html' '//a[@href="../primitive_doc/primitive.usize.html"]' 'usize'
diff --git a/tests/rustdoc/fn-pointer-arg-name.rs b/tests/rustdoc/fn-pointer-arg-name.rs
index 3bde6e9ecfa..0ee1964511a 100644
--- a/tests/rustdoc/fn-pointer-arg-name.rs
+++ b/tests/rustdoc/fn-pointer-arg-name.rs
@@ -3,3 +3,11 @@
 //@ has foo/fn.f.html
 //@ has - '//pre[@class="rust item-decl"]' 'pub fn f(callback: fn(len: usize, foo: u32))'
 pub fn f(callback: fn(len: usize, foo: u32)) {}
+
+//@ has foo/fn.g.html
+//@ has - '//pre[@class="rust item-decl"]' 'pub fn g(_: fn(usize, u32))'
+pub fn g(_: fn(usize, _: u32)) {}
+
+//@ has foo/fn.mixed.html
+//@ has - '//pre[@class="rust item-decl"]' 'pub fn mixed(_: fn(_: usize, foo: u32))'
+pub fn mixed(_: fn(usize, foo: u32)) {}
diff --git a/tests/rustdoc/inherent-projections.rs b/tests/rustdoc/inherent-projections.rs
index 4fc769f70f5..ced4db9a490 100644
--- a/tests/rustdoc/inherent-projections.rs
+++ b/tests/rustdoc/inherent-projections.rs
@@ -13,7 +13,7 @@ impl Owner {
 }
 
 // Make sure we handle bound vars correctly.
-//@ has 'inherent_projections/fn.user.html' '//pre[@class="rust item-decl"]' "user(_: for<'a> fn(_: Carrier<'a>::Focus))"
+//@ has 'inherent_projections/fn.user.html' '//pre[@class="rust item-decl"]' "user(_: for<'a> fn(Carrier<'a>::Focus))"
 pub fn user(_: for<'a> fn(Carrier<'a>::Focus)) {}
 
 pub struct Carrier<'a>(&'a ());
diff --git a/tests/rustdoc/inline_local/fully-stable-path-is-better.rs b/tests/rustdoc/inline_local/fully-stable-path-is-better.rs
index 88b0b0d57b0..41bf42d2e7a 100644
--- a/tests/rustdoc/inline_local/fully-stable-path-is-better.rs
+++ b/tests/rustdoc/inline_local/fully-stable-path-is-better.rs
@@ -16,10 +16,10 @@ pub mod stb1 {
 #[unstable(feature = "uns", issue = "135003")]
 pub mod uns {
     #[stable(since = "1.0", feature = "stb1")]
-    #[rustc_allowed_through_unstable_modules]
+    #[rustc_allowed_through_unstable_modules = "use stable path instead"]
     pub struct Inside1;
     #[stable(since = "1.0", feature = "stb2")]
-    #[rustc_allowed_through_unstable_modules]
+    #[rustc_allowed_through_unstable_modules = "use stable path instead"]
     pub struct Inside2;
 }
 
diff --git a/tests/rustdoc/intra-doc/no-doc-primitive.rs b/tests/rustdoc/intra-doc/no-doc-primitive.rs
index 1f8622ab867..79825643b98 100644
--- a/tests/rustdoc/intra-doc/no-doc-primitive.rs
+++ b/tests/rustdoc/intra-doc/no-doc-primitive.rs
@@ -6,8 +6,13 @@
 #![rustc_coherence_is_core]
 #![crate_type = "rlib"]
 
+
 //@ has no_doc_primitive/index.html
 //! A [`char`] and its [`char::len_utf8`].
+
+#[lang = "sized"]
+trait Sized {}
+
 impl char {
     pub fn len_utf8(self) -> usize {
         42
diff --git a/tests/rustdoc/macro-higher-kinded-function.rs b/tests/rustdoc/macro-higher-kinded-function.rs
index f14125d1309..738ea8fb3f1 100644
--- a/tests/rustdoc/macro-higher-kinded-function.rs
+++ b/tests/rustdoc/macro-higher-kinded-function.rs
@@ -11,10 +11,10 @@ macro_rules! gen {
 }
 
 //@ has 'foo/struct.Providers.html'
-//@ has - '//*[@class="rust item-decl"]//code' "pub a: for<'tcx> fn(_: TyCtxt<'tcx>, _: u8) -> i8,"
-//@ has - '//*[@class="rust item-decl"]//code' "pub b: for<'tcx> fn(_: TyCtxt<'tcx>, _: u16) -> i16,"
-//@ has - '//*[@id="structfield.a"]/code' "a: for<'tcx> fn(_: TyCtxt<'tcx>, _: u8) -> i8"
-//@ has - '//*[@id="structfield.b"]/code' "b: for<'tcx> fn(_: TyCtxt<'tcx>, _: u16) -> i16"
+//@ has - '//*[@class="rust item-decl"]//code' "pub a: for<'tcx> fn(TyCtxt<'tcx>, u8) -> i8,"
+//@ has - '//*[@class="rust item-decl"]//code' "pub b: for<'tcx> fn(TyCtxt<'tcx>, u16) -> i16,"
+//@ has - '//*[@id="structfield.a"]/code' "a: for<'tcx> fn(TyCtxt<'tcx>, u8) -> i8"
+//@ has - '//*[@id="structfield.b"]/code' "b: for<'tcx> fn(TyCtxt<'tcx>, u16) -> i16"
 gen! {
     (a, 'tcx, [u8], [i8])
     (b, 'tcx, [u16], [i16])
diff --git a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs b/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs
index 2b21f9862b4..61060b3ff7c 100644
--- a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs
+++ b/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs
@@ -1,8 +1,11 @@
 // Regression test for <https://github.com/rust-lang/rust/issues/111064>.
-#![feature(no_core)]
+#![feature(no_core, lang_items)]
 #![no_core]
 #![crate_name = "foo"]
 
+#[lang = "sized"]
+trait Sized {}
+
 //@ files "foo" "['sidebar-items.js', 'all.html', 'hidden', 'index.html', 'struct.Bar.html', \
 //        'visible']"
 //@ files "foo/hidden" "['inner']"
diff --git a/tests/rustdoc/safe-intrinsic.rs b/tests/rustdoc/safe-intrinsic.rs
index 07af04ace60..1edc1d9f79b 100644
--- a/tests/rustdoc/safe-intrinsic.rs
+++ b/tests/rustdoc/safe-intrinsic.rs
@@ -1,10 +1,13 @@
 #![feature(intrinsics)]
-#![feature(no_core)]
+#![feature(no_core, lang_items)]
 #![feature(rustc_attrs)]
 
 #![no_core]
 #![crate_name = "foo"]
 
+#[lang = "sized"]
+trait Sized {}
+
 //@ has 'foo/fn.abort.html'
 //@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !'
 #[rustc_intrinsic]
diff --git a/tests/rustdoc/stability.rs b/tests/rustdoc/stability.rs
index b74abb0e0ba..22cd4b9cd59 100644
--- a/tests/rustdoc/stability.rs
+++ b/tests/rustdoc/stability.rs
@@ -85,7 +85,7 @@ pub mod stable_later {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_allowed_through_unstable_modules]
+#[rustc_allowed_through_unstable_modules = "use stable path instead"]
 pub mod stable_earlier1 {
     //@ has stability/stable_earlier1/struct.StableInUnstable.html \
     //      '//div[@class="main-heading"]//span[@class="since"]' '1.0.0'
diff --git a/tests/rustdoc/type-layout.rs b/tests/rustdoc/type-layout.rs
index 5f34c8b99e0..6de435dbcc1 100644
--- a/tests/rustdoc/type-layout.rs
+++ b/tests/rustdoc/type-layout.rs
@@ -86,11 +86,11 @@ pub enum WithNiche {
 }
 
 //@ hasraw type_layout/enum.Uninhabited.html 'Size: '
-//@ hasraw - '0 bytes (<a href="https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited">uninhabited</a>)'
+//@ hasraw - '0 bytes (<a href="{{channel}}/reference/glossary.html#uninhabited">uninhabited</a>)'
 pub enum Uninhabited {}
 
 //@ hasraw type_layout/struct.Uninhabited2.html 'Size: '
-//@ hasraw - '8 bytes (<a href="https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited">uninhabited</a>)'
+//@ hasraw - '8 bytes (<a href="{{channel}}/reference/glossary.html#uninhabited">uninhabited</a>)'
 pub struct Uninhabited2(std::convert::Infallible, u64);
 
 pub trait Project { type Assoc; }
diff --git a/tests/ui-fulldeps/obtain-borrowck.rs b/tests/ui-fulldeps/obtain-borrowck.rs
index f8064c245a8..c6bec4f77a0 100644
--- a/tests/ui-fulldeps/obtain-borrowck.rs
+++ b/tests/ui-fulldeps/obtain-borrowck.rs
@@ -48,7 +48,6 @@ fn main() {
         let mut callbacks = CompilerCalls::default();
         // Call the Rust compiler with our callbacks.
         rustc_driver::run_compiler(&rustc_args, &mut callbacks);
-        Ok(())
     });
     std::process::exit(exit_code);
 }
diff --git a/tests/ui-fulldeps/stable-mir/check_abi.rs b/tests/ui-fulldeps/stable-mir/check_abi.rs
index 8caf3032afc..ef2d5b4854b 100644
--- a/tests/ui-fulldeps/stable-mir/check_abi.rs
+++ b/tests/ui-fulldeps/stable-mir/check_abi.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 
 #![feature(rustc_private)]
 #![feature(assert_matches)]
diff --git a/tests/ui-fulldeps/stable-mir/check_allocation.rs b/tests/ui-fulldeps/stable-mir/check_allocation.rs
index 072c8ba6a44..c102f86a228 100644
--- a/tests/ui-fulldeps/stable-mir/check_allocation.rs
+++ b/tests/ui-fulldeps/stable-mir/check_allocation.rs
@@ -5,7 +5,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/check_attribute.rs b/tests/ui-fulldeps/stable-mir/check_attribute.rs
index 22481e275a9..11cb63f3f8a 100644
--- a/tests/ui-fulldeps/stable-mir/check_attribute.rs
+++ b/tests/ui-fulldeps/stable-mir/check_attribute.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 
 #![feature(rustc_private)]
 
diff --git a/tests/ui-fulldeps/stable-mir/check_binop.rs b/tests/ui-fulldeps/stable-mir/check_binop.rs
index 8c44e285108..65b3ffd27ab 100644
--- a/tests/ui-fulldeps/stable-mir/check_binop.rs
+++ b/tests/ui-fulldeps/stable-mir/check_binop.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 
 #![feature(rustc_private)]
 
diff --git a/tests/ui-fulldeps/stable-mir/check_crate_defs.rs b/tests/ui-fulldeps/stable-mir/check_crate_defs.rs
index ed093903381..71cca94c34f 100644
--- a/tests/ui-fulldeps/stable-mir/check_crate_defs.rs
+++ b/tests/ui-fulldeps/stable-mir/check_crate_defs.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 
 #![feature(rustc_private)]
 #![feature(assert_matches)]
diff --git a/tests/ui-fulldeps/stable-mir/check_def_ty.rs b/tests/ui-fulldeps/stable-mir/check_def_ty.rs
index 482dbd22d5f..37b9a83e33e 100644
--- a/tests/ui-fulldeps/stable-mir/check_def_ty.rs
+++ b/tests/ui-fulldeps/stable-mir/check_def_ty.rs
@@ -5,7 +5,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/check_defs.rs b/tests/ui-fulldeps/stable-mir/check_defs.rs
index bf1f1a2ceab..cd3d76d8760 100644
--- a/tests/ui-fulldeps/stable-mir/check_defs.rs
+++ b/tests/ui-fulldeps/stable-mir/check_defs.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/check_foreign.rs b/tests/ui-fulldeps/stable-mir/check_foreign.rs
index 4acbabbb6be..bc3956b3090 100644
--- a/tests/ui-fulldeps/stable-mir/check_foreign.rs
+++ b/tests/ui-fulldeps/stable-mir/check_foreign.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/check_instance.rs b/tests/ui-fulldeps/stable-mir/check_instance.rs
index 464350b1045..72a138f907e 100644
--- a/tests/ui-fulldeps/stable-mir/check_instance.rs
+++ b/tests/ui-fulldeps/stable-mir/check_instance.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
index 6edebaf756c..2f772b97886 100644
--- a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
+++ b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
@@ -8,7 +8,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 
 #![feature(rustc_private)]
 #![feature(assert_matches)]
diff --git a/tests/ui-fulldeps/stable-mir/check_item_kind.rs b/tests/ui-fulldeps/stable-mir/check_item_kind.rs
index 23b54e6c60b..647ce534589 100644
--- a/tests/ui-fulldeps/stable-mir/check_item_kind.rs
+++ b/tests/ui-fulldeps/stable-mir/check_item_kind.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/check_normalization.rs b/tests/ui-fulldeps/stable-mir/check_normalization.rs
index 928173b154b..de14202adb9 100644
--- a/tests/ui-fulldeps/stable-mir/check_normalization.rs
+++ b/tests/ui-fulldeps/stable-mir/check_normalization.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/check_trait_queries.rs b/tests/ui-fulldeps/stable-mir/check_trait_queries.rs
index 304a7ce9255..23c2844d3f1 100644
--- a/tests/ui-fulldeps/stable-mir/check_trait_queries.rs
+++ b/tests/ui-fulldeps/stable-mir/check_trait_queries.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/check_transform.rs b/tests/ui-fulldeps/stable-mir/check_transform.rs
index bcf79c456b0..d9fc924933f 100644
--- a/tests/ui-fulldeps/stable-mir/check_transform.rs
+++ b/tests/ui-fulldeps/stable-mir/check_transform.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 
 #![feature(rustc_private)]
 #![feature(assert_matches)]
diff --git a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
index e21508c9b46..9fa4929d68e 100644
--- a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
+++ b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
@@ -5,7 +5,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/compilation-result.rs b/tests/ui-fulldeps/stable-mir/compilation-result.rs
index d921de73f43..b8a9e720e54 100644
--- a/tests/ui-fulldeps/stable-mir/compilation-result.rs
+++ b/tests/ui-fulldeps/stable-mir/compilation-result.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index 53be8eb10c1..7f0e9b50335 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/projections.rs b/tests/ui-fulldeps/stable-mir/projections.rs
index fdb7eeed1b0..3cc71247e67 100644
--- a/tests/ui-fulldeps/stable-mir/projections.rs
+++ b/tests/ui-fulldeps/stable-mir/projections.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/smir_internal.rs b/tests/ui-fulldeps/stable-mir/smir_internal.rs
index 6f5478c08bf..453e5372de4 100644
--- a/tests/ui-fulldeps/stable-mir/smir_internal.rs
+++ b/tests/ui-fulldeps/stable-mir/smir_internal.rs
@@ -5,7 +5,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/smir_serde.rs b/tests/ui-fulldeps/stable-mir/smir_serde.rs
index 7dbf892f9e4..2c74276d550 100644
--- a/tests/ui-fulldeps/stable-mir/smir_serde.rs
+++ b/tests/ui-fulldeps/stable-mir/smir_serde.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui-fulldeps/stable-mir/smir_visitor.rs b/tests/ui-fulldeps/stable-mir/smir_visitor.rs
index 666000d3b07..0a6415d490e 100644
--- a/tests/ui-fulldeps/stable-mir/smir_visitor.rs
+++ b/tests/ui-fulldeps/stable-mir/smir_visitor.rs
@@ -4,7 +4,6 @@
 //@ ignore-stage1
 //@ ignore-cross-compile
 //@ ignore-remote
-//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
 //@ edition: 2021
 
 #![feature(rustc_private)]
diff --git a/tests/ui/abi/abi-sysv64-arg-passing.rs b/tests/ui/abi/abi-sysv64-arg-passing.rs
index 04942e984a8..c18752418a1 100644
--- a/tests/ui/abi/abi-sysv64-arg-passing.rs
+++ b/tests/ui/abi/abi-sysv64-arg-passing.rs
@@ -29,7 +29,8 @@
 //@ ignore-aarch64
 //@ ignore-windows
 
-// note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows
+// Windows is ignored because bootstrap doesn't yet know to compile rust_test_helpers with
+// the sysv64 ABI on Windows.
 
 #[allow(dead_code)]
 #[allow(improper_ctypes)]
diff --git a/tests/ui/abi/large-byval-align.rs b/tests/ui/abi/large-byval-align.rs
index e39170df72b..ddd579f264e 100644
--- a/tests/ui/abi/large-byval-align.rs
+++ b/tests/ui/abi/large-byval-align.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: -Copt-level=0
 //@ only-x86_64
-//@ ignore-windows
 //@ min-llvm-version: 19
 //@ build-pass
 
diff --git a/tests/ui/associated-consts/issue-58022.stderr b/tests/ui/associated-consts/issue-58022.stderr
index 82cbc9ed3b0..37cb162b2b2 100644
--- a/tests/ui/associated-consts/issue-58022.stderr
+++ b/tests/ui/associated-consts/issue-58022.stderr
@@ -1,12 +1,3 @@
-error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
-  --> $DIR/issue-58022.rs:4:25
-   |
-LL |     const SIZE: usize;
-   |     ------------------ `Foo::SIZE` defined here
-LL |
-LL |     fn new(slice: &[u8; Foo::SIZE]) -> Self;
-   |                         ^^^^^^^^^ cannot refer to the associated constant of trait
-
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> $DIR/issue-58022.rs:13:41
    |
@@ -21,6 +12,15 @@ LL | pub struct Bar<T: ?Sized>(T);
    |            ^^^
    = note: the return type of a function must have a statically known size
 
+error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
+  --> $DIR/issue-58022.rs:4:25
+   |
+LL |     const SIZE: usize;
+   |     ------------------ `Foo::SIZE` defined here
+LL |
+LL |     fn new(slice: &[u8; Foo::SIZE]) -> Self;
+   |                         ^^^^^^^^^ cannot refer to the associated constant of trait
+
 error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo`
   --> $DIR/issue-58022.rs:15:9
    |
diff --git a/tests/ui/async-await/async-closures/is-not-fn.current.stderr b/tests/ui/async-await/async-closures/is-not-fn.current.stderr
index e7be1d5b10e..0fab1c15f27 100644
--- a/tests/ui/async-await/async-closures/is-not-fn.current.stderr
+++ b/tests/ui/async-await/async-closures/is-not-fn.current.stderr
@@ -1,4 +1,4 @@
-error[E0271]: expected `{async closure@is-not-fn.rs:8:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}`
+error[E0271]: expected `{async closure@is-not-fn.rs:8:14}` to return `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}`
   --> $DIR/is-not-fn.rs:8:14
    |
 LL |     needs_fn(async || {});
diff --git a/tests/ui/async-await/async-closures/is-not-fn.next.stderr b/tests/ui/async-await/async-closures/is-not-fn.next.stderr
index e7be1d5b10e..0fab1c15f27 100644
--- a/tests/ui/async-await/async-closures/is-not-fn.next.stderr
+++ b/tests/ui/async-await/async-closures/is-not-fn.next.stderr
@@ -1,4 +1,4 @@
-error[E0271]: expected `{async closure@is-not-fn.rs:8:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}`
+error[E0271]: expected `{async closure@is-not-fn.rs:8:14}` to return `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}`
   --> $DIR/is-not-fn.rs:8:14
    |
 LL |     needs_fn(async || {});
diff --git a/tests/ui/async-await/async-closures/is-not-fn.rs b/tests/ui/async-await/async-closures/is-not-fn.rs
index eacd07b7cdd..e5ab4742dab 100644
--- a/tests/ui/async-await/async-closures/is-not-fn.rs
+++ b/tests/ui/async-await/async-closures/is-not-fn.rs
@@ -6,5 +6,5 @@
 fn main() {
     fn needs_fn(x: impl FnOnce()) {}
     needs_fn(async || {});
-    //~^ ERROR expected `{async closure@is-not-fn.rs:8:14}` to be a closure that returns `()`
+    //~^ ERROR expected `{async closure@is-not-fn.rs:8:14}` to return `()`
 }
diff --git a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr
index f478d55d10e..ce023397db9 100644
--- a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr
+++ b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr
@@ -20,7 +20,7 @@ LL |         true
    = note: expected enum `Option<()>`
               found type `bool`
 
-error[E0271]: expected `{closure@dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10}` to be a closure that returns `bool`, but it returns `Option<()>`
+error[E0271]: expected `{closure@dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10}` to return `bool`, but it returns `Option<()>`
   --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:6:16
    |
 LL |     call(|| -> Option<()> {
diff --git a/tests/ui/async-await/issue-98634.rs b/tests/ui/async-await/issue-98634.rs
index 02e869f4325..3bfc2bf8a7c 100644
--- a/tests/ui/async-await/issue-98634.rs
+++ b/tests/ui/async-await/issue-98634.rs
@@ -43,8 +43,8 @@ impl Runtime {
 fn main() {
     Runtime.block_on(async {
         StructAsync { callback }.await;
-        //~^ ERROR expected `callback` to be a fn item that returns `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
-        //~| ERROR expected `callback` to be a fn item that returns `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
-        //~| ERROR expected `callback` to be a fn item that returns `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
+        //~^ ERROR expected `callback` to return `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
+        //~| ERROR expected `callback` to return `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
+        //~| ERROR expected `callback` to return `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
     });
 }
diff --git a/tests/ui/async-await/issue-98634.stderr b/tests/ui/async-await/issue-98634.stderr
index 574904ceafa..e0739ae3a9b 100644
--- a/tests/ui/async-await/issue-98634.stderr
+++ b/tests/ui/async-await/issue-98634.stderr
@@ -1,4 +1,4 @@
-error[E0271]: expected `callback` to be a fn item that returns `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
+error[E0271]: expected `callback` to return `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
   --> $DIR/issue-98634.rs:45:23
    |
 LL |         StructAsync { callback }.await;
@@ -10,7 +10,7 @@ note: required by a bound in `StructAsync`
 LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`
 
-error[E0271]: expected `callback` to be a fn item that returns `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
+error[E0271]: expected `callback` to return `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
   --> $DIR/issue-98634.rs:45:9
    |
 LL |         StructAsync { callback }.await;
@@ -22,7 +22,7 @@ note: required by a bound in `StructAsync`
 LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`
 
-error[E0271]: expected `callback` to be a fn item that returns `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
+error[E0271]: expected `callback` to return `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
   --> $DIR/issue-98634.rs:45:34
    |
 LL |         StructAsync { callback }.await;
diff --git a/tests/ui/borrowck/already-borrowed-as-mutable-if-let-133941.rs b/tests/ui/borrowck/already-borrowed-as-mutable-if-let-133941.rs
new file mode 100644
index 00000000000..934aac8383d
--- /dev/null
+++ b/tests/ui/borrowck/already-borrowed-as-mutable-if-let-133941.rs
@@ -0,0 +1,46 @@
+// https://github.com/rust-lang/rust/issues/133941
+use std::marker::PhantomData;
+
+struct Bar<'a>(PhantomData<&'a mut i32>);
+
+impl<'a> Drop for Bar<'a> {
+    fn drop(&mut self) {}
+}
+
+struct Foo();
+
+impl Foo {
+    fn f(&mut self) -> Option<Bar<'_>> {
+        None
+    }
+
+    fn g(&mut self) {}
+}
+
+fn main() {
+    let mut foo = Foo();
+    while let Some(_) = foo.f() {
+        //~^ HELP matches!
+        foo.g();
+        //~^ ERROR [E0499]
+    }
+    if let Some(_) = foo.f() {
+        //~^ HELP matches!
+        foo.g();
+        //~^ ERROR [E0499]
+    }
+    while let Some(_x) = foo.f() {
+        foo.g();
+        //~^ ERROR [E0499]
+    }
+    if let Some(_x) = foo.f() {
+        foo.g();
+        //~^ ERROR [E0499]
+    }
+    while let Some(_x) = {let _x = foo.f(); foo.g(); None::<()>} {
+        //~^ ERROR [E0499]
+    }
+    if let Some(_x) = {let _x = foo.f(); foo.g(); None::<()>} {
+        //~^ ERROR [E0499]
+    }
+}
diff --git a/tests/ui/borrowck/already-borrowed-as-mutable-if-let-133941.stderr b/tests/ui/borrowck/already-borrowed-as-mutable-if-let-133941.stderr
new file mode 100644
index 00000000000..bb21caccbaf
--- /dev/null
+++ b/tests/ui/borrowck/already-borrowed-as-mutable-if-let-133941.stderr
@@ -0,0 +1,89 @@
+error[E0499]: cannot borrow `foo` as mutable more than once at a time
+  --> $DIR/already-borrowed-as-mutable-if-let-133941.rs:24:9
+   |
+LL |     while let Some(_) = foo.f() {
+   |                         -------
+   |                         |
+   |                         first mutable borrow occurs here
+   |                         a temporary with access to the first borrow is created here ...
+LL |
+LL |         foo.g();
+   |         ^^^ second mutable borrow occurs here
+LL |
+LL |     }
+   |     - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `Option<Bar<'_>>`
+   |
+help: consider using the `matches!` macro
+   |
+LL |     while matches!(foo.f(), Some(_)) {
+   |           ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0499]: cannot borrow `foo` as mutable more than once at a time
+  --> $DIR/already-borrowed-as-mutable-if-let-133941.rs:29:9
+   |
+LL |     if let Some(_) = foo.f() {
+   |                      -------
+   |                      |
+   |                      first mutable borrow occurs here
+   |                      a temporary with access to the first borrow is created here ...
+LL |
+LL |         foo.g();
+   |         ^^^ second mutable borrow occurs here
+LL |
+LL |     }
+   |     - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `Option<Bar<'_>>`
+   |
+help: consider using the `matches!` macro
+   |
+LL |     if matches!(foo.f(), Some(_)) {
+   |        ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0499]: cannot borrow `foo` as mutable more than once at a time
+  --> $DIR/already-borrowed-as-mutable-if-let-133941.rs:33:9
+   |
+LL |     while let Some(_x) = foo.f() {
+   |                          -------
+   |                          |
+   |                          first mutable borrow occurs here
+   |                          a temporary with access to the first borrow is created here ...
+LL |         foo.g();
+   |         ^^^ second mutable borrow occurs here
+LL |
+LL |     }
+   |     - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `Option<Bar<'_>>`
+
+error[E0499]: cannot borrow `foo` as mutable more than once at a time
+  --> $DIR/already-borrowed-as-mutable-if-let-133941.rs:37:9
+   |
+LL |     if let Some(_x) = foo.f() {
+   |                       -------
+   |                       |
+   |                       first mutable borrow occurs here
+   |                       a temporary with access to the first borrow is created here ...
+LL |         foo.g();
+   |         ^^^ second mutable borrow occurs here
+LL |
+LL |     }
+   |     - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `Option<Bar<'_>>`
+
+error[E0499]: cannot borrow `foo` as mutable more than once at a time
+  --> $DIR/already-borrowed-as-mutable-if-let-133941.rs:40:45
+   |
+LL |     while let Some(_x) = {let _x = foo.f(); foo.g(); None::<()>} {
+   |                                    ---      ^^^                - first borrow might be used here, when `_x` is dropped and runs the destructor for type `Option<Bar<'_>>`
+   |                                    |        |
+   |                                    |        second mutable borrow occurs here
+   |                                    first mutable borrow occurs here
+
+error[E0499]: cannot borrow `foo` as mutable more than once at a time
+  --> $DIR/already-borrowed-as-mutable-if-let-133941.rs:43:42
+   |
+LL |     if let Some(_x) = {let _x = foo.f(); foo.g(); None::<()>} {
+   |                                 ---      ^^^                - first borrow might be used here, when `_x` is dropped and runs the destructor for type `Option<Bar<'_>>`
+   |                                 |        |
+   |                                 |        second mutable borrow occurs here
+   |                                 first mutable borrow occurs here
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0499`.
diff --git a/tests/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.stderr b/tests/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.stderr
index 11ee8f7bb91..6e0c69a4eb0 100644
--- a/tests/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.stderr
+++ b/tests/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.stderr
@@ -4,7 +4,7 @@ error[E0712]: thread-local variable borrowed past end of function
 LL |      assert_static(&FOO);
    |                    ^^^^ thread-local variables cannot be borrowed beyond the end of the function
 LL | }
-   |  - end of enclosing function is here
+   | - end of enclosing function is here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/check-cfg/cargo-build-script.stderr b/tests/ui/check-cfg/cargo-build-script.stderr
index df0bc47571c..03a7156a4d6 100644
--- a/tests/ui/check-cfg/cargo-build-script.stderr
+++ b/tests/ui/check-cfg/cargo-build-script.stderr
@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `has_foo`
 LL | #[cfg(has_foo)]
    |       ^^^^^^^
    |
-   = help: expected names are: `has_bar` and 30 more
+   = help: expected names are: `has_bar` and 31 more
    = help: consider using a Cargo feature instead
    = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
             [lints.rust]
diff --git a/tests/ui/check-cfg/cargo-feature.none.stderr b/tests/ui/check-cfg/cargo-feature.none.stderr
index 58813a1f677..b83d1794984 100644
--- a/tests/ui/check-cfg/cargo-feature.none.stderr
+++ b/tests/ui/check-cfg/cargo-feature.none.stderr
@@ -25,7 +25,7 @@ warning: unexpected `cfg` condition name: `tokio_unstable`
 LL | #[cfg(tokio_unstable)]
    |       ^^^^^^^^^^^^^^
    |
-   = help: expected names are: `docsrs`, `feature`, and `test` and 30 more
+   = help: expected names are: `docsrs`, `feature`, and `test` and 31 more
    = help: consider using a Cargo feature instead
    = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
             [lints.rust]
diff --git a/tests/ui/check-cfg/cargo-feature.some.stderr b/tests/ui/check-cfg/cargo-feature.some.stderr
index 5a12be81338..2cddcbbcd7f 100644
--- a/tests/ui/check-cfg/cargo-feature.some.stderr
+++ b/tests/ui/check-cfg/cargo-feature.some.stderr
@@ -25,7 +25,7 @@ warning: unexpected `cfg` condition name: `tokio_unstable`
 LL | #[cfg(tokio_unstable)]
    |       ^^^^^^^^^^^^^^
    |
-   = help: expected names are: `CONFIG_NVME`, `docsrs`, `feature`, and `test` and 30 more
+   = help: expected names are: `CONFIG_NVME`, `docsrs`, `feature`, and `test` and 31 more
    = help: consider using a Cargo feature instead
    = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
             [lints.rust]
diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr
index 7c276c58170..68e1259dbb8 100644
--- a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr
+++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr
@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `value`
 LL | #[cfg(value)]
    |       ^^^^^
    |
-   = help: expected names are: `bar`, `bee`, `cow`, and `foo` and 30 more
+   = help: expected names are: `bar`, `bee`, `cow`, and `foo` and 31 more
    = help: to expect this configuration use `--check-cfg=cfg(value)`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr
index 9687a043e83..138c7fc7584 100644
--- a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr
+++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr
@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `my_value`
 LL | #[cfg(my_value)]
    |       ^^^^^^^^
    |
-   = help: expected names are: `bar` and `foo` and 30 more
+   = help: expected names are: `bar` and `foo` and 31 more
    = help: to expect this configuration use `--check-cfg=cfg(my_value)`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
diff --git a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
index 10302f0a7e4..af66cbd8189 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr
@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `unknown_key`
 LL | #[cfg(unknown_key = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: expected names are: `feature` and 30 more
+   = help: expected names are: `feature` and 31 more
    = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
diff --git a/tests/ui/check-cfg/exhaustive-names-values.full.stderr b/tests/ui/check-cfg/exhaustive-names-values.full.stderr
index 10302f0a7e4..af66cbd8189 100644
--- a/tests/ui/check-cfg/exhaustive-names-values.full.stderr
+++ b/tests/ui/check-cfg/exhaustive-names-values.full.stderr
@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `unknown_key`
 LL | #[cfg(unknown_key = "value")]
    |       ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: expected names are: `feature` and 30 more
+   = help: expected names are: `feature` and 31 more
    = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr
index 033aaef848f..be4d7c77276 100644
--- a/tests/ui/check-cfg/mix.stderr
+++ b/tests/ui/check-cfg/mix.stderr
@@ -44,7 +44,7 @@ warning: unexpected `cfg` condition name: `uu`
 LL | #[cfg_attr(uu, unix)]
    |            ^^
    |
-   = help: expected names are: `feature` and 30 more
+   = help: expected names are: `feature` and 31 more
    = help: to expect this configuration use `--check-cfg=cfg(uu)`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
diff --git a/tests/ui/check-cfg/raw-keywords.edition2015.stderr b/tests/ui/check-cfg/raw-keywords.edition2015.stderr
index f19ded9cb67..8ca33e088fc 100644
--- a/tests/ui/check-cfg/raw-keywords.edition2015.stderr
+++ b/tests/ui/check-cfg/raw-keywords.edition2015.stderr
@@ -14,7 +14,7 @@ warning: unexpected `cfg` condition name: `r#false`
 LL | #[cfg(r#false)]
    |       ^^^^^^^
    |
-   = help: expected names are: `async`, `edition2015`, `edition2021`, and `r#true` and 30 more
+   = help: expected names are: `async`, `edition2015`, `edition2021`, and `r#true` and 31 more
    = help: to expect this configuration use `--check-cfg=cfg(r#false)`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
diff --git a/tests/ui/check-cfg/raw-keywords.edition2021.stderr b/tests/ui/check-cfg/raw-keywords.edition2021.stderr
index 6096148a259..cce55720bdd 100644
--- a/tests/ui/check-cfg/raw-keywords.edition2021.stderr
+++ b/tests/ui/check-cfg/raw-keywords.edition2021.stderr
@@ -14,7 +14,7 @@ warning: unexpected `cfg` condition name: `r#false`
 LL | #[cfg(r#false)]
    |       ^^^^^^^
    |
-   = help: expected names are: `r#async`, `edition2015`, `edition2021`, and `r#true` and 30 more
+   = help: expected names are: `r#async`, `edition2015`, `edition2021`, and `r#true` and 31 more
    = help: to expect this configuration use `--check-cfg=cfg(r#false)`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
diff --git a/tests/ui/check-cfg/report-in-external-macros.cargo.stderr b/tests/ui/check-cfg/report-in-external-macros.cargo.stderr
index a6584d777a3..989a01f2244 100644
--- a/tests/ui/check-cfg/report-in-external-macros.cargo.stderr
+++ b/tests/ui/check-cfg/report-in-external-macros.cargo.stderr
@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `my_lib_cfg`
 LL |     cfg_macro::my_lib_macro!();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: expected names are: `feature` and 30 more
+   = help: expected names are: `feature` and 31 more
    = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
    = help: try referring to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg
    = help: the macro `cfg_macro::my_lib_macro` may come from an old version of the `cfg_macro` crate, try updating your dependency with `cargo update -p cfg_macro`
diff --git a/tests/ui/check-cfg/report-in-external-macros.rustc.stderr b/tests/ui/check-cfg/report-in-external-macros.rustc.stderr
index 914b5a0efe3..95d10e014f3 100644
--- a/tests/ui/check-cfg/report-in-external-macros.rustc.stderr
+++ b/tests/ui/check-cfg/report-in-external-macros.rustc.stderr
@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `my_lib_cfg`
 LL |     cfg_macro::my_lib_macro!();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: expected names are: `feature` and 30 more
+   = help: expected names are: `feature` and 31 more
    = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
    = help: try referring to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg
    = help: to expect this configuration use `--check-cfg=cfg(my_lib_cfg)`
diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr
index bf54d17f6ec..70852423bdb 100644
--- a/tests/ui/check-cfg/target_feature.stderr
+++ b/tests/ui/check-cfg/target_feature.stderr
@@ -127,6 +127,7 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `isa-68881`
 `isa-68882`
 `jsconv`
+`kl`
 `lahfsahf`
 `lasx`
 `lbt`
@@ -271,6 +272,7 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `vsx`
 `wfxt`
 `wide-arithmetic`
+`widekl`
 `x87`
 `xop`
 `xsave`
diff --git a/tests/ui/check-cfg/well-known-names.stderr b/tests/ui/check-cfg/well-known-names.stderr
index 4ff90261158..000315443f8 100644
--- a/tests/ui/check-cfg/well-known-names.stderr
+++ b/tests/ui/check-cfg/well-known-names.stderr
@@ -5,6 +5,7 @@ LL | #[cfg(list_all_well_known_cfgs)]
    |       ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: expected names are: `clippy`
+`contract_checks`
 `debug_assertions`
 `doc`
 `doctest`
diff --git a/tests/ui/closures/return-type-doesnt-match-bound.rs b/tests/ui/closures/return-type-doesnt-match-bound.rs
index f9098d0cb5c..af15385d4b0 100644
--- a/tests/ui/closures/return-type-doesnt-match-bound.rs
+++ b/tests/ui/closures/return-type-doesnt-match-bound.rs
@@ -5,7 +5,7 @@ fn foo<F>(f: F) -> ()
 where
     F: FnOnce() -> Result<(), Box<dyn Error>>,
 {
-    f().or_else(|e| -> ! { //~ ERROR to be a closure that returns
+    f().or_else(|e| -> ! { //~ ERROR to return
         eprintln!("{:?}", e);
         exit(1)
     });
@@ -15,7 +15,7 @@ fn bar<F>(f: F) -> ()
 where
     F: FnOnce() -> Result<(), Box<dyn Error>>,
 {
-    let c = |e| -> ! { //~ ERROR to be a closure that returns
+    let c = |e| -> ! { //~ ERROR to return
         eprintln!("{:?}", e);
         exit(1)
     };
diff --git a/tests/ui/closures/return-type-doesnt-match-bound.stderr b/tests/ui/closures/return-type-doesnt-match-bound.stderr
index f796a5552ac..c0bc2f6084c 100644
--- a/tests/ui/closures/return-type-doesnt-match-bound.stderr
+++ b/tests/ui/closures/return-type-doesnt-match-bound.stderr
@@ -1,4 +1,4 @@
-error[E0271]: expected `{closure@return-type-doesnt-match-bound.rs:8:17}` to be a closure that returns `Result<(), _>`, but it returns `!`
+error[E0271]: expected `{closure@return-type-doesnt-match-bound.rs:8:17}` to return `Result<(), _>`, but it returns `!`
   --> $DIR/return-type-doesnt-match-bound.rs:8:24
    |
 LL |     f().or_else(|e| -> ! {
@@ -13,7 +13,7 @@ LL |     f().or_else(|e| -> ! {
 note: required by a bound in `Result::<T, E>::or_else`
   --> $SRC_DIR/core/src/result.rs:LL:COL
 
-error[E0271]: expected `{closure@return-type-doesnt-match-bound.rs:18:13}` to be a closure that returns `Result<(), _>`, but it returns `!`
+error[E0271]: expected `{closure@return-type-doesnt-match-bound.rs:18:13}` to return `Result<(), _>`, but it returns `!`
   --> $DIR/return-type-doesnt-match-bound.rs:18:20
    |
 LL |     let c = |e| -> ! {
diff --git a/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr b/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr
index 0c220a13876..b682bdac034 100644
--- a/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr
+++ b/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr
@@ -29,7 +29,7 @@ error[E0308]: mismatched types
   --> $DIR/coerce-expect-unsized-ascribed.rs:14:27
    |
 LL |     let _ = type_ascribe!(Box::new( { |x| (x as u8) }), Box<dyn Fn(i32) -> _>);
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Fn(i32) -> u8>`, found `Box<{closure@coerce-expect-unsized-ascribed.rs:14:39}>`
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Fn(i32) -> u8>`, found `Box<{closure@...}>`
    |
    = note: expected struct `Box<dyn Fn(i32) -> u8>`
               found struct `Box<{closure@$DIR/coerce-expect-unsized-ascribed.rs:14:39: 14:42}>`
@@ -85,7 +85,7 @@ error[E0308]: mismatched types
   --> $DIR/coerce-expect-unsized-ascribed.rs:22:27
    |
 LL |     let _ = type_ascribe!(&{ |x| (x as u8) }, &dyn Fn(i32) -> _);
-   |                           ^^^^^^^^^^^^^^^^^^ expected `&dyn Fn(i32) -> u8`, found `&{closure@coerce-expect-unsized-ascribed.rs:22:30}`
+   |                           ^^^^^^^^^^^^^^^^^^ expected `&dyn Fn(i32) -> u8`, found `&{closure@...}`
    |
    = note: expected reference `&dyn Fn(i32) -> u8`
               found reference `&{closure@$DIR/coerce-expect-unsized-ascribed.rs:22:30: 22:33}`
@@ -123,7 +123,7 @@ error[E0308]: mismatched types
   --> $DIR/coerce-expect-unsized-ascribed.rs:27:27
    |
 LL |     let _ = type_ascribe!(Box::new(|x| (x as u8)), Box<dyn Fn(i32) -> _>);
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Fn(i32) -> u8>`, found `Box<{closure@coerce-expect-unsized-ascribed.rs:27:36}>`
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Fn(i32) -> u8>`, found `Box<{closure@...}>`
    |
    = note: expected struct `Box<dyn Fn(i32) -> u8>`
               found struct `Box<{closure@$DIR/coerce-expect-unsized-ascribed.rs:27:36: 27:39}>`
diff --git a/tests/ui/const-generics/std/const-generics-range.full.stderr b/tests/ui/const-generics/std/const-generics-range.full.stderr
index 5bf48ad7385..2b5c63e6643 100644
--- a/tests/ui/const-generics/std/const-generics-range.full.stderr
+++ b/tests/ui/const-generics/std/const-generics-range.full.stderr
@@ -4,7 +4,7 @@ error[E0741]: `std::ops::Range<usize>` must implement `ConstParamTy` to be used
 LL | struct _Range<const R: std::ops::Range<usize>>;
    |                        ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0741]: `RangeFrom<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
+error[E0741]: `std::ops::RangeFrom<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
   --> $DIR/const-generics-range.rs:13:28
    |
 LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
@@ -16,7 +16,7 @@ error[E0741]: `RangeFull` must implement `ConstParamTy` to be used as the type o
 LL | struct _RangeFull<const R: std::ops::RangeFull>;
    |                            ^^^^^^^^^^^^^^^^^^^
 
-error[E0741]: `RangeInclusive<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
+error[E0741]: `std::ops::RangeInclusive<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
   --> $DIR/const-generics-range.rs:24:33
    |
 LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
diff --git a/tests/ui/const-generics/std/const-generics-range.min.stderr b/tests/ui/const-generics/std/const-generics-range.min.stderr
index fd23b9b248a..04e3fe74453 100644
--- a/tests/ui/const-generics/std/const-generics-range.min.stderr
+++ b/tests/ui/const-generics/std/const-generics-range.min.stderr
@@ -10,7 +10,7 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
 LL + #![feature(adt_const_params)]
    |
 
-error: `RangeFrom<usize>` is forbidden as the type of a const generic parameter
+error: `std::ops::RangeFrom<usize>` is forbidden as the type of a const generic parameter
   --> $DIR/const-generics-range.rs:13:28
    |
 LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
@@ -34,7 +34,7 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
 LL + #![feature(adt_const_params)]
    |
 
-error: `RangeInclusive<usize>` is forbidden as the type of a const generic parameter
+error: `std::ops::RangeInclusive<usize>` is forbidden as the type of a const generic parameter
   --> $DIR/const-generics-range.rs:24:33
    |
 LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
diff --git a/tests/ui/const-generics/std/const-generics-range.rs b/tests/ui/const-generics/std/const-generics-range.rs
index f959f1e2949..3a238ed177e 100644
--- a/tests/ui/const-generics/std/const-generics-range.rs
+++ b/tests/ui/const-generics/std/const-generics-range.rs
@@ -11,7 +11,7 @@ const RANGE : _Range<{ 0 .. 1000 }> = _Range;
 
 // `RangeFrom` should be usable within const generics:
 struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
-//[min]~^ ERROR `RangeFrom<usize>` is forbidden
+//[min]~^ ERROR `std::ops::RangeFrom<usize>` is forbidden
 const RANGE_FROM : _RangeFrom<{ 0 .. }> = _RangeFrom;
 
 // `RangeFull` should be usable within const generics:
@@ -22,7 +22,7 @@ const RANGE_FULL : _RangeFull<{ .. }> = _RangeFull;
 // Regression test for #70155
 // `RangeInclusive` should be usable within const generics:
 struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
-//[min]~^ ERROR `RangeInclusive<usize>` is forbidden
+//[min]~^ ERROR `std::ops::RangeInclusive<usize>` is forbidden
 const RANGE_INCLUSIVE : _RangeInclusive<{ 0 ..= 999 }> = _RangeInclusive;
 
 // `RangeTo` should be usable within const generics:
diff --git a/tests/ui/const-ptr/forbidden_slices.stderr b/tests/ui/const-ptr/forbidden_slices.stderr
index fad078ad2b2..2e0c04dcf1e 100644
--- a/tests/ui/const-ptr/forbidden_slices.stderr
+++ b/tests/ui/const-ptr/forbidden_slices.stderr
@@ -190,7 +190,7 @@ LL |     from_ptr_range(ptr..ptr.add(1))
 error[E0080]: could not evaluate static initializer
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
    |
-   = note: `ptr_offset_from_unsigned` called on pointers into different allocations
+   = note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
    |
 note: inside `std::ptr::const_ptr::<impl *const u32>::sub_ptr`
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
@@ -205,7 +205,7 @@ LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).ad
 error[E0080]: could not evaluate static initializer
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
    |
-   = note: `ptr_offset_from_unsigned` called on pointers into different allocations
+   = note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
    |
 note: inside `std::ptr::const_ptr::<impl *const u32>::sub_ptr`
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
diff --git a/tests/ui/consts/const-slice-array-deref.rs b/tests/ui/consts/const-slice-array-deref.rs
index 9d84ed4bdb0..99563ac968c 100644
--- a/tests/ui/consts/const-slice-array-deref.rs
+++ b/tests/ui/consts/const-slice-array-deref.rs
@@ -1,6 +1,5 @@
 const ONE: [u16] = [1];
 //~^ ERROR the size for values of type `[u16]` cannot be known at compilation time
-//~| ERROR the size for values of type `[u16]` cannot be known at compilation time
 //~| ERROR mismatched types
 
 const TWO: &'static u16 = &ONE[0];
diff --git a/tests/ui/consts/const-slice-array-deref.stderr b/tests/ui/consts/const-slice-array-deref.stderr
index 6e69744144e..346685380cc 100644
--- a/tests/ui/consts/const-slice-array-deref.stderr
+++ b/tests/ui/consts/const-slice-array-deref.stderr
@@ -12,22 +12,13 @@ error[E0308]: mismatched types
 LL | const ONE: [u16] = [1];
    |                    ^^^ expected `[u16]`, found `[u16; 1]`
 
-error[E0277]: the size for values of type `[u16]` cannot be known at compilation time
-  --> $DIR/const-slice-array-deref.rs:1:20
-   |
-LL | const ONE: [u16] = [1];
-   |                    ^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[u16]`
-   = note: constant expressions must have a statically known size
-
 error[E0161]: cannot move a value of type `[u16]`
-  --> $DIR/const-slice-array-deref.rs:6:28
+  --> $DIR/const-slice-array-deref.rs:5:28
    |
 LL | const TWO: &'static u16 = &ONE[0];
    |                            ^^^ the size of `[u16]` cannot be statically determined
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0161, E0277, E0308.
 For more information about an error, try `rustc --explain E0161`.
diff --git a/tests/ui/consts/const-unsized.rs b/tests/ui/consts/const-unsized.rs
index 18682aa6eb6..e8af3323ceb 100644
--- a/tests/ui/consts/const-unsized.rs
+++ b/tests/ui/consts/const-unsized.rs
@@ -2,19 +2,19 @@ use std::fmt::Debug;
 
 const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
 //~^ ERROR the size for values of type
-//~| ERROR the size for values of type
+//~| ERROR cannot move out of a shared reference
 
 const CONST_FOO: str = *"foo";
 //~^ ERROR the size for values of type
-//~| ERROR the size for values of type
+//~| ERROR cannot move out of a shared reference
 
 static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
 //~^ ERROR the size for values of type
-//~| ERROR the size for values of type
+//~| ERROR cannot move out of a shared reference
 
 static STATIC_BAR: str = *"bar";
 //~^ ERROR the size for values of type
-//~| ERROR the size for values of type
+//~| ERROR cannot move out of a shared reference
 
 fn main() {
     println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
diff --git a/tests/ui/consts/const-unsized.stderr b/tests/ui/consts/const-unsized.stderr
index 0b69cad9651..7931d7adafd 100644
--- a/tests/ui/consts/const-unsized.stderr
+++ b/tests/ui/consts/const-unsized.stderr
@@ -6,15 +6,6 @@ LL | const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
    |
    = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
 
-error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
-  --> $DIR/const-unsized.rs:3:35
-   |
-LL | const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
-   = note: constant expressions must have a statically known size
-
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/const-unsized.rs:7:18
    |
@@ -23,15 +14,6 @@ LL | const CONST_FOO: str = *"foo";
    |
    = help: the trait `Sized` is not implemented for `str`
 
-error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/const-unsized.rs:7:24
-   |
-LL | const CONST_FOO: str = *"foo";
-   |                        ^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `str`
-   = note: constant expressions must have a statically known size
-
 error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
   --> $DIR/const-unsized.rs:11:18
    |
@@ -40,15 +22,6 @@ LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
    |
    = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
 
-error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
-  --> $DIR/const-unsized.rs:11:37
-   |
-LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
-   = note: constant expressions must have a statically known size
-
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/const-unsized.rs:15:20
    |
@@ -57,14 +30,29 @@ LL | static STATIC_BAR: str = *"bar";
    |
    = help: the trait `Sized` is not implemented for `str`
 
-error[E0277]: the size for values of type `str` cannot be known at compilation time
+error[E0507]: cannot move out of a shared reference
+  --> $DIR/const-unsized.rs:3:35
+   |
+LL | const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `dyn Debug + Sync`, which does not implement the `Copy` trait
+
+error[E0507]: cannot move out of a shared reference
+  --> $DIR/const-unsized.rs:7:24
+   |
+LL | const CONST_FOO: str = *"foo";
+   |                        ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
+
+error[E0507]: cannot move out of a shared reference
+  --> $DIR/const-unsized.rs:11:37
+   |
+LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `dyn Debug + Sync`, which does not implement the `Copy` trait
+
+error[E0507]: cannot move out of a shared reference
   --> $DIR/const-unsized.rs:15:26
    |
 LL | static STATIC_BAR: str = *"bar";
-   |                          ^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `str`
-   = note: constant expressions must have a statically known size
+   |                          ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
 
 error[E0161]: cannot move a value of type `str`
   --> $DIR/const-unsized.rs:20:48
@@ -80,5 +68,5 @@ LL |     println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATI
 
 error: aborting due to 10 previous errors
 
-Some errors have detailed explanations: E0161, E0277.
+Some errors have detailed explanations: E0161, E0277, E0507.
 For more information about an error, try `rustc --explain E0161`.
diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.rs b/tests/ui/consts/const_refs_to_static-ice-121413.rs
index 7ef67d9a984..432ae1ad5e3 100644
--- a/tests/ui/consts/const_refs_to_static-ice-121413.rs
+++ b/tests/ui/consts/const_refs_to_static-ice-121413.rs
@@ -9,11 +9,9 @@ const REF_INTERIOR_MUT: &usize = {
     //~^ ERROR failed to resolve: use of undeclared type `AtomicUsize`
     //~| WARN trait objects without an explicit `dyn` are deprecated
     //~| ERROR the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
-    //~| ERROR the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
     //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
     //~| HELP if this is a dyn-compatible trait, use `dyn`
     //~| HELP the trait `Sized` is not implemented for `(dyn Sync + 'static)`
-    //~| HELP the trait `Sized` is not implemented for `(dyn Sync + 'static)`
     unsafe { &*(&FOO as *const _ as *const usize) }
 };
 pub fn main() {}
diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.stderr b/tests/ui/consts/const_refs_to_static-ice-121413.stderr
index 7beb43d84fb..8665d9b6852 100644
--- a/tests/ui/consts/const_refs_to_static-ice-121413.stderr
+++ b/tests/ui/consts/const_refs_to_static-ice-121413.stderr
@@ -31,16 +31,7 @@ LL |     static FOO: Sync = AtomicUsize::new(0);
    |
    = help: the trait `Sized` is not implemented for `(dyn Sync + 'static)`
 
-error[E0277]: the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
-  --> $DIR/const_refs_to_static-ice-121413.rs:8:24
-   |
-LL |     static FOO: Sync = AtomicUsize::new(0);
-   |                        ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Sync + 'static)`
-   = note: constant expressions must have a statically known size
-
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0277, E0433.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/offset_from_ub.rs b/tests/ui/consts/offset_from_ub.rs
index 0232b03a813..88356900605 100644
--- a/tests/ui/consts/offset_from_ub.rs
+++ b/tests/ui/consts/offset_from_ub.rs
@@ -17,7 +17,7 @@ pub const DIFFERENT_ALLOC: usize = {
     let uninit2 = std::mem::MaybeUninit::<Struct>::uninit();
     let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct;
     let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; //~ERROR evaluation of constant value failed
-    //~| pointers into different allocations
+    //~| not both derived from the same allocation
     offset as usize
 };
 
@@ -37,7 +37,7 @@ pub const DIFFERENT_INT: isize = { // offset_from with two different integers: l
     let ptr1 = 8 as *const u8;
     let ptr2 = 16 as *const u8;
     unsafe { ptr_offset_from(ptr2, ptr1) } //~ERROR evaluation of constant value failed
-    //~| dangling pointer
+    //~| not both derived from the same allocation
 };
 
 const OUT_OF_BOUNDS_1: isize = {
@@ -46,7 +46,7 @@ const OUT_OF_BOUNDS_1: isize = {
     let end_ptr = (start_ptr).wrapping_add(length);
     // First ptr is out of bounds
     unsafe { ptr_offset_from(end_ptr, start_ptr) } //~ERROR evaluation of constant value failed
-    //~| expected a pointer to 10 bytes of memory
+    //~| the memory range between them is not in-bounds of an allocation
 };
 
 const OUT_OF_BOUNDS_2: isize = {
@@ -55,7 +55,7 @@ const OUT_OF_BOUNDS_2: isize = {
     let end_ptr = (start_ptr).wrapping_add(length);
     // Second ptr is out of bounds
     unsafe { ptr_offset_from(start_ptr, end_ptr) } //~ERROR evaluation of constant value failed
-    //~| expected a pointer to the end of 10 bytes of memory
+    //~| the memory range between them is not in-bounds of an allocation
 };
 
 pub const DIFFERENT_ALLOC_UNSIGNED: usize = {
@@ -64,7 +64,7 @@ pub const DIFFERENT_ALLOC_UNSIGNED: usize = {
     let uninit2 = std::mem::MaybeUninit::<Struct>::uninit();
     let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct;
     unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) } //~ERROR evaluation of constant value failed
-    //~| pointers into different allocations
+    //~| not both derived from the same allocation
 };
 
 pub const TOO_FAR_APART1: isize = {
diff --git a/tests/ui/consts/offset_from_ub.stderr b/tests/ui/consts/offset_from_ub.stderr
index ac4597ff011..1379365cc25 100644
--- a/tests/ui/consts/offset_from_ub.stderr
+++ b/tests/ui/consts/offset_from_ub.stderr
@@ -2,12 +2,12 @@ error[E0080]: evaluation of constant value failed
   --> $DIR/offset_from_ub.rs:19:27
    |
 LL |     let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) };
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on pointers into different allocations
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
 
 error[E0080]: evaluation of constant value failed
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
    |
-   = note: `ptr_offset_from` called on pointers into different allocations
+   = note: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
    |
 note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
@@ -27,25 +27,25 @@ error[E0080]: evaluation of constant value failed
   --> $DIR/offset_from_ub.rs:39:14
    |
 LL |     unsafe { ptr_offset_from(ptr2, ptr1) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to $BYTES bytes of memory, but got 0x8[noalloc] which is a dangling pointer (it has no provenance)
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/offset_from_ub.rs:48:14
    |
 LL |     unsafe { ptr_offset_from(end_ptr, start_ptr) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to $BYTES bytes of memory, but got ALLOC0 which is only $BYTES bytes from the end of the allocation
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/offset_from_ub.rs:57:14
    |
 LL |     unsafe { ptr_offset_from(start_ptr, end_ptr) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to the end of $BYTES bytes of memory, but got ALLOC1+0xa which does not have enough space to the beginning of the allocation
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/offset_from_ub.rs:66:14
    |
 LL |     unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/offset_from_ub.rs:73:14
@@ -80,7 +80,7 @@ LL |     unsafe { ptr_offset_from_unsigned(ptr2, ptr1) }
 error[E0080]: evaluation of constant value failed
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
    |
-   = note: out-of-bounds `offset_from` origin: expected a pointer to $BYTES bytes of memory, but got a null pointer
+   = note: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
    |
 note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
diff --git a/tests/ui/contracts/contract-annotation-limitations.rs b/tests/ui/contracts/contract-annotation-limitations.rs
new file mode 100644
index 00000000000..10b3bacab5c
--- /dev/null
+++ b/tests/ui/contracts/contract-annotation-limitations.rs
@@ -0,0 +1,28 @@
+//! Test for some of the existing limitations and the current error messages.
+//! Some of these limitations may be removed in the future.
+
+#![feature(contracts)]
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+#![allow(dead_code)]
+
+/// Represent a 5-star system.
+struct Stars(u8);
+
+impl Stars {
+    fn is_valid(&self) -> bool {
+        self.0 <= 5
+    }
+}
+
+trait ParseStars {
+    #[core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
+    //~^ ERROR contract annotations is only supported in functions with bodies
+    fn parse_string(input: String) -> Option<Stars>;
+
+    #[core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
+    //~^ ERROR contract annotations is only supported in functions with bodies
+    fn parse<T>(input: T) -> Option<Stars> where T: for<'a> Into<&'a str>;
+}
+
+fn main() {
+}
diff --git a/tests/ui/contracts/contract-annotation-limitations.stderr b/tests/ui/contracts/contract-annotation-limitations.stderr
new file mode 100644
index 00000000000..14338cf4b86
--- /dev/null
+++ b/tests/ui/contracts/contract-annotation-limitations.stderr
@@ -0,0 +1,23 @@
+error: contract annotations is only supported in functions with bodies
+  --> $DIR/contract-annotation-limitations.rs:18:5
+   |
+LL |     #[core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: contract annotations is only supported in functions with bodies
+  --> $DIR/contract-annotation-limitations.rs:22:5
+   |
+LL |     #[core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-annotation-limitations.rs:4:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr b/tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr
new file mode 100644
index 00000000000..0630811d4f7
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-generics.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr b/tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr
new file mode 100644
index 00000000000..0630811d4f7
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-generics.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr
new file mode 100644
index 00000000000..0630811d4f7
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-generics.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-generics.chk_pass.stderr b/tests/ui/contracts/contract-attributes-generics.chk_pass.stderr
new file mode 100644
index 00000000000..0630811d4f7
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-generics.chk_pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-generics.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-generics.rs b/tests/ui/contracts/contract-attributes-generics.rs
new file mode 100644
index 00000000000..fd79c6abedd
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-generics.rs
@@ -0,0 +1,71 @@
+//! Test that contracts can be applied to generic functions.
+
+//@ revisions: unchk_pass chk_pass chk_fail_pre chk_fail_post chk_const_fail
+//
+//@ [unchk_pass] run-pass
+//@ [chk_pass] run-pass
+//
+//@ [chk_fail_pre] run-fail
+//@ [chk_fail_post] run-fail
+//@ [chk_const_fail] run-fail
+//
+//@ [unchk_pass] compile-flags: -Zcontract-checks=no
+//
+//@ [chk_pass] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_post] compile-flags: -Zcontract-checks=yes
+//@ [chk_const_fail] compile-flags: -Zcontract-checks=yes
+
+#![feature(contracts)]
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+
+use std::ops::Sub;
+
+/// Dummy fn contract that precondition fails for val < 0, and post-condition fail for val == 1
+#[core::contracts::requires(val > 0u8.into())]
+#[core::contracts::ensures(|ret| *ret > 0u8.into())]
+fn decrement<T>(val: T) -> T
+where T: PartialOrd + Sub<Output=T> + From<u8>
+{
+    val - 1u8.into()
+}
+
+/// Create a structure that takes a constant parameter.
+#[allow(dead_code)]
+struct Capped<const MAX: usize>(usize);
+
+/// Now declare a function to create stars which shouldn't exceed 5 stars.
+// Add redundant braces to ensure the built-in macro can handle this syntax.
+#[allow(unused_braces)]
+#[core::contracts::requires(num <= 5)]
+unsafe fn stars_unchecked(num: usize) -> Capped<{ 5 }> {
+    Capped(num)
+}
+
+
+fn main() {
+    check_decrement();
+    check_stars();
+}
+
+fn check_stars() {
+    // This should always pass.
+    let _ = unsafe { stars_unchecked(3) };
+
+    // This violates the contract.
+    #[cfg(any(unchk_pass, chk_const_fail))]
+    let _ = unsafe { stars_unchecked(10) };
+}
+
+fn check_decrement() {
+    // This should always pass
+    assert_eq!(decrement(10u8), 9u8);
+
+    // This should fail requires but pass with no contract check.
+    #[cfg(any(unchk_pass, chk_fail_pre))]
+    assert_eq!(decrement(-2i128), -3i128);
+
+    // This should fail ensures but pass with no contract check.
+    #[cfg(any(unchk_pass, chk_fail_post))]
+    assert_eq!(decrement(1i32), 0i32);
+}
diff --git a/tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr b/tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr
new file mode 100644
index 00000000000..0630811d4f7
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-generics.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr b/tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr
new file mode 100644
index 00000000000..9ca95b8bb01
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-nest.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr
new file mode 100644
index 00000000000..9ca95b8bb01
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-nest.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr b/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr
new file mode 100644
index 00000000000..9ca95b8bb01
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-nest.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-nest.rs b/tests/ui/contracts/contract-attributes-nest.rs
new file mode 100644
index 00000000000..e1e61b88f28
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-nest.rs
@@ -0,0 +1,45 @@
+//@ revisions: unchk_pass unchk_fail_pre unchk_fail_post chk_pass chk_fail_pre chk_fail_post
+//
+//@ [unchk_pass] run-pass
+//@ [unchk_fail_pre] run-pass
+//@ [unchk_fail_post] run-pass
+//@ [chk_pass] run-pass
+//
+//@ [chk_fail_pre] run-fail
+//@ [chk_fail_post] run-fail
+//
+//@ [unchk_pass] compile-flags: -Zcontract-checks=no
+//@ [unchk_fail_pre] compile-flags: -Zcontract-checks=no
+//@ [unchk_fail_post] compile-flags: -Zcontract-checks=no
+//
+//@ [chk_pass] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_post] compile-flags: -Zcontract-checks=yes
+
+#![feature(contracts)]
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+
+#[core::contracts::requires(x.baz > 0)]
+#[core::contracts::ensures(|ret| *ret > 100)]
+fn nest(x: Baz) -> i32
+{
+    loop {
+        return x.baz + 50;
+    }
+}
+
+struct Baz { baz: i32 }
+
+const BAZ_PASS_PRE_POST: Baz = Baz { baz: 100 };
+#[cfg(any(unchk_fail_post, chk_fail_post))]
+const BAZ_FAIL_POST: Baz = Baz { baz: 10 };
+#[cfg(any(unchk_fail_pre, chk_fail_pre))]
+const BAZ_FAIL_PRE: Baz = Baz { baz: -10 };
+
+fn main() {
+    assert_eq!(nest(BAZ_PASS_PRE_POST), 150);
+    #[cfg(any(unchk_fail_pre, chk_fail_pre))]
+    nest(BAZ_FAIL_PRE);
+    #[cfg(any(unchk_fail_post, chk_fail_post))]
+    nest(BAZ_FAIL_POST);
+}
diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr
new file mode 100644
index 00000000000..9ca95b8bb01
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-nest.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr
new file mode 100644
index 00000000000..9ca95b8bb01
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-nest.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr
new file mode 100644
index 00000000000..9ca95b8bb01
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-nest.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr b/tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr
new file mode 100644
index 00000000000..f87e7e19fa3
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-tail.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr
new file mode 100644
index 00000000000..f87e7e19fa3
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-tail.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-tail.chk_pass.stderr b/tests/ui/contracts/contract-attributes-tail.chk_pass.stderr
new file mode 100644
index 00000000000..f87e7e19fa3
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-tail.chk_pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-tail.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-tail.rs b/tests/ui/contracts/contract-attributes-tail.rs
new file mode 100644
index 00000000000..ce4a6be5b82
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-tail.rs
@@ -0,0 +1,43 @@
+//@ revisions: unchk_pass unchk_fail_pre unchk_fail_post chk_pass chk_fail_pre chk_fail_post
+//
+//@ [unchk_pass] run-pass
+//@ [unchk_fail_pre] run-pass
+//@ [unchk_fail_post] run-pass
+//@ [chk_pass] run-pass
+//
+//@ [chk_fail_pre] run-fail
+//@ [chk_fail_post] run-fail
+//
+//@ [unchk_pass] compile-flags: -Zcontract-checks=no
+//@ [unchk_fail_pre] compile-flags: -Zcontract-checks=no
+//@ [unchk_fail_post] compile-flags: -Zcontract-checks=no
+//
+//@ [chk_pass] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_post] compile-flags: -Zcontract-checks=yes
+
+#![feature(contracts)]
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+
+#[core::contracts::requires(x.baz > 0)]
+#[core::contracts::ensures(|ret| *ret > 100)]
+fn tail(x: Baz) -> i32
+{
+    x.baz + 50
+}
+
+struct Baz { baz: i32 }
+
+const BAZ_PASS_PRE_POST: Baz = Baz { baz: 100 };
+#[cfg(any(unchk_fail_post, chk_fail_post))]
+const BAZ_FAIL_POST: Baz = Baz { baz: 10 };
+#[cfg(any(unchk_fail_pre, chk_fail_pre))]
+const BAZ_FAIL_PRE: Baz = Baz { baz: -10 };
+
+fn main() {
+    assert_eq!(tail(BAZ_PASS_PRE_POST), 150);
+    #[cfg(any(unchk_fail_pre, chk_fail_pre))]
+    tail(BAZ_FAIL_PRE);
+    #[cfg(any(unchk_fail_post, chk_fail_post))]
+    tail(BAZ_FAIL_POST);
+}
diff --git a/tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr b/tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr
new file mode 100644
index 00000000000..f87e7e19fa3
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-tail.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr
new file mode 100644
index 00000000000..f87e7e19fa3
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-tail.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr b/tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr
new file mode 100644
index 00000000000..f87e7e19fa3
--- /dev/null
+++ b/tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-attributes-tail.rs:19:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-captures-via-closure-copy.rs b/tests/ui/contracts/contract-captures-via-closure-copy.rs
new file mode 100644
index 00000000000..32c6d2bf4fe
--- /dev/null
+++ b/tests/ui/contracts/contract-captures-via-closure-copy.rs
@@ -0,0 +1,26 @@
+//@ run-fail
+//@ compile-flags: -Zcontract-checks=yes
+
+#![feature(contracts)]
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+
+struct Baz {
+    baz: i32
+}
+
+#[track_caller]
+#[core::contracts::requires(x.baz > 0)]
+#[core::contracts::ensures({let old = x.baz; move |ret:&Baz| ret.baz == old*2 })]
+// Relevant thing is this:  ^^^^^^^^^^^^^^^
+// because we are capturing state that is Copy
+fn doubler(x: Baz) -> Baz {
+    Baz { baz: x.baz + 10 }
+}
+
+fn main() {
+    assert_eq!(doubler(Baz { baz: 10 }).baz, 20);
+    assert_eq!(doubler(Baz { baz: 100 }).baz, 200);
+    // This is a *run-fail* test because it is still exercising the
+    // contract machinery, specifically because this second invocation
+    // of `doubler` shows how the code does not meet its contract.
+}
diff --git a/tests/ui/contracts/contract-captures-via-closure-copy.stderr b/tests/ui/contracts/contract-captures-via-closure-copy.stderr
new file mode 100644
index 00000000000..d92db601608
--- /dev/null
+++ b/tests/ui/contracts/contract-captures-via-closure-copy.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-captures-via-closure-copy.rs:4:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contract-captures-via-closure-noncopy.rs b/tests/ui/contracts/contract-captures-via-closure-noncopy.rs
new file mode 100644
index 00000000000..976f64c7fd9
--- /dev/null
+++ b/tests/ui/contracts/contract-captures-via-closure-noncopy.rs
@@ -0,0 +1,23 @@
+//@ compile-flags: -Zcontract-checks=yes
+
+#![feature(contracts)]
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+
+struct Baz {
+    baz: i32
+}
+
+#[track_caller]
+#[core::contracts::requires(x.baz > 0)]
+#[core::contracts::ensures({let old = x; move |ret:&Baz| ret.baz == old.baz*2 })]
+// Relevant thing is this:  ^^^^^^^^^^^
+// because we are capturing state that is non-Copy.
+//~^^^ ERROR trait bound `Baz: std::marker::Copy` is not satisfied
+fn doubler(x: Baz) -> Baz {
+    Baz { baz: x.baz + 10 }
+}
+
+fn main() {
+    assert_eq!(doubler(Baz { baz: 10 }).baz, 20);
+    assert_eq!(doubler(Baz { baz: 100 }).baz, 200);
+}
diff --git a/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr b/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr
new file mode 100644
index 00000000000..4a47671fee1
--- /dev/null
+++ b/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr
@@ -0,0 +1,36 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-captures-via-closure-noncopy.rs:3:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `Baz: std::marker::Copy` is not satisfied in `{closure@$DIR/contract-captures-via-closure-noncopy.rs:12:42: 12:57}`
+  --> $DIR/contract-captures-via-closure-noncopy.rs:12:1
+   |
+LL | #[core::contracts::ensures({let old = x; move |ret:&Baz| ret.baz == old.baz*2 })]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^^
+   | |                                        |
+   | |                                        within this `{closure@$DIR/contract-captures-via-closure-noncopy.rs:12:42: 12:57}`
+   | |                                        this tail expression is of type `{closure@contract-captures-via-closure-noncopy.rs:12:42}`
+   | unsatisfied trait bound
+   |
+   = help: within `{closure@$DIR/contract-captures-via-closure-noncopy.rs:12:42: 12:57}`, the trait `std::marker::Copy` is not implemented for `Baz`
+note: required because it's used within this closure
+  --> $DIR/contract-captures-via-closure-noncopy.rs:12:42
+   |
+LL | #[core::contracts::ensures({let old = x; move |ret:&Baz| ret.baz == old.baz*2 })]
+   |                                          ^^^^^^^^^^^^^^^
+note: required by a bound in `build_check_ensures`
+  --> $SRC_DIR/core/src/contracts.rs:LL:COL
+help: consider annotating `Baz` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct Baz {
+   |
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr
new file mode 100644
index 00000000000..d693fad446a
--- /dev/null
+++ b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contracts-ensures-early-fn-exit.rs:16:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr
new file mode 100644
index 00000000000..d693fad446a
--- /dev/null
+++ b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contracts-ensures-early-fn-exit.rs:16:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr
new file mode 100644
index 00000000000..d693fad446a
--- /dev/null
+++ b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contracts-ensures-early-fn-exit.rs:16:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr
new file mode 100644
index 00000000000..d693fad446a
--- /dev/null
+++ b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contracts-ensures-early-fn-exit.rs:16:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.rs b/tests/ui/contracts/contracts-ensures-early-fn-exit.rs
new file mode 100644
index 00000000000..034cead3b4e
--- /dev/null
+++ b/tests/ui/contracts/contracts-ensures-early-fn-exit.rs
@@ -0,0 +1,49 @@
+//@ revisions: unchk_pass chk_pass chk_fail_try chk_fail_ret chk_fail_yeet
+//
+//@ [unchk_pass] run-pass
+//@ [chk_pass] run-pass
+//@ [chk_fail_try] run-fail
+//@ [chk_fail_ret] run-fail
+//@ [chk_fail_yeet] run-fail
+//
+//@ [unchk_pass] compile-flags: -Zcontract-checks=no
+//@ [chk_pass] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_try] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_ret] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_yeet] compile-flags: -Zcontract-checks=yes
+//! This test ensures that ensures clauses are checked for different return points of a function.
+
+#![feature(contracts)]
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+#![feature(yeet_expr)]
+
+/// This ensures will fail in different return points depending on the input.
+#[core::contracts::ensures(|ret: &Option<u32>| ret.is_some())]
+fn try_sum(x: u32, y: u32, z: u32) -> Option<u32> {
+    // Use Yeet to return early.
+    if x == u32::MAX && (y > 0 || z > 0) { do yeet }
+
+    // Use `?` to early return.
+    let partial = x.checked_add(y)?;
+
+    // Explicitly use `return` clause.
+    if u32::MAX - partial < z {
+        return None;
+    }
+
+    Some(partial + z)
+}
+
+fn main() {
+    // This should always succeed
+    assert_eq!(try_sum(0, 1, 2), Some(3));
+
+    #[cfg(any(unchk_pass, chk_fail_yeet))]
+    assert_eq!(try_sum(u32::MAX, 1, 1), None);
+
+    #[cfg(any(unchk_pass, chk_fail_try))]
+    assert_eq!(try_sum(u32::MAX - 10, 12, 0), None);
+
+    #[cfg(any(unchk_pass, chk_fail_ret))]
+    assert_eq!(try_sum(u32::MAX - 10, 2, 100), None);
+}
diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr
new file mode 100644
index 00000000000..d693fad446a
--- /dev/null
+++ b/tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contracts-ensures-early-fn-exit.rs:16:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs b/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs
new file mode 100644
index 00000000000..f01a852fbff
--- /dev/null
+++ b/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs
@@ -0,0 +1,15 @@
+//@ run-pass
+//@ compile-flags: -Zcontract-checks=yes
+#![feature(contracts)]
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+
+#[core::contracts::ensures(|ret| *ret > 0)]
+fn outer() -> i32 {
+    let inner_closure = || -> i32 { 0 };
+    inner_closure();
+    10
+}
+
+fn main() {
+    outer();
+}
diff --git a/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr b/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr
new file mode 100644
index 00000000000..49a372b53c7
--- /dev/null
+++ b/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contracts-ensures-is-not-inherited-when-nesting.rs:3:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs b/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs
new file mode 100644
index 00000000000..2c2a4a69785
--- /dev/null
+++ b/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs
@@ -0,0 +1,17 @@
+//@ run-pass
+//@ compile-flags: -Zcontract-checks=yes
+#![feature(contracts)]
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+
+struct Outer { outer: std::cell::Cell<i32> }
+
+#[core::contracts::requires(x.outer.get() > 0)]
+fn outer(x: Outer) {
+    let inner_closure = || { };
+    x.outer.set(0);
+    inner_closure();
+}
+
+fn main() {
+    outer(Outer { outer: 1.into() });
+}
diff --git a/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr b/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr
new file mode 100644
index 00000000000..48898c4434a
--- /dev/null
+++ b/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contracts-requires-is-not-inherited-when-nesting.rs:3:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs
new file mode 100644
index 00000000000..69be906782a
--- /dev/null
+++ b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs
@@ -0,0 +1,53 @@
+//! Checks for compilation errors related to adding contracts to non-function items.
+
+#![feature(contracts)]
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+#![allow(dead_code)]
+
+#[core::contracts::requires(true)]
+//~^ ERROR contract annotations can only be used on functions
+struct Dummy(usize);
+
+#[core::contracts::ensures(|v| v == 100)]
+//~^ ERROR contract annotations can only be used on functions
+const MAX_VAL: usize = 100;
+
+// FIXME: Improve the error message here. The macro thinks this is a function.
+#[core::contracts::ensures(|v| v == 100)]
+//~^ ERROR contract annotations is only supported in functions with bodies
+type NewDummy = fn(usize) -> Dummy;
+
+#[core::contracts::ensures(|v| v == 100)]
+//~^ ERROR contract annotations is only supported in functions with bodies
+const NEW_DUMMY_FN : fn(usize) -> Dummy = || { Dummy(0) };
+
+#[core::contracts::requires(true)]
+//~^ ERROR contract annotations can only be used on functions
+impl Dummy {
+
+    // This should work
+    #[core::contracts::ensures(|ret| ret.0 == v)]
+    fn new(v: usize) -> Dummy {
+        Dummy(v)
+    }
+}
+
+#[core::contracts::ensures(|dummy| dummy.0 > 0)]
+//~^ ERROR contract annotations can only be used on functions
+impl From<usize> for Dummy {
+    // This should work.
+    #[core::contracts::ensures(|ret| ret.0 == v)]
+    fn from(value: usize) -> Self {
+        Dummy::new(value)
+    }
+}
+
+/// You should not be able to annotate a trait either.
+#[core::contracts::requires(true)]
+//~^ ERROR contract annotations can only be used on functions
+pub trait DummyBuilder {
+    fn build() -> Dummy;
+}
+
+fn main() {
+}
diff --git a/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr
new file mode 100644
index 00000000000..0a7fff8183e
--- /dev/null
+++ b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr
@@ -0,0 +1,53 @@
+error: contract annotations can only be used on functions
+  --> $DIR/disallow-contract-annotation-on-non-fn.rs:7:1
+   |
+LL | #[core::contracts::requires(true)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: contract annotations can only be used on functions
+  --> $DIR/disallow-contract-annotation-on-non-fn.rs:11:1
+   |
+LL | #[core::contracts::ensures(|v| v == 100)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: contract annotations is only supported in functions with bodies
+  --> $DIR/disallow-contract-annotation-on-non-fn.rs:16:1
+   |
+LL | #[core::contracts::ensures(|v| v == 100)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: contract annotations is only supported in functions with bodies
+  --> $DIR/disallow-contract-annotation-on-non-fn.rs:20:1
+   |
+LL | #[core::contracts::ensures(|v| v == 100)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: contract annotations can only be used on functions
+  --> $DIR/disallow-contract-annotation-on-non-fn.rs:24:1
+   |
+LL | #[core::contracts::requires(true)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: contract annotations can only be used on functions
+  --> $DIR/disallow-contract-annotation-on-non-fn.rs:35:1
+   |
+LL | #[core::contracts::ensures(|dummy| dummy.0 > 0)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: contract annotations can only be used on functions
+  --> $DIR/disallow-contract-annotation-on-non-fn.rs:46:1
+   |
+LL | #[core::contracts::requires(true)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/disallow-contract-annotation-on-non-fn.rs:3:12
+   |
+LL | #![feature(contracts)]
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: aborting due to 7 previous errors; 1 warning emitted
+
diff --git a/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs b/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs
new file mode 100644
index 00000000000..6d8cd3949ee
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs
@@ -0,0 +1,44 @@
+//@ revisions: unchk_pass unchk_fail_pre unchk_fail_post chk_pass chk_fail_pre chk_fail_post
+//
+//@ [unchk_pass] run-pass
+//@ [unchk_fail_pre] run-pass
+//@ [unchk_fail_post] run-pass
+//@ [chk_pass] run-pass
+//
+//@ [chk_fail_pre] run-fail
+//@ [chk_fail_post] run-fail
+//
+//@ [unchk_pass] compile-flags: -Zcontract-checks=no
+//@ [unchk_fail_pre] compile-flags: -Zcontract-checks=no
+//@ [unchk_fail_post] compile-flags: -Zcontract-checks=no
+//
+//@ [chk_pass] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_post] compile-flags: -Zcontract-checks=yes
+
+#![feature(contracts_internals)]
+
+fn nest(x: Baz) -> i32
+    contract_requires(|| x.baz > 0)
+    contract_ensures(|ret| *ret > 100)
+{
+    loop {
+        return x.baz + 50;
+    }
+}
+
+struct Baz { baz: i32 }
+
+const BAZ_PASS_PRE_POST: Baz = Baz { baz: 100 };
+#[cfg(any(unchk_fail_post, chk_fail_post))]
+const BAZ_FAIL_POST: Baz = Baz { baz: 10 };
+#[cfg(any(unchk_fail_pre, chk_fail_pre))]
+const BAZ_FAIL_PRE: Baz = Baz { baz: -10 };
+
+fn main() {
+    assert_eq!(nest(BAZ_PASS_PRE_POST), 150);
+    #[cfg(any(unchk_fail_pre, chk_fail_pre))]
+    nest(BAZ_FAIL_PRE);
+    #[cfg(any(unchk_fail_post, chk_fail_post))]
+    nest(BAZ_FAIL_POST);
+}
diff --git a/tests/ui/contracts/internal_machinery/contract-ast-extensions-tail.rs b/tests/ui/contracts/internal_machinery/contract-ast-extensions-tail.rs
new file mode 100644
index 00000000000..07ec26f921b
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/contract-ast-extensions-tail.rs
@@ -0,0 +1,42 @@
+//@ revisions: unchk_pass unchk_fail_pre unchk_fail_post chk_pass chk_fail_pre chk_fail_post
+//
+//@ [unchk_pass] run-pass
+//@ [unchk_fail_pre] run-pass
+//@ [unchk_fail_post] run-pass
+//@ [chk_pass] run-pass
+//
+//@ [chk_fail_pre] run-fail
+//@ [chk_fail_post] run-fail
+//
+//@ [unchk_pass] compile-flags: -Zcontract-checks=no
+//@ [unchk_fail_pre] compile-flags: -Zcontract-checks=no
+//@ [unchk_fail_post] compile-flags: -Zcontract-checks=no
+//
+//@ [chk_pass] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_post] compile-flags: -Zcontract-checks=yes
+
+#![feature(contracts_internals)]
+
+fn tail(x: Baz) -> i32
+    contract_requires(|| x.baz > 0)
+    contract_ensures(|ret| *ret > 100)
+{
+    x.baz + 50
+}
+
+struct Baz { baz: i32 }
+
+const BAZ_PASS_PRE_POST: Baz = Baz { baz: 100 };
+#[cfg(any(unchk_fail_post, chk_fail_post))]
+const BAZ_FAIL_POST: Baz = Baz { baz: 10 };
+#[cfg(any(unchk_fail_pre, chk_fail_pre))]
+const BAZ_FAIL_PRE: Baz = Baz { baz: -10 };
+
+fn main() {
+    assert_eq!(tail(BAZ_PASS_PRE_POST), 150);
+    #[cfg(any(unchk_fail_pre, chk_fail_pre))]
+    tail(BAZ_FAIL_PRE);
+    #[cfg(any(unchk_fail_post, chk_fail_post))]
+    tail(BAZ_FAIL_POST);
+}
diff --git a/tests/ui/contracts/internal_machinery/contract-intrinsics.rs b/tests/ui/contracts/internal_machinery/contract-intrinsics.rs
new file mode 100644
index 00000000000..ae692afd146
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/contract-intrinsics.rs
@@ -0,0 +1,36 @@
+//@ revisions: default unchk_pass chk_pass chk_fail_ensures chk_fail_requires
+//
+//@ [default] run-pass
+//@ [unchk_pass] run-pass
+//@ [chk_pass] run-pass
+//@ [chk_fail_requires] run-fail
+//@ [chk_fail_ensures] run-fail
+//
+//@ [unchk_pass] compile-flags: -Zcontract-checks=no
+//@ [chk_pass] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_requires] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_ensures] compile-flags: -Zcontract-checks=yes
+#![feature(cfg_contract_checks, contracts_internals, core_intrinsics)]
+
+fn main() {
+    #[cfg(any(default, unchk_pass))] // default: disabled
+    assert_eq!(core::intrinsics::contract_checks(), false);
+
+    #[cfg(chk_pass)] // explicitly enabled
+    assert_eq!(core::intrinsics::contract_checks(), true);
+
+    // always pass
+    core::intrinsics::contract_check_requires(|| true);
+
+    // fail if enabled
+    #[cfg(any(default, unchk_pass, chk_fail_requires))]
+    core::intrinsics::contract_check_requires(|| false);
+
+    let doubles_to_two = { let old = 2; move |ret| ret + ret == old };
+    // Always pass
+    core::intrinsics::contract_check_ensures(&1, doubles_to_two);
+
+    // Fail if enabled
+    #[cfg(any(default, unchk_pass, chk_fail_ensures))]
+    core::intrinsics::contract_check_ensures(&2, doubles_to_two);
+}
diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr
new file mode 100644
index 00000000000..a60ce160265
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-lang-items.rs:15:12
+   |
+LL | #![feature(contracts)] // to access core::contracts
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr
new file mode 100644
index 00000000000..a60ce160265
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-lang-items.rs:15:12
+   |
+LL | #![feature(contracts)] // to access core::contracts
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.rs b/tests/ui/contracts/internal_machinery/contract-lang-items.rs
new file mode 100644
index 00000000000..e91bbed294d
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/contract-lang-items.rs
@@ -0,0 +1,39 @@
+//@ revisions: unchk_pass unchk_fail_post chk_pass chk_fail_post
+//
+//@ [unchk_pass] run-pass
+//@ [unchk_fail_post] run-pass
+//@ [chk_pass] run-pass
+//
+//@ [chk_fail_post] run-fail
+//
+//@ [unchk_pass] compile-flags: -Zcontract-checks=no
+//@ [unchk_fail_post] compile-flags: -Zcontract-checks=no
+//
+//@ [chk_pass] compile-flags: -Zcontract-checks=yes
+//@ [chk_fail_post] compile-flags: -Zcontract-checks=yes
+
+#![feature(contracts)] // to access core::contracts
+//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
+#![feature(contracts_internals)] // to access check_requires lang item
+
+fn foo(x: Baz) -> i32 {
+    let injected_checker = {
+        core::contracts::build_check_ensures(|ret| *ret > 100)
+    };
+
+    let ret = x.baz + 50;
+    injected_checker(ret)
+}
+
+struct Baz { baz: i32 }
+
+
+const BAZ_PASS_PRE_POST: Baz = Baz { baz: 100 };
+#[cfg(any(unchk_fail_post, chk_fail_post))]
+const BAZ_FAIL_POST: Baz = Baz { baz: 10 };
+
+fn main() {
+    assert_eq!(foo(BAZ_PASS_PRE_POST), 150);
+    #[cfg(any(unchk_fail_post, chk_fail_post))]
+    foo(BAZ_FAIL_POST);
+}
diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_fail_post.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_fail_post.stderr
new file mode 100644
index 00000000000..a60ce160265
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_fail_post.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-lang-items.rs:15:12
+   |
+LL | #![feature(contracts)] // to access core::contracts
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr
new file mode 100644
index 00000000000..a60ce160265
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr
@@ -0,0 +1,11 @@
+warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/contract-lang-items.rs:15:12
+   |
+LL | #![feature(contracts)] // to access core::contracts
+   |            ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/contracts/internal_machinery/contracts-lowering-ensures-is-not-inherited-when-nesting.rs b/tests/ui/contracts/internal_machinery/contracts-lowering-ensures-is-not-inherited-when-nesting.rs
new file mode 100644
index 00000000000..960ccaed358
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/contracts-lowering-ensures-is-not-inherited-when-nesting.rs
@@ -0,0 +1,15 @@
+//@ run-pass
+//@ compile-flags: -Zcontract-checks=yes
+#![feature(contracts_internals)]
+
+fn outer() -> i32
+    contract_ensures(|ret| *ret > 0)
+{
+    let inner_closure = || -> i32 { 0 };
+    inner_closure();
+    10
+}
+
+fn main() {
+    outer();
+}
diff --git a/tests/ui/contracts/internal_machinery/contracts-lowering-requires-is-not-inherited-when-nesting.rs b/tests/ui/contracts/internal_machinery/contracts-lowering-requires-is-not-inherited-when-nesting.rs
new file mode 100644
index 00000000000..bee703de16a
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/contracts-lowering-requires-is-not-inherited-when-nesting.rs
@@ -0,0 +1,17 @@
+//@ run-pass
+//@ compile-flags: -Zcontract-checks=yes
+#![feature(contracts_internals)]
+
+struct Outer { outer: std::cell::Cell<i32> }
+
+fn outer(x: Outer)
+    contract_requires(|| x.outer.get() > 0)
+{
+    let inner_closure = || { };
+    x.outer.set(0);
+    inner_closure();
+}
+
+fn main() {
+    outer(Outer { outer: 1.into() });
+}
diff --git a/tests/ui/contracts/internal_machinery/internal-feature-gating.rs b/tests/ui/contracts/internal_machinery/internal-feature-gating.rs
new file mode 100644
index 00000000000..1b76eef6780
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/internal-feature-gating.rs
@@ -0,0 +1,20 @@
+// gate-test-contracts_internals
+
+fn main() {
+    // intrinsics are guarded by contracts_internals feature gate.
+    core::intrinsics::contract_checks();
+    //~^ ERROR use of unstable library feature `contracts_internals`
+    core::intrinsics::contract_check_requires(|| true);
+    //~^ ERROR use of unstable library feature `contracts_internals`
+    core::intrinsics::contract_check_ensures(&1, |_|true);
+    //~^ ERROR use of unstable library feature `contracts_internals`
+
+    core::contracts::build_check_ensures(|_: &()| true);
+    //~^ ERROR use of unstable library feature `contracts_internals`
+
+    // ast extensions are guarded by contracts_internals feature gate
+    fn identity_1() -> i32 contract_requires(|| true) { 10 }
+    //~^ ERROR contract internal machinery is for internal use only
+    fn identity_2() -> i32 contract_ensures(|_| true) { 10 }
+    //~^ ERROR contract internal machinery is for internal use only
+}
diff --git a/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr b/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr
new file mode 100644
index 00000000000..c0e1522f54c
--- /dev/null
+++ b/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr
@@ -0,0 +1,63 @@
+error[E0658]: contract internal machinery is for internal use only
+  --> $DIR/internal-feature-gating.rs:16:45
+   |
+LL |     fn identity_1() -> i32 contract_requires(|| true) { 10 }
+   |                                             ^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(contracts_internals)]` 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]: contract internal machinery is for internal use only
+  --> $DIR/internal-feature-gating.rs:18:44
+   |
+LL |     fn identity_2() -> i32 contract_ensures(|_| true) { 10 }
+   |                                            ^^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(contracts_internals)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `contracts_internals`
+  --> $DIR/internal-feature-gating.rs:5:5
+   |
+LL |     core::intrinsics::contract_checks();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(contracts_internals)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `contracts_internals`
+  --> $DIR/internal-feature-gating.rs:7:5
+   |
+LL |     core::intrinsics::contract_check_requires(|| true);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(contracts_internals)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `contracts_internals`
+  --> $DIR/internal-feature-gating.rs:9:5
+   |
+LL |     core::intrinsics::contract_check_ensures(&1, |_|true);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(contracts_internals)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `contracts_internals`
+  --> $DIR/internal-feature-gating.rs:12:5
+   |
+LL |     core::contracts::build_check_ensures(|_: &()| true);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(contracts_internals)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/crate-loading/crateresolve1.rs b/tests/ui/crate-loading/crateresolve1.rs
index 9200b6a6231..91c34c82558 100644
--- a/tests/ui/crate-loading/crateresolve1.rs
+++ b/tests/ui/crate-loading/crateresolve1.rs
@@ -2,11 +2,11 @@
 //@ aux-build:crateresolve1-2.rs
 //@ aux-build:crateresolve1-3.rs
 
-//@ normalize-stderr: "\.nll/" -> "/"
+//@ normalize-stderr: "crateresolve1\..+/auxiliary/" -> "crateresolve1/auxiliary/"
 //@ normalize-stderr: "\\\?\\" -> ""
 //@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib"
 
-// NOTE: This test is duplicated at `tests/ui/error-codes/E0464.rs`.
+// NOTE: This test is duplicated at `tests/ui/error-codes/E0464.rs` and `E0523.rs`.
 
 extern crate crateresolve1;
 //~^ ERROR multiple candidates for `rlib` dependency `crateresolve1` found
diff --git a/tests/ui/crate-loading/crateresolve2.rs b/tests/ui/crate-loading/crateresolve2.rs
index bec692eb8d2..6446740a321 100644
--- a/tests/ui/crate-loading/crateresolve2.rs
+++ b/tests/ui/crate-loading/crateresolve2.rs
@@ -4,7 +4,7 @@
 //@ aux-build:crateresolve2-2.rs
 //@ aux-build:crateresolve2-3.rs
 
-//@ normalize-stderr: "\.nll/" -> "/"
+//@ normalize-stderr: "crateresolve2\..+/auxiliary/" -> "crateresolve2/auxiliary/"
 //@ normalize-stderr: "\\\?\\" -> ""
 
 extern crate crateresolve2;
diff --git a/tests/ui/derives/rustc-decodable-issue-123156.rs b/tests/ui/derives/rustc-decodable-issue-123156.rs
deleted file mode 100644
index 1983837ed8d..00000000000
--- a/tests/ui/derives/rustc-decodable-issue-123156.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ check-pass
-//@ edition:2021
-//@ aux-build:rustc-serialize.rs
-
-#![crate_type = "lib"]
-#![allow(deprecated, soft_unstable)]
-
-extern crate rustc_serialize;
-
-#[derive(RustcDecodable)]
-pub enum Foo {}
diff --git a/tests/ui/derives/rustc-decodable-issue-123156.stderr b/tests/ui/derives/rustc-decodable-issue-123156.stderr
deleted file mode 100644
index 93a993b90d8..00000000000
--- a/tests/ui/derives/rustc-decodable-issue-123156.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-Future incompatibility report: Future breakage diagnostic:
-warning: use of unstable library feature `rustc_encodable_decodable`: derive macro for `rustc-serialize`; should not be used in new code
-  --> $DIR/rustc-decodable-issue-123156.rs:10:10
-   |
-LL | #[derive(RustcDecodable)]
-   |          ^^^^^^^^^^^^^^
-   |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-
diff --git a/tests/ui/diagnostic-width/E0271.ascii.stderr b/tests/ui/diagnostic-width/E0271.ascii.stderr
index 7446b1a543e..9a9c12a938f 100644
--- a/tests/ui/diagnostic-width/E0271.ascii.stderr
+++ b/tests/ui/diagnostic-width/E0271.ascii.stderr
@@ -1,4 +1,4 @@
-error[E0271]: type mismatch resolving `<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ...>>, ...>>, ...> as Future>::Error == Foo`
+error[E0271]: type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
   --> $DIR/E0271.rs:20:5
    |
 LL | /     Box::new(
@@ -7,14 +7,16 @@ LL | |             Err::<(), _>(
 LL | |                 Ok::<_, ()>(
 ...  |
 LL | |     )
-   | |_____^ type mismatch resolving `<Result<Result<(), Result<Result<(), ...>, ...>>, ...> as Future>::Error == Foo`
+   | |_____^ type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
    |
 note: expected this to be `Foo`
   --> $DIR/E0271.rs:10:18
    |
 LL |     type Error = E;
    |                  ^
-   = note: required for the cast from `Box<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ()>>, ()>>, ()>>` to `Box<(dyn Future<Error = Foo> + 'static)>`
+   = note: required for the cast from `Box<Result<..., ()>>` to `Box<...>`
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs
index 061ba45c219..06187721041 100644
--- a/tests/ui/diagnostic-width/E0271.rs
+++ b/tests/ui/diagnostic-width/E0271.rs
@@ -1,7 +1,7 @@
 //@ revisions: ascii unicode
-//@[ascii] compile-flags: --diagnostic-width=40
-//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
+//@[ascii] compile-flags: --diagnostic-width=40 -Zwrite-long-types-to-disk=yes
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 -Zwrite-long-types-to-disk=yes
+//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
 trait Future {
     type Error;
 }
diff --git a/tests/ui/diagnostic-width/E0271.unicode.stderr b/tests/ui/diagnostic-width/E0271.unicode.stderr
index 72df2a381a4..9c3deae6660 100644
--- a/tests/ui/diagnostic-width/E0271.unicode.stderr
+++ b/tests/ui/diagnostic-width/E0271.unicode.stderr
@@ -1,4 +1,4 @@
-error[E0271]: type mismatch resolving `<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ...>>, ...>>, ...> as Future>::Error == Foo`
+error[E0271]: type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
    ╭▸ $DIR/E0271.rs:20:5

 LL │ ┏     Box::new(
@@ -7,14 +7,16 @@ LL │ ┃             Err::<(), _>(
 LL │ ┃                 Ok::<_, ()>(
    ‡ ┃
 LL │ ┃     )
-   │ ┗━━━━━┛ type mismatch resolving `<Result<Result<(), Result<Result<(), ...>, ...>>, ...> as Future>::Error == Foo`
+   │ ┗━━━━━┛ type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
    ╰╴
 note: expected this to be `Foo`
    ╭▸ $DIR/E0271.rs:10:18

 LL │     type Error = E;
    │                  ━
-   ╰ note: required for the cast from `Box<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ()>>, ()>>, ()>>` to `Box<(dyn Future<Error = Foo> + 'static)>`
+   ├ note: required for the cast from `Box<Result<..., ()>>` to `Box<...>`
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ╰ note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/diagnostic-width/long-E0308.ascii.stderr b/tests/ui/diagnostic-width/long-E0308.ascii.stderr
index 3053e37a87a..83da5586188 100644
--- a/tests/ui/diagnostic-width/long-E0308.ascii.stderr
+++ b/tests/ui/diagnostic-width/long-E0308.ascii.stderr
@@ -16,11 +16,11 @@ LL |  |         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok...
 LL |  |             Ok("")
 LL |  |         ))))))))))))))))))))))))))))))
 LL |  |     ))))))))))))))))))))))))))))));
-   |  |__________________________________^ expected `Atype<Btype<..., ...>, ...>`, found `Result<Result<..., ...>, ...>`
+   |  |__________________________________^ expected `Atype<Btype<Ctype<..., i32>, i32>, i32>`, found `Result<Result<Result<..., _>, _>, _>`
    |
-   = note: expected struct `Atype<Btype<..., ...>, ...>`
-                found enum `Result<Result<..., ...>, ...>`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: expected struct `Atype<Btype<..., i32>, i32>`
+                found enum `Result<Result<..., _>, _>`
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -32,11 +32,11 @@ LL | |         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(...
 LL | |             Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
 LL | |         ))))))))))))))))))))))))))))))
 LL | |     ))))))))))))))))))))))));
-   | |____________________________^ expected `Option<Result<..., ...>>`, found `Result<Result<..., ...>, ...>`
+   | |____________________________^ expected `Option<Result<Option<Option<...>>, _>>`, found `Result<Result<Result<..., _>, _>, _>`
    |
-   = note: expected enum `Option<Result<..., ...>>`
-              found enum `Result<Result<..., ...>, ...>`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: expected enum `Option<Result<Option<...>, _>>`
+              found enum `Result<Result<..., _>, _>`
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -50,13 +50,13 @@ LL | |           Atype<
 ...  |
 LL | |       i32
 LL | |     > = ();
-   | |     -   ^^ expected `Atype<Btype<..., ...>, ...>`, found `()`
+   | |     -   ^^ expected `Atype<Btype<Ctype<..., i32>, i32>, i32>`, found `()`
    | |_____|
    |       expected due to this
    |
-   = note: expected struct `Atype<Btype<..., ...>, ...>`
+   = note: expected struct `Atype<Btype<..., i32>, i32>`
            found unit type `()`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -70,11 +70,11 @@ LL | |         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(...
 LL | |             Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
 LL | |         ))))))))))))))))))))))))))))))
 LL | |     ))))))))))))))))))))))));
-   | |____________________________^ expected `()`, found `Result<Result<..., ...>, ...>`
+   | |____________________________^ expected `()`, found `Result<Result<Result<..., _>, _>, _>`
    |
    = note: expected unit type `()`
-                   found enum `Result<Result<..., ...>, ...>`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+                   found enum `Result<Result<..., _>, _>`
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/diagnostic-width/long-E0308.unicode.stderr b/tests/ui/diagnostic-width/long-E0308.unicode.stderr
index 50b386325b9..54abf576dbd 100644
--- a/tests/ui/diagnostic-width/long-E0308.unicode.stderr
+++ b/tests/ui/diagnostic-width/long-E0308.unicode.stderr
@@ -16,11 +16,11 @@ LL │  ┃         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O…
 LL │  ┃             Ok("")
 LL │  ┃         ))))))))))))))))))))))))))))))
 LL │  ┃     ))))))))))))))))))))))))))))));
-   │  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Atype<Btype<..., ...>, ...>`, found `Result<Result<..., ...>, ...>`
+   │  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Atype<Btype<Ctype<..., i32>, i32>, i32>`, found `Result<Result<Result<..., _>, _>, _>`

-   ├ note: expected struct `Atype<Btype<..., ...>, ...>`
-   │            found enum `Result<Result<..., ...>, ...>`
-   ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: expected struct `Atype<Btype<..., i32>, i32>`
+   │            found enum `Result<Result<..., _>, _>`
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -32,11 +32,11 @@ LL │ ┃         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok…
 LL │ ┃             Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
 LL │ ┃         ))))))))))))))))))))))))))))))
 LL │ ┃     ))))))))))))))))))))))));
-   │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Option<Result<..., ...>>`, found `Result<Result<..., ...>, ...>`
+   │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Option<Result<Option<Option<...>>, _>>`, found `Result<Result<Result<..., _>, _>, _>`

-   ├ note: expected enum `Option<Result<..., ...>>`
-   │          found enum `Result<Result<..., ...>, ...>`
-   ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: expected enum `Option<Result<Option<...>, _>>`
+   │          found enum `Result<Result<..., _>, _>`
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -50,13 +50,13 @@ LL │ │           Atype<
    ‡ │
 LL │ │       i32
 LL │ │     > = ();
-   │ │     │   ━━ expected `Atype<Btype<..., ...>, ...>`, found `()`
+   │ │     │   ━━ expected `Atype<Btype<Ctype<..., i32>, i32>, i32>`, found `()`
    │ └─────┤
    │       expected due to this

-   ├ note: expected struct `Atype<Btype<..., ...>, ...>`
+   ├ note: expected struct `Atype<Btype<..., i32>, i32>`
    │       found unit type `()`
-   ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -70,11 +70,11 @@ LL │ ┃         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok…
 LL │ ┃             Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
 LL │ ┃         ))))))))))))))))))))))))))))))
 LL │ ┃     ))))))))))))))))))))))));
-   │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `()`, found `Result<Result<..., ...>, ...>`
+   │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `()`, found `Result<Result<Result<..., _>, _>, _>`

    ├ note: expected unit type `()`
-   │               found enum `Result<Result<..., ...>, ...>`
-   ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   │               found enum `Result<Result<..., _>, _>`
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/diagnostic-width/long-e0277.rs b/tests/ui/diagnostic-width/long-e0277.rs
new file mode 100644
index 00000000000..9b3bd8bb728
--- /dev/null
+++ b/tests/ui/diagnostic-width/long-e0277.rs
@@ -0,0 +1,15 @@
+//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
+// The regex below normalizes the long type file name to make it suitable for compare-modes.
+//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
+type A = (i32, i32, i32, i32);
+type B = (A, A, A, A);
+type C = (B, B, B, B);
+type D = (C, C, C, C);
+
+trait Trait {}
+
+fn require_trait<T: Trait>() {}
+
+fn main() {
+    require_trait::<D>(); //~ ERROR the trait bound `(...
+}
diff --git a/tests/ui/diagnostic-width/long-e0277.stderr b/tests/ui/diagnostic-width/long-e0277.stderr
new file mode 100644
index 00000000000..a57270df7e2
--- /dev/null
+++ b/tests/ui/diagnostic-width/long-e0277.stderr
@@ -0,0 +1,23 @@
+error[E0277]: the trait bound `(..., ..., ..., ...): Trait` is not satisfied
+  --> $DIR/long-e0277.rs:14:21
+   |
+LL |     require_trait::<D>();
+   |                     ^ unsatisfied trait bound
+   |
+   = help: the trait `Trait` is not implemented for `(..., ..., ..., ...)`
+help: this trait has no implementations, consider adding one
+  --> $DIR/long-e0277.rs:9:1
+   |
+LL | trait Trait {}
+   | ^^^^^^^^^^^
+note: required by a bound in `require_trait`
+  --> $DIR/long-e0277.rs:11:21
+   |
+LL | fn require_trait<T: Trait>() {}
+   |                     ^^^^^ required by this bound in `require_trait`
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: consider using `--verbose` to print the full type name to the console
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.stderr b/tests/ui/diagnostic-width/non-copy-type-moved.stderr
index 889a2b3666d..254542c7b39 100644
--- a/tests/ui/diagnostic-width/non-copy-type-moved.stderr
+++ b/tests/ui/diagnostic-width/non-copy-type-moved.stderr
@@ -2,13 +2,13 @@ error[E0382]: use of moved value: `x`
   --> $DIR/non-copy-type-moved.rs:16:14
    |
 LL | fn foo(x: D) {
-   |        - move occurs because `x` has type `((..., ..., ..., ...), ..., ..., ...)`, which does not implement the `Copy` trait
+   |        - move occurs because `x` has type `(..., ..., ..., ...)`, which does not implement the `Copy` trait
 LL |     let _a = x;
    |              - value moved here
 LL |     let _b = x;
    |              ^ value used here after move
    |
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 help: consider cloning the value if the performance cost is acceptable
    |
diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs
index 4caa9424425..c8845af3183 100644
--- a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs
+++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs
@@ -12,7 +12,7 @@ fn foo(x: D) {
     //~^ NOTE this expression has type `((...,
     //~| NOTE expected `((...,
     //~| NOTE expected tuple
-    //~| NOTE the full type name has been written to
+    //~| NOTE the full name for the type has been written to
     //~| NOTE consider using `--verbose` to print the full type name to the console
 }
 
diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr
index 346b112019f..a95e1709148 100644
--- a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr
+++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr
@@ -8,7 +8,7 @@ LL |     let () = x;
    |
    = note:  expected tuple `((..., ..., ..., ...), ..., ..., ...)`
            found unit type `()`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/error-codes/E0462.rs b/tests/ui/error-codes/E0462.rs
index 12214331445..45d35c345cb 100644
--- a/tests/ui/error-codes/E0462.rs
+++ b/tests/ui/error-codes/E0462.rs
@@ -1,6 +1,6 @@
 //@ aux-build:found-staticlib.rs
 
-//@ normalize-stderr: "\.nll/" -> "/"
+//@ normalize-stderr: "E0462\..+/auxiliary/" -> "E0462/auxiliary/"
 //@ normalize-stderr: "\\\?\\" -> ""
 //@ normalize-stderr: "(lib)?found_staticlib\.[a-z]+" -> "libfound_staticlib.somelib"
 
diff --git a/tests/ui/error-codes/E0464.rs b/tests/ui/error-codes/E0464.rs
index aaf4d3a8f50..d1303ae91b1 100644
--- a/tests/ui/error-codes/E0464.rs
+++ b/tests/ui/error-codes/E0464.rs
@@ -2,7 +2,7 @@
 //@ aux-build:crateresolve1-2.rs
 //@ aux-build:crateresolve1-3.rs
 
-//@ normalize-stderr: "\.nll/" -> "/"
+//@ normalize-stderr: "E0464\..+/auxiliary/" -> "E0464/auxiliary/"
 //@ normalize-stderr: "\\\?\\" -> ""
 //@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib"
 
diff --git a/tests/ui/error-codes/E0523.rs b/tests/ui/error-codes/E0523.rs
index aaf4d3a8f50..7c1869c055b 100644
--- a/tests/ui/error-codes/E0523.rs
+++ b/tests/ui/error-codes/E0523.rs
@@ -2,7 +2,7 @@
 //@ aux-build:crateresolve1-2.rs
 //@ aux-build:crateresolve1-3.rs
 
-//@ normalize-stderr: "\.nll/" -> "/"
+//@ normalize-stderr: "E0523\..+/auxiliary/" -> "E0523/auxiliary/"
 //@ normalize-stderr: "\\\?\\" -> ""
 //@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib"
 
diff --git a/tests/ui/error-codes/E0746.stderr b/tests/ui/error-codes/E0746.stderr
index ce3e9736969..ec785561415 100644
--- a/tests/ui/error-codes/E0746.stderr
+++ b/tests/ui/error-codes/E0746.stderr
@@ -1,4 +1,4 @@
-error[E0746]: return type cannot have an unboxed trait object
+error[E0746]: return type cannot be a trait object without pointer indirection
   --> $DIR/E0746.rs:8:13
    |
 LL | fn foo() -> dyn Trait { Struct }
@@ -13,7 +13,7 @@ help: alternatively, box the return type, and wrap all of the returned values in
 LL | fn foo() -> Box<dyn Trait> { Box::new(Struct) }
    |             ++++         +   +++++++++      +
 
-error[E0746]: return type cannot have an unboxed trait object
+error[E0746]: return type cannot be a trait object without pointer indirection
   --> $DIR/E0746.rs:11:13
    |
 LL | fn bar() -> dyn Trait {
diff --git a/tests/ui/error-codes/E0789.rs b/tests/ui/error-codes/E0789.rs
index 3acc983edc4..08471e1b3f3 100644
--- a/tests/ui/error-codes/E0789.rs
+++ b/tests/ui/error-codes/E0789.rs
@@ -4,7 +4,7 @@
 #![feature(staged_api)]
 #![unstable(feature = "foo_module", reason = "...", issue = "123")]
 
-#[rustc_allowed_through_unstable_modules]
+#[rustc_allowed_through_unstable_modules = "use stable path instead"]
 // #[stable(feature = "foo", since = "1.0")]
 struct Foo;
 //~^ ERROR `rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute
diff --git a/tests/ui/error-emitter/E0308-clarification.rs b/tests/ui/error-emitter/E0308-clarification.rs
new file mode 100644
index 00000000000..4c15ede0041
--- /dev/null
+++ b/tests/ui/error-emitter/E0308-clarification.rs
@@ -0,0 +1,16 @@
+//@ compile-flags: -Zunstable-options --error-format=human-unicode --color=always
+//@ only-linux
+// Ensure that when we have a type error where both types have the same textual representation, the
+// diagnostic machinery highlights the clarifying comment that comes after in parentheses.
+trait Foo: Copy + ToString {}
+
+impl<T: Copy + ToString> Foo for T {}
+
+fn hide<T: Foo>(x: T) -> impl Foo {
+    x
+}
+
+fn main() {
+    let mut x = (hide(0_u32), hide(0_i32));
+    x = (x.1, x.0);
+}
diff --git a/tests/ui/error-emitter/E0308-clarification.svg b/tests/ui/error-emitter/E0308-clarification.svg
new file mode 100644
index 00000000000..9432e3a4ee9
--- /dev/null
+++ b/tests/ui/error-emitter/E0308-clarification.svg
@@ -0,0 +1,97 @@
+<svg width="740px" height="668px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .fg-ansi256-009 { fill: #FF5555 }
+    .fg-ansi256-012 { fill: #5555FF }
+    .fg-magenta { fill: #AA00AA }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    .bold { font-weight: bold; }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: mismatched types</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold"> ╭▸ </tspan><tspan>$DIR/E0308-clarification.rs:15:10</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> fn hide&lt;T: Foo&gt;(x: T) -&gt; impl Foo {</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>                          </tspan><tspan class="fg-ansi256-012 bold">┬───────</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>                          </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>                          </tspan><tspan class="fg-ansi256-012 bold">the expected opaque type</tspan>
+</tspan>
+    <tspan x="10px" y="154px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>                          </tspan><tspan class="fg-ansi256-012 bold">the found opaque type</tspan>
+</tspan>
+    <tspan x="10px" y="172px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan>
+</tspan>
+    <tspan x="10px" y="190px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>     x = (x.1, x.0);</tspan>
+</tspan>
+    <tspan x="10px" y="208px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>          </tspan><tspan class="fg-ansi256-009 bold">━━━</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected `u32`, found `i32`</tspan>
+</tspan>
+    <tspan x="10px" y="226px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="244px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">├ </tspan><tspan class="bold">note</tspan><tspan>: expected opaque type `</tspan><tspan class="fg-magenta bold">impl Foo</tspan><tspan>` (</tspan><tspan class="fg-magenta bold">`u32`</tspan><tspan>)</tspan>
+</tspan>
+    <tspan x="10px" y="262px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>          found opaque type `</tspan><tspan class="fg-magenta bold">impl Foo</tspan><tspan>` (</tspan><tspan class="fg-magenta bold">`i32`</tspan><tspan>)</tspan>
+</tspan>
+    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">╰ </tspan><tspan class="bold">note</tspan><tspan>: distinct uses of `impl Trait` result in different opaque types</tspan>
+</tspan>
+    <tspan x="10px" y="298px">
+</tspan>
+    <tspan x="10px" y="316px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: mismatched types</tspan>
+</tspan>
+    <tspan x="10px" y="334px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold"> ╭▸ </tspan><tspan>$DIR/E0308-clarification.rs:15:15</tspan>
+</tspan>
+    <tspan x="10px" y="352px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="370px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> fn hide&lt;T: Foo&gt;(x: T) -&gt; impl Foo {</tspan>
+</tspan>
+    <tspan x="10px" y="388px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>                          </tspan><tspan class="fg-ansi256-012 bold">┬───────</tspan>
+</tspan>
+    <tspan x="10px" y="406px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>                          </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="424px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>                          </tspan><tspan class="fg-ansi256-012 bold">the expected opaque type</tspan>
+</tspan>
+    <tspan x="10px" y="442px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>                          </tspan><tspan class="fg-ansi256-012 bold">the found opaque type</tspan>
+</tspan>
+    <tspan x="10px" y="460px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan>
+</tspan>
+    <tspan x="10px" y="478px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>     x = (x.1, x.0);</tspan>
+</tspan>
+    <tspan x="10px" y="496px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>               </tspan><tspan class="fg-ansi256-009 bold">━━━</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected `i32`, found `u32`</tspan>
+</tspan>
+    <tspan x="10px" y="514px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="532px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">├ </tspan><tspan class="bold">note</tspan><tspan>: expected opaque type `</tspan><tspan class="fg-magenta bold">impl Foo</tspan><tspan>` (</tspan><tspan class="fg-magenta bold">`i32`</tspan><tspan>)</tspan>
+</tspan>
+    <tspan x="10px" y="550px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>          found opaque type `</tspan><tspan class="fg-magenta bold">impl Foo</tspan><tspan>` (</tspan><tspan class="fg-magenta bold">`u32`</tspan><tspan>)</tspan>
+</tspan>
+    <tspan x="10px" y="568px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">╰ </tspan><tspan class="bold">note</tspan><tspan>: distinct uses of `impl Trait` result in different opaque types</tspan>
+</tspan>
+    <tspan x="10px" y="586px">
+</tspan>
+    <tspan x="10px" y="604px"><tspan class="fg-ansi256-009 bold">error</tspan><tspan class="bold">: aborting due to 2 previous errors</tspan>
+</tspan>
+    <tspan x="10px" y="622px">
+</tspan>
+    <tspan x="10px" y="640px"><tspan class="bold">For more information about this error, try `rustc --explain E0308`.</tspan>
+</tspan>
+    <tspan x="10px" y="658px">
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/ui/extern-flag/empty-extern-arg.stderr b/tests/ui/extern-flag/empty-extern-arg.stderr
index 2785b12a0ae..b9a128e02e1 100644
--- a/tests/ui/extern-flag/empty-extern-arg.stderr
+++ b/tests/ui/extern-flag/empty-extern-arg.stderr
@@ -8,6 +8,10 @@ error: unwinding panics are not supported without std
    = note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
 
 error: requires `sized` lang_item
+  --> $DIR/empty-extern-arg.rs:6:11
+   |
+LL | fn main() {}
+   |           ^^
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/feature-gates/feature-gate-cfg-contract-checks.rs b/tests/ui/feature-gates/feature-gate-cfg-contract-checks.rs
new file mode 100644
index 00000000000..cd9bf12b5e7
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-cfg-contract-checks.rs
@@ -0,0 +1,5 @@
+#![crate_type = "lib"]
+
+pub fn contract_checks_are_enabled() -> bool {
+    cfg!(contract_checks) //~ ERROR `cfg(contract_checks)` is experimental
+}
diff --git a/tests/ui/feature-gates/feature-gate-cfg-contract-checks.stderr b/tests/ui/feature-gates/feature-gate-cfg-contract-checks.stderr
new file mode 100644
index 00000000000..89c6d077f97
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-cfg-contract-checks.stderr
@@ -0,0 +1,13 @@
+error[E0658]: `cfg(contract_checks)` is experimental and subject to change
+  --> $DIR/feature-gate-cfg-contract-checks.rs:4:10
+   |
+LL |     cfg!(contract_checks)
+   |          ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(cfg_contract_checks)]` 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-cfg-target-thread-local.rs b/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs
index 3ab5a500dfd..131a10ea03b 100644
--- a/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs
+++ b/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs
@@ -1,4 +1,4 @@
-//@ ignore-windows
+//@ ignore-windows FIXME(134939): thread_local + no_mangle doesn't work on Windows
 //@ aux-build:cfg-target-thread-local.rs
 
 #![feature(thread_local)]
diff --git a/tests/ui/feature-gates/feature-gate-contracts.rs b/tests/ui/feature-gates/feature-gate-contracts.rs
new file mode 100644
index 00000000000..5544f1d82ee
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-contracts.rs
@@ -0,0 +1,11 @@
+#![crate_type = "lib"]
+
+#[core::contracts::requires(x > 0)]
+pub fn requires_needs_it(x: i32) { }
+//~^^  ERROR use of unstable library feature `contracts`
+//~^^^ ERROR contracts are incomplete
+
+#[core::contracts::ensures(|ret| *ret > 0)]
+pub fn ensures_needs_it() -> i32 { 10 }
+//~^^  ERROR use of unstable library feature `contracts`
+//~^^^ ERROR contracts are incomplete
diff --git a/tests/ui/feature-gates/feature-gate-contracts.stderr b/tests/ui/feature-gates/feature-gate-contracts.stderr
new file mode 100644
index 00000000000..4403e7df50b
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-contracts.stderr
@@ -0,0 +1,43 @@
+error[E0658]: use of unstable library feature `contracts`
+  --> $DIR/feature-gate-contracts.rs:3:3
+   |
+LL | #[core::contracts::requires(x > 0)]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(contracts)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `contracts`
+  --> $DIR/feature-gate-contracts.rs:8:3
+   |
+LL | #[core::contracts::ensures(|ret| *ret > 0)]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(contracts)]` 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]: contracts are incomplete
+  --> $DIR/feature-gate-contracts.rs:3:1
+   |
+LL | #[core::contracts::requires(x > 0)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(contracts)]` 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]: contracts are incomplete
+  --> $DIR/feature-gate-contracts.rs:8:1
+   |
+LL | #[core::contracts::ensures(|ret| *ret > 0)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #128044 <https://github.com/rust-lang/rust/issues/128044> for more information
+   = help: add `#![feature(contracts)]` 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 4 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-keylocker_x86.rs b/tests/ui/feature-gates/feature-gate-keylocker_x86.rs
new file mode 100644
index 00000000000..cef80ad41a8
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-keylocker_x86.rs
@@ -0,0 +1,6 @@
+//@ only-x86_64
+#[target_feature(enable = "kl")]
+//~^ ERROR: currently unstable
+unsafe fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-keylocker_x86.stderr b/tests/ui/feature-gates/feature-gate-keylocker_x86.stderr
new file mode 100644
index 00000000000..ed814d3a3ce
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-keylocker_x86.stderr
@@ -0,0 +1,13 @@
+error[E0658]: the target feature `kl` is currently unstable
+  --> $DIR/feature-gate-keylocker_x86.rs:2:18
+   |
+LL | #[target_feature(enable = "kl")]
+   |                  ^^^^^^^^^^^^^
+   |
+   = note: see issue #134813 <https://github.com/rust-lang/rust/issues/134813> for more information
+   = help: add `#![feature(keylocker_x86)]` 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-new_range.rs b/tests/ui/feature-gates/feature-gate-new_range.rs
new file mode 100644
index 00000000000..ecb73546d6a
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-new_range.rs
@@ -0,0 +1,10 @@
+#![feature(new_range_api)]
+
+fn main() {
+    let a: core::range::RangeFrom<u8> = 1..;
+    //~^ mismatched types
+    let b: core::range::Range<u8> = 2..3;
+    //~^ mismatched types
+    let c: core::range::RangeInclusive<u8> = 4..=5;
+    //~^ mismatched types
+}
diff --git a/tests/ui/feature-gates/feature-gate-new_range.stderr b/tests/ui/feature-gates/feature-gate-new_range.stderr
new file mode 100644
index 00000000000..c4241390418
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-new_range.stderr
@@ -0,0 +1,48 @@
+error[E0308]: mismatched types
+  --> $DIR/feature-gate-new_range.rs:4:41
+   |
+LL |     let a: core::range::RangeFrom<u8> = 1..;
+   |            --------------------------   ^^^ expected `RangeFrom<u8>`, found `RangeFrom<{integer}>`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `std::range::RangeFrom<u8>`
+              found struct `std::ops::RangeFrom<{integer}>`
+help: call `Into::into` on this expression to convert `std::ops::RangeFrom<{integer}>` into `std::range::RangeFrom<u8>`
+   |
+LL |     let a: core::range::RangeFrom<u8> = 1...into();
+   |                                            +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/feature-gate-new_range.rs:6:37
+   |
+LL |     let b: core::range::Range<u8> = 2..3;
+   |            ----------------------   ^^^^ expected `Range<u8>`, found `Range<{integer}>`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `std::range::Range<u8>`
+              found struct `std::ops::Range<{integer}>`
+help: call `Into::into` on this expression to convert `std::ops::Range<{integer}>` into `std::range::Range<u8>`
+   |
+LL |     let b: core::range::Range<u8> = 2..3.into();
+   |                                         +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/feature-gate-new_range.rs:8:46
+   |
+LL |     let c: core::range::RangeInclusive<u8> = 4..=5;
+   |            -------------------------------   ^^^^^ expected `RangeInclusive<u8>`, found `RangeInclusive<{integer}>`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `std::range::RangeInclusive<u8>`
+              found struct `std::ops::RangeInclusive<{integer}>`
+help: call `Into::into` on this expression to convert `std::ops::RangeInclusive<{integer}>` into `std::range::RangeInclusive<u8>`
+   |
+LL |     let c: core::range::RangeInclusive<u8> = 4..=5.into();
+   |                                                   +++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.rs b/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.rs
deleted file mode 100644
index 71caf43806d..00000000000
--- a/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-#![crate_type = "lib"]
-
-// This isn't intended to compile, so it's easiest to just ignore this error.
-extern crate rustc_serialize; //~ERROR can't find crate for `rustc_serialize`
-
-#[derive(
-    RustcEncodable,
-    //~^   ERROR   use of unstable library feature `rustc_encodable_decodable`
-    //~^^  WARNING this was previously accepted by the compiler
-    //~^^^ WARNING use of deprecated macro `RustcEncodable`
-    RustcDecodable,
-    //~^   ERROR   use of unstable library feature `rustc_encodable_decodable`
-    //~^^  WARNING this was previously accepted by the compiler
-    //~^^^ WARNING use of deprecated macro `RustcDecodable`
-)]
-struct S;
diff --git a/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.stderr b/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.stderr
deleted file mode 100644
index b949dbb9da2..00000000000
--- a/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.stderr
+++ /dev/null
@@ -1,66 +0,0 @@
-error[E0463]: can't find crate for `rustc_serialize`
-  --> $DIR/feature-gate-rustc_encodable_decodable.rs:4:1
-   |
-LL | extern crate rustc_serialize;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
-   |
-   = help: maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview`
-
-error: use of unstable library feature `rustc_encodable_decodable`: derive macro for `rustc-serialize`; should not be used in new code
-  --> $DIR/feature-gate-rustc_encodable_decodable.rs:7:5
-   |
-LL |     RustcEncodable,
-   |     ^^^^^^^^^^^^^^
-   |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-   = note: `#[deny(soft_unstable)]` on by default
-
-warning: use of deprecated macro `RustcEncodable`: rustc-serialize is deprecated and no longer supported
-  --> $DIR/feature-gate-rustc_encodable_decodable.rs:7:5
-   |
-LL |     RustcEncodable,
-   |     ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(deprecated)]` on by default
-
-error: use of unstable library feature `rustc_encodable_decodable`: derive macro for `rustc-serialize`; should not be used in new code
-  --> $DIR/feature-gate-rustc_encodable_decodable.rs:11:5
-   |
-LL |     RustcDecodable,
-   |     ^^^^^^^^^^^^^^
-   |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-
-warning: use of deprecated macro `RustcDecodable`: rustc-serialize is deprecated and no longer supported
-  --> $DIR/feature-gate-rustc_encodable_decodable.rs:11:5
-   |
-LL |     RustcDecodable,
-   |     ^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors; 2 warnings emitted
-
-For more information about this error, try `rustc --explain E0463`.
-Future incompatibility report: Future breakage diagnostic:
-error: use of unstable library feature `rustc_encodable_decodable`: derive macro for `rustc-serialize`; should not be used in new code
-  --> $DIR/feature-gate-rustc_encodable_decodable.rs:7:5
-   |
-LL |     RustcEncodable,
-   |     ^^^^^^^^^^^^^^
-   |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-   = note: `#[deny(soft_unstable)]` on by default
-
-Future breakage diagnostic:
-error: use of unstable library feature `rustc_encodable_decodable`: derive macro for `rustc-serialize`; should not be used in new code
-  --> $DIR/feature-gate-rustc_encodable_decodable.rs:11:5
-   |
-LL |     RustcDecodable,
-   |     ^^^^^^^^^^^^^^
-   |
-   = 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 #64266 <https://github.com/rust-lang/rust/issues/64266>
-   = note: `#[deny(soft_unstable)]` on by default
-
diff --git a/tests/ui/fn/error-recovery-mismatch.rs b/tests/ui/fn/error-recovery-mismatch.rs
new file mode 100644
index 00000000000..a50a30c8c78
--- /dev/null
+++ b/tests/ui/fn/error-recovery-mismatch.rs
@@ -0,0 +1,20 @@
+// Used to ICE due to a size mismatch between the actual fake signature of `fold` and the
+// generated signature used reporting the parameter mismatch at the call site.
+// See issue #135124
+
+trait A  {
+    fn y(&self)
+    {
+        fn call() -> impl Sized {}
+        self.fold(call(), call());
+    }
+    fn fold<T>(&self, _: T, &self._) {}
+    //~^ ERROR unexpected `self` parameter in function
+    //~| ERROR expected one of `)` or `,`, found `.`
+    //~| ERROR identifier `self` is bound more than once in this parameter list
+    //~| WARNING anonymous parameters are deprecated
+    //~| WARNING this is accepted in the current edition
+    //~| ERROR the placeholder `_` is not allowed within types
+}
+
+fn main() {}
diff --git a/tests/ui/fn/error-recovery-mismatch.stderr b/tests/ui/fn/error-recovery-mismatch.stderr
new file mode 100644
index 00000000000..ad4652c11c1
--- /dev/null
+++ b/tests/ui/fn/error-recovery-mismatch.stderr
@@ -0,0 +1,46 @@
+error: unexpected `self` parameter in function
+  --> $DIR/error-recovery-mismatch.rs:11:29
+   |
+LL |     fn fold<T>(&self, _: T, &self._) {}
+   |                             ^^^^^ must be the first parameter of an associated function
+
+error: expected one of `)` or `,`, found `.`
+  --> $DIR/error-recovery-mismatch.rs:11:34
+   |
+LL |     fn fold<T>(&self, _: T, &self._) {}
+   |                                  ^
+   |                                  |
+   |                                  expected one of `)` or `,`
+   |                                  help: missing `,`
+
+error[E0415]: identifier `self` is bound more than once in this parameter list
+  --> $DIR/error-recovery-mismatch.rs:11:30
+   |
+LL |     fn fold<T>(&self, _: T, &self._) {}
+   |                              ^^^^ used as parameter more than once
+
+warning: anonymous parameters are deprecated and will be removed in the next edition
+  --> $DIR/error-recovery-mismatch.rs:11:35
+   |
+LL |     fn fold<T>(&self, _: T, &self._) {}
+   |                                   ^ help: try naming the parameter or explicitly ignoring it: `_: _`
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
+   = note: `#[warn(anonymous_parameters)]` on by default
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/error-recovery-mismatch.rs:11:35
+   |
+LL |     fn fold<T>(&self, _: T, &self._) {}
+   |                                   ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn fold<T, U>(&self, _: T, &self.U) {}
+   |              +++                     ~
+
+error: aborting due to 4 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0121, E0415.
+For more information about an error, try `rustc --explain E0121`.
diff --git a/tests/ui/fn/fn-pointer-mismatch.stderr b/tests/ui/fn/fn-pointer-mismatch.stderr
index 9cda11639d0..2aa840911f6 100644
--- a/tests/ui/fn/fn-pointer-mismatch.stderr
+++ b/tests/ui/fn/fn-pointer-mismatch.stderr
@@ -67,7 +67,7 @@ LL |     let d: &fn(u32) -> u32 = foo;
 help: consider using a reference
    |
 LL |     let d: &fn(u32) -> u32 = &foo;
-   |                              ~~~~
+   |                              +
 
 error[E0308]: mismatched types
   --> $DIR/fn-pointer-mismatch.rs:48:30
diff --git a/tests/ui/fn/param-mismatch-trait-fn.rs b/tests/ui/fn/param-mismatch-trait-fn.rs
new file mode 100644
index 00000000000..69ded6a9068
--- /dev/null
+++ b/tests/ui/fn/param-mismatch-trait-fn.rs
@@ -0,0 +1,10 @@
+trait Foo {
+    fn same_type<T>(_: T, _: T);
+}
+
+fn f<T: Foo, X, Y>(x: X, y: Y) {
+    T::same_type([x], Some(y));
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/fn/param-mismatch-trait-fn.stderr b/tests/ui/fn/param-mismatch-trait-fn.stderr
new file mode 100644
index 00000000000..28e1bcaaf49
--- /dev/null
+++ b/tests/ui/fn/param-mismatch-trait-fn.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+  --> $DIR/param-mismatch-trait-fn.rs:6:23
+   |
+LL |     T::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: associated function defined here
+  --> $DIR/param-mismatch-trait-fn.rs:2:8
+   |
+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/force-inlining/cast.stderr b/tests/ui/force-inlining/cast.stderr
index 116919e5fe7..53132959659 100644
--- a/tests/ui/force-inlining/cast.stderr
+++ b/tests/ui/force-inlining/cast.stderr
@@ -12,7 +12,7 @@ LL |     let _: fn(isize) -> usize = callee;
 help: consider casting to a fn pointer
    |
 LL |     let _: fn(isize) -> usize = callee as fn(isize) -> usize;
-   |                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |                                        +++++++++++++++++++++
 
 error[E0605]: non-primitive cast: `fn(isize) -> usize {callee}` as `fn(isize) -> usize`
   --> $DIR/cast.rs:15:13
@@ -32,7 +32,7 @@ LL |         callee,
 help: consider casting to a fn pointer
    |
 LL |         callee as fn(isize) -> usize,
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |                +++++++++++++++++++++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
index 67417a5e525..be2eca3e61a 100644
--- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
@@ -11,7 +11,7 @@ LL | |     ),
 LL | | ) {
    | |_- expected `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))` because of return type
 LL |       f
-   |       ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&...)))`, found `&dyn Fn(u32)`
+   |       ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&...))))`, found `&dyn Fn(u32)`
    |
    = note: expected reference `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))`
               found reference `&dyn Fn(u32)`
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs
index f2b73d69261..c8963e078f0 100644
--- a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs
@@ -39,7 +39,7 @@ fn main() {
         L { //~ ERROR type mismatch
             f: |x| {
                 drop(x);
-                Unit4 //~ ERROR to be a closure that returns `Unit3`, but it returns `Unit4`
+                Unit4 //~ ERROR to return `Unit3`, but it returns `Unit4`
             },
         },
     );
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr
index d0675d5020c..4302570cdbd 100644
--- a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr
@@ -29,7 +29,7 @@ LL |     where
 LL |         F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
    |                                                   ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
 
-error[E0271]: expected `{closure@issue-62203-hrtb-ice.rs:40:16}` to be a closure that returns `Unit3`, but it returns `Unit4`
+error[E0271]: expected `{closure@issue-62203-hrtb-ice.rs:40:16}` to return `Unit3`, but it returns `Unit4`
   --> $DIR/issue-62203-hrtb-ice.rs:42:17
    |
 LL |     let v = Unit2.m(
diff --git a/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.rs b/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.rs
index 046ced072ba..901d4b39cf3 100644
--- a/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.rs
+++ b/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.rs
@@ -20,7 +20,7 @@ impl DynIncompatible for B {
 }
 
 fn car() -> dyn DynIncompatible { //~ ERROR the trait `DynIncompatible` is not dyn compatible
-//~^ ERROR return type cannot have an unboxed trait object
+//~^ ERROR return type cannot be a trait object without pointer indirection
     if true {
         return A;
     }
diff --git a/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr b/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr
index 2869702d7fc..c2fd11fe23d 100644
--- a/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr
+++ b/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr
@@ -26,6 +26,26 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
 LL |     fn foo() -> Self where Self: Sized;
    |                      +++++++++++++++++
 
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:22:13
+   |
+LL | fn car() -> dyn DynIncompatible {
+   |             ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+help: consider returning an `impl Trait` instead of a `dyn Trait`
+   |
+LL | fn car() -> impl DynIncompatible {
+   |             ~~~~
+help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL ~ fn car() -> Box<dyn DynIncompatible> {
+LL |
+LL |     if true {
+LL ~         return Box::new(A);
+LL |     }
+LL ~     Box::new(B)
+   |
+
 error[E0038]: the trait `DynIncompatible` is not dyn compatible
   --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:30:17
    |
@@ -54,23 +74,6 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
 LL |     fn foo() -> Self where Self: Sized;
    |                      +++++++++++++++++
 
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:22:13
-   |
-LL | fn car() -> dyn DynIncompatible {
-   |             ^^^^^^^^^^^^^^^^^^^ 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`
-   |
-LL ~ fn car() -> Box<dyn DynIncompatible> {
-LL |
-LL |     if true {
-LL ~         return Box::new(A);
-LL |     }
-LL ~     Box::new(B)
-   |
-
 error[E0038]: the trait `DynIncompatible` is not dyn compatible
   --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:32:16
    |
diff --git a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs
index af368203de0..ccf0a1ad3d4 100644
--- a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs
+++ b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs
@@ -6,9 +6,11 @@ impl Trait for u32 {}
 
 fn fuz() -> (usize, Trait) { (42, Struct) }
 //~^ ERROR E0277
+//~| ERROR E0277
 //~| ERROR E0308
 fn bar() -> (usize, dyn Trait) { (42, Struct) }
 //~^ ERROR E0277
+//~| ERROR E0277
 //~| ERROR E0308
 fn bap() -> Trait { Struct }
 //~^ ERROR E0746
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 9ed3d21c13c..11491a55738 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
@@ -1,49 +1,25 @@
-error[E0308]: mismatched types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:35
-   |
-LL | fn fuz() -> (usize, Trait) { (42, Struct) }
-   |                                   ^^^^^^ expected `dyn Trait`, found `Struct`
-   |
-   = note: expected trait object `(dyn Trait + 'static)`
-                    found struct `Struct`
-   = help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
-
 error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13
    |
 LL | fn fuz() -> (usize, Trait) { (42, Struct) }
-   |             ^^^^^^^^^^^^^^   ------------ this returned value is of type `(usize, (dyn Trait + 'static))`
-   |             |
-   |             doesn't have a size known at compile-time
+   |             ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
    = note: required because it appears within the type `(usize, (dyn Trait + 'static))`
    = note: the return type of a function must have a statically known size
 
-error[E0308]: mismatched types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:39
-   |
-LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
-   |                                       ^^^^^^ expected `dyn Trait`, found `Struct`
-   |
-   = note: expected trait object `(dyn Trait + 'static)`
-                    found struct `Struct`
-   = help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
-
 error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:13
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:11:13
    |
 LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
-   |             ^^^^^^^^^^^^^^^^^^   ------------ this returned value is of type `(usize, (dyn Trait + 'static))`
-   |             |
-   |             doesn't have a size known at compile-time
+   |             ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
    = note: required because it appears within the type `(usize, (dyn Trait + 'static))`
    = note: the return type of a function must have a statically known size
 
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13
    |
 LL | fn bap() -> Trait { Struct }
    |             ^^^^^ doesn't have a size known at compile-time
@@ -57,8 +33,8 @@ help: alternatively, box the return type, and wrap all of the returned values in
 LL | fn bap() -> Box<dyn Trait> { Box::new(Struct) }
    |             +++++++      +   +++++++++      +
 
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:17:13
    |
 LL | fn ban() -> dyn Trait { Struct }
    |             ^^^^^^^^^ doesn't have a size known at compile-time
@@ -72,8 +48,8 @@ help: alternatively, box the return type, and wrap all of the returned values in
 LL | fn ban() -> Box<dyn Trait> { Box::new(Struct) }
    |             ++++         +   +++++++++      +
 
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:17:13
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13
    |
 LL | fn bak() -> dyn Trait { unimplemented!() }
    |             ^^^^^^^^^ doesn't have a size known at compile-time
@@ -87,14 +63,17 @@ help: alternatively, box the return type, and wrap all of the returned values in
 LL | fn bak() -> Box<dyn Trait> { Box::new(unimplemented!()) }
    |             ++++         +   +++++++++                +
 
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:21:13
    |
 LL | fn bal() -> 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 bal() -> impl Trait {
+   |             ~~~~
+help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
    |
 LL ~ fn bal() -> Box<dyn Trait> {
 LL |     if true {
@@ -103,14 +82,17 @@ LL |     }
 LL ~     Box::new(42)
    |
 
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:13
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:13
    |
 LL | fn bax() -> 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 bax() -> impl Trait {
+   |             ~~~~
+help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
    |
 LL ~ fn bax() -> Box<dyn Trait> {
 LL |     if true {
@@ -119,8 +101,86 @@ LL |     } else {
 LL ~         Box::new(42)
    |
 
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:62:13
+   |
+LL | fn bat() -> dyn Trait {
+   |             ^^^^^^^^^ doesn't have a size known at compile-time
+   |
+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 {
+LL ~         return Box::new(0);
+LL |     }
+LL ~     Box::new(42)
+   |
+
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:68:13
+   |
+LL | fn bay() -> dyn Trait {
+   |             ^^^^^^^^^ doesn't have a size known at compile-time
+   |
+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 {
+LL ~         Box::new(0)
+LL |     } else {
+LL ~         Box::new(42)
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:35
+   |
+LL | fn fuz() -> (usize, Trait) { (42, Struct) }
+   |                                   ^^^^^^ expected `dyn Trait`, found `Struct`
+   |
+   = note: expected trait object `(dyn Trait + 'static)`
+                    found struct `Struct`
+   = help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
+
+error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:30
+   |
+LL | fn fuz() -> (usize, Trait) { (42, Struct) }
+   |                              ^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
+   = note: required because it appears within the type `(usize, (dyn Trait + 'static))`
+   = note: tuples must have a statically known size to be initialized
+
 error[E0308]: mismatched types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:34:16
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:11:39
+   |
+LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
+   |                                       ^^^^^^ expected `dyn Trait`, found `Struct`
+   |
+   = note: expected trait object `(dyn Trait + 'static)`
+                    found struct `Struct`
+   = help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
+
+error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:11:34
+   |
+LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
+   |                                  ^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
+   = note: required because it appears within the type `(usize, (dyn Trait + 'static))`
+   = note: tuples must have a statically known size to be initialized
+
+error[E0308]: mismatched types
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:36:16
    |
 LL | fn bam() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -137,7 +197,7 @@ LL |         return Box::new(Struct);
    |                +++++++++      +
 
 error[E0308]: mismatched types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:36:5
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:38:5
    |
 LL | fn bam() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -154,7 +214,7 @@ LL |     Box::new(42)
    |     +++++++++  +
 
 error[E0308]: mismatched types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:40:16
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:42:16
    |
 LL | fn baq() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -171,7 +231,7 @@ LL |         return Box::new(0);
    |                +++++++++ +
 
 error[E0308]: mismatched types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:42:5
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:44:5
    |
 LL | fn baq() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -188,7 +248,7 @@ LL |     Box::new(42)
    |     +++++++++  +
 
 error[E0308]: mismatched types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9
    |
 LL | fn baz() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -205,7 +265,7 @@ LL |         Box::new(Struct)
    |         +++++++++      +
 
 error[E0308]: mismatched types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:50:9
    |
 LL | fn baz() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -222,7 +282,7 @@ LL |         Box::new(42)
    |         +++++++++  +
 
 error[E0308]: mismatched types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:9
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:55:9
    |
 LL | fn baw() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -239,7 +299,7 @@ LL |         Box::new(0)
    |         +++++++++ +
 
 error[E0308]: mismatched types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:55:9
+  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:57:9
    |
 LL | fn baw() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -255,45 +315,7 @@ help: store this in the heap by calling `Box::new`
 LL |         Box::new(42)
    |         +++++++++  +
 
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:60:13
-   |
-LL | fn bat() -> dyn Trait {
-   |             ^^^^^^^^^ doesn't have a size known at compile-time
-   |
-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 {
-LL ~         return Box::new(0);
-LL |     }
-LL ~     Box::new(42)
-   |
-
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:66:13
-   |
-LL | fn bay() -> dyn Trait {
-   |             ^^^^^^^^^ doesn't have a size known at compile-time
-   |
-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 {
-LL ~         Box::new(0)
-LL |     } else {
-LL ~         Box::new(42)
-   |
-
-error: aborting due to 19 previous errors
+error: aborting due to 21 previous errors
 
 Some errors have detailed explanations: E0277, E0308, E0746.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/impl-trait-in-macro.stderr b/tests/ui/impl-trait/impl-trait-in-macro.stderr
index 4380f47c5de..2f934694f83 100644
--- a/tests/ui/impl-trait/impl-trait-in-macro.stderr
+++ b/tests/ui/impl-trait/impl-trait-in-macro.stderr
@@ -12,8 +12,8 @@ LL |     let mut a = x;
 LL |     a = y;
    |         ^ expected type parameter `impl Debug`, found a different type parameter `impl Debug`
    |
-   = note: expected type parameter `impl Debug` (type parameter `impl Debug`)
-              found type parameter `impl Debug` (type parameter `impl Debug`)
+   = note: expected type parameter `impl Debug`
+              found type parameter `impl Debug`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
diff --git a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs
index a8a6288eb56..719edd525de 100644
--- a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs
+++ b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs
@@ -63,7 +63,7 @@ fn dog() -> impl std::fmt::Display {
     }
 }
 
-fn hat() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed trait object
+fn hat() -> dyn std::fmt::Display { //~ ERROR return type cannot be a trait object without pointer indirection
     match 13 {
         0 => {
             return 0i32;
@@ -74,7 +74,7 @@ fn hat() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed
     }
 }
 
-fn pug() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed trait object
+fn pug() -> dyn std::fmt::Display { //~ ERROR return type cannot be a trait object without pointer indirection
     match 13 {
         0 => 0i32,
         1 => 1u32,
@@ -82,7 +82,7 @@ fn pug() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed
     }
 }
 
-fn man() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed trait object
+fn man() -> dyn std::fmt::Display { //~ ERROR return type cannot be a trait object without pointer indirection
     if false {
         0i32
     } else {
diff --git a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
index 54849c112f5..17eaed436df 100644
--- a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
+++ b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
@@ -1,3 +1,62 @@
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:66:13
+   |
+LL | fn hat() -> dyn std::fmt::Display {
+   |             ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+help: consider returning an `impl Trait` instead of a `dyn Trait`
+   |
+LL | fn hat() -> impl std::fmt::Display {
+   |             ~~~~
+help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL ~ fn hat() -> Box<dyn std::fmt::Display> {
+LL |     match 13 {
+LL |         0 => {
+LL ~             return Box::new(0i32);
+LL |         }
+LL |         _ => {
+LL ~             Box::new(1u32)
+   |
+
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13
+   |
+LL | fn pug() -> dyn std::fmt::Display {
+   |             ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+help: consider returning an `impl Trait` instead of a `dyn Trait`
+   |
+LL | fn pug() -> impl std::fmt::Display {
+   |             ~~~~
+help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL ~ fn pug() -> Box<dyn std::fmt::Display> {
+LL |     match 13 {
+LL ~         0 => Box::new(0i32),
+LL ~         1 => Box::new(1u32),
+LL ~         _ => Box::new(2u32),
+   |
+
+error[E0746]: return type cannot be a trait object without pointer indirection
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:85:13
+   |
+LL | fn man() -> dyn std::fmt::Display {
+   |             ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+help: consider returning an `impl Trait` instead of a `dyn Trait`
+   |
+LL | fn man() -> impl std::fmt::Display {
+   |             ~~~~
+help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL ~ fn man() -> Box<dyn std::fmt::Display> {
+LL |     if false {
+LL ~         Box::new(0i32)
+LL |     } else {
+LL ~         Box::new(1u32)
+   |
+
 error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5
    |
@@ -165,62 +224,6 @@ help: change the type of the numeric literal from `u32` to `i32`
 LL |         1i32
    |          ~~~
 
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:66:13
-   |
-LL | fn hat() -> dyn std::fmt::Display {
-   |             ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-help: consider returning an `impl Trait` instead of a `dyn Trait`
-   |
-LL | fn hat() -> impl std::fmt::Display {
-   |             ~~~~
-help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
-   |
-LL ~ fn hat() -> Box<dyn std::fmt::Display> {
-LL |     match 13 {
-LL |         0 => {
-LL ~             return Box::new(0i32);
-LL |         }
-LL |         _ => {
-LL ~             Box::new(1u32)
-   |
-
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13
-   |
-LL | fn pug() -> dyn std::fmt::Display {
-   |             ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-help: consider returning an `impl Trait` instead of a `dyn Trait`
-   |
-LL | fn pug() -> impl std::fmt::Display {
-   |             ~~~~
-help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
-   |
-LL ~ fn pug() -> Box<dyn std::fmt::Display> {
-LL |     match 13 {
-LL ~         0 => Box::new(0i32),
-LL ~         1 => Box::new(1u32),
-LL ~         _ => Box::new(2u32),
-   |
-
-error[E0746]: return type cannot have an unboxed trait object
-  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:85:13
-   |
-LL | fn man() -> dyn std::fmt::Display {
-   |             ^^^^^^^^^^^^^^^^^^^^^ 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`
-   |
-LL ~ fn man() -> Box<dyn std::fmt::Display> {
-LL |     if false {
-LL ~         Box::new(0i32)
-LL |     } else {
-LL ~         Box::new(1u32)
-   |
-
 error: aborting due to 12 previous errors
 
 Some errors have detailed explanations: E0308, E0746.
diff --git a/tests/ui/impl-trait/universal-two-impl-traits.stderr b/tests/ui/impl-trait/universal-two-impl-traits.stderr
index 3b4844ab133..f2f5dd0a0c8 100644
--- a/tests/ui/impl-trait/universal-two-impl-traits.stderr
+++ b/tests/ui/impl-trait/universal-two-impl-traits.stderr
@@ -10,8 +10,8 @@ LL |     let mut a = x;
 LL |     a = y;
    |         ^ expected type parameter `impl Debug`, found a different type parameter `impl Debug`
    |
-   = note: expected type parameter `impl Debug` (type parameter `impl Debug`)
-              found type parameter `impl Debug` (type parameter `impl Debug`)
+   = note: expected type parameter `impl Debug`
+              found type parameter `impl Debug`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
diff --git a/tests/ui/inference/issue-71584.rs b/tests/ui/inference/issue-71584.rs
index 7e4d45ec4a0..61568e5467c 100644
--- a/tests/ui/inference/issue-71584.rs
+++ b/tests/ui/inference/issue-71584.rs
@@ -1,4 +1,4 @@
-//@ ignore-windows different list of satisfying impls
+//@ ignore-windows FIXME: We get an extra E0283 on Windows
 fn main() {
     let n: u32 = 1;
     let mut d: u64 = 2;
diff --git a/tests/ui/intrinsics/const-eval-select-bad.rs b/tests/ui/intrinsics/const-eval-select-bad.rs
index 7e75de88d29..3365d57af7c 100644
--- a/tests/ui/intrinsics/const-eval-select-bad.rs
+++ b/tests/ui/intrinsics/const-eval-select-bad.rs
@@ -30,7 +30,7 @@ fn baz(n: bool) -> i32 {
 
 const fn return_ty_mismatch() {
     const_eval_select((1,), foo, bar);
-    //~^ ERROR expected `bar` to be a fn item that returns `i32`, but it returns `bool`
+    //~^ ERROR expected `bar` to return `i32`, but it returns `bool`
 }
 
 const fn args_ty_mismatch() {
diff --git a/tests/ui/intrinsics/const-eval-select-bad.stderr b/tests/ui/intrinsics/const-eval-select-bad.stderr
index e317ed23ab1..bb159bed282 100644
--- a/tests/ui/intrinsics/const-eval-select-bad.stderr
+++ b/tests/ui/intrinsics/const-eval-select-bad.stderr
@@ -60,7 +60,7 @@ LL |     const_eval_select((), 42, 0xDEADBEEF);
    = note: expected a function item, found {integer}
    = help: consult the documentation on `const_eval_select` for more information
 
-error[E0271]: expected `bar` to be a fn item that returns `i32`, but it returns `bool`
+error[E0271]: expected `bar` to return `i32`, but it returns `bool`
   --> $DIR/const-eval-select-bad.rs:32:34
    |
 LL |     const_eval_select((1,), foo, bar);
diff --git a/tests/ui/issues/issue-17954.stderr b/tests/ui/issues/issue-17954.stderr
index bba7e725b12..0dddea83364 100644
--- a/tests/ui/issues/issue-17954.stderr
+++ b/tests/ui/issues/issue-17954.stderr
@@ -5,7 +5,7 @@ LL |     let a = &FOO;
    |             ^^^^ thread-local variables cannot be borrowed beyond the end of the function
 ...
 LL | }
-   |  - end of enclosing function is here
+   | - end of enclosing function is here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-18107.rs b/tests/ui/issues/issue-18107.rs
index 4bf5b6c0f30..b1b6ff4f7ad 100644
--- a/tests/ui/issues/issue-18107.rs
+++ b/tests/ui/issues/issue-18107.rs
@@ -2,7 +2,7 @@ pub trait AbstractRenderer {}
 
 fn _create_render(_: &()) ->
     dyn AbstractRenderer
-//~^ ERROR return type cannot have an unboxed trait object
+//~^ ERROR return type cannot be a trait object without pointer indirection
 {
     match 0 {
         _ => unimplemented!()
diff --git a/tests/ui/issues/issue-18107.stderr b/tests/ui/issues/issue-18107.stderr
index 705f7d0df12..6956d6a34aa 100644
--- a/tests/ui/issues/issue-18107.stderr
+++ b/tests/ui/issues/issue-18107.stderr
@@ -1,4 +1,4 @@
-error[E0746]: return type cannot have an unboxed trait object
+error[E0746]: return type cannot be a trait object without pointer indirection
   --> $DIR/issue-18107.rs:4:5
    |
 LL |     dyn AbstractRenderer
diff --git a/tests/ui/issues/issue-5883.rs b/tests/ui/issues/issue-5883.rs
index f9dd2c54d99..dd4753e0344 100644
--- a/tests/ui/issues/issue-5883.rs
+++ b/tests/ui/issues/issue-5883.rs
@@ -6,7 +6,7 @@ struct Struct {
 
 fn new_struct(
     r: dyn A + 'static //~ ERROR the size for values of type
-) -> Struct {
+) -> Struct { //~ ERROR the size for values of type
     Struct { r: r }
 }
 
diff --git a/tests/ui/issues/issue-5883.stderr b/tests/ui/issues/issue-5883.stderr
index d481d0ef94e..d7278ec32f5 100644
--- a/tests/ui/issues/issue-5883.stderr
+++ b/tests/ui/issues/issue-5883.stderr
@@ -1,4 +1,18 @@
 error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
+  --> $DIR/issue-5883.rs:9:6
+   |
+LL | ) -> Struct {
+   |      ^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `Struct`, the trait `Sized` is not implemented for `(dyn A + 'static)`
+note: required because it appears within the type `Struct`
+  --> $DIR/issue-5883.rs:3:8
+   |
+LL | struct Struct {
+   |        ^^^^^^
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
   --> $DIR/issue-5883.rs:8:8
    |
 LL |     r: dyn A + 'static
@@ -15,6 +29,6 @@ help: function arguments must have a statically known size, borrowed types alway
 LL |     r: &dyn A + 'static
    |        +
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/issues/issue-76191.stderr b/tests/ui/issues/issue-76191.stderr
index 3702bfb7769..3b89ec7cb9c 100644
--- a/tests/ui/issues/issue-76191.stderr
+++ b/tests/ui/issues/issue-76191.stderr
@@ -21,7 +21,7 @@ LL |         RANGE => {}
    |         `RANGE` is interpreted as a constant, not a new binding
    |
    = note: expected type `i32`
-            found struct `RangeInclusive<i32>`
+            found struct `std::ops::RangeInclusive<i32>`
 help: you may want to move the range into the match block
    |
 LL |         0..=255 => {}
@@ -43,7 +43,7 @@ LL |         RANGE2 => {}
    |         `RANGE2` is interpreted as a constant, not a new binding
    |
    = note: expected type `i32`
-            found struct `RangeInclusive<i32>`
+            found struct `std::ops::RangeInclusive<i32>`
    = note: constants only support matching by type, if you meant to match against a range of values, consider using a range pattern like `min ..= max` in the match block
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/json/json-multiple.rs b/tests/ui/json/json-multiple.rs
index 296a60d2453..8ad57939d5d 100644
--- a/tests/ui/json/json-multiple.rs
+++ b/tests/ui/json/json-multiple.rs
@@ -1,5 +1,6 @@
 //@ build-pass
 //@ ignore-pass (different metadata emitted in different modes)
 //@ compile-flags: --json=diagnostic-short --json artifacts --error-format=json
+//@ normalize-stderr: "json-multiple\..+/libjson_multiple.rlib" -> "json-multiple/libjson_multiple.rlib"
 
 #![crate_type = "lib"]
diff --git a/tests/ui/json/json-options.rs b/tests/ui/json/json-options.rs
index 33df25e27b6..a6654bfcac6 100644
--- a/tests/ui/json/json-options.rs
+++ b/tests/ui/json/json-options.rs
@@ -1,5 +1,6 @@
 //@ build-pass
 //@ ignore-pass (different metadata emitted in different modes)
 //@ compile-flags: --json=diagnostic-short,artifacts --error-format=json
+//@ normalize-stderr: "json-options\..+/libjson_options.rlib" -> "json-options/libjson_options.rlib"
 
 #![crate_type = "lib"]
diff --git a/tests/ui/lang-items/lang-item-missing.stderr b/tests/ui/lang-items/lang-item-missing.stderr
index 08e679a7c55..63bca95adf7 100644
--- a/tests/ui/lang-items/lang-item-missing.stderr
+++ b/tests/ui/lang-items/lang-item-missing.stderr
@@ -1,4 +1,8 @@
 error: requires `sized` lang_item
+  --> $DIR/lang-item-missing.rs:11:60
+   |
+LL | extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
+   |                                                            ^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lazy-type-alias/def-site-param-defaults-wf.rs b/tests/ui/lazy-type-alias/def-site-param-defaults-wf.rs
new file mode 100644
index 00000000000..90bb0a294f8
--- /dev/null
+++ b/tests/ui/lazy-type-alias/def-site-param-defaults-wf.rs
@@ -0,0 +1,9 @@
+//! Ensure that we check generic parameter defaults for well-formedness at the definition site.
+#![feature(lazy_type_alias)]
+#![allow(incomplete_features)]
+
+type Alias<T = Vec<str>, const N: usize = {0 - 1}> = T;
+//~^ ERROR evaluation of constant value failed
+//~| ERROR the size for values of type `str` cannot be known at compilation time
+
+fn main() {}
diff --git a/tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr b/tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr
new file mode 100644
index 00000000000..da0021ccaf4
--- /dev/null
+++ b/tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr
@@ -0,0 +1,20 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/def-site-param-defaults-wf.rs:5:44
+   |
+LL | type Alias<T = Vec<str>, const N: usize = {0 - 1}> = T;
+   |                                            ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/def-site-param-defaults-wf.rs:5:16
+   |
+LL | type Alias<T = Vec<str>, const N: usize = {0 - 1}> = T;
+   |                ^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+note: required by an implicit `Sized` bound in `Vec`
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0080, E0277.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/lazy-type-alias/def-site-predicates-wf.rs b/tests/ui/lazy-type-alias/def-site-predicates-wf.rs
new file mode 100644
index 00000000000..5d9235347cb
--- /dev/null
+++ b/tests/ui/lazy-type-alias/def-site-predicates-wf.rs
@@ -0,0 +1,13 @@
+//! Ensure that we check the predicates at the definition site for well-formedness.
+#![feature(lazy_type_alias)]
+#![allow(incomplete_features)]
+
+type Alias0 = ()
+where
+    Vec<str>:; //~ ERROR the size for values of type `str` cannot be known at compilation time
+
+type Alias1 = ()
+where
+    Vec<str>: Sized; //~ ERROR the size for values of type `str` cannot be known at compilation time
+
+fn main() {}
diff --git a/tests/ui/lazy-type-alias/def-site-predicates-wf.stderr b/tests/ui/lazy-type-alias/def-site-predicates-wf.stderr
new file mode 100644
index 00000000000..b44e702c35c
--- /dev/null
+++ b/tests/ui/lazy-type-alias/def-site-predicates-wf.stderr
@@ -0,0 +1,23 @@
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/def-site-predicates-wf.rs:7:5
+   |
+LL |     Vec<str>:;
+   |     ^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+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 `str` cannot be known at compilation time
+  --> $DIR/def-site-predicates-wf.rs:11:15
+   |
+LL |     Vec<str>: Sized;
+   |               ^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+note: required by an implicit `Sized` bound in `Vec`
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/lifetimes/tail-expr-lock-poisoning.rs b/tests/ui/lifetimes/tail-expr-lock-poisoning.rs
index d7c7b2e2414..1c838a9e5e1 100644
--- a/tests/ui/lifetimes/tail-expr-lock-poisoning.rs
+++ b/tests/ui/lifetimes/tail-expr-lock-poisoning.rs
@@ -1,5 +1,4 @@
 //@ revisions: edition2021 edition2024
-//@ ignore-wasm no panic support
 //@ needs-subprocess
 //@ [edition2024] edition: 2024
 //@ run-pass
diff --git a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs
index a169997927e..df73eddd8d5 100644
--- a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs
+++ b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ ignore-windows
 //@ ignore-apple
 //@ ignore-wasm32 common linkage not implemented right now
 
@@ -11,9 +10,11 @@ pub static TEST2: bool = true;
 #[linkage = "internal"]
 pub static TEST3: bool = true;
 
+#[cfg(not(target_env = "msvc"))]
 #[linkage = "linkonce"]
 pub static TEST4: bool = true;
 
+#[cfg(not(target_env = "msvc"))]
 #[linkage = "linkonce_odr"]
 pub static TEST5: bool = true;
 
diff --git a/tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs b/tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs
index 56a9358cce3..8c194ec50df 100644
--- a/tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs
+++ b/tests/ui/linkage-attr/propagate-generic-issue-18804/main.rs
@@ -3,7 +3,6 @@
 // functions. Failure results in a linker error.
 
 //@ ignore-emscripten no weak symbol support
-//@ ignore-windows no extern_weak linkage
 //@ ignore-apple no extern_weak linkage
 
 //@ aux-build:lib.rs
diff --git a/tests/ui/lint/issue-106991.rs b/tests/ui/lint/issue-106991.rs
index e4d7f765b4a..b70f751195a 100644
--- a/tests/ui/lint/issue-106991.rs
+++ b/tests/ui/lint/issue-106991.rs
@@ -3,7 +3,7 @@ fn foo(items: &mut Vec<u8>) {
 }
 
 fn bar() -> impl Iterator<Item = i32> {
-    //~^ ERROR expected `foo` to be a fn item that returns `i32`, but it returns `()` [E0271]
+    //~^ ERROR expected `foo` to return `i32`, but it returns `()` [E0271]
     let mut x: Vec<Vec<u8>> = vec![vec![0, 2, 1], vec![5, 4, 3]];
     x.iter_mut().map(foo)
 }
diff --git a/tests/ui/lint/issue-106991.stderr b/tests/ui/lint/issue-106991.stderr
index 0441a6377d0..15e0ba5337f 100644
--- a/tests/ui/lint/issue-106991.stderr
+++ b/tests/ui/lint/issue-106991.stderr
@@ -1,4 +1,4 @@
-error[E0271]: expected `foo` to be a fn item that returns `i32`, but it returns `()`
+error[E0271]: expected `foo` to return `i32`, but it returns `()`
   --> $DIR/issue-106991.rs:5:13
    |
 LL | fn bar() -> impl Iterator<Item = i32> {
diff --git a/tests/ui/logging-only-prints-once.rs b/tests/ui/logging-only-prints-once.rs
index 5377d5eeae2..bb8c29694b5 100644
--- a/tests/ui/logging-only-prints-once.rs
+++ b/tests/ui/logging-only-prints-once.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-//@ ignore-windows
 //@ needs-threads
 
 use std::cell::Cell;
diff --git a/tests/ui/lto/weak-works.rs b/tests/ui/lto/weak-works.rs
index 00e10b97d60..1ff47ca602d 100644
--- a/tests/ui/lto/weak-works.rs
+++ b/tests/ui/lto/weak-works.rs
@@ -1,7 +1,8 @@
 //@ run-pass
 
 //@ compile-flags: -C codegen-units=8 -Z thinlto
-//@ ignore-windows
+//@ ignore-i686-pc-windows-gnu
+//@ ignore-x86_64-pc-windows-gnu
 
 #![feature(linkage)]
 
diff --git a/tests/ui/methods/issues/issue-61525.stderr b/tests/ui/methods/issues/issue-61525.stderr
index 35001ae22a6..7ac3d3dc0cf 100644
--- a/tests/ui/methods/issues/issue-61525.stderr
+++ b/tests/ui/methods/issues/issue-61525.stderr
@@ -32,7 +32,7 @@ note: method defined here
   --> $DIR/issue-61525.rs:2:8
    |
 LL |     fn query<Q>(self, q: Q);
-   |        ^^^^^
+   |        ^^^^^          -
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed
index 25943d11fc4..ba46a447802 100644
--- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed
@@ -5,9 +5,9 @@
 fn main() {
     let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
     //[current]~^ ERROR type mismatch in closure arguments
-    //[next]~^^ ERROR expected a `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found
+    //[next]~^^ ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found
     let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
     //[current]~^ ERROR type mismatch in closure arguments
     //[next]~^^ ERROR expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}`
-    //[next]~| ERROR expected a `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found
+    //[next]~| ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found
 }
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr
index 696214c0a3c..b7161310619 100644
--- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr
@@ -1,14 +1,14 @@
-error[E0277]: expected a `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
+error[E0277]: expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
   --> $DIR/closure-arg-type-mismatch-issue-45727.rs:6:29
    |
 LL |     let _ = (-10..=10).find(|x: i32| x.signum() == 0);
-   |                        ---- ^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
+   |                        ---- ^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
    |                        |
    |                        required by a bound introduced by this call
    |
-   = help: the trait `for<'a> FnMut(&'a <RangeInclusive<{integer}> as Iterator>::Item)` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
+   = help: the trait `for<'a> FnMut(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
    = note: expected a closure with arguments `(i32,)`
-              found a closure with arguments `(&<RangeInclusive<{integer}> as Iterator>::Item,)`
+              found a closure with arguments `(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item,)`
 note: required by a bound in `find`
   --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
 
@@ -18,17 +18,17 @@ error[E0271]: expected `RangeInclusive<{integer}>` to be an iterator that yields
 LL |     let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
    |                        ^^^^ expected `&&i32`, found integer
 
-error[E0277]: expected a `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}`
+error[E0277]: expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}`
   --> $DIR/closure-arg-type-mismatch-issue-45727.rs:9:29
    |
 LL |     let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
-   |                        ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}`
+   |                        ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}`
    |                        |
    |                        required by a bound introduced by this call
    |
-   = help: the trait `for<'a> FnMut(&'a <RangeInclusive<{integer}> as Iterator>::Item)` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}`
+   = help: the trait `for<'a> FnMut(&'a <std::ops::RangeInclusive<{integer}> as Iterator>::Item)` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:9:29: 9:40}`
    = note: expected a closure with arguments `(&&&i32,)`
-              found a closure with arguments `(&<RangeInclusive<{integer}> as Iterator>::Item,)`
+              found a closure with arguments `(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item,)`
 note: required by a bound in `find`
   --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
 
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs
index 9e44489cbf1..0fd56707763 100644
--- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs
@@ -5,9 +5,9 @@
 fn main() {
     let _ = (-10..=10).find(|x: i32| x.signum() == 0);
     //[current]~^ ERROR type mismatch in closure arguments
-    //[next]~^^ ERROR expected a `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found
+    //[next]~^^ ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found
     let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
     //[current]~^ ERROR type mismatch in closure arguments
     //[next]~^^ ERROR expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}`
-    //[next]~| ERROR expected a `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found
+    //[next]~| ERROR expected a `FnMut(&<std::ops::RangeInclusive<{integer}> as Iterator>::Item)` closure, found
 }
diff --git a/tests/ui/never_type/fallback-closure-wrap.fallback.stderr b/tests/ui/never_type/fallback-closure-wrap.fallback.stderr
index a559a95a334..ac99a1fc24c 100644
--- a/tests/ui/never_type/fallback-closure-wrap.fallback.stderr
+++ b/tests/ui/never_type/fallback-closure-wrap.fallback.stderr
@@ -1,4 +1,4 @@
-error[E0271]: expected `{closure@fallback-closure-wrap.rs:18:40}` to be a closure that returns `()`, but it returns `!`
+error[E0271]: expected `{closure@fallback-closure-wrap.rs:18:40}` to return `()`, but it returns `!`
   --> $DIR/fallback-closure-wrap.rs:19:9
    |
 LL |     let error = Closure::wrap(Box::new(move || {
diff --git a/tests/ui/never_type/fallback-closure-wrap.rs b/tests/ui/never_type/fallback-closure-wrap.rs
index e97505b6bc0..e7f7d5aae3f 100644
--- a/tests/ui/never_type/fallback-closure-wrap.rs
+++ b/tests/ui/never_type/fallback-closure-wrap.rs
@@ -17,7 +17,7 @@ use std::marker::PhantomData;
 fn main() {
     let error = Closure::wrap(Box::new(move || {
         panic!("Can't connect to server.");
-        //[fallback]~^ to be a closure that returns `()`, but it returns `!`
+        //[fallback]~^ to return `()`, but it returns `!`
     }) as Box<dyn FnMut()>);
 }
 
diff --git a/tests/ui/never_type/issue-52443.stderr b/tests/ui/never_type/issue-52443.stderr
index 1c5a0d65142..bb60c33595c 100644
--- a/tests/ui/never_type/issue-52443.stderr
+++ b/tests/ui/never_type/issue-52443.stderr
@@ -31,7 +31,7 @@ help: give the `break` a value of the expected type
 LL |     [(); loop { break 42 }];
    |                       ++
 
-error[E0015]: cannot use `for` loop on `RangeFrom<usize>` in constants
+error[E0015]: cannot use `for` loop on `std::ops::RangeFrom<usize>` in constants
   --> $DIR/issue-52443.rs:9:21
    |
 LL |     [(); { for _ in 0usize.. {}; 0}];
@@ -39,7 +39,7 @@ LL |     [(); { for _ in 0usize.. {}; 0}];
    |
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
-error[E0015]: cannot use `for` loop on `RangeFrom<usize>` in constants
+error[E0015]: cannot use `for` loop on `std::ops::RangeFrom<usize>` in constants
   --> $DIR/issue-52443.rs:9:21
    |
 LL |     [(); { for _ in 0usize.. {}; 0}];
diff --git a/tests/ui/new-range/disabled.rs b/tests/ui/new-range/disabled.rs
new file mode 100644
index 00000000000..1a5fe3f9743
--- /dev/null
+++ b/tests/ui/new-range/disabled.rs
@@ -0,0 +1,27 @@
+//@ check-pass
+
+#![feature(new_range_api)]
+
+fn main() {
+    // Unchanged
+    let a: core::range::RangeFull = ..;
+    let b: core::range::RangeTo<u8> = ..2;
+    let c: core::range::RangeToInclusive<u8> = ..=3;
+
+    let _: core::ops::RangeFull = a;
+    let _: core::ops::RangeTo<u8> = b;
+    let _: core::ops::RangeToInclusive<u8> = c;
+
+    // Changed
+    let a: core::range::legacy::RangeFrom<u8> = 1..;
+    let b: core::range::legacy::Range<u8> = 2..3;
+    let c: core::range::legacy::RangeInclusive<u8> = 4..=5;
+
+    let a: core::ops::RangeFrom<u8> = a;
+    let b: core::ops::Range<u8> = b;
+    let c: core::ops::RangeInclusive<u8> = c;
+
+    let _: core::ops::RangeFrom<u8> = a.into_iter();
+    let _: core::ops::Range<u8> = b.into_iter();
+    let _: core::ops::RangeInclusive<u8> = c.into_iter();
+}
diff --git a/tests/ui/new-range/enabled.rs b/tests/ui/new-range/enabled.rs
new file mode 100644
index 00000000000..a5fb76ad52b
--- /dev/null
+++ b/tests/ui/new-range/enabled.rs
@@ -0,0 +1,24 @@
+//@ check-pass
+
+#![feature(new_range_api)]
+#![feature(new_range)]
+
+fn main() {
+    // Unchanged
+    let a: core::range::RangeFull = ..;
+    let b: core::range::RangeTo<u8> = ..2;
+    let c: core::range::RangeToInclusive<u8> = ..=3;
+
+    let _: core::ops::RangeFull = a;
+    let _: core::ops::RangeTo<u8> = b;
+    let _: core::ops::RangeToInclusive<u8> = c;
+
+    // Changed
+    let a: core::range::RangeFrom<u8> = 1..;
+    let b: core::range::Range<u8> = 2..3;
+    let c: core::range::RangeInclusive<u8> = 4..=5;
+
+    let _: core::range::IterRangeFrom<u8> = a.into_iter();
+    let _: core::range::IterRange<u8> = b.into_iter();
+    let _: core::range::IterRangeInclusive<u8> = c.into_iter();
+}
diff --git a/tests/ui/nll/get_default.legacy.stderr b/tests/ui/nll/get_default.legacy.stderr
new file mode 100644
index 00000000000..699250312dc
--- /dev/null
+++ b/tests/ui/nll/get_default.legacy.stderr
@@ -0,0 +1,18 @@
+error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
+  --> $DIR/get_default.rs:35:17
+   |
+LL | fn err(map: &mut Map) -> &String {
+   |             - let's call the lifetime of this reference `'1`
+LL |     loop {
+LL |         match map.get() {
+   |               --- immutable borrow occurs here
+LL |             Some(v) => {
+LL |                 map.set(String::new()); // We always expect an error here.
+   |                 ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+LL |
+LL |                 return v;
+   |                        - returning this value requires that `*map` is borrowed for `'1`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0502`.
diff --git a/tests/ui/nll/get_default.stderr b/tests/ui/nll/get_default.nll.stderr
index af79771e7e1..9b5976ca717 100644
--- a/tests/ui/nll/get_default.stderr
+++ b/tests/ui/nll/get_default.nll.stderr
@@ -1,5 +1,5 @@
 error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
-  --> $DIR/get_default.rs:21:17
+  --> $DIR/get_default.rs:24:17
    |
 LL | fn ok(map: &mut Map) -> &String {
    |            - let's call the lifetime of this reference `'1`
@@ -14,7 +14,7 @@ LL |                 map.set(String::new()); // Ideally, this would not error.
    |                 ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
 
 error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
-  --> $DIR/get_default.rs:32:17
+  --> $DIR/get_default.rs:35:17
    |
 LL | fn err(map: &mut Map) -> &String {
    |             - let's call the lifetime of this reference `'1`
@@ -22,14 +22,14 @@ LL |     loop {
 LL |         match map.get() {
    |               --- immutable borrow occurs here
 LL |             Some(v) => {
-LL |                 map.set(String::new()); // Both AST and MIR error here
+LL |                 map.set(String::new()); // We always expect an error here.
    |                 ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
 LL |
 LL |                 return v;
    |                        - returning this value requires that `*map` is borrowed for `'1`
 
 error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
-  --> $DIR/get_default.rs:37:17
+  --> $DIR/get_default.rs:40:17
    |
 LL | fn err(map: &mut Map) -> &String {
    |             - let's call the lifetime of this reference `'1`
@@ -40,7 +40,7 @@ LL |         match map.get() {
 LL |                 return v;
    |                        - returning this value requires that `*map` is borrowed for `'1`
 ...
-LL |                 map.set(String::new()); // Ideally, just AST would error here
+LL |                 map.set(String::new()); // Ideally, this would not error.
    |                 ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/nll/get_default.polonius.stderr b/tests/ui/nll/get_default.polonius.stderr
new file mode 100644
index 00000000000..699250312dc
--- /dev/null
+++ b/tests/ui/nll/get_default.polonius.stderr
@@ -0,0 +1,18 @@
+error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
+  --> $DIR/get_default.rs:35:17
+   |
+LL | fn err(map: &mut Map) -> &String {
+   |             - let's call the lifetime of this reference `'1`
+LL |     loop {
+LL |         match map.get() {
+   |               --- immutable borrow occurs here
+LL |             Some(v) => {
+LL |                 map.set(String::new()); // We always expect an error here.
+   |                 ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+LL |
+LL |                 return v;
+   |                        - returning this value requires that `*map` is borrowed for `'1`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0502`.
diff --git a/tests/ui/nll/get_default.rs b/tests/ui/nll/get_default.rs
index ffac8a33da1..c3c09e9c2c5 100644
--- a/tests/ui/nll/get_default.rs
+++ b/tests/ui/nll/get_default.rs
@@ -1,7 +1,10 @@
 // Basic test for free regions in the NLL code. This test ought to
-// report an error due to a reborrowing constraint. Right now, we get
-// a variety of errors from the older, AST-based machinery (notably
-// borrowck), and then we get the NLL error at the end.
+// report an error due to a reborrowing constraint.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius legacy
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] compile-flags: -Z polonius=legacy
 
 struct Map {
 }
@@ -19,7 +22,7 @@ fn ok(map: &mut Map) -> &String {
             }
             None => {
                 map.set(String::new()); // Ideally, this would not error.
-                //~^ ERROR borrowed as immutable
+                //[nll]~^ ERROR borrowed as immutable
             }
         }
     }
@@ -29,13 +32,13 @@ fn err(map: &mut Map) -> &String {
     loop {
         match map.get() {
             Some(v) => {
-                map.set(String::new()); // Both AST and MIR error here
+                map.set(String::new()); // We always expect an error here.
                 //~^ ERROR borrowed as immutable
                 return v;
             }
             None => {
-                map.set(String::new()); // Ideally, just AST would error here
-                //~^ ERROR borrowed as immutable
+                map.set(String::new()); // Ideally, this would not error.
+                //[nll]~^ ERROR borrowed as immutable
             }
         }
     }
diff --git a/tests/ui/nll/issue-46589.stderr b/tests/ui/nll/issue-46589.nll.stderr
index abf62aaa510..dc80c1d08de 100644
--- a/tests/ui/nll/issue-46589.stderr
+++ b/tests/ui/nll/issue-46589.nll.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `**other` as mutable more than once at a time
-  --> $DIR/issue-46589.rs:23:21
+  --> $DIR/issue-46589.rs:24:21
    |
 LL |         *other = match (*other).get_self() {
    |                        -------- first mutable borrow occurs here
diff --git a/tests/ui/nll/issue-46589.rs b/tests/ui/nll/issue-46589.rs
index 417d9cab657..10aff0d7b4e 100644
--- a/tests/ui/nll/issue-46589.rs
+++ b/tests/ui/nll/issue-46589.rs
@@ -1,8 +1,9 @@
-// This tests passes in Polonius mode, so is skipped in the automated compare-mode.
-// We will manually check it passes in Polonius tests, as we can't have a test here
-// which conditionally passes depending on a test revision/compile-flags.
-
-//@ ignore-compare-mode-polonius
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: nll polonius_next polonius
+//@ [polonius_next] check-pass
+//@ [polonius_next] compile-flags: -Zpolonius=next
+//@ [polonius] check-pass
+//@ [polonius] compile-flags: -Zpolonius
 
 struct Foo;
 
@@ -21,7 +22,7 @@ impl Foo {
         *other = match (*other).get_self() {
             Some(s) => s,
             None => (*other).new_self()
-            //~^ ERROR cannot borrow `**other` as mutable more than once at a time [E0499]
+            //[nll]~^ ERROR cannot borrow `**other` as mutable more than once at a time [E0499]
         };
 
         let c = other;
diff --git a/tests/ui/nll/polonius/assignment-kills-loans.rs b/tests/ui/nll/polonius/assignment-kills-loans.rs
index 182262e5c4b..56ea9c2f1f9 100644
--- a/tests/ui/nll/polonius/assignment-kills-loans.rs
+++ b/tests/ui/nll/polonius/assignment-kills-loans.rs
@@ -4,8 +4,11 @@
 // facts only on simple assignments, but not projections, incorrectly causing errors to be emitted
 // for code accepted by NLL. They are all variations from example code in the NLL RFC.
 
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: polonius_next polonius
 //@ check-pass
-//@ compile-flags: -Z polonius
+//@ [polonius_next] compile-flags: -Z polonius=next
+//@ [polonius] compile-flags: -Z polonius
 
 struct List<T> {
     value: T,
diff --git a/tests/ui/nll/polonius/assignment-to-differing-field.stderr b/tests/ui/nll/polonius/assignment-to-differing-field.legacy.stderr
index c46d010e4f5..cf5594dbd07 100644
--- a/tests/ui/nll/polonius/assignment-to-differing-field.stderr
+++ b/tests/ui/nll/polonius/assignment-to-differing-field.legacy.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `list.0.value` as mutable more than once at a time
-  --> $DIR/assignment-to-differing-field.rs:20:21
+  --> $DIR/assignment-to-differing-field.rs:23:21
    |
 LL | fn assignment_to_field_projection<'a, T>(
    |                                   -- lifetime `'a` defined here
@@ -11,7 +11,7 @@ LL |             return result;
    |                    ------ returning this value requires that `list.0.value` is borrowed for `'a`
 
 error[E0499]: cannot borrow `list.0.next` as mutable more than once at a time
-  --> $DIR/assignment-to-differing-field.rs:23:26
+  --> $DIR/assignment-to-differing-field.rs:26:26
    |
 LL | fn assignment_to_field_projection<'a, T>(
    |                                   -- lifetime `'a` defined here
@@ -23,7 +23,7 @@ LL |             list.1 = n;
    |             ---------- assignment requires that `list.0.next` is borrowed for `'a`
 
 error[E0499]: cannot borrow `list.0.0.0.0.0.value` as mutable more than once at a time
-  --> $DIR/assignment-to-differing-field.rs:37:21
+  --> $DIR/assignment-to-differing-field.rs:40:21
    |
 LL | fn assignment_through_projection_chain<'a, T>(
    |                                        -- lifetime `'a` defined here
@@ -35,7 +35,7 @@ LL |             return result;
    |                    ------ returning this value requires that `list.0.0.0.0.0.value` is borrowed for `'a`
 
 error[E0499]: cannot borrow `list.0.0.0.0.0.next` as mutable more than once at a time
-  --> $DIR/assignment-to-differing-field.rs:40:26
+  --> $DIR/assignment-to-differing-field.rs:43:26
    |
 LL | fn assignment_through_projection_chain<'a, T>(
    |                                        -- lifetime `'a` defined here
diff --git a/tests/ui/nll/polonius/assignment-to-differing-field.polonius.stderr b/tests/ui/nll/polonius/assignment-to-differing-field.polonius.stderr
new file mode 100644
index 00000000000..cf5594dbd07
--- /dev/null
+++ b/tests/ui/nll/polonius/assignment-to-differing-field.polonius.stderr
@@ -0,0 +1,51 @@
+error[E0499]: cannot borrow `list.0.value` as mutable more than once at a time
+  --> $DIR/assignment-to-differing-field.rs:23:21
+   |
+LL | fn assignment_to_field_projection<'a, T>(
+   |                                   -- lifetime `'a` defined here
+...
+LL |         result.push(&mut (list.0).value);
+   |                     ^^^^^^^^^^^^^^^^^^^ `list.0.value` was mutably borrowed here in the previous iteration of the loop
+...
+LL |             return result;
+   |                    ------ returning this value requires that `list.0.value` is borrowed for `'a`
+
+error[E0499]: cannot borrow `list.0.next` as mutable more than once at a time
+  --> $DIR/assignment-to-differing-field.rs:26:26
+   |
+LL | fn assignment_to_field_projection<'a, T>(
+   |                                   -- lifetime `'a` defined here
+...
+LL |         if let Some(n) = (list.0).next.as_mut() {
+   |                          ^^^^^^^^^^^^^ `list.0.next` was mutably borrowed here in the previous iteration of the loop
+LL |
+LL |             list.1 = n;
+   |             ---------- assignment requires that `list.0.next` is borrowed for `'a`
+
+error[E0499]: cannot borrow `list.0.0.0.0.0.value` as mutable more than once at a time
+  --> $DIR/assignment-to-differing-field.rs:40:21
+   |
+LL | fn assignment_through_projection_chain<'a, T>(
+   |                                        -- lifetime `'a` defined here
+...
+LL |         result.push(&mut ((((list.0).0).0).0).0.value);
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `list.0.0.0.0.0.value` was mutably borrowed here in the previous iteration of the loop
+...
+LL |             return result;
+   |                    ------ returning this value requires that `list.0.0.0.0.0.value` is borrowed for `'a`
+
+error[E0499]: cannot borrow `list.0.0.0.0.0.next` as mutable more than once at a time
+  --> $DIR/assignment-to-differing-field.rs:43:26
+   |
+LL | fn assignment_through_projection_chain<'a, T>(
+   |                                        -- lifetime `'a` defined here
+...
+LL |         if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() {
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `list.0.0.0.0.0.next` was mutably borrowed here in the previous iteration of the loop
+LL |
+LL |             *((((list.0).0).0).0).1 = n;
+   |             --------------------------- assignment requires that `list.0.0.0.0.0.next` is borrowed for `'a`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0499`.
diff --git a/tests/ui/nll/polonius/assignment-to-differing-field.rs b/tests/ui/nll/polonius/assignment-to-differing-field.rs
index fb6c9569525..9701cd2bb5e 100644
--- a/tests/ui/nll/polonius/assignment-to-differing-field.rs
+++ b/tests/ui/nll/polonius/assignment-to-differing-field.rs
@@ -4,7 +4,10 @@
 // that we do not kill too many borrows. Assignments to the `.1`
 // field projections should leave the borrows on `.0` intact.
 
-//@ compile-flags: -Z polonius
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: polonius legacy
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] compile-flags: -Z polonius=legacy
 
 struct List<T> {
     value: T,
diff --git a/tests/ui/nll/polonius/call-kills-loans.rs b/tests/ui/nll/polonius/call-kills-loans.rs
index c02293c9a78..0657c42f48c 100644
--- a/tests/ui/nll/polonius/call-kills-loans.rs
+++ b/tests/ui/nll/polonius/call-kills-loans.rs
@@ -4,8 +4,11 @@
 // by NLL but was incorrectly rejected by Polonius because of these
 // missing `killed` facts.
 
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: polonius_next polonius
 //@ check-pass
-//@ compile-flags: -Z polonius
+//@ [polonius_next] compile-flags: -Z polonius=next
+//@ [polonius] compile-flags: -Z polonius
 
 struct Thing;
 
diff --git a/tests/ui/nll/polonius/issue-46589.rs b/tests/ui/nll/polonius/issue-46589.rs
deleted file mode 100644
index af791f7e24d..00000000000
--- a/tests/ui/nll/polonius/issue-46589.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-// This test is a copy of `ui/nll/issue-46589.rs` which fails in NLL but succeeds in Polonius.
-// As we can't have a test here which conditionally passes depending on a test
-// revision/compile-flags. We ensure here that it passes in Polonius mode.
-
-//@ check-pass
-//@ compile-flags: -Z polonius
-
-struct Foo;
-
-impl Foo {
-    fn get_self(&mut self) -> Option<&mut Self> {
-        Some(self)
-    }
-
-    fn new_self(&mut self) -> &mut Self {
-        self
-    }
-
-    fn trigger_bug(&mut self) {
-        let other = &mut (&mut *self);
-
-        *other = match (*other).get_self() {
-            Some(s) => s,
-            None => (*other).new_self()
-        };
-
-        let c = other;
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs b/tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs
index cb56c8f6deb..677b7aa1df8 100644
--- a/tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs
+++ b/tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs
@@ -5,9 +5,11 @@
 // than `liveness::trace`, on some specific CFGs shapes: a variable was dead during tracing but its
 // regions were marked live later, and live loans were not recomputed at this point.
 
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: polonius_next polonius
 //@ check-pass
-//@ revisions: nll polonius
-//@ [polonius] compile-flags: -Zpolonius=next
+//@ [polonius_next] compile-flags: -Z polonius=next
+//@ [polonius] compile-flags: -Z polonius
 
 // minimized from wavefc-cli-3.0.0
 fn repro1() {
diff --git a/tests/ui/nll/polonius/polonius-smoke-test.stderr b/tests/ui/nll/polonius/polonius-smoke-test.legacy.stderr
index a8a8267290d..1268f6167f8 100644
--- a/tests/ui/nll/polonius/polonius-smoke-test.stderr
+++ b/tests/ui/nll/polonius/polonius-smoke-test.legacy.stderr
@@ -1,11 +1,11 @@
 error[E0515]: cannot return reference to local variable `x`
-  --> $DIR/polonius-smoke-test.rs:6:5
+  --> $DIR/polonius-smoke-test.rs:10:5
    |
 LL |     &x
    |     ^^ returns a reference to data owned by the current function
 
 error[E0503]: cannot use `x` because it was mutably borrowed
-  --> $DIR/polonius-smoke-test.rs:12:13
+  --> $DIR/polonius-smoke-test.rs:16:13
    |
 LL |     let y = &mut x;
    |             ------ `x` is borrowed here
@@ -15,7 +15,7 @@ LL |     let w = y;
    |             - borrow later used here
 
 error[E0505]: cannot move out of `x` because it is borrowed
-  --> $DIR/polonius-smoke-test.rs:18:13
+  --> $DIR/polonius-smoke-test.rs:22:13
    |
 LL | pub fn use_while_mut_fr(x: &mut i32) -> &mut i32 {
    |                         -  - let's call the lifetime of this reference `'1`
@@ -35,7 +35,7 @@ LL +     let y = &mut x.clone();
    |
 
 error[E0505]: cannot move out of `s` because it is borrowed
-  --> $DIR/polonius-smoke-test.rs:42:5
+  --> $DIR/polonius-smoke-test.rs:46:5
    |
 LL |     let s = &mut 1;
    |         - binding `s` declared here
diff --git a/tests/ui/nll/polonius/polonius-smoke-test.polonius.stderr b/tests/ui/nll/polonius/polonius-smoke-test.polonius.stderr
new file mode 100644
index 00000000000..1268f6167f8
--- /dev/null
+++ b/tests/ui/nll/polonius/polonius-smoke-test.polonius.stderr
@@ -0,0 +1,59 @@
+error[E0515]: cannot return reference to local variable `x`
+  --> $DIR/polonius-smoke-test.rs:10:5
+   |
+LL |     &x
+   |     ^^ returns a reference to data owned by the current function
+
+error[E0503]: cannot use `x` because it was mutably borrowed
+  --> $DIR/polonius-smoke-test.rs:16:13
+   |
+LL |     let y = &mut x;
+   |             ------ `x` is borrowed here
+LL |     let z = x;
+   |             ^ use of borrowed `x`
+LL |     let w = y;
+   |             - borrow later used here
+
+error[E0505]: cannot move out of `x` because it is borrowed
+  --> $DIR/polonius-smoke-test.rs:22:13
+   |
+LL | pub fn use_while_mut_fr(x: &mut i32) -> &mut i32 {
+   |                         -  - let's call the lifetime of this reference `'1`
+   |                         |
+   |                         binding `x` declared here
+LL |     let y = &mut *x;
+   |             ------- borrow of `*x` occurs here
+LL |     let z = x;
+   |             ^ move out of `x` occurs here
+LL |     y
+   |     - returning this value requires that `*x` is borrowed for `'1`
+   |
+help: consider cloning the value if the performance cost is acceptable
+   |
+LL -     let y = &mut *x;
+LL +     let y = &mut x.clone();
+   |
+
+error[E0505]: cannot move out of `s` because it is borrowed
+  --> $DIR/polonius-smoke-test.rs:46:5
+   |
+LL |     let s = &mut 1;
+   |         - binding `s` declared here
+LL |     let r = &mut *s;
+   |             ------- borrow of `*s` occurs here
+LL |     let tmp = foo(&r);
+LL |     s;
+   |     ^ move out of `s` occurs here
+LL |     tmp;
+   |     --- borrow later used here
+   |
+help: consider cloning the value if the performance cost is acceptable
+   |
+LL -     let r = &mut *s;
+LL +     let r = &mut s.clone();
+   |
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0503, E0505, E0515.
+For more information about an error, try `rustc --explain E0503`.
diff --git a/tests/ui/nll/polonius/polonius-smoke-test.rs b/tests/ui/nll/polonius/polonius-smoke-test.rs
index ea5cdb263f5..7fbb3f9b47c 100644
--- a/tests/ui/nll/polonius/polonius-smoke-test.rs
+++ b/tests/ui/nll/polonius/polonius-smoke-test.rs
@@ -1,5 +1,9 @@
-// Check that Polonius borrow check works for simple cases.
-//@ compile-flags: -Z polonius
+// Check that Polonius works for simple cases.
+
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: polonius legacy
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] compile-flags: -Z polonius=legacy
 
 pub fn return_ref_to_local() -> &'static i32 {
     let x = 0;
diff --git a/tests/ui/nll/polonius/storagedead-kills-loans.rs b/tests/ui/nll/polonius/storagedead-kills-loans.rs
index 89cf919bb48..75a37e6ece5 100644
--- a/tests/ui/nll/polonius/storagedead-kills-loans.rs
+++ b/tests/ui/nll/polonius/storagedead-kills-loans.rs
@@ -3,8 +3,11 @@
 // is correctly accepted by NLL but was incorrectly rejected by
 // Polonius because of these missing `killed` facts.
 
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: polonius_next polonius
 //@ check-pass
-//@ compile-flags: -Z polonius
+//@ [polonius_next] compile-flags: -Z polonius=next
+//@ [polonius] compile-flags: -Z polonius
 
 use std::{io, mem};
 use std::io::Read;
diff --git a/tests/ui/nll/polonius/subset-relations.stderr b/tests/ui/nll/polonius/subset-relations.legacy.stderr
index 9deca6449a8..10d42ca58d9 100644
--- a/tests/ui/nll/polonius/subset-relations.stderr
+++ b/tests/ui/nll/polonius/subset-relations.legacy.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/subset-relations.rs:10:5
+  --> $DIR/subset-relations.rs:13:5
    |
 LL | fn missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
    |                   --  -- lifetime `'b` defined here
diff --git a/tests/ui/nll/polonius/subset-relations.polonius.stderr b/tests/ui/nll/polonius/subset-relations.polonius.stderr
new file mode 100644
index 00000000000..10d42ca58d9
--- /dev/null
+++ b/tests/ui/nll/polonius/subset-relations.polonius.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/subset-relations.rs:13:5
+   |
+LL | fn missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
+   |                   --  -- lifetime `'b` defined here
+   |                   |
+   |                   lifetime `'a` defined here
+LL |     y
+   |     ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/nll/polonius/subset-relations.rs b/tests/ui/nll/polonius/subset-relations.rs
index 3c1af1983cf..d47e4e05533 100644
--- a/tests/ui/nll/polonius/subset-relations.rs
+++ b/tests/ui/nll/polonius/subset-relations.rs
@@ -3,7 +3,10 @@
 // two free regions outlive each other, without any evidence that this
 // relation holds.
 
-//@ compile-flags: -Z polonius
+//@ ignore-compare-mode-polonius (explicit revisions)
+//@ revisions: polonius legacy
+//@ [polonius] compile-flags: -Z polonius=next
+//@ [legacy] compile-flags: -Z polonius=legacy
 
 // returning `y` requires that `'b: 'a`, but it's not known to be true
 fn missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
@@ -22,7 +25,7 @@ fn implied_bounds_subset<'a, 'b>(x: &'a &'b mut u32) -> &'a u32 {
 
 // `'b: 'a` is declared, and `'a: 'c` is known via implied bounds:
 // `'b: 'c` is therefore known to hold transitively
-fn transitively_valid_subset<'a, 'b: 'a, 'c>(x: &'c &'a u32, y: &'b u32) -> &'c u32  {
+fn transitively_valid_subset<'a, 'b: 'a, 'c>(x: &'c &'a u32, y: &'b u32) -> &'c u32 {
     y
 }
 
diff --git a/tests/ui/panics/issue-47429-short-backtraces.rs b/tests/ui/panics/issue-47429-short-backtraces.rs
index 4a73ebe8712..378ade67bfd 100644
--- a/tests/ui/panics/issue-47429-short-backtraces.rs
+++ b/tests/ui/panics/issue-47429-short-backtraces.rs
@@ -17,8 +17,6 @@
 //@ ignore-msvc see #62897 and `backtrace-debuginfo.rs` test
 //@ ignore-android FIXME #17520
 //@ ignore-openbsd no support for libbacktrace without filename
-//@ ignore-wasm no panic support
-//@ ignore-emscripten no panic support
 //@ ignore-fuchsia Backtraces not symbolized
 //@ needs-subprocess
 
diff --git a/tests/ui/panics/issue-47429-short-backtraces.run.stderr b/tests/ui/panics/issue-47429-short-backtraces.run.stderr
index c6e2d13fb5d..32dc6592271 100644
--- a/tests/ui/panics/issue-47429-short-backtraces.run.stderr
+++ b/tests/ui/panics/issue-47429-short-backtraces.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:26:5:
+thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:24:5:
 explicit panic
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/panics/runtime-switch.rs b/tests/ui/panics/runtime-switch.rs
index 9f0be8c7ddf..7d5b4169340 100644
--- a/tests/ui/panics/runtime-switch.rs
+++ b/tests/ui/panics/runtime-switch.rs
@@ -18,7 +18,6 @@
 //@ ignore-android FIXME #17520
 //@ ignore-openbsd no support for libbacktrace without filename
 //@ ignore-wasm no backtrace support
-//@ ignore-emscripten no panic support
 //@ ignore-fuchsia Backtrace not symbolized
 //@ needs-subprocess
 
diff --git a/tests/ui/panics/runtime-switch.run.stderr b/tests/ui/panics/runtime-switch.run.stderr
index 458a0ee534a..70ed127af86 100644
--- a/tests/ui/panics/runtime-switch.run.stderr
+++ b/tests/ui/panics/runtime-switch.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at $DIR/runtime-switch.rs:29:5:
+thread 'main' panicked at $DIR/runtime-switch.rs:28:5:
 explicit panic
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.rs b/tests/ui/panics/short-ice-remove-middle-frames-2.rs
index 48f60b14170..660530f0ead 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames-2.rs
+++ b/tests/ui/panics/short-ice-remove-middle-frames-2.rs
@@ -5,7 +5,6 @@
 //@ needs-unwind
 //@ ignore-android FIXME #17520
 //@ ignore-openbsd no support for libbacktrace without filename
-//@ ignore-emscripten no panic
 //@ ignore-sgx Backtraces not symbolized
 //@ ignore-fuchsia Backtraces not symbolized
 //@ ignore-msvc the `__rust_{begin,end}_short_backtrace` symbols aren't reliable.
diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
index 1fddcca6951..664d51e185d 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
+++ b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:63:5:
+thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:62:5:
 debug!!!
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/panics/short-ice-remove-middle-frames.rs b/tests/ui/panics/short-ice-remove-middle-frames.rs
index 216c5127799..41fb6e9950e 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames.rs
+++ b/tests/ui/panics/short-ice-remove-middle-frames.rs
@@ -5,7 +5,6 @@
 //@ needs-unwind
 //@ ignore-android FIXME #17520
 //@ ignore-openbsd no support for libbacktrace without filename
-//@ ignore-emscripten no panic
 //@ ignore-sgx Backtraces not symbolized
 //@ ignore-fuchsia Backtraces not symbolized
 //@ ignore-msvc the `__rust_{begin,end}_short_backtrace` symbols aren't reliable.
diff --git a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
index 630b09d8d1e..e966462331f 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
+++ b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:59:5:
+thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:58:5:
 debug!!!
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/parser/mod_file_not_exist.rs b/tests/ui/parser/mod_file_not_exist.rs
index e7727944147..49ce44982ab 100644
--- a/tests/ui/parser/mod_file_not_exist.rs
+++ b/tests/ui/parser/mod_file_not_exist.rs
@@ -1,5 +1,3 @@
-//@ ignore-windows
-
 mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file`
 //~^ HELP to create the module `not_a_real_file`, create file
 
diff --git a/tests/ui/parser/mod_file_not_exist.stderr b/tests/ui/parser/mod_file_not_exist.stderr
index 40041b11c8b..d9e4e8f31f5 100644
--- a/tests/ui/parser/mod_file_not_exist.stderr
+++ b/tests/ui/parser/mod_file_not_exist.stderr
@@ -1,5 +1,5 @@
 error[E0583]: file not found for module `not_a_real_file`
-  --> $DIR/mod_file_not_exist.rs:3:1
+  --> $DIR/mod_file_not_exist.rs:1:1
    |
 LL | mod not_a_real_file;
    | ^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | mod not_a_real_file;
    = note: if there is a `mod not_a_real_file` elsewhere in the crate already, import it with `use crate::...` instead
 
 error[E0433]: failed to resolve: use of unresolved module or unlinked crate `mod_file_aux`
-  --> $DIR/mod_file_not_exist.rs:7:16
+  --> $DIR/mod_file_not_exist.rs:5:16
    |
 LL |     assert_eq!(mod_file_aux::bar(), 10);
    |                ^^^^^^^^^^^^ use of unresolved module or unlinked crate `mod_file_aux`
diff --git a/tests/ui/privacy/privacy2.rs b/tests/ui/privacy/privacy2.rs
index ab6d805544e..c82cd442559 100644
--- a/tests/ui/privacy/privacy2.rs
+++ b/tests/ui/privacy/privacy2.rs
@@ -14,16 +14,20 @@ mod bar {
 }
 
 pub fn foo() {}
+//~^ ERROR requires `sized` lang_item
 
 fn test1() {
+    //~^ ERROR requires `sized` lang_item
     use bar::foo;
     //~^ ERROR unresolved import `bar::foo` [E0432]
     //~| no `foo` in `bar`
 }
 
 fn test2() {
+    //~^ ERROR requires `sized` lang_item
     use bar::glob::foo;
     //~^ ERROR `foo` is private
 }
 
 fn main() {}
+//~^ ERROR requires `sized` lang_item
diff --git a/tests/ui/privacy/privacy2.stderr b/tests/ui/privacy/privacy2.stderr
index 46bb9823dbf..39bab67a660 100644
--- a/tests/ui/privacy/privacy2.stderr
+++ b/tests/ui/privacy/privacy2.stderr
@@ -1,11 +1,11 @@
 error[E0432]: unresolved import `bar::foo`
-  --> $DIR/privacy2.rs:19:9
+  --> $DIR/privacy2.rs:21:9
    |
 LL |     use bar::foo;
    |         ^^^^^^^^ no `foo` in `bar`
 
 error[E0603]: function import `foo` is private
-  --> $DIR/privacy2.rs:25:20
+  --> $DIR/privacy2.rs:28:20
    |
 LL |     use bar::glob::foo;
    |                    ^^^ private function import
@@ -22,8 +22,40 @@ LL | pub fn foo() {}
    | ^^^^^^^^^^^^ you could import this directly
 
 error: requires `sized` lang_item
+  --> $DIR/privacy2.rs:16:14
+   |
+LL | pub fn foo() {}
+   |              ^^
+
+error: requires `sized` lang_item
+  --> $DIR/privacy2.rs:19:12
+   |
+LL |   fn test1() {
+   |  ____________^
+LL | |
+LL | |     use bar::foo;
+...  |
+LL | | }
+   | |_^
+
+error: requires `sized` lang_item
+  --> $DIR/privacy2.rs:26:12
+   |
+LL |   fn test2() {
+   |  ____________^
+LL | |
+LL | |     use bar::glob::foo;
+LL | |
+LL | | }
+   | |_^
+
+error: requires `sized` lang_item
+  --> $DIR/privacy2.rs:32:11
+   |
+LL | fn main() {}
+   |           ^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0432, E0603.
 For more information about an error, try `rustc --explain E0432`.
diff --git a/tests/ui/privacy/privacy3.rs b/tests/ui/privacy/privacy3.rs
index 6298a6bc8cf..2bb3c1b3c61 100644
--- a/tests/ui/privacy/privacy3.rs
+++ b/tests/ui/privacy/privacy3.rs
@@ -11,12 +11,15 @@ mod bar {
 
     mod glob {
         fn gpriv() {}
+    //~^ ERROR requires `sized` lang_item
     }
 }
 
 pub fn foo() {}
+//~^ ERROR requires `sized` lang_item
 
 fn test1() {
+    //~^ ERROR requires `sized` lang_item
     use bar::gpriv;
     //~^ ERROR unresolved import `bar::gpriv` [E0432]
     //~| no `gpriv` in `bar`
@@ -27,3 +30,4 @@ fn test1() {
 }
 
 fn main() {}
+//~^ ERROR requires `sized` lang_item
diff --git a/tests/ui/privacy/privacy3.stderr b/tests/ui/privacy/privacy3.stderr
index df66c84751b..06a287d35ea 100644
--- a/tests/ui/privacy/privacy3.stderr
+++ b/tests/ui/privacy/privacy3.stderr
@@ -1,11 +1,39 @@
 error[E0432]: unresolved import `bar::gpriv`
-  --> $DIR/privacy3.rs:20:9
+  --> $DIR/privacy3.rs:23:9
    |
 LL |     use bar::gpriv;
    |         ^^^^^^^^^^ no `gpriv` in `bar`
 
 error: requires `sized` lang_item
+  --> $DIR/privacy3.rs:18:14
+   |
+LL | pub fn foo() {}
+   |              ^^
+
+error: requires `sized` lang_item
+  --> $DIR/privacy3.rs:21:12
+   |
+LL |   fn test1() {
+   |  ____________^
+LL | |
+LL | |     use bar::gpriv;
+...  |
+LL | |     gpriv();
+LL | | }
+   | |_^
+
+error: requires `sized` lang_item
+  --> $DIR/privacy3.rs:32:11
+   |
+LL | fn main() {}
+   |           ^^
+
+error: requires `sized` lang_item
+  --> $DIR/privacy3.rs:13:20
+   |
+LL |         fn gpriv() {}
+   |                    ^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr
index 08e679a7c55..2d0c92ff297 100644
--- a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr
+++ b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr
@@ -1,4 +1,10 @@
 error: requires `sized` lang_item
+  --> $DIR/issue-59191-replace-root-with-fn.rs:9:1
+   |
+LL | #![issue_59191::no_main]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in the attribute macro `issue_59191::no_main` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/range/issue-54505-no-literals.stderr b/tests/ui/range/issue-54505-no-literals.stderr
index 5894bb6ba55..c6d4384bcd3 100644
--- a/tests/ui/range/issue-54505-no-literals.stderr
+++ b/tests/ui/range/issue-54505-no-literals.stderr
@@ -47,7 +47,7 @@ LL |     take_range(std::ops::RangeFrom { start: 1 });
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `RangeFrom<{integer}>`
+                 found struct `std::ops::RangeFrom<{integer}>`
 note: function defined here
   --> $DIR/issue-54505-no-literals.rs:12:4
    |
@@ -67,7 +67,7 @@ LL |     take_range(::std::ops::RangeFrom { start: 1 });
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `RangeFrom<{integer}>`
+                 found struct `std::ops::RangeFrom<{integer}>`
 note: function defined here
   --> $DIR/issue-54505-no-literals.rs:12:4
    |
@@ -127,7 +127,7 @@ LL |     take_range(std::ops::RangeInclusive::new(0, 1));
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `RangeInclusive<{integer}>`
+                 found struct `std::ops::RangeInclusive<{integer}>`
 note: function defined here
   --> $DIR/issue-54505-no-literals.rs:12:4
    |
@@ -147,7 +147,7 @@ LL |     take_range(::std::ops::RangeInclusive::new(0, 1));
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `RangeInclusive<{integer}>`
+                 found struct `std::ops::RangeInclusive<{integer}>`
 note: function defined here
   --> $DIR/issue-54505-no-literals.rs:12:4
    |
diff --git a/tests/ui/range/issue-54505.stderr b/tests/ui/range/issue-54505.stderr
index 291e097e865..8b669b2910f 100644
--- a/tests/ui/range/issue-54505.stderr
+++ b/tests/ui/range/issue-54505.stderr
@@ -27,7 +27,7 @@ LL |     take_range(1..);
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `RangeFrom<{integer}>`
+                 found struct `std::ops::RangeFrom<{integer}>`
 note: function defined here
   --> $DIR/issue-54505.rs:10:4
    |
@@ -72,7 +72,7 @@ LL |     take_range(0..=1);
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `RangeInclusive<{integer}>`
+                 found struct `std::ops::RangeInclusive<{integer}>`
 note: function defined here
   --> $DIR/issue-54505.rs:10:4
    |
diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr
index f77601bc43c..37669dd3f47 100644
--- a/tests/ui/range/range-1.stderr
+++ b/tests/ui/range/range-1.stderr
@@ -30,7 +30,7 @@ LL |     let range = *arr..;
    |                 ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[{integer}]`
-note: required by an implicit `Sized` bound in `RangeFrom`
+note: required by an implicit `Sized` bound in `std::ops::RangeFrom`
   --> $SRC_DIR/core/src/ops/range.rs:LL:COL
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/self/dispatch-from-dyn-layout-2.rs b/tests/ui/self/dispatch-from-dyn-layout-2.rs
new file mode 100644
index 00000000000..cd52f060dc8
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-layout-2.rs
@@ -0,0 +1,16 @@
+//@ check-pass
+// Regression test for #90110.
+
+// Make sure that object safety checking doesn't freak out when
+// we have impossible-to-satisfy `Sized` predicates.
+
+trait Parser
+where
+    for<'a> (dyn Parser + 'a): Sized,
+{
+    fn parse_line(&self);
+}
+
+fn foo(_: &dyn Parser) {}
+
+fn main() {}
diff --git a/tests/ui/self/dispatch-from-dyn-layout-3.rs b/tests/ui/self/dispatch-from-dyn-layout-3.rs
new file mode 100644
index 00000000000..6878a4f4ac2
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-layout-3.rs
@@ -0,0 +1,19 @@
+//@ check-pass
+
+// Make sure that object safety checking doesn't freak out when
+// we have impossible-to-satisfy `DispatchFromDyn` predicates.
+
+#![feature(dispatch_from_dyn)]
+#![feature(arbitrary_self_types)]
+
+use std::ops::Deref;
+use std::ops::DispatchFromDyn;
+
+trait Trait<T: Deref<Target = Self>>
+where
+    for<'a> &'a T: DispatchFromDyn<&'a T>,
+{
+    fn foo(self: &T) -> Box<dyn Trait<T>>;
+}
+
+fn main() {}
diff --git a/tests/crashes/57276.rs b/tests/ui/self/dispatch-from-dyn-layout.rs
index f70be4fba6d..468dc89a73e 100644
--- a/tests/crashes/57276.rs
+++ b/tests/ui/self/dispatch-from-dyn-layout.rs
@@ -1,4 +1,8 @@
-//@ known-bug: #57276
+//@ check-pass
+// Regression test for #57276.
+
+// Make sure that object safety checking doesn't freak out when
+// we have impossible-to-satisfy `DispatchFromDyn` predicates.
 
 #![feature(arbitrary_self_types, dispatch_from_dyn)]
 
diff --git a/tests/ui/simd/array-trait.rs b/tests/ui/simd/array-trait.rs
index 67583bf8208..32cbf01428c 100644
--- a/tests/ui/simd/array-trait.rs
+++ b/tests/ui/simd/array-trait.rs
@@ -24,10 +24,12 @@ pub struct T<S: Simd>([S::Lane; S::SIZE]);
 //~| ERROR SIMD vector element type should be a primitive scalar
 //~| ERROR unconstrained generic constant
 
-extern "rust-intrinsic" {
-    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
-    fn simd_extract<T, E>(x: T, idx: u32) -> E;
-}
+#[rustc_intrinsic]
+unsafe fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_extract<T, E>(x: T, idx: u32) -> E;
+
 
 pub fn main() {
     let mut t = T::<i32x4>([0; 4]);
diff --git a/tests/ui/simd/array-type.rs b/tests/ui/simd/array-type.rs
index 8ca53b1a453..d1de7004416 100644
--- a/tests/ui/simd/array-type.rs
+++ b/tests/ui/simd/array-type.rs
@@ -12,10 +12,12 @@ struct S([i32; 4]);
 #[derive(Copy, Clone)]
 struct T<const N: usize>([i32; N]);
 
-extern "rust-intrinsic" {
-    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
-    fn simd_extract<T, E>(x: T, idx: u32) -> E;
-}
+#[rustc_intrinsic]
+unsafe fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_extract<T, E>(x: T, idx: u32) -> E;
+
 
 pub fn main() {
     let mut s = S([0; 4]);
diff --git a/tests/ui/simd/generics.rs b/tests/ui/simd/generics.rs
index f96a7cd75e9..453ed86c14a 100644
--- a/tests/ui/simd/generics.rs
+++ b/tests/ui/simd/generics.rs
@@ -21,9 +21,8 @@ struct B<T>([T; 4]);
 struct C<T, const N: usize>([T; N]);
 
 
-extern "rust-intrinsic" {
-    fn simd_add<T>(x: T, y: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_add<T>(x: T, y: T) -> T;
 
 fn add<T: ops::Add<Output=T>>(lhs: T, rhs: T) -> T {
     lhs + rhs
diff --git a/tests/ui/simd/intrinsic/float-math-pass.rs b/tests/ui/simd/intrinsic/float-math-pass.rs
index 24b9941133e..74cb51a0606 100644
--- a/tests/ui/simd/intrinsic/float-math-pass.rs
+++ b/tests/ui/simd/intrinsic/float-math-pass.rs
@@ -15,27 +15,59 @@
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct f32x4(pub [f32; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_fsqrt<T>(x: T) -> T;
-    fn simd_fabs<T>(x: T) -> T;
-    fn simd_fsin<T>(x: T) -> T;
-    fn simd_fcos<T>(x: T) -> T;
-    fn simd_fexp<T>(x: T) -> T;
-    fn simd_fexp2<T>(x: T) -> T;
-    fn simd_fma<T>(x: T, y: T, z: T) -> T;
-    fn simd_relaxed_fma<T>(x: T, y: T, z: T) -> T;
-    fn simd_flog<T>(x: T) -> T;
-    fn simd_flog10<T>(x: T) -> T;
-    fn simd_flog2<T>(x: T) -> T;
-    fn simd_fpow<T>(x: T, y: T) -> T;
-    fn simd_fpowi<T>(x: T, y: i32) -> T;
-
-    // rounding functions
-    fn simd_ceil<T>(x: T) -> T;
-    fn simd_floor<T>(x: T) -> T;
-    fn simd_round<T>(x: T) -> T;
-    fn simd_trunc<T>(x: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_fsqrt<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_fabs<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_fsin<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_fcos<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_fexp<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_fexp2<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_fma<T>(x: T, y: T, z: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_relaxed_fma<T>(x: T, y: T, z: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_flog<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_flog10<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_flog2<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_fpow<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_fpowi<T>(x: T, y: i32) -> T;
+
+
+// rounding functions
+#[rustc_intrinsic]
+unsafe fn simd_ceil<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_floor<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_round<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_trunc<T>(x: T) -> T;
+
 
 macro_rules! assert_approx_eq_f32 {
     ($a:expr, $b:expr) => ({
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
index 663bcdf1981..0fcff8584c8 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
@@ -14,25 +14,54 @@ pub struct u32x4(pub [u32; 4]);
 #[derive(Copy, Clone)]
 pub struct f32x4(pub [f32; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_add<T>(x: T, y: T) -> T;
-    fn simd_sub<T>(x: T, y: T) -> T;
-    fn simd_mul<T>(x: T, y: T) -> T;
-    fn simd_div<T>(x: T, y: T) -> T;
-    fn simd_rem<T>(x: T, y: T) -> T;
-    fn simd_shl<T>(x: T, y: T) -> T;
-    fn simd_shr<T>(x: T, y: T) -> T;
-    fn simd_and<T>(x: T, y: T) -> T;
-    fn simd_or<T>(x: T, y: T) -> T;
-    fn simd_xor<T>(x: T, y: T) -> T;
-
-    fn simd_neg<T>(x: T) -> T;
-    fn simd_bswap<T>(x: T) -> T;
-    fn simd_bitreverse<T>(x: T) -> T;
-    fn simd_ctlz<T>(x: T) -> T;
-    fn simd_ctpop<T>(x: T) -> T;
-    fn simd_cttz<T>(x: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_add<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_sub<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_mul<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_div<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_rem<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_shl<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_shr<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_and<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_or<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_xor<T>(x: T, y: T) -> T;
+
+
+#[rustc_intrinsic]
+unsafe fn simd_neg<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_bswap<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_bitreverse<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_ctlz<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_ctpop<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_cttz<T>(x: T) -> T;
 
 fn main() {
     let x = i32x4([0, 0, 0, 0]);
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr b/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr
index 6f5f86d7d37..e67de2fe903 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr
@@ -1,143 +1,143 @@
 error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:81:9
+  --> $DIR/generic-arithmetic-2.rs:110:9
    |
 LL |         simd_add(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_sub` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:83:9
+  --> $DIR/generic-arithmetic-2.rs:112:9
    |
 LL |         simd_sub(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_mul` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:85:9
+  --> $DIR/generic-arithmetic-2.rs:114:9
    |
 LL |         simd_mul(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_div` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:87:9
+  --> $DIR/generic-arithmetic-2.rs:116:9
    |
 LL |         simd_div(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shl` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:89:9
+  --> $DIR/generic-arithmetic-2.rs:118:9
    |
 LL |         simd_shl(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shr` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:91:9
+  --> $DIR/generic-arithmetic-2.rs:120:9
    |
 LL |         simd_shr(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_and` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:93:9
+  --> $DIR/generic-arithmetic-2.rs:122:9
    |
 LL |         simd_and(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_or` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:95:9
+  --> $DIR/generic-arithmetic-2.rs:124:9
    |
 LL |         simd_or(0, 0);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_xor` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:97:9
+  --> $DIR/generic-arithmetic-2.rs:126:9
    |
 LL |         simd_xor(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_neg` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:100:9
+  --> $DIR/generic-arithmetic-2.rs:129:9
    |
 LL |         simd_neg(0);
    |         ^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bswap` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:102:9
+  --> $DIR/generic-arithmetic-2.rs:131:9
    |
 LL |         simd_bswap(0);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitreverse` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:104:9
+  --> $DIR/generic-arithmetic-2.rs:133:9
    |
 LL |         simd_bitreverse(0);
    |         ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ctlz` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:106:9
+  --> $DIR/generic-arithmetic-2.rs:135:9
    |
 LL |         simd_ctlz(0);
    |         ^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cttz` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:108:9
+  --> $DIR/generic-arithmetic-2.rs:137:9
    |
 LL |         simd_cttz(0);
    |         ^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shl` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:111:9
+  --> $DIR/generic-arithmetic-2.rs:140:9
    |
 LL |         simd_shl(z, z);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shr` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:113:9
+  --> $DIR/generic-arithmetic-2.rs:142:9
    |
 LL |         simd_shr(z, z);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_and` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:115:9
+  --> $DIR/generic-arithmetic-2.rs:144:9
    |
 LL |         simd_and(z, z);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_or` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:117:9
+  --> $DIR/generic-arithmetic-2.rs:146:9
    |
 LL |         simd_or(z, z);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_xor` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:119:9
+  --> $DIR/generic-arithmetic-2.rs:148:9
    |
 LL |         simd_xor(z, z);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bswap` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:121:9
+  --> $DIR/generic-arithmetic-2.rs:150:9
    |
 LL |         simd_bswap(z);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitreverse` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:123:9
+  --> $DIR/generic-arithmetic-2.rs:152:9
    |
 LL |         simd_bitreverse(z);
    |         ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ctlz` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:125:9
+  --> $DIR/generic-arithmetic-2.rs:154:9
    |
 LL |         simd_ctlz(z);
    |         ^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ctpop` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:127:9
+  --> $DIR/generic-arithmetic-2.rs:156:9
    |
 LL |         simd_ctpop(z);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cttz` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:129:9
+  --> $DIR/generic-arithmetic-2.rs:158:9
    |
 LL |         simd_cttz(z);
    |         ^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
index e4eb2a9da27..4a18c0164e4 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
@@ -23,25 +23,54 @@ macro_rules! all_eq {
     }};
 }
 
-extern "rust-intrinsic" {
-    fn simd_add<T>(x: T, y: T) -> T;
-    fn simd_sub<T>(x: T, y: T) -> T;
-    fn simd_mul<T>(x: T, y: T) -> T;
-    fn simd_div<T>(x: T, y: T) -> T;
-    fn simd_rem<T>(x: T, y: T) -> T;
-    fn simd_shl<T>(x: T, y: T) -> T;
-    fn simd_shr<T>(x: T, y: T) -> T;
-    fn simd_and<T>(x: T, y: T) -> T;
-    fn simd_or<T>(x: T, y: T) -> T;
-    fn simd_xor<T>(x: T, y: T) -> T;
-
-    fn simd_neg<T>(x: T) -> T;
-    fn simd_bswap<T>(x: T) -> T;
-    fn simd_bitreverse<T>(x: T) -> T;
-    fn simd_ctlz<T>(x: T) -> T;
-    fn simd_ctpop<T>(x: T) -> T;
-    fn simd_cttz<T>(x: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_add<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_sub<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_mul<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_div<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_rem<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_shl<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_shr<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_and<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_or<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_xor<T>(x: T, y: T) -> T;
+
+
+#[rustc_intrinsic]
+unsafe fn simd_neg<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_bswap<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_bitreverse<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_ctlz<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_ctpop<T>(x: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_cttz<T>(x: T) -> T;
 
 fn main() {
     let x1 = i32x4([1, 2, 3, 4]);
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
index ec6ac78df1a..85464402d6a 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
@@ -14,10 +14,12 @@ pub struct x4<T>(pub [T; 4]);
 #[derive(Copy, Clone)]
 pub struct f32x4(pub [f32; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_saturating_add<T>(x: T, y: T) -> T;
-    fn simd_saturating_sub<T>(x: T, y: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_saturating_add<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_saturating_sub<T>(x: T, y: T) -> T;
+
 
 fn main() {
     let x = i32x4([0, 0, 0, 0]);
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr
index f349cb56560..cf275db7e43 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr
@@ -1,11 +1,11 @@
 error[E0511]: invalid monomorphization of `simd_saturating_add` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
-  --> $DIR/generic-arithmetic-saturating-2.rs:33:9
+  --> $DIR/generic-arithmetic-saturating-2.rs:35:9
    |
 LL |         simd_saturating_add(z, z);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_saturating_sub` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
-  --> $DIR/generic-arithmetic-saturating-2.rs:35:9
+  --> $DIR/generic-arithmetic-saturating-2.rs:37:9
    |
 LL |         simd_saturating_sub(z, z);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
index 57bda5c2d62..5fe65257d15 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
@@ -12,10 +12,12 @@ struct u32x4(pub [u32; 4]);
 #[derive(Copy, Clone)]
 struct I32<const N: usize>([i32; N]);
 
-extern "rust-intrinsic" {
-    fn simd_saturating_add<T>(x: T, y: T) -> T;
-    fn simd_saturating_sub<T>(x: T, y: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_saturating_add<T>(x: T, y: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_saturating_sub<T>(x: T, y: T) -> T;
+
 
 fn main() {
     // unsigned
diff --git a/tests/ui/simd/intrinsic/generic-as.rs b/tests/ui/simd/intrinsic/generic-as.rs
index e97bf12c144..124ca56bc88 100644
--- a/tests/ui/simd/intrinsic/generic-as.rs
+++ b/tests/ui/simd/intrinsic/generic-as.rs
@@ -2,9 +2,9 @@
 
 #![feature(repr_simd, intrinsics)]
 
-extern "rust-intrinsic" {
-    fn simd_as<T, U>(x: T) -> U;
-}
+
+#[rustc_intrinsic]
+unsafe fn simd_as<T, U>(x: T) -> U;
 
 #[derive(Copy, Clone)]
 #[repr(simd)]
diff --git a/tests/ui/simd/intrinsic/generic-bitmask-pass.rs b/tests/ui/simd/intrinsic/generic-bitmask-pass.rs
index db10020bd46..08526991fbe 100644
--- a/tests/ui/simd/intrinsic/generic-bitmask-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-bitmask-pass.rs
@@ -21,9 +21,8 @@ struct u8x4(pub [u8; 4]);
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct Tx4<T>(pub [T; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_bitmask<T, U>(x: T) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_bitmask<T, U>(x: T) -> U;
 
 fn main() {
     let z = u32x4([0, 0, 0, 0]);
diff --git a/tests/ui/simd/intrinsic/generic-bitmask.rs b/tests/ui/simd/intrinsic/generic-bitmask.rs
index 29b9279c370..49589d22bbf 100644
--- a/tests/ui/simd/intrinsic/generic-bitmask.rs
+++ b/tests/ui/simd/intrinsic/generic-bitmask.rs
@@ -30,9 +30,8 @@ struct u8x32([u8; 32]);
 #[derive(Copy, Clone)]
 struct u8x64([u8; 64]);
 
-extern "rust-intrinsic" {
-    fn simd_bitmask<T, U>(x: T) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_bitmask<T, U>(x: T) -> U;
 
 fn main() {
     let m2 = u32x2([0; 2]);
diff --git a/tests/ui/simd/intrinsic/generic-bitmask.stderr b/tests/ui/simd/intrinsic/generic-bitmask.stderr
index 0de3f8eead8..c217bb2d8f1 100644
--- a/tests/ui/simd/intrinsic/generic-bitmask.stderr
+++ b/tests/ui/simd/intrinsic/generic-bitmask.stderr
@@ -1,29 +1,29 @@
 error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: cannot return `u16`, expected `u8` or `[u8; 1]`
-  --> $DIR/generic-bitmask.rs:53:22
+  --> $DIR/generic-bitmask.rs:52:22
    |
 LL |         let _: u16 = simd_bitmask(m2);
    |                      ^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: cannot return `u16`, expected `u8` or `[u8; 1]`
-  --> $DIR/generic-bitmask.rs:56:22
+  --> $DIR/generic-bitmask.rs:55:22
    |
 LL |         let _: u16 = simd_bitmask(m8);
    |                      ^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: cannot return `u32`, expected `u16` or `[u8; 2]`
-  --> $DIR/generic-bitmask.rs:59:22
+  --> $DIR/generic-bitmask.rs:58:22
    |
 LL |         let _: u32 = simd_bitmask(m16);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: cannot return `u64`, expected `u32` or `[u8; 4]`
-  --> $DIR/generic-bitmask.rs:62:22
+  --> $DIR/generic-bitmask.rs:61:22
    |
 LL |         let _: u64 = simd_bitmask(m32);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: cannot return `u128`, expected `u64` or `[u8; 8]`
-  --> $DIR/generic-bitmask.rs:65:23
+  --> $DIR/generic-bitmask.rs:64:23
    |
 LL |         let _: u128 = simd_bitmask(m64);
    |                       ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-bswap-byte.rs b/tests/ui/simd/intrinsic/generic-bswap-byte.rs
index f1702538165..4521573636c 100644
--- a/tests/ui/simd/intrinsic/generic-bswap-byte.rs
+++ b/tests/ui/simd/intrinsic/generic-bswap-byte.rs
@@ -10,9 +10,8 @@ struct i8x4([i8; 4]);
 #[derive(Copy, Clone)]
 struct u8x4([u8; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_bswap<T>(x: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_bswap<T>(x: T) -> T;
 
 fn main() {
     unsafe {
diff --git a/tests/ui/simd/intrinsic/generic-cast-pass.rs b/tests/ui/simd/intrinsic/generic-cast-pass.rs
index e0319a6461a..2155d845864 100644
--- a/tests/ui/simd/intrinsic/generic-cast-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-cast-pass.rs
@@ -3,9 +3,9 @@
 
 #![feature(repr_simd, intrinsics)]
 
-extern "rust-intrinsic" {
-    fn simd_cast<T, U>(x: T) -> U;
-}
+
+#[rustc_intrinsic]
+unsafe fn simd_cast<T, U>(x: T) -> U;
 
 use std::cmp::{max, min};
 
diff --git a/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs b/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs
index 1c09a9fbf3b..9f28898654f 100644
--- a/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs
+++ b/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs
@@ -1,9 +1,8 @@
 //@ run-pass
 #![feature(repr_simd, intrinsics)]
 
-extern "rust-intrinsic" {
-    fn simd_cast<T, U>(x: T) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_cast<T, U>(x: T) -> U;
 
 #[derive(Copy, Clone)]
 #[repr(simd)]
diff --git a/tests/ui/simd/intrinsic/generic-cast.rs b/tests/ui/simd/intrinsic/generic-cast.rs
index 33978a2f739..7f398804eb4 100644
--- a/tests/ui/simd/intrinsic/generic-cast.rs
+++ b/tests/ui/simd/intrinsic/generic-cast.rs
@@ -21,9 +21,8 @@ struct f32x4([f32; 4]);
 struct f32x8([f32; 8]);
 
 
-extern "rust-intrinsic" {
-    fn simd_cast<T, U>(x: T) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_cast<T, U>(x: T) -> U;
 
 fn main() {
     let x = i32x4([0, 0, 0, 0]);
diff --git a/tests/ui/simd/intrinsic/generic-cast.stderr b/tests/ui/simd/intrinsic/generic-cast.stderr
index 2f9d44037af..1b6ac03f8c9 100644
--- a/tests/ui/simd/intrinsic/generic-cast.stderr
+++ b/tests/ui/simd/intrinsic/generic-cast.stderr
@@ -1,23 +1,23 @@
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-cast.rs:32:9
+  --> $DIR/generic-cast.rs:31:9
    |
 LL |         simd_cast::<i32, i32>(0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-cast.rs:34:9
+  --> $DIR/generic-cast.rs:33:9
    |
 LL |         simd_cast::<i32, i32x4>(0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-cast.rs:36:9
+  --> $DIR/generic-cast.rs:35:9
    |
 LL |         simd_cast::<i32x4, i32>(x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8
-  --> $DIR/generic-cast.rs:38:9
+  --> $DIR/generic-cast.rs:37:9
    |
 LL |         simd_cast::<_, i32x8>(x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-comparison-pass.rs b/tests/ui/simd/intrinsic/generic-comparison-pass.rs
index a4d84a4c534..68f98372e1d 100644
--- a/tests/ui/simd/intrinsic/generic-comparison-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-comparison-pass.rs
@@ -14,14 +14,24 @@ struct u32x4(pub [u32; 4]);
 #[derive(Copy, Clone)]
 struct f32x4(pub [f32; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_eq<T, U>(x: T, y: T) -> U;
-    fn simd_ne<T, U>(x: T, y: T) -> U;
-    fn simd_lt<T, U>(x: T, y: T) -> U;
-    fn simd_le<T, U>(x: T, y: T) -> U;
-    fn simd_gt<T, U>(x: T, y: T) -> U;
-    fn simd_ge<T, U>(x: T, y: T) -> U;
-}
+
+#[rustc_intrinsic]
+unsafe fn simd_eq<T, U>(x: T, y: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_ne<T, U>(x: T, y: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_lt<T, U>(x: T, y: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_le<T, U>(x: T, y: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_gt<T, U>(x: T, y: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_ge<T, U>(x: T, y: T) -> U;
 
 macro_rules! cmp {
     ($method: ident($lhs: expr, $rhs: expr)) => {{
diff --git a/tests/ui/simd/intrinsic/generic-comparison.rs b/tests/ui/simd/intrinsic/generic-comparison.rs
index f7f0655f3d2..e5adb49f6a3 100644
--- a/tests/ui/simd/intrinsic/generic-comparison.rs
+++ b/tests/ui/simd/intrinsic/generic-comparison.rs
@@ -11,14 +11,24 @@ struct i32x4([i32; 4]);
 #[allow(non_camel_case_types)]
 struct i16x8([i16; 8]);
 
-extern "rust-intrinsic" {
-    fn simd_eq<T, U>(x: T, y: T) -> U;
-    fn simd_ne<T, U>(x: T, y: T) -> U;
-    fn simd_lt<T, U>(x: T, y: T) -> U;
-    fn simd_le<T, U>(x: T, y: T) -> U;
-    fn simd_gt<T, U>(x: T, y: T) -> U;
-    fn simd_ge<T, U>(x: T, y: T) -> U;
-}
+
+#[rustc_intrinsic]
+unsafe fn simd_eq<T, U>(x: T, y: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_ne<T, U>(x: T, y: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_lt<T, U>(x: T, y: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_le<T, U>(x: T, y: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_gt<T, U>(x: T, y: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_ge<T, U>(x: T, y: T) -> U;
 
 fn main() {
     let x = i32x4([0, 0, 0, 0]);
diff --git a/tests/ui/simd/intrinsic/generic-comparison.stderr b/tests/ui/simd/intrinsic/generic-comparison.stderr
index ac4d4918827..cc66d2ce40a 100644
--- a/tests/ui/simd/intrinsic/generic-comparison.stderr
+++ b/tests/ui/simd/intrinsic/generic-comparison.stderr
@@ -1,107 +1,107 @@
 error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:27:9
+  --> $DIR/generic-comparison.rs:37:9
    |
 LL |         simd_eq::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:29:9
+  --> $DIR/generic-comparison.rs:39:9
    |
 LL |         simd_ne::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:31:9
+  --> $DIR/generic-comparison.rs:41:9
    |
 LL |         simd_lt::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:33:9
+  --> $DIR/generic-comparison.rs:43:9
    |
 LL |         simd_le::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:35:9
+  --> $DIR/generic-comparison.rs:45:9
    |
 LL |         simd_gt::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:37:9
+  --> $DIR/generic-comparison.rs:47:9
    |
 LL |         simd_ge::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:40:9
+  --> $DIR/generic-comparison.rs:50:9
    |
 LL |         simd_eq::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:42:9
+  --> $DIR/generic-comparison.rs:52:9
    |
 LL |         simd_ne::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:44:9
+  --> $DIR/generic-comparison.rs:54:9
    |
 LL |         simd_lt::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:46:9
+  --> $DIR/generic-comparison.rs:56:9
    |
 LL |         simd_le::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:48:9
+  --> $DIR/generic-comparison.rs:58:9
    |
 LL |         simd_gt::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:50:9
+  --> $DIR/generic-comparison.rs:60:9
    |
 LL |         simd_ge::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:53:9
+  --> $DIR/generic-comparison.rs:63:9
    |
 LL |         simd_eq::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:55:9
+  --> $DIR/generic-comparison.rs:65:9
    |
 LL |         simd_ne::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:57:9
+  --> $DIR/generic-comparison.rs:67:9
    |
 LL |         simd_lt::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:59:9
+  --> $DIR/generic-comparison.rs:69:9
    |
 LL |         simd_le::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:61:9
+  --> $DIR/generic-comparison.rs:71:9
    |
 LL |         simd_gt::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:63:9
+  --> $DIR/generic-comparison.rs:73:9
    |
 LL |         simd_ge::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-elements-pass.rs b/tests/ui/simd/intrinsic/generic-elements-pass.rs
index 7b1bda4fbcd..8cb600bc9e4 100644
--- a/tests/ui/simd/intrinsic/generic-elements-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-elements-pass.rs
@@ -16,12 +16,15 @@ struct i32x4([i32; 4]);
 #[allow(non_camel_case_types)]
 struct i32x8([i32; 8]);
 
-extern "rust-intrinsic" {
-    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
-    fn simd_extract<T, E>(x: T, idx: u32) -> E;
+#[rustc_intrinsic]
+unsafe fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
 
-    fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_extract<T, E>(x: T, idx: u32) -> E;
+
+
+#[rustc_intrinsic]
+unsafe fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
 
 #[repr(simd)]
 struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
diff --git a/tests/ui/simd/intrinsic/generic-elements.rs b/tests/ui/simd/intrinsic/generic-elements.rs
index 5d784a25eab..4be6645f029 100644
--- a/tests/ui/simd/intrinsic/generic-elements.rs
+++ b/tests/ui/simd/intrinsic/generic-elements.rs
@@ -29,13 +29,20 @@ struct f32x4([f32; 4]);
 #[allow(non_camel_case_types)]
 struct f32x8([f32; 8]);
 
-extern "rust-intrinsic" {
-    fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
-    fn simd_extract<T, E>(x: T, idx: u32) -> E;
 
-    fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
-    fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_extract<T, E>(x: T, idx: u32) -> E;
+
+
+#[rustc_intrinsic]
+unsafe fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
+
 
 #[repr(simd)]
 struct SimdShuffleIdx<const LEN: usize>([u32; LEN]);
diff --git a/tests/ui/simd/intrinsic/generic-elements.stderr b/tests/ui/simd/intrinsic/generic-elements.stderr
index fd726d75326..8104c3ba5a2 100644
--- a/tests/ui/simd/intrinsic/generic-elements.stderr
+++ b/tests/ui/simd/intrinsic/generic-elements.stderr
@@ -1,125 +1,125 @@
 error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:47:9
+  --> $DIR/generic-elements.rs:54:9
    |
 LL |         simd_insert(0, 0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64`
-  --> $DIR/generic-elements.rs:49:9
+  --> $DIR/generic-elements.rs:56:9
    |
 LL |         simd_insert(x, 0, 1.0);
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32`
-  --> $DIR/generic-elements.rs:51:9
+  --> $DIR/generic-elements.rs:58:9
    |
 LL |         simd_extract::<_, f32>(x, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:55:9
+  --> $DIR/generic-elements.rs:62:9
    |
 LL |         simd_shuffle::<i32, _, i32>(0, 0, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:58:9
+  --> $DIR/generic-elements.rs:65:9
    |
 LL |         simd_shuffle::<i32, _, i32>(0, 0, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:61:9
+  --> $DIR/generic-elements.rs:68:9
    |
 LL |         simd_shuffle::<i32, _, i32>(0, 0, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
-  --> $DIR/generic-elements.rs:64:9
+  --> $DIR/generic-elements.rs:71:9
    |
 LL |         simd_shuffle::<_, _, f32x2>(x, x, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
-  --> $DIR/generic-elements.rs:66:9
+  --> $DIR/generic-elements.rs:73:9
    |
 LL |         simd_shuffle::<_, _, f32x4>(x, x, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
-  --> $DIR/generic-elements.rs:68:9
+  --> $DIR/generic-elements.rs:75:9
    |
 LL |         simd_shuffle::<_, _, f32x8>(x, x, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `i32x8` with length 8
-  --> $DIR/generic-elements.rs:71:9
+  --> $DIR/generic-elements.rs:78:9
    |
 LL |         simd_shuffle::<_, _, i32x8>(x, x, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 4, found `i32x8` with length 8
-  --> $DIR/generic-elements.rs:73:9
+  --> $DIR/generic-elements.rs:80:9
    |
 LL |         simd_shuffle::<_, _, i32x8>(x, x, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 8, found `i32x2` with length 2
-  --> $DIR/generic-elements.rs:75:9
+  --> $DIR/generic-elements.rs:82:9
    |
 LL |         simd_shuffle::<_, _, i32x2>(x, x, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:79:9
+  --> $DIR/generic-elements.rs:86:9
    |
 LL |         simd_shuffle_generic::<i32, i32, I2>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:82:9
+  --> $DIR/generic-elements.rs:89:9
    |
 LL |         simd_shuffle_generic::<i32, i32, I4>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:85:9
+  --> $DIR/generic-elements.rs:92:9
    |
 LL |         simd_shuffle_generic::<i32, i32, I8>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
-  --> $DIR/generic-elements.rs:88:9
+  --> $DIR/generic-elements.rs:95:9
    |
 LL |         simd_shuffle_generic::<_, f32x2, I2>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
-  --> $DIR/generic-elements.rs:90:9
+  --> $DIR/generic-elements.rs:97:9
    |
 LL |         simd_shuffle_generic::<_, f32x4, I4>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
-  --> $DIR/generic-elements.rs:92:9
+  --> $DIR/generic-elements.rs:99:9
    |
 LL |         simd_shuffle_generic::<_, f32x8, I8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 2, found `i32x8` with length 8
-  --> $DIR/generic-elements.rs:95:9
+  --> $DIR/generic-elements.rs:102:9
    |
 LL |         simd_shuffle_generic::<_, i32x8, I2>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 4, found `i32x8` with length 8
-  --> $DIR/generic-elements.rs:97:9
+  --> $DIR/generic-elements.rs:104:9
    |
 LL |         simd_shuffle_generic::<_, i32x8, I4>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 8, found `i32x2` with length 2
-  --> $DIR/generic-elements.rs:99:9
+  --> $DIR/generic-elements.rs:106:9
    |
 LL |         simd_shuffle_generic::<_, i32x2, I8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-gather-pass.rs b/tests/ui/simd/intrinsic/generic-gather-pass.rs
index 3315d1cdaa2..0b2cf47e989 100644
--- a/tests/ui/simd/intrinsic/generic-gather-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-gather-pass.rs
@@ -10,10 +10,11 @@
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct x4<T>(pub [T; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
-    fn simd_scatter<T, U, V>(x: T, y: U, z: V) -> ();
-}
+#[rustc_intrinsic]
+unsafe fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_scatter<T, U, V>(x: T, y: U, z: V) -> ();
 
 fn main() {
     let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.];
diff --git a/tests/ui/simd/intrinsic/generic-reduction-pass.rs b/tests/ui/simd/intrinsic/generic-reduction-pass.rs
index 699fb396259..8408d0f203b 100644
--- a/tests/ui/simd/intrinsic/generic-reduction-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-reduction-pass.rs
@@ -24,19 +24,38 @@ struct f32x4(pub [f32; 4]);
 #[derive(Copy, Clone)]
 struct b8x4(pub [i8; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_reduce_add_unordered<T, U>(x: T) -> U;
-    fn simd_reduce_mul_unordered<T, U>(x: T) -> U;
-    fn simd_reduce_add_ordered<T, U>(x: T, acc: U) -> U;
-    fn simd_reduce_mul_ordered<T, U>(x: T, acc: U) -> U;
-    fn simd_reduce_min<T, U>(x: T) -> U;
-    fn simd_reduce_max<T, U>(x: T) -> U;
-    fn simd_reduce_and<T, U>(x: T) -> U;
-    fn simd_reduce_or<T, U>(x: T) -> U;
-    fn simd_reduce_xor<T, U>(x: T) -> U;
-    fn simd_reduce_all<T>(x: T) -> bool;
-    fn simd_reduce_any<T>(x: T) -> bool;
-}
+#[rustc_intrinsic]
+unsafe fn simd_reduce_add_unordered<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_mul_unordered<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_add_ordered<T, U>(x: T, acc: U) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_mul_ordered<T, U>(x: T, acc: U) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_min<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_max<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_and<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_or<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_xor<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_all<T>(x: T) -> bool;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_any<T>(x: T) -> bool;
 
 fn main() {
     unsafe {
diff --git a/tests/ui/simd/intrinsic/generic-reduction.rs b/tests/ui/simd/intrinsic/generic-reduction.rs
index 1986deafb6a..ead13250643 100644
--- a/tests/ui/simd/intrinsic/generic-reduction.rs
+++ b/tests/ui/simd/intrinsic/generic-reduction.rs
@@ -15,16 +15,26 @@ pub struct f32x4(pub [f32; 4]);
 #[derive(Copy, Clone)]
 pub struct u32x4(pub [u32; 4]);
 
+#[rustc_intrinsic]
+unsafe fn simd_reduce_add_ordered<T, U>(x: T, y: U) -> U;
 
-extern "rust-intrinsic" {
-    fn simd_reduce_add_ordered<T, U>(x: T, y: U) -> U;
-    fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
-    fn simd_reduce_and<T, U>(x: T) -> U;
-    fn simd_reduce_or<T, U>(x: T) -> U;
-    fn simd_reduce_xor<T, U>(x: T) -> U;
-    fn simd_reduce_all<T>(x: T) -> bool;
-    fn simd_reduce_any<T>(x: T) -> bool;
-}
+#[rustc_intrinsic]
+unsafe fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_and<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_or<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_xor<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_all<T>(x: T) -> bool;
+
+#[rustc_intrinsic]
+unsafe fn simd_reduce_any<T>(x: T) -> bool;
 
 fn main() {
     let x = u32x4([0, 0, 0, 0]);
diff --git a/tests/ui/simd/intrinsic/generic-reduction.stderr b/tests/ui/simd/intrinsic/generic-reduction.stderr
index 1028faf69a7..302b9ae1d77 100644
--- a/tests/ui/simd/intrinsic/generic-reduction.stderr
+++ b/tests/ui/simd/intrinsic/generic-reduction.stderr
@@ -1,59 +1,59 @@
 error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
-  --> $DIR/generic-reduction.rs:34:9
+  --> $DIR/generic-reduction.rs:44:9
    |
 LL |         simd_reduce_add_ordered(z, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
-  --> $DIR/generic-reduction.rs:36:9
+  --> $DIR/generic-reduction.rs:46:9
    |
 LL |         simd_reduce_mul_ordered(z, 1);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/generic-reduction.rs:39:22
+  --> $DIR/generic-reduction.rs:49:22
    |
 LL |         let _: f32 = simd_reduce_and(x);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/generic-reduction.rs:41:22
+  --> $DIR/generic-reduction.rs:51:22
    |
 LL |         let _: f32 = simd_reduce_or(x);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/generic-reduction.rs:43:22
+  --> $DIR/generic-reduction.rs:53:22
    |
 LL |         let _: f32 = simd_reduce_xor(x);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: unsupported simd_reduce_and from `f32x4` with element `f32` to `f32`
-  --> $DIR/generic-reduction.rs:46:22
+  --> $DIR/generic-reduction.rs:56:22
    |
 LL |         let _: f32 = simd_reduce_and(z);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: unsupported simd_reduce_or from `f32x4` with element `f32` to `f32`
-  --> $DIR/generic-reduction.rs:48:22
+  --> $DIR/generic-reduction.rs:58:22
    |
 LL |         let _: f32 = simd_reduce_or(z);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32`
-  --> $DIR/generic-reduction.rs:50:22
+  --> $DIR/generic-reduction.rs:60:22
    |
 LL |         let _: f32 = simd_reduce_xor(z);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_all` intrinsic: unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
-  --> $DIR/generic-reduction.rs:53:23
+  --> $DIR/generic-reduction.rs:63:23
    |
 LL |         let _: bool = simd_reduce_all(z);
    |                       ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_any` intrinsic: unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
-  --> $DIR/generic-reduction.rs:55:23
+  --> $DIR/generic-reduction.rs:65:23
    |
 LL |         let _: bool = simd_reduce_any(z);
    |                       ^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-select-pass.rs b/tests/ui/simd/intrinsic/generic-select-pass.rs
index 5690bad5048..6b1b6cb79db 100644
--- a/tests/ui/simd/intrinsic/generic-select-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-select-pass.rs
@@ -29,10 +29,12 @@ struct f32x4(pub [f32; 4]);
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct b8x4(pub [i8; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_select<T, U>(x: T, a: U, b: U) -> U;
-    fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_select<T, U>(x: T, a: U, b: U) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
+
 
 fn main() {
     let m0 = b8x4([!0, !0, !0, !0]);
diff --git a/tests/ui/simd/intrinsic/generic-select.rs b/tests/ui/simd/intrinsic/generic-select.rs
index 52e02649590..340fe3f3592 100644
--- a/tests/ui/simd/intrinsic/generic-select.rs
+++ b/tests/ui/simd/intrinsic/generic-select.rs
@@ -22,10 +22,13 @@ struct b8x4(pub [i8; 4]);
 #[derive(Copy, Clone, PartialEq)]
 struct b8x8(pub [i8; 8]);
 
-extern "rust-intrinsic" {
-    fn simd_select<T, U>(x: T, a: U, b: U) -> U;
-    fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
-}
+
+#[rustc_intrinsic]
+unsafe fn simd_select<T, U>(x: T, a: U, b: U) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
+
 
 fn main() {
     let m4 = b8x4([0, 0, 0, 0]);
diff --git a/tests/ui/simd/intrinsic/generic-select.stderr b/tests/ui/simd/intrinsic/generic-select.stderr
index d576f1bc774..a97fc91f951 100644
--- a/tests/ui/simd/intrinsic/generic-select.stderr
+++ b/tests/ui/simd/intrinsic/generic-select.stderr
@@ -1,47 +1,47 @@
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
-  --> $DIR/generic-select.rs:39:9
+  --> $DIR/generic-select.rs:42:9
    |
 LL |         simd_select(m8, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `u32`, expected `i_`
-  --> $DIR/generic-select.rs:42:9
+  --> $DIR/generic-select.rs:45:9
    |
 LL |         simd_select(x, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `f32`, expected `i_`
-  --> $DIR/generic-select.rs:45:9
+  --> $DIR/generic-select.rs:48:9
    |
 LL |         simd_select(z, z, z);
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: expected SIMD argument type, found non-SIMD `u32`
-  --> $DIR/generic-select.rs:48:9
+  --> $DIR/generic-select.rs:51:9
    |
 LL |         simd_select(m4, 0u32, 1u32);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: invalid bitmask `u16`, expected `u8` or `[u8; 1]`
-  --> $DIR/generic-select.rs:51:9
+  --> $DIR/generic-select.rs:54:9
    |
 LL |         simd_select_bitmask(0u16, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: expected SIMD argument type, found non-SIMD `u32`
-  --> $DIR/generic-select.rs:54:9
+  --> $DIR/generic-select.rs:57:9
    |
 LL |         simd_select_bitmask(0u8, 1u32, 2u32);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: invalid bitmask `f32`, expected `u8` or `[u8; 1]`
-  --> $DIR/generic-select.rs:57:9
+  --> $DIR/generic-select.rs:60:9
    |
 LL |         simd_select_bitmask(0.0f32, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: invalid bitmask `&str`, expected `u8` or `[u8; 1]`
-  --> $DIR/generic-select.rs:60:9
+  --> $DIR/generic-select.rs:63:9
    |
 LL |         simd_select_bitmask("x", x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-shuffle.rs b/tests/ui/simd/intrinsic/generic-shuffle.rs
index 2752718d99d..1223b8ebe19 100644
--- a/tests/ui/simd/intrinsic/generic-shuffle.rs
+++ b/tests/ui/simd/intrinsic/generic-shuffle.rs
@@ -9,9 +9,9 @@
 #[derive(Copy, Clone)]
 pub struct Simd<T, const N: usize>([T; N]);
 
-extern "rust-intrinsic" {
-    fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
+
 
 fn main() {
     const I: Simd<u32, 2> = Simd([0; 2]);
diff --git a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
index d9239ef5801..b324ac40749 100644
--- a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
+++ b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
@@ -5,9 +5,8 @@
 //@ compile-flags: -Zmir-opt-level=4
 #![feature(intrinsics, repr_simd)]
 
-extern "rust-intrinsic" {
-    fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
 
 #[repr(simd)]
 #[derive(Debug, PartialEq)]
diff --git a/tests/ui/simd/intrinsic/inlining-issue67557.rs b/tests/ui/simd/intrinsic/inlining-issue67557.rs
index 23dd5075f96..319bb15c015 100644
--- a/tests/ui/simd/intrinsic/inlining-issue67557.rs
+++ b/tests/ui/simd/intrinsic/inlining-issue67557.rs
@@ -5,9 +5,8 @@
 //@ compile-flags: -Zmir-opt-level=4
 #![feature(intrinsics, repr_simd)]
 
-extern "rust-intrinsic" {
-    fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
 
 #[repr(simd)]
 #[derive(Debug, PartialEq)]
diff --git a/tests/ui/simd/intrinsic/issue-85855.rs b/tests/ui/simd/intrinsic/issue-85855.rs
index dc04699f7f8..daeea793d1b 100644
--- a/tests/ui/simd/intrinsic/issue-85855.rs
+++ b/tests/ui/simd/intrinsic/issue-85855.rs
@@ -5,15 +5,18 @@
 #![feature(intrinsics)]
 #![crate_type="lib"]
 
-extern "rust-intrinsic" {
-    fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
-    //~^ ERROR: intrinsic has wrong number of lifetime parameters
 
-    fn simd_add<'a, T>(x: T, y: T) -> T;
+#[rustc_intrinsic]
+unsafe fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
+//~^ ERROR: intrinsic has wrong number of lifetime parameters
 
-    fn simd_sub<T, U>(x: T, y: U);
-    //~^ ERROR: intrinsic has wrong number of type parameters
+#[rustc_intrinsic]
+unsafe fn simd_add<'a, T>(x: T, y: T) -> T;
 
-    fn simd_mul<T, const N: usize>(x: T, y: T);
-    //~^ ERROR: intrinsic has wrong number of const parameters
-}
+#[rustc_intrinsic]
+unsafe fn simd_sub<T, U>(x: T, y: U);
+//~^ ERROR: intrinsic has wrong number of type parameters
+
+#[rustc_intrinsic]
+unsafe fn simd_mul<T, const N: usize>(x: T, y: T);
+//~^ ERROR: intrinsic has wrong number of const parameters
diff --git a/tests/ui/simd/intrinsic/issue-85855.stderr b/tests/ui/simd/intrinsic/issue-85855.stderr
index fb2f1fbc5b1..b91a606ba68 100644
--- a/tests/ui/simd/intrinsic/issue-85855.stderr
+++ b/tests/ui/simd/intrinsic/issue-85855.stderr
@@ -1,20 +1,20 @@
 error[E0094]: intrinsic has wrong number of lifetime parameters: found 1, expected 0
-  --> $DIR/issue-85855.rs:9:27
+  --> $DIR/issue-85855.rs:10:30
    |
-LL |     fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
-   |                           ^^^^^^^^^^^ expected 0 lifetime parameters
+LL | unsafe fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
+   |                              ^^^^^^^^^^^ expected 0 lifetime parameters
 
 error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1
-  --> $DIR/issue-85855.rs:14:16
+  --> $DIR/issue-85855.rs:17:19
    |
-LL |     fn simd_sub<T, U>(x: T, y: U);
-   |                ^^^^^^ expected 1 type parameter
+LL | unsafe fn simd_sub<T, U>(x: T, y: U);
+   |                   ^^^^^^ expected 1 type parameter
 
 error[E0094]: intrinsic has wrong number of const parameters: found 1, expected 0
-  --> $DIR/issue-85855.rs:17:16
+  --> $DIR/issue-85855.rs:21:19
    |
-LL |     fn simd_mul<T, const N: usize>(x: T, y: T);
-   |                ^^^^^^^^^^^^^^^^^^^ expected 0 const parameters
+LL | unsafe fn simd_mul<T, const N: usize>(x: T, y: T);
+   |                   ^^^^^^^^^^^^^^^^^^^ expected 0 const parameters
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/simd/intrinsic/ptr-cast.rs b/tests/ui/simd/intrinsic/ptr-cast.rs
index 0490734b48a..559b8ba1b5c 100644
--- a/tests/ui/simd/intrinsic/ptr-cast.rs
+++ b/tests/ui/simd/intrinsic/ptr-cast.rs
@@ -2,11 +2,15 @@
 
 #![feature(repr_simd, intrinsics)]
 
-extern "rust-intrinsic" {
-    fn simd_cast_ptr<T, U>(x: T) -> U;
-    fn simd_expose_provenance<T, U>(x: T) -> U;
-    fn simd_with_exposed_provenance<T, U>(x: T) -> U;
-}
+
+#[rustc_intrinsic]
+unsafe fn simd_cast_ptr<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_expose_provenance<T, U>(x: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_with_exposed_provenance<T, U>(x: T) -> U;
 
 #[derive(Copy, Clone)]
 #[repr(simd)]
diff --git a/tests/ui/simd/issue-105439.rs b/tests/ui/simd/issue-105439.rs
index 3cb43fc8b1a..108bb282df2 100644
--- a/tests/ui/simd/issue-105439.rs
+++ b/tests/ui/simd/issue-105439.rs
@@ -9,9 +9,8 @@
 #[repr(simd)]
 struct i32x4([i32; 4]);
 
-extern "rust-intrinsic" {
-    pub(crate) fn simd_add<T>(x: T, y: T) -> T;
-}
+#[rustc_intrinsic]
+pub(crate) unsafe fn simd_add<T>(x: T, y: T) -> T;
 
 #[inline(always)]
 fn to_array(a: i32x4) -> [i32; 4] {
diff --git a/tests/ui/simd/issue-39720.rs b/tests/ui/simd/issue-39720.rs
index 2b51c0224c6..8d7666faaf9 100644
--- a/tests/ui/simd/issue-39720.rs
+++ b/tests/ui/simd/issue-39720.rs
@@ -11,9 +11,8 @@ pub struct Char3(pub [i8; 3]);
 #[derive(Copy, Clone, Debug)]
 pub struct Short3(pub [i16; 3]);
 
-extern "rust-intrinsic" {
-    fn simd_cast<T, U>(x: T) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_cast<T, U>(x: T) -> U;
 
 fn main() {
     let cast: Short3 = unsafe { simd_cast(Char3([10, -3, -9])) };
diff --git a/tests/ui/simd/issue-85915-simd-ptrs.rs b/tests/ui/simd/issue-85915-simd-ptrs.rs
index edf60e0205c..2e7baf48ee3 100644
--- a/tests/ui/simd/issue-85915-simd-ptrs.rs
+++ b/tests/ui/simd/issue-85915-simd-ptrs.rs
@@ -22,10 +22,12 @@ struct f32x4([f32; 4]);
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct i32x4([i32; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
-    fn simd_scatter<T, U, V>(x: T, y: U, z: V) -> ();
-}
+
+#[rustc_intrinsic]
+unsafe fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_scatter<T, U, V>(x: T, y: U, z: V) -> ();
 
 fn main() {
     let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.];
diff --git a/tests/ui/simd/issue-89193.rs b/tests/ui/simd/issue-89193.rs
index 9530124a7cc..4b4fb9d9169 100644
--- a/tests/ui/simd/issue-89193.rs
+++ b/tests/ui/simd/issue-89193.rs
@@ -10,9 +10,8 @@
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct x4<T>(pub [T; 4]);
 
-extern "rust-intrinsic" {
-    fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
 
 fn main() {
     let x: [usize; 4] = [10, 11, 12, 13];
diff --git a/tests/ui/simd/masked-load-store-build-fail.rs b/tests/ui/simd/masked-load-store-build-fail.rs
index fbd657763c9..b8742184eb0 100644
--- a/tests/ui/simd/masked-load-store-build-fail.rs
+++ b/tests/ui/simd/masked-load-store-build-fail.rs
@@ -1,10 +1,12 @@
 //@ build-fail
 #![feature(repr_simd, intrinsics)]
 
-extern "rust-intrinsic" {
-    fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
-    fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
-}
+
+#[rustc_intrinsic]
+unsafe fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
 
 #[derive(Copy, Clone)]
 #[repr(simd)]
diff --git a/tests/ui/simd/masked-load-store-build-fail.stderr b/tests/ui/simd/masked-load-store-build-fail.stderr
index 59af83fe0e8..8a8d8eb99e2 100644
--- a/tests/ui/simd/masked-load-store-build-fail.stderr
+++ b/tests/ui/simd/masked-load-store-build-fail.stderr
@@ -1,5 +1,5 @@
 error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected third argument with length 8 (same as input type `Simd<i8, 8>`), found `Simd<u8, 4>` with length 4
-  --> $DIR/masked-load-store-build-fail.rs:18:9
+  --> $DIR/masked-load-store-build-fail.rs:20:9
    |
 LL | /         simd_masked_load(
 LL | |             Simd::<i8, 8>([-1, 0, -1, -1, 0, 0, 0, 0]),
@@ -9,7 +9,7 @@ LL | |         );
    | |_________^
 
 error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u8` of second argument `*const i8` to be a pointer to the element type `u8` of the first argument `Simd<u8, 4>`, found `u8` != `*_ u8`
-  --> $DIR/masked-load-store-build-fail.rs:25:9
+  --> $DIR/masked-load-store-build-fail.rs:27:9
    |
 LL | /         simd_masked_load(
 LL | |             Simd::<i8, 4>([-1, 0, -1, -1]),
@@ -19,7 +19,7 @@ LL | |         );
    | |_________^
 
 error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd<u32, 4>`, found `u32` != `*_ u32`
-  --> $DIR/masked-load-store-build-fail.rs:32:9
+  --> $DIR/masked-load-store-build-fail.rs:34:9
    |
 LL | /         simd_masked_load(
 LL | |             Simd::<i8, 4>([-1, 0, -1, -1]),
@@ -29,7 +29,7 @@ LL | |         );
    | |_________^
 
 error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u8` of third argument `Simd<u8, 4>` to be a signed integer type
-  --> $DIR/masked-load-store-build-fail.rs:39:9
+  --> $DIR/masked-load-store-build-fail.rs:41:9
    |
 LL | /         simd_masked_load(
 LL | |             Simd::<u8, 4>([1, 0, 1, 1]),
@@ -39,7 +39,7 @@ LL | |         );
    | |_________^
 
 error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd<u32, 4>`, found `u32` != `*mut u32`
-  --> $DIR/masked-load-store-build-fail.rs:46:9
+  --> $DIR/masked-load-store-build-fail.rs:48:9
    |
 LL | /         simd_masked_store(
 LL | |             Simd([-1i8; 4]),
@@ -49,7 +49,7 @@ LL | |         );
    | |_________^
 
 error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd<u8, 4>`, found `u8` != `*mut u8`
-  --> $DIR/masked-load-store-build-fail.rs:53:9
+  --> $DIR/masked-load-store-build-fail.rs:55:9
    |
 LL | /         simd_masked_store(
 LL | |             Simd([-1i8; 4]),
@@ -59,7 +59,7 @@ LL | |         );
    | |_________^
 
 error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected third argument with length 4 (same as input type `Simd<i8, 4>`), found `Simd<u8, 2>` with length 2
-  --> $DIR/masked-load-store-build-fail.rs:60:9
+  --> $DIR/masked-load-store-build-fail.rs:62:9
    |
 LL | /         simd_masked_store(
 LL | |             Simd([-1i8; 4]),
@@ -69,7 +69,7 @@ LL | |         );
    | |_________^
 
 error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u8` of third argument `Simd<u32, 4>` to be a signed integer type
-  --> $DIR/masked-load-store-build-fail.rs:67:9
+  --> $DIR/masked-load-store-build-fail.rs:69:9
    |
 LL | /         simd_masked_store(
 LL | |             Simd([1u32; 4]),
diff --git a/tests/ui/simd/masked-load-store-check-fail.rs b/tests/ui/simd/masked-load-store-check-fail.rs
index 39c82c41385..0f36bf6443f 100644
--- a/tests/ui/simd/masked-load-store-check-fail.rs
+++ b/tests/ui/simd/masked-load-store-check-fail.rs
@@ -1,10 +1,11 @@
 //@ check-fail
 #![feature(repr_simd, intrinsics)]
 
-extern "rust-intrinsic" {
-    fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
-    fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
-}
+#[rustc_intrinsic]
+unsafe fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
 
 #[derive(Copy, Clone)]
 #[repr(simd)]
diff --git a/tests/ui/simd/masked-load-store-check-fail.stderr b/tests/ui/simd/masked-load-store-check-fail.stderr
index 5d205d607c9..fa65798fc94 100644
--- a/tests/ui/simd/masked-load-store-check-fail.stderr
+++ b/tests/ui/simd/masked-load-store-check-fail.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/masked-load-store-check-fail.rs:21:13
+  --> $DIR/masked-load-store-check-fail.rs:22:13
    |
 LL |         let _x: Simd<u8, 2> = simd_masked_load(
    |                               ---------------- arguments to this function are incorrect
@@ -10,7 +10,7 @@ LL |             Simd::<u8, 4>([9; 4])
    = note: expected struct `Simd<_, 2>`
               found struct `Simd<_, 4>`
 help: the return type of this call is `Simd<u8, 4>` due to the type of the argument passed
-  --> $DIR/masked-load-store-check-fail.rs:18:31
+  --> $DIR/masked-load-store-check-fail.rs:19:31
    |
 LL |           let _x: Simd<u8, 2> = simd_masked_load(
    |  _______________________________^
@@ -21,13 +21,13 @@ LL | |             Simd::<u8, 4>([9; 4])
 LL | |         );
    | |_________^
 note: function defined here
-  --> $DIR/masked-load-store-check-fail.rs:5:8
+  --> $DIR/masked-load-store-check-fail.rs:5:11
    |
-LL |     fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
-   |        ^^^^^^^^^^^^^^^^
+LL | unsafe fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
+   |           ^^^^^^^^^^^^^^^^                               ---------
 
 error[E0308]: mismatched types
-  --> $DIR/masked-load-store-check-fail.rs:28:13
+  --> $DIR/masked-load-store-check-fail.rs:29:13
    |
 LL |         let _x: Simd<u32, 4> = simd_masked_load(
    |                                ---------------- arguments to this function are incorrect
@@ -38,7 +38,7 @@ LL |             default
    = note: expected struct `Simd<u32, _>`
               found struct `Simd<u8, _>`
 help: the return type of this call is `Simd<u8, 4>` due to the type of the argument passed
-  --> $DIR/masked-load-store-check-fail.rs:25:32
+  --> $DIR/masked-load-store-check-fail.rs:26:32
    |
 LL |           let _x: Simd<u32, 4> = simd_masked_load(
    |  ________________________________^
@@ -49,10 +49,10 @@ LL | |             default
 LL | |         );
    | |_________^
 note: function defined here
-  --> $DIR/masked-load-store-check-fail.rs:5:8
+  --> $DIR/masked-load-store-check-fail.rs:5:11
    |
-LL |     fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
-   |        ^^^^^^^^^^^^^^^^
+LL | unsafe fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
+   |           ^^^^^^^^^^^^^^^^                               ---------
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/simd/masked-load-store.rs b/tests/ui/simd/masked-load-store.rs
index 902143f9261..4b4195f51f1 100644
--- a/tests/ui/simd/masked-load-store.rs
+++ b/tests/ui/simd/masked-load-store.rs
@@ -1,10 +1,11 @@
 //@ run-pass
 #![feature(repr_simd, intrinsics)]
 
-extern "rust-intrinsic" {
-    fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
-    fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
-}
+#[rustc_intrinsic]
+unsafe fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
+
+#[rustc_intrinsic]
+unsafe fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
 
 #[derive(Copy, Clone)]
 #[repr(simd)]
diff --git a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr
index 2d1fa1f8da2..b0a8da59fac 100644
--- a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr
+++ b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr
@@ -1,5 +1,5 @@
 error: overly complex generic constant
-  --> $DIR/monomorphize-shuffle-index.rs:29:45
+  --> $DIR/monomorphize-shuffle-index.rs:32:45
    |
 LL |         return simd_shuffle_generic::<_, _, { &Self::I.0 }>(a, b);
    |                                             ^^----------^^
diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs
index 140cf6fbe96..01926408a2c 100644
--- a/tests/ui/simd/monomorphize-shuffle-index.rs
+++ b/tests/ui/simd/monomorphize-shuffle-index.rs
@@ -4,12 +4,15 @@
 #![feature(repr_simd, intrinsics, adt_const_params, unsized_const_params, generic_const_exprs)]
 #![allow(incomplete_features)]
 
-extern "rust-intrinsic" {
-    #[cfg(old)]
-    fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
-    #[cfg(any(generic, generic_with_fn))]
-    fn simd_shuffle_generic<T, U, const I: &'static [u32]>(a: T, b: T) -> U;
-}
+
+#[rustc_intrinsic]
+#[cfg(old)]
+unsafe fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
+
+#[rustc_intrinsic]
+#[cfg(any(generic, generic_with_fn))]
+unsafe fn simd_shuffle_generic<T, U, const I: &'static [u32]>(a: T, b: T) -> U;
+
 
 #[derive(Copy, Clone)]
 #[repr(simd)]
diff --git a/tests/ui/simd/repr_packed.rs b/tests/ui/simd/repr_packed.rs
index 1ba15bda98d..a666892226e 100644
--- a/tests/ui/simd/repr_packed.rs
+++ b/tests/ui/simd/repr_packed.rs
@@ -22,9 +22,8 @@ fn check_ty<T>() {
     check_size_align::<T, 15>();
 }
 
-extern "rust-intrinsic" {
-    fn simd_add<T>(a: T, b: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_add<T>(a: T, b: T) -> T;
 
 fn main() {
     check_ty::<u8>();
diff --git a/tests/ui/simd/shuffle.rs b/tests/ui/simd/shuffle.rs
index 96c0ed2118f..2cae5a1e7de 100644
--- a/tests/ui/simd/shuffle.rs
+++ b/tests/ui/simd/shuffle.rs
@@ -8,9 +8,8 @@
 
 use std::marker::ConstParamTy;
 
-extern "rust-intrinsic" {
-    fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
 
 #[derive(Copy, Clone, ConstParamTy, PartialEq, Eq)]
 #[repr(simd)]
diff --git a/tests/ui/simd/simd-bitmask-notpow2.rs b/tests/ui/simd/simd-bitmask-notpow2.rs
index 3499bf33ed5..d7572ef4a2a 100644
--- a/tests/ui/simd/simd-bitmask-notpow2.rs
+++ b/tests/ui/simd/simd-bitmask-notpow2.rs
@@ -4,10 +4,12 @@
 //@ ignore-endian-big
 #![feature(repr_simd, intrinsics)]
 
-extern "rust-intrinsic" {
-    fn simd_bitmask<T, U>(v: T) -> U;
-    fn simd_select_bitmask<T, U>(m: T, a: U, b: U) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_bitmask<T, U>(v: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_select_bitmask<T, U>(m: T, a: U, b: U) -> U;
+
 
 fn main() {
     // Non-power-of-2 multi-byte mask.
diff --git a/tests/ui/simd/simd-bitmask.rs b/tests/ui/simd/simd-bitmask.rs
index 82f73fca951..4275ab0f40c 100644
--- a/tests/ui/simd/simd-bitmask.rs
+++ b/tests/ui/simd/simd-bitmask.rs
@@ -1,10 +1,12 @@
 //@run-pass
 #![feature(repr_simd, intrinsics)]
 
-extern "rust-intrinsic" {
-    fn simd_bitmask<T, U>(v: T) -> U;
-    fn simd_select_bitmask<T, U>(m: T, a: U, b: U) -> U;
-}
+#[rustc_intrinsic]
+unsafe fn simd_bitmask<T, U>(v: T) -> U;
+
+#[rustc_intrinsic]
+unsafe fn simd_select_bitmask<T, U>(m: T, a: U, b: U) -> U;
+
 
 #[derive(Copy, Clone)]
 #[repr(simd)]
diff --git a/tests/ui/stability-attribute/allowed-through-unstable.rs b/tests/ui/stability-attribute/allowed-through-unstable.rs
index e03417a4dae..5baa0fda940 100644
--- a/tests/ui/stability-attribute/allowed-through-unstable.rs
+++ b/tests/ui/stability-attribute/allowed-through-unstable.rs
@@ -5,6 +5,5 @@
 
 extern crate allowed_through_unstable_core;
 
-use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstable;
-use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstableWithDeprecation; //~WARN use of deprecated module `allowed_through_unstable_core::unstable_module`: use the new path instead
+use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstable; //~WARN use of deprecated module `allowed_through_unstable_core::unstable_module`: use the new path instead
 use allowed_through_unstable_core::unstable_module::NewStableTraitNotAllowedThroughUnstable; //~ ERROR use of unstable library feature `unstable_test_feature`
diff --git a/tests/ui/stability-attribute/allowed-through-unstable.stderr b/tests/ui/stability-attribute/allowed-through-unstable.stderr
index 8d07b0cf9e8..bda68045002 100644
--- a/tests/ui/stability-attribute/allowed-through-unstable.stderr
+++ b/tests/ui/stability-attribute/allowed-through-unstable.stderr
@@ -1,13 +1,13 @@
 warning: use of deprecated module `allowed_through_unstable_core::unstable_module`: use the new path instead
-  --> $DIR/allowed-through-unstable.rs:9:53
+  --> $DIR/allowed-through-unstable.rs:8:53
    |
-LL | use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstableWithDeprecation;
-   |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstable;
+   |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(deprecated)]` on by default
 
 error[E0658]: use of unstable library feature `unstable_test_feature`
-  --> $DIR/allowed-through-unstable.rs:10:5
+  --> $DIR/allowed-through-unstable.rs:9:5
    |
 LL | use allowed_through_unstable_core::unstable_module::NewStableTraitNotAllowedThroughUnstable;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs b/tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs
index 9dfbb451d04..23c722d6e8e 100644
--- a/tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs
+++ b/tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs
@@ -6,12 +6,8 @@
 #[unstable(feature = "unstable_test_feature", issue = "1")]
 pub mod unstable_module {
     #[stable(feature = "stable_test_feature", since = "1.2.0")]
-    #[rustc_allowed_through_unstable_modules]
-    pub trait OldStableTraitAllowedThoughUnstable {}
-
-    #[stable(feature = "stable_test_feature", since = "1.2.0")]
     #[rustc_allowed_through_unstable_modules = "use the new path instead"]
-    pub trait OldStableTraitAllowedThoughUnstableWithDeprecation {}
+    pub trait OldStableTraitAllowedThoughUnstable {}
 
     #[stable(feature = "stable_test_feature", since = "1.2.0")]
     pub trait NewStableTraitNotAllowedThroughUnstable {}
diff --git a/tests/ui/static/issue-24446.rs b/tests/ui/static/issue-24446.rs
index 6cf8846506d..830e373c189 100644
--- a/tests/ui/static/issue-24446.rs
+++ b/tests/ui/static/issue-24446.rs
@@ -2,7 +2,6 @@ fn main() {
     static foo: dyn Fn() -> u32 = || -> u32 {
         //~^ ERROR the size for values of type
         //~| ERROR cannot be shared between threads safely
-        //~| ERROR the size for values of type
         //~| ERROR mismatched types
         0
     };
diff --git a/tests/ui/static/issue-24446.stderr b/tests/ui/static/issue-24446.stderr
index 8cb034000be..033caf07d8e 100644
--- a/tests/ui/static/issue-24446.stderr
+++ b/tests/ui/static/issue-24446.stderr
@@ -15,33 +15,19 @@ LL |     static foo: dyn Fn() -> u32 = || -> u32 {
    |
    = help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`
 
-error[E0277]: the size for values of type `(dyn Fn() -> u32 + 'static)` cannot be known at compilation time
-  --> $DIR/issue-24446.rs:2:35
-   |
-LL |       static foo: dyn Fn() -> u32 = || -> u32 {
-   |  ___________________________________^
-...  |
-LL | |         0
-LL | |     };
-   | |_____^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`
-   = note: constant expressions must have a statically known size
-
 error[E0308]: mismatched types
   --> $DIR/issue-24446.rs:2:35
    |
 LL |       static foo: dyn Fn() -> u32 = || -> u32 {
    |  ___________________________________^
 ...  |
-LL | |         0
 LL | |     };
    | |_____^ expected `dyn Fn`, found closure
    |
    = note: expected trait object `(dyn Fn() -> u32 + 'static)`
                    found closure `{closure@$DIR/issue-24446.rs:2:35: 2:44}`
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/statics/unsized_type2.stderr b/tests/ui/statics/unsized_type2.stderr
index b18a99fab72..ffbbe218c87 100644
--- a/tests/ui/statics/unsized_type2.stderr
+++ b/tests/ui/statics/unsized_type2.stderr
@@ -11,6 +11,12 @@ note: required because it appears within the type `Foo`
 LL | pub struct Foo {
    |            ^^^
 
+error[E0308]: mismatched types
+  --> $DIR/unsized_type2.rs:14:45
+   |
+LL | pub static WITH_ERROR: Foo = Foo { version: 0 };
+   |                                             ^ expected `str`, found integer
+
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/unsized_type2.rs:14:30
    |
@@ -23,13 +29,7 @@ note: required because it appears within the type `Foo`
    |
 LL | pub struct Foo {
    |            ^^^
-   = note: constant expressions must have a statically known size
-
-error[E0308]: mismatched types
-  --> $DIR/unsized_type2.rs:14:45
-   |
-LL | pub static WITH_ERROR: Foo = Foo { version: 0 };
-   |                                             ^ expected `str`, found integer
+   = note: structs must have a statically known size to be initialized
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/suggestions/box-future-wrong-output.stderr b/tests/ui/suggestions/box-future-wrong-output.stderr
index 6a232c3444d..bac26ae8fb5 100644
--- a/tests/ui/suggestions/box-future-wrong-output.stderr
+++ b/tests/ui/suggestions/box-future-wrong-output.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/box-future-wrong-output.rs:20:39
    |
 LL |     let _: BoxFuture<'static, bool> = async {}.boxed();
-   |            ------------------------   ^^^^^^^^^^^^^^^^ expected `bool`, found `()`
+   |            ------------------------   ^^^^^^^^^^^^^^^^ expected `Pin<Box<...>>`, found `Pin<Box<dyn Future<Output = ()> + Send>>`
    |            |
    |            expected due to this
    |
diff --git a/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.rs b/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.rs
index 47a590668dd..e03c43d15ee 100644
--- a/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.rs
+++ b/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.rs
@@ -7,6 +7,6 @@ fn bar<X>(x: Box<dyn FnOnce() -> X>) {}
 
 fn main() {
     foo(async move || {});
-    //~^ ERROR expected `{async closure@dont-suggest-boxing-async-closure-body.rs:9:9}` to be a closure that returns `Box<_>`
+    //~^ ERROR expected `{async closure@dont-suggest-boxing-async-closure-body.rs:9:9}` to return `Box<_>`
     bar(async move || {}); //~ ERROR mismatched types
 }
diff --git a/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.stderr b/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.stderr
index db2a3b9a9c1..abf8e2d824b 100644
--- a/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.stderr
+++ b/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.stderr
@@ -1,4 +1,4 @@
-error[E0271]: expected `{async closure@dont-suggest-boxing-async-closure-body.rs:9:9}` to be a closure that returns `Box<_>`, but it returns `{async closure body@$DIR/dont-suggest-boxing-async-closure-body.rs:9:23: 9:25}`
+error[E0271]: expected `{async closure@dont-suggest-boxing-async-closure-body.rs:9:9}` to return `Box<_>`, but it returns `{async closure body@$DIR/dont-suggest-boxing-async-closure-body.rs:9:23: 9:25}`
   --> $DIR/dont-suggest-boxing-async-closure-body.rs:9:9
    |
 LL |     foo(async move || {});
diff --git a/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr b/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr
index ae009d26029..4576017abaf 100644
--- a/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr
+++ b/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr
@@ -34,6 +34,18 @@ LL | trait Other: Sized {}
    |       this trait is not dyn compatible...
 
 error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/dyn-incompatible-trait-references-self.rs:4:22
+   |
+LL |     fn bat(&self) -> Self {}
+   |                      ^^^^ doesn't have a size known at compile-time
+   |
+   = note: the return type of a function must have a statically known size
+help: consider further restricting `Self`
+   |
+LL |     fn bat(&self) -> Self where Self: Sized {}
+   |                           +++++++++++++++++
+
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
   --> $DIR/dyn-incompatible-trait-references-self.rs:2:22
    |
 LL |     fn baz(&self, _: Self) {}
@@ -61,18 +73,6 @@ LL |     fn bat(&self) -> Self {}
    = note: expected type parameter `Self`
                    found unit type `()`
 
-error[E0277]: the size for values of type `Self` cannot be known at compilation time
-  --> $DIR/dyn-incompatible-trait-references-self.rs:4:22
-   |
-LL |     fn bat(&self) -> Self {}
-   |                      ^^^^ doesn't have a size known at compile-time
-   |
-   = note: the return type of a function must have a statically known size
-help: consider further restricting `Self`
-   |
-LL |     fn bat(&self) -> Self where Self: Sized {}
-   |                           +++++++++++++++++
-
 error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0038, E0277, E0308.
diff --git a/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
index 42bc094859a..61a1d30d31d 100644
--- a/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
+++ b/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -32,7 +32,7 @@ error[E0308]: mismatched types
 LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
    |        - found this type parameter
 LL |     Pin::new(x)
-   |     -------- ^ expected `Box<dyn Future<Output = ...> + Send>`, found type parameter `F`
+   |     -------- ^ expected `Box<dyn Future<Output = i32> + Send>`, found type parameter `F`
    |     |
    |     arguments to this function are incorrect
    |     help: use `Box::pin` to pin and box this expression: `Box::pin`
diff --git a/tests/ui/suggestions/issue-107860.stderr b/tests/ui/suggestions/issue-107860.stderr
index 4be495da46b..2bfd2193981 100644
--- a/tests/ui/suggestions/issue-107860.stderr
+++ b/tests/ui/suggestions/issue-107860.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-107860.rs:3:36
    |
 LL | async fn str<T>(T: &str) -> &str { &str }
-   |                                    ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<...>}`
+   |                                    ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<_>}`
    |
    = note: expected reference `&str`
               found reference `&for<'a> fn(&'a str) -> impl Future<Output = &'a str> {str::<_>}`
diff --git a/tests/ui/suggestions/missing-lifetime-specifier.rs b/tests/ui/suggestions/missing-lifetime-specifier.rs
index dd437fc0c0b..a957477897d 100644
--- a/tests/ui/suggestions/missing-lifetime-specifier.rs
+++ b/tests/ui/suggestions/missing-lifetime-specifier.rs
@@ -1,6 +1,5 @@
 // The specific errors produced depend the thread-local implementation.
 // Run only on platforms with "fast" TLS.
-//@ ignore-windows FIXME(#84933)
 //@ ignore-wasm globals are used instead of thread locals
 //@ ignore-emscripten globals are used instead of thread locals
 //@ ignore-android does not use #[thread_local]
diff --git a/tests/ui/suggestions/missing-lifetime-specifier.stderr b/tests/ui/suggestions/missing-lifetime-specifier.stderr
index e0b6bb872b5..1fdbf3b0c79 100644
--- a/tests/ui/suggestions/missing-lifetime-specifier.stderr
+++ b/tests/ui/suggestions/missing-lifetime-specifier.stderr
@@ -1,5 +1,5 @@
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:28:44
+  --> $DIR/missing-lifetime-specifier.rs:27:44
    |
 LL |     static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
    |                                            ^^^ expected 2 lifetime parameters
@@ -11,7 +11,7 @@ LL |     static a: RefCell<HashMap<i32, Vec<Vec<Foo<'static, 'static>>>>> = RefC
    |                                               ++++++++++++++++++
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:32:44
+  --> $DIR/missing-lifetime-specifier.rs:31:44
    |
 LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
    |                                            ^^^^ expected 2 lifetime parameters
@@ -25,7 +25,7 @@ LL |     static b: RefCell<HashMap<i32, Vec<Vec<&'static Bar<'static, 'static>>>
    |                                             +++++++    ++++++++++++++++++
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:36:47
+  --> $DIR/missing-lifetime-specifier.rs:35:47
    |
 LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
    |                                               ^ expected 2 lifetime parameters
@@ -37,7 +37,7 @@ LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> =
    |                                                +++++++++++++++++
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:40:44
+  --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^   ^ expected 2 lifetime parameters
@@ -51,7 +51,7 @@ LL |     static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, 'static, i
    |                                             +++++++     +++++++++++++++++
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-specifier.rs:49:44
+  --> $DIR/missing-lifetime-specifier.rs:48:44
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^ expected named lifetime parameter
@@ -63,7 +63,7 @@ LL |     static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> =
    |                                             +++++++
 
 error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
-  --> $DIR/missing-lifetime-specifier.rs:45:44
+  --> $DIR/missing-lifetime-specifier.rs:44:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^^^ ------- supplied 1 lifetime argument
@@ -71,7 +71,7 @@ LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell:
    |                                            expected 2 lifetime arguments
    |
 note: union defined here, with 2 lifetime parameters: `'t`, `'k`
-  --> $DIR/missing-lifetime-specifier.rs:21:11
+  --> $DIR/missing-lifetime-specifier.rs:20:11
    |
 LL | pub union Qux<'t, 'k, I> {
    |           ^^^ --  --
@@ -81,7 +81,7 @@ LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> =
    |                                                       +++++++++
 
 error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
-  --> $DIR/missing-lifetime-specifier.rs:49:45
+  --> $DIR/missing-lifetime-specifier.rs:48:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                             ^^^ ------- supplied 1 lifetime argument
@@ -89,7 +89,7 @@ LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell
    |                                             expected 2 lifetime arguments
    |
 note: trait defined here, with 2 lifetime parameters: `'t`, `'k`
-  --> $DIR/missing-lifetime-specifier.rs:25:7
+  --> $DIR/missing-lifetime-specifier.rs:24:7
    |
 LL | trait Tar<'t, 'k, I> {}
    |       ^^^ --  --
diff --git a/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr b/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
index 980c2455c8e..df59a28c4b9 100644
--- a/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
+++ b/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
@@ -94,7 +94,7 @@ note: method defined here
   --> $DIR/trait-with-missing-associated-type-restriction.rs:9:8
    |
 LL |     fn funk(&self, _: Self::A);
-   |        ^^^^
+   |        ^^^^        -
 help: consider constraining the associated type `<T as Trait<i32>>::A` to `{integer}`
    |
 LL | fn bar2<T: Trait<i32, A = {integer}>>(x: T) {
diff --git a/tests/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr b/tests/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr
index 8b48ee9f124..c0162ec2cab 100644
--- a/tests/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr
+++ b/tests/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr
@@ -22,7 +22,7 @@ LL |     let _: f64 = 1..;
    |            expected due to this
    |
    = note: expected type `f64`
-            found struct `RangeFrom<{integer}>`
+            found struct `std::ops::RangeFrom<{integer}>`
 help: remove the unnecessary `.` operator for a floating point literal
    |
 LL |     let _: f64 = 1.;
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs
index dab01179c0b..215e64979f7 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs
@@ -1,3 +1,4 @@
+//! Ensure ABI-incompatible features cannot be enabled via `#[target_feature]`.
 //@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib
 //@ needs-llvm-components: riscv
 #![feature(no_core, lang_items, riscv_target_feature)]
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr
index 9df56d86729..bfe767e5ffb 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr
@@ -1,5 +1,5 @@
 error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI
-  --> $DIR/forbidden-hardfloat-target-feature-attribute.rs:9:18
+  --> $DIR/forbidden-hardfloat-target-feature-attribute.rs:10:18
    |
 LL | #[target_feature(enable = "d")]
    |                  ^^^^^^^^^^^^
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs
deleted file mode 100644
index 8755791c1c0..00000000000
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
-//@ needs-llvm-components: x86
-//@ check-pass
-#![feature(no_core, lang_items)]
-#![no_core]
-#![allow(unexpected_cfgs)]
-
-#[lang = "sized"]
-pub trait Sized {}
-
-// The compile_error macro does not exist, so if the `cfg` evaluates to `true` this
-// complains about the missing macro rather than showing the error... but that's good enough.
-#[cfg(not(target_feature = "x87"))]
-compile_error!("the x87 feature *should* be exposed in `cfg`");
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs
index 3d09217327a..81f138b175f 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs
@@ -1,8 +1,11 @@
+//! Ensure that if disabling a target feature implies disabling an ABI-required target feature,
+//! we complain.
 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
 //@ needs-llvm-components: x86
 //@ compile-flags: -Ctarget-feature=-sse
 // For now this is just a warning.
 //@ build-pass
+//@error-pattern: must be enabled to ensure that the ABI
 #![feature(no_core, lang_items)]
 #![no_core]
 
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs
index 95c366bb3f5..7242bcc85bf 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs
@@ -3,6 +3,7 @@
 //@ compile-flags: -Ctarget-feature=-neon
 // For now this is just a warning.
 //@ build-pass
+//@error-pattern: must be enabled to ensure that the ABI
 #![feature(no_core, lang_items)]
 #![no_core]
 
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs
index fd8023664da..7eebcf05dc0 100644
--- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs
@@ -1,8 +1,10 @@
+//! Ensure ABI-required features cannot be disabled via `-Ctarget-feature`.
 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
 //@ needs-llvm-components: x86
 //@ compile-flags: -Ctarget-feature=-x87
 // For now this is just a warning.
 //@ build-pass
+//@error-pattern: must be enabled to ensure that the ABI
 #![feature(no_core, lang_items)]
 #![no_core]
 
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs
new file mode 100644
index 00000000000..f277a309cd6
--- /dev/null
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs
@@ -0,0 +1,12 @@
+//! Ensure ABI-incompatible features cannot be enabled via `-Ctarget-feature`.
+//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
+//@ needs-llvm-components: x86
+//@ compile-flags: -Ctarget-feature=+soft-float
+// For now this is just a warning.
+//@ build-pass
+//@error-pattern: must be disabled to ensure that the ABI
+#![feature(no_core, lang_items, riscv_target_feature)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.stderr
new file mode 100644
index 00000000000..e49672f33b9
--- /dev/null
+++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.stderr
@@ -0,0 +1,11 @@
+warning: target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctly
+   |
+   = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
+
+warning: unstable feature specified for `-Ctarget-feature`: `soft-float`
+   |
+   = note: this feature is not stably supported; its behavior can change in the future
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-target-feature-attribute.rs
index 2ba5f2215c7..6bb6f8aaffb 100644
--- a/tests/ui/target-feature/forbidden-target-feature-attribute.rs
+++ b/tests/ui/target-feature/forbidden-target-feature-attribute.rs
@@ -1,11 +1,12 @@
-//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
-//@ needs-llvm-components: x86
+//! Ensure "forbidden" target features cannot be enabled via `#[target_feature]`.
+//@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib
+//@ needs-llvm-components: riscv
 #![feature(no_core, lang_items)]
 #![no_core]
 
 #[lang = "sized"]
 pub trait Sized {}
 
-#[target_feature(enable = "soft-float")]
+#[target_feature(enable = "forced-atomics")]
 //~^ERROR: cannot be enabled with
 pub unsafe fn my_fun() {}
diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr
index f3d54cc19d3..f8ea0c0e793 100644
--- a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr
+++ b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr
@@ -1,8 +1,8 @@
-error: target feature `soft-float` cannot be enabled with `#[target_feature]`: unsound because it changes float ABI
-  --> $DIR/forbidden-target-feature-attribute.rs:9:18
+error: target feature `forced-atomics` cannot be enabled with `#[target_feature]`: unsound because it changes the ABI of atomic operations
+  --> $DIR/forbidden-target-feature-attribute.rs:10:18
    |
-LL | #[target_feature(enable = "soft-float")]
-   |                  ^^^^^^^^^^^^^^^^^^^^^
+LL | #[target_feature(enable = "forced-atomics")]
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/target-feature/forbidden-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-target-feature-cfg.rs
index 1f001e9f8ff..e848ffde018 100644
--- a/tests/ui/target-feature/forbidden-target-feature-cfg.rs
+++ b/tests/ui/target-feature/forbidden-target-feature-cfg.rs
@@ -1,5 +1,6 @@
-//@ compile-flags: --target=x86_64-unknown-none --crate-type=lib
-//@ needs-llvm-components: x86
+//! Ensure "forbidden" target features are not exposed via `cfg`.
+//@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib
+//@ needs-llvm-components: riscv
 //@ check-pass
 #![feature(no_core, lang_items)]
 #![no_core]
@@ -10,5 +11,5 @@ pub trait Sized {}
 
 // The compile_error macro does not exist, so if the `cfg` evaluates to `true` this
 // complains about the missing macro rather than showing the error... but that's good enough.
-#[cfg(target_feature = "soft-float")]
-compile_error!("the soft-float feature should not be exposed in `cfg`");
+#[cfg(target_feature = "forced-atomics")]
+compile_error!("the forced-atomics feature should not be exposed in `cfg`");
diff --git a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs
index b09c53bd46a..cf85c521228 100644
--- a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs
+++ b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs
@@ -1,8 +1,10 @@
-//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
-//@ needs-llvm-components: x86
-//@ compile-flags: -Ctarget-feature=-soft-float
+//! Ensure "forbidden" target features cannot be disabled via `-Ctarget-feature`.
+//@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib
+//@ needs-llvm-components: riscv
+//@ compile-flags: -Ctarget-feature=-forced-atomics
 // For now this is just a warning.
 //@ build-pass
+//@error-pattern: unsound because it changes the ABI
 #![feature(no_core, lang_items)]
 #![no_core]
 
diff --git a/tests/ui/target-feature/forbidden-target-feature-flag-disable.stderr b/tests/ui/target-feature/forbidden-target-feature-flag-disable.stderr
index 797cd4be5c2..171ed0de6aa 100644
--- a/tests/ui/target-feature/forbidden-target-feature-flag-disable.stderr
+++ b/tests/ui/target-feature/forbidden-target-feature-flag-disable.stderr
@@ -1,4 +1,4 @@
-warning: target feature `soft-float` cannot be disabled with `-Ctarget-feature`: unsound because it changes float ABI
+warning: target feature `forced-atomics` cannot be disabled with `-Ctarget-feature`: unsound because it changes the ABI of atomic operations
    |
    = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
diff --git a/tests/ui/target-feature/forbidden-target-feature-flag.rs b/tests/ui/target-feature/forbidden-target-feature-flag.rs
index 0f688fde7f4..245841eb039 100644
--- a/tests/ui/target-feature/forbidden-target-feature-flag.rs
+++ b/tests/ui/target-feature/forbidden-target-feature-flag.rs
@@ -1,8 +1,10 @@
-//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
-//@ needs-llvm-components: x86
-//@ compile-flags: -Ctarget-feature=+soft-float
+//! Ensure "forbidden" target features cannot be enabled via `-Ctarget-feature`.
+//@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib
+//@ needs-llvm-components: riscv
+//@ compile-flags: -Ctarget-feature=+forced-atomics
 // For now this is just a warning.
 //@ build-pass
+//@error-pattern: unsound because it changes the ABI
 #![feature(no_core, lang_items)]
 #![no_core]
 
diff --git a/tests/ui/target-feature/forbidden-target-feature-flag.stderr b/tests/ui/target-feature/forbidden-target-feature-flag.stderr
index 075666fbf66..f8490f066d1 100644
--- a/tests/ui/target-feature/forbidden-target-feature-flag.stderr
+++ b/tests/ui/target-feature/forbidden-target-feature-flag.stderr
@@ -1,4 +1,4 @@
-warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: unsound because it changes float ABI
+warning: target feature `forced-atomics` cannot be enabled with `-Ctarget-feature`: unsound because it changes the ABI of atomic operations
    |
    = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
diff --git a/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs b/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs
new file mode 100644
index 00000000000..355e7c56e94
--- /dev/null
+++ b/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs
@@ -0,0 +1,20 @@
+//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
+// Auxiliary build problems with aarch64-apple:
+// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
+// Auxiliary build problems with i686-mingw: linker `cc` not found
+//@ only-x86
+//@ ignore-windows
+//@ ignore-apple
+//@ needs-llvm-components: x86
+#![crate_type = "rlib"]
+#![no_core]
+#![feature(no_core, lang_items, repr_simd)]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+pub fn somefun() {}
+
+pub struct S;
diff --git a/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs b/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs
new file mode 100644
index 00000000000..2e16f1ee747
--- /dev/null
+++ b/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs
@@ -0,0 +1,20 @@
+//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Cpanic=abort
+// Auxiliary build problems with aarch64-apple:
+// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
+// Auxiliary build problems with i686-mingw: linker `cc` not found
+//@ only-x86
+//@ ignore-windows
+//@ ignore-apple
+//@ needs-llvm-components: x86
+#![crate_type = "rlib"]
+#![no_core]
+#![feature(no_core, lang_items, repr_simd)]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+pub fn somefun() {}
+
+pub struct S;
diff --git a/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs b/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs
new file mode 100644
index 00000000000..39c6be9d589
--- /dev/null
+++ b/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs
@@ -0,0 +1,20 @@
+//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Zreg-struct-return=true -Cpanic=abort
+// Auxiliary build problems with aarch64-apple:
+// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
+// Auxiliary build problems with i686-mingw: linker `cc` not found
+//@ only-x86
+//@ ignore-windows
+//@ ignore-apple
+//@ needs-llvm-components: x86
+#![crate_type = "rlib"]
+#![no_core]
+#![feature(no_core, lang_items, repr_simd)]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+pub fn somefun() {}
+
+pub struct S;
diff --git a/tests/ui/target_modifiers/defaults_check.error.stderr b/tests/ui/target_modifiers/defaults_check.error.stderr
new file mode 100644
index 00000000000..c545dd71069
--- /dev/null
+++ b/tests/ui/target_modifiers/defaults_check.error.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check`
+  --> $DIR/defaults_check.rs:20:1
+   |
+LL | #![crate_type = "rlib"]
+   | ^
+   |
+   = help: the `-Zreg-struct-return` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: `-Zreg-struct-return=true` in this crate is incompatible with `-Zreg-struct-return=` in dependency `default_reg_struct_return`
+   = help: set `-Zreg-struct-return=` in this crate or `-Zreg-struct-return=true` in `default_reg_struct_return`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=reg-struct-return` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/defaults_check.rs b/tests/ui/target_modifiers/defaults_check.rs
new file mode 100644
index 00000000000..b8f4848d3a4
--- /dev/null
+++ b/tests/ui/target_modifiers/defaults_check.rs
@@ -0,0 +1,27 @@
+// Tests that default unspecified target modifier value in dependency crate is ok linked
+// with the same value, explicitly specified
+//@ aux-crate:default_reg_struct_return=default_reg_struct_return.rs
+//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
+//@ revisions:error ok ok_explicit
+//@[ok] compile-flags:
+//@[ok_explicit] compile-flags: -Zreg-struct-return=false
+//@[error] compile-flags: -Zreg-struct-return=true
+
+// Auxiliary build problems with aarch64-apple:
+// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
+// Auxiliary build problems with i686-mingw: linker `cc` not found
+//@ only-x86
+//@ ignore-windows
+//@ ignore-apple
+//@ needs-llvm-components: x86
+//@[ok] build-pass
+//@[ok_explicit] build-pass
+
+#![crate_type = "rlib"]
+//[error]~^ ERROR mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check`
+#![no_core]
+#![feature(no_core, lang_items, repr_simd)]
+
+fn foo() {
+    default_reg_struct_return::somefun();
+}
diff --git a/tests/ui/target_modifiers/incompatible_regparm.allow_no_value.stderr b/tests/ui/target_modifiers/incompatible_regparm.allow_no_value.stderr
new file mode 100644
index 00000000000..8597332825b
--- /dev/null
+++ b/tests/ui/target_modifiers/incompatible_regparm.allow_no_value.stderr
@@ -0,0 +1,2 @@
+error: codegen option `unsafe-allow-abi-mismatch` requires a comma-separated list of strings (C unsafe-allow-abi-mismatch=<value>)
+
diff --git a/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr b/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr
new file mode 100644
index 00000000000..692fc7a4e3f
--- /dev/null
+++ b/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm`
+  --> $DIR/incompatible_regparm.rs:16:1
+   |
+LL | #![crate_type = "rlib"]
+   | ^
+   |
+   = help: the `-Zregparm` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: `-Zregparm=1` in this crate is incompatible with `-Zregparm=2` in dependency `wrong_regparm`
+   = help: set `-Zregparm=2` in this crate or `-Zregparm=1` in `wrong_regparm`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=regparm` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/incompatible_regparm.rs b/tests/ui/target_modifiers/incompatible_regparm.rs
new file mode 100644
index 00000000000..e866c5aa891
--- /dev/null
+++ b/tests/ui/target_modifiers/incompatible_regparm.rs
@@ -0,0 +1,23 @@
+//@ aux-crate:wrong_regparm=wrong_regparm.rs
+//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=1 -Cpanic=abort
+// Auxiliary build problems with aarch64-apple:
+// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
+// Auxiliary build problems with i686-mingw: linker `cc` not found
+//@ only-x86
+//@ ignore-windows
+//@ ignore-apple
+//@ needs-llvm-components: x86
+//@ revisions:error_generated allow_regparm_mismatch allow_no_value
+
+//@[allow_regparm_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=regparm
+//@[allow_regparm_mismatch] build-pass
+//@[allow_no_value] compile-flags: -Cunsafe-allow-abi-mismatch
+
+#![crate_type = "rlib"]
+//[error_generated]~^ ERROR mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm`
+#![no_core]
+#![feature(no_core, lang_items, repr_simd)]
+
+fn foo() {
+    wrong_regparm::somefun();
+}
diff --git a/tests/ui/target_modifiers/two_flags.rs b/tests/ui/target_modifiers/two_flags.rs
new file mode 100644
index 00000000000..ca17117a267
--- /dev/null
+++ b/tests/ui/target_modifiers/two_flags.rs
@@ -0,0 +1,23 @@
+//@ aux-crate:wrong_regparm_and_ret=wrong_regparm_and_ret.rs
+//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
+// Auxiliary build problems with aarch64-apple:
+// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
+// Auxiliary build problems with i686-mingw: linker `cc` not found
+//@ only-x86
+//@ ignore-windows
+//@ ignore-apple
+//@ needs-llvm-components: x86
+//@ revisions:two_allowed unknown_allowed
+
+//@[two_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=regparm,reg-struct-return
+//@[two_allowed] build-pass
+//@[unknown_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=unknown_flag -Zregparm=2 -Zreg-struct-return=true
+
+#![crate_type = "rlib"]
+//[unknown_allowed]~^ ERROR unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag`
+#![no_core]
+#![feature(no_core, lang_items, repr_simd)]
+
+fn foo() {
+    wrong_regparm_and_ret::somefun();
+}
diff --git a/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr b/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr
new file mode 100644
index 00000000000..c8040c6e389
--- /dev/null
+++ b/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr
@@ -0,0 +1,8 @@
+error: unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag`
+  --> $DIR/two_flags.rs:16:1
+   |
+LL | #![crate_type = "rlib"]
+   | ^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/test-attrs/test-panic-abort-disabled.rs b/tests/ui/test-attrs/test-panic-abort-disabled.rs
index 05dd9395c2b..e83be65f925 100644
--- a/tests/ui/test-attrs/test-panic-abort-disabled.rs
+++ b/tests/ui/test-attrs/test-panic-abort-disabled.rs
@@ -4,8 +4,6 @@
 //@ run-flags: --test-threads=1
 
 //@ needs-unwind
-//@ ignore-wasm no panic support
-//@ ignore-emscripten no panic support
 //@ needs-subprocess
 
 #![cfg(test)]
diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.rs b/tests/ui/test-attrs/test-panic-abort-nocapture.rs
index f7e15dbdbc3..6a1025ea087 100644
--- a/tests/ui/test-attrs/test-panic-abort-nocapture.rs
+++ b/tests/ui/test-attrs/test-panic-abort-nocapture.rs
@@ -7,8 +7,6 @@
 //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
 
 //@ ignore-android #120567
-//@ ignore-wasm no panic support
-//@ ignore-emscripten no panic support
 //@ needs-subprocess
 
 #![cfg(test)]
diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
index 25681171170..b9f267838b1 100644
--- a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
+++ b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
@@ -1,11 +1,11 @@
 
-thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:34:5:
+thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:32:5:
 assertion `left == right` failed
   left: 2
  right: 4
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
-thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:28:5:
+thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:26:5:
 assertion `left == right` failed
   left: 2
  right: 4
diff --git a/tests/ui/test-attrs/test-panic-abort.rs b/tests/ui/test-attrs/test-panic-abort.rs
index 951cf54346b..6c9b641fb6f 100644
--- a/tests/ui/test-attrs/test-panic-abort.rs
+++ b/tests/ui/test-attrs/test-panic-abort.rs
@@ -7,8 +7,6 @@
 //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
 
 //@ ignore-android #120567
-//@ ignore-wasm no panic support
-//@ ignore-emscripten no panic support
 //@ needs-subprocess
 
 #![cfg(test)]
diff --git a/tests/ui/test-attrs/test-panic-abort.run.stdout b/tests/ui/test-attrs/test-panic-abort.run.stdout
index 844808e8637..0faa7f0dfce 100644
--- a/tests/ui/test-attrs/test-panic-abort.run.stdout
+++ b/tests/ui/test-attrs/test-panic-abort.run.stdout
@@ -18,7 +18,7 @@ testing123
 ---- it_fails stderr ----
 testing321
 
-thread 'main' panicked at $DIR/test-panic-abort.rs:39:5:
+thread 'main' panicked at $DIR/test-panic-abort.rs:37:5:
 assertion `left == right` failed
   left: 2
  right: 5
diff --git a/tests/ui/threads-sendsync/spawning-with-debug.rs b/tests/ui/threads-sendsync/spawning-with-debug.rs
index 90a81c1e53b..3b7107e2dbf 100644
--- a/tests/ui/threads-sendsync/spawning-with-debug.rs
+++ b/tests/ui/threads-sendsync/spawning-with-debug.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
 #![allow(unused_mut)]
-//@ ignore-windows
 //@ exec-env:RUST_LOG=debug
 //@ needs-threads
 
diff --git a/tests/ui/threads-sendsync/thread-local-extern-static.rs b/tests/ui/threads-sendsync/thread-local-extern-static.rs
index ca66f8ad1d3..ce2a221ec2e 100644
--- a/tests/ui/threads-sendsync/thread-local-extern-static.rs
+++ b/tests/ui/threads-sendsync/thread-local-extern-static.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-windows
+//@ ignore-windows FIXME(134939): thread_local + no_mangle doesn't work on Windows
 //@ aux-build:thread-local-extern-static.rs
 
 #![feature(cfg_target_thread_local, thread_local)]
diff --git a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs
index c3a2ab82adc..5277de29464 100644
--- a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs
+++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs
@@ -8,7 +8,6 @@ type Fn = dyn FnOnce() -> u8;
 const TEST: Fn = some_fn;
 //~^ ERROR cannot find value `some_fn` in this scope
 //~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
-//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
 const TEST2: (Fn, u8) = (TEST, 0);
 //~^ ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
 //~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
diff --git a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr
index 0e92979ccd5..76e015a7238 100644
--- a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr
+++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr
@@ -13,16 +13,7 @@ LL | const TEST: Fn = some_fn;
    = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
 
 error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
-  --> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18
-   |
-LL | const TEST: Fn = some_fn;
-   |                  ^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
-   = note: constant expressions must have a statically known size
-
-error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
-  --> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:14
+  --> $DIR/ice-unsized-tuple-const-issue-121443.rs:11:14
    |
 LL | const TEST2: (Fn, u8) = (TEST, 0);
    |              ^^^^^^^^ doesn't have a size known at compile-time
@@ -31,7 +22,7 @@ LL | const TEST2: (Fn, u8) = (TEST, 0);
    = note: only the last element of a tuple may have a dynamically sized type
 
 error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
-  --> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:25
+  --> $DIR/ice-unsized-tuple-const-issue-121443.rs:11:25
    |
 LL | const TEST2: (Fn, u8) = (TEST, 0);
    |                         ^^^^^^^^^ doesn't have a size known at compile-time
@@ -39,7 +30,7 @@ LL | const TEST2: (Fn, u8) = (TEST, 0);
    = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
    = note: only the last element of a tuple may have a dynamically sized type
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0277, E0425.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/span-bug-issue-121418.stderr b/tests/ui/traits/const-traits/span-bug-issue-121418.stderr
index f41c19b4573..92cfecd0540 100644
--- a/tests/ui/traits/const-traits/span-bug-issue-121418.stderr
+++ b/tests/ui/traits/const-traits/span-bug-issue-121418.stderr
@@ -8,17 +8,6 @@ LL | impl const dyn T {
    |
    = note: only trait implementations may be annotated with `const`
 
-error[E0308]: mismatched types
-  --> $DIR/span-bug-issue-121418.rs:8:27
-   |
-LL |     pub const fn new() -> std::sync::Mutex<dyn T> {}
-   |                  ---      ^^^^^^^^^^^^^^^^^^^^^^^ expected `Mutex<dyn T>`, found `()`
-   |                  |
-   |                  implicitly returns `()` as its body has no tail or `return` expression
-   |
-   = note: expected struct `Mutex<(dyn T + 'static)>`
-           found unit type `()`
-
 error[E0277]: the size for values of type `(dyn T + 'static)` cannot be known at compilation time
   --> $DIR/span-bug-issue-121418.rs:8:27
    |
@@ -30,6 +19,17 @@ note: required because it appears within the type `Mutex<(dyn T + 'static)>`
   --> $SRC_DIR/std/src/sync/poison/mutex.rs:LL:COL
    = note: the return type of a function must have a statically known size
 
+error[E0308]: mismatched types
+  --> $DIR/span-bug-issue-121418.rs:8:27
+   |
+LL |     pub const fn new() -> std::sync::Mutex<dyn T> {}
+   |                  ---      ^^^^^^^^^^^^^^^^^^^^^^^ expected `Mutex<dyn T>`, found `()`
+   |                  |
+   |                  implicitly returns `()` as its body has no tail or `return` expression
+   |
+   = note: expected struct `Mutex<(dyn T + 'static)>`
+           found unit type `()`
+
 error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
diff --git a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr
index 8bfda71bac1..5299236026d 100644
--- a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr
+++ b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr
@@ -2,7 +2,7 @@ error[E0271]: type mismatch resolving `<dyn Pointee<Metadata = ()> as Pointee>::
   --> $DIR/ice-with-dyn-pointee-errors.rs:9:33
    |
 LL |     unknown_sized_object_ptr_in(x)
-   |     --------------------------- ^ expected `()`, found `DynMetadata<dyn Pointee<Metadata = ...>>`
+   |     --------------------------- ^ expected `()`, found `DynMetadata<dyn Pointee<Metadata = ()>>`
    |     |
    |     required by a bound introduced by this call
    |
diff --git a/tests/ui/traits/issue-52893.stderr b/tests/ui/traits/issue-52893.stderr
index c37dde90e33..3c5df82fcdc 100644
--- a/tests/ui/traits/issue-52893.stderr
+++ b/tests/ui/traits/issue-52893.stderr
@@ -22,7 +22,7 @@ note: method defined here
   --> $DIR/issue-52893.rs:11:8
    |
 LL |     fn push(self, other: T) -> Self::PushRes;
-   |        ^^^^
+   |        ^^^^       -----
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/issue-77982.rs b/tests/ui/traits/issue-77982.rs
index dce25e62e46..b2a488e18e8 100644
--- a/tests/ui/traits/issue-77982.rs
+++ b/tests/ui/traits/issue-77982.rs
@@ -1,5 +1,6 @@
-//@ ignore-windows different list of satisfying impls
-//@ ignore-arm different list of satisfying impls
+//@ ignore-windows FIXME: We get an extra E0283 on Windows
+//@ ignore-arm extra satisfying impls
+
 use std::collections::HashMap;
 
 fn what() {
diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr
index 2b26a1b7ab1..4907a6dd17a 100644
--- a/tests/ui/traits/issue-77982.stderr
+++ b/tests/ui/traits/issue-77982.stderr
@@ -1,5 +1,5 @@
 error[E0283]: type annotations needed
-  --> $DIR/issue-77982.rs:10:10
+  --> $DIR/issue-77982.rs:11:10
    |
 LL |     opts.get(opt.as_ref());
    |          ^^^ ------------ type must be known at this point
@@ -18,7 +18,7 @@ LL |     opts.get::<Q>(opt.as_ref());
    |             +++++
 
 error[E0283]: type annotations needed
-  --> $DIR/issue-77982.rs:10:10
+  --> $DIR/issue-77982.rs:11:10
    |
 LL |     opts.get(opt.as_ref());
    |          ^^^     ------ type must be known at this point
@@ -36,7 +36,7 @@ LL |     opts.get::<Q>(opt.as_ref());
    |             +++++
 
 error[E0283]: type annotations needed
-  --> $DIR/issue-77982.rs:15:59
+  --> $DIR/issue-77982.rs:16:59
    |
 LL |     let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect();
    |                                            ---            ^^^^
@@ -56,13 +56,13 @@ LL |     let ips: Vec<_> = (0..100_000).map(|_| u32::from(<u32 as Into<T>>::into
    |                                                      +++++++++++++++++++++++    ~
 
 error[E0283]: type annotations needed for `Box<_>`
-  --> $DIR/issue-77982.rs:38:9
+  --> $DIR/issue-77982.rs:39:9
    |
 LL |     let _ = ().foo();
    |         ^      --- type must be known at this point
    |
 note: multiple `impl`s satisfying `(): Foo<'_, _>` found
-  --> $DIR/issue-77982.rs:31:1
+  --> $DIR/issue-77982.rs:32:1
    |
 LL | impl Foo<'static, u32> for () {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -74,13 +74,13 @@ LL |     let _: Box<T> = ().foo();
    |          ++++++++
 
 error[E0283]: type annotations needed for `Box<_>`
-  --> $DIR/issue-77982.rs:42:9
+  --> $DIR/issue-77982.rs:43:9
    |
 LL |     let _ = (&()).bar();
    |         ^         --- type must be known at this point
    |
 note: multiple `impl`s satisfying `&(): Bar<'_, _>` found
-  --> $DIR/issue-77982.rs:34:1
+  --> $DIR/issue-77982.rs:35:1
    |
 LL | impl<'a> Bar<'static, u32> for &'a () {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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 cbd591eec96..ea6df938704 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
@@ -13,8 +13,9 @@ fn main() {
 }
 
 fn weird0() -> impl Sized + !Sized {}
-//~^ ERROR the trait bound `(): !Sized` is not satisfied
+//~^ ERROR type mismatch resolving
 fn weird1() -> impl !Sized + Sized {}
-//~^ ERROR the trait bound `(): !Sized` is not satisfied
+//~^ ERROR type mismatch resolving
 fn weird2() -> impl !Sized {}
-//~^ ERROR the trait bound `(): !Sized` is not satisfied
+//~^ ERROR type mismatch resolving
+//~| ERROR the size for values of type
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 3dad6d534fd..41d9e74f807 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
@@ -1,20 +1,29 @@
-error[E0277]: the trait bound `(): !Sized` is not satisfied
+error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time
+  --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
+   |
+LL | fn weird2() -> impl !Sized {}
+   |                ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `impl !Sized`
+   = note: the return type of a function must have a statically known size
+
+error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:16
    |
 LL | fn weird0() -> impl Sized + !Sized {}
-   |                ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
+   |                ^^^^^^^^^^^^^^^^^^^ types differ
 
-error[E0277]: the trait bound `(): !Sized` is not satisfied
+error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
   --> $DIR/opaque-type-unsatisfied-bound.rs:17:16
    |
 LL | fn weird1() -> impl !Sized + Sized {}
-   |                ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
+   |                ^^^^^^^^^^^^^^^^^^^ types differ
 
-error[E0277]: the trait bound `(): !Sized` is not satisfied
+error[E0271]: type mismatch resolving `impl !Sized == ()`
   --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
    |
 LL | fn weird2() -> impl !Sized {}
-   |                ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
+   |                ^^^^^^^^^^^ types differ
 
 error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:12:13
@@ -30,6 +39,7 @@ note: required by a bound in `consume`
 LL | fn consume(_: impl Trait) {}
    |                    ^^^^^ required by this bound in `consume`
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0271, E0277.
+For more information about an error, try `rustc --explain E0271`.
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 39422914afc..ce42bce0ad4 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
@@ -3,6 +3,6 @@
 #![feature(negative_bounds, unboxed_closures)]
 
 fn produce() -> impl !Fn<(u32,)> {}
-//~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied
+//~^ ERROR type mismatch resolving
 
 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 760e5aa62f2..e1b84e0df7a 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
@@ -1,9 +1,9 @@
-error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
+error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()`
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
    |
 LL | fn produce() -> impl !Fn<(u32,)> {}
-   |                 ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
+   |                 ^^^^^^^^^^^^^^^^ types differ
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr
index af941e69c5f..2f9fdf151f0 100644
--- a/tests/ui/traits/object/pretty.stderr
+++ b/tests/ui/traits/object/pretty.stderr
@@ -110,7 +110,7 @@ error[E0308]: mismatched types
   --> $DIR/pretty.rs:36:79
    |
 LL | fn dyn_fixed_generic_multi(x: &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>) { x }
-   |                                                                            -  ^ expected `()`, found `&dyn FixedGeneric1<'a, Assoc2 = ...>`
+   |                                                                            -  ^ expected `()`, found `&dyn FixedGeneric1<'a, Assoc2 = &u8>`
    |                                                                            |
    |                                                                            help: try adding a return type: `-> &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>`
    |
@@ -132,7 +132,7 @@ error[E0308]: mismatched types
   --> $DIR/pretty.rs:38:73
    |
 LL | fn dyn_any_different_binders(x: &dyn AnyDifferentBinders<Assoc = u8>) { x }
-   |                                                                      -  ^ expected `()`, found `&dyn AnyDifferentBinders<Assoc = ...>`
+   |                                                                      -  ^ expected `()`, found `&dyn AnyDifferentBinders<Assoc = u8>`
    |                                                                      |
    |                                                                      help: try adding a return type: `-> &dyn AnyDifferentBinders<Assoc = u8>`
    |
diff --git a/tests/ui/traits/on_unimplemented_long_types.stderr b/tests/ui/traits/on_unimplemented_long_types.stderr
index 5722f4006ff..2705d7c501e 100644
--- a/tests/ui/traits/on_unimplemented_long_types.stderr
+++ b/tests/ui/traits/on_unimplemented_long_types.stderr
@@ -13,8 +13,6 @@ LL | |         ))))))))))),
 LL | |     )))))))))))
    | |_______________- return type was inferred to be `Option<Option<Option<...>>>` here
    |
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
-   = note: consider using `--verbose` to print the full type name to the console
    = help: the trait `std::fmt::Display` is not implemented for `Option<Option<Option<...>>>`
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
    = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
diff --git a/tests/ui/type-alias-impl-trait/issue-98604.rs b/tests/ui/type-alias-impl-trait/issue-98604.rs
index 9231e82d9f4..35c25c7f726 100644
--- a/tests/ui/type-alias-impl-trait/issue-98604.rs
+++ b/tests/ui/type-alias-impl-trait/issue-98604.rs
@@ -7,5 +7,5 @@ async fn test() {}
 #[allow(unused_must_use)]
 fn main() {
     Box::new(test) as AsyncFnPtr;
-    //~^ ERROR expected `test` to be a fn item that returns `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>
+    //~^ ERROR expected `test` to return `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-98604.stderr b/tests/ui/type-alias-impl-trait/issue-98604.stderr
index 2390b725356..77c6ba3003f 100644
--- a/tests/ui/type-alias-impl-trait/issue-98604.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-98604.stderr
@@ -1,4 +1,4 @@
-error[E0271]: expected `test` to be a fn item that returns `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
+error[E0271]: expected `test` to return `Pin<Box<dyn Future<Output = ()>>>`, but it returns `impl Future<Output = ()>`
   --> $DIR/issue-98604.rs:9:5
    |
 LL |     Box::new(test) as AsyncFnPtr;
diff --git a/tests/ui/type-alias-impl-trait/issue-98608.rs b/tests/ui/type-alias-impl-trait/issue-98608.rs
index 5e026ea4096..5612ccd6cae 100644
--- a/tests/ui/type-alias-impl-trait/issue-98608.rs
+++ b/tests/ui/type-alias-impl-trait/issue-98608.rs
@@ -4,7 +4,7 @@ fn hi() -> impl Sized {
 
 fn main() {
     let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);
-    //~^ ERROR expected `hi` to be a fn item that returns `Box<u8>`, but it returns `impl Sized`
+    //~^ ERROR expected `hi` to return `Box<u8>`, but it returns `impl Sized`
     let boxed = b();
     let null = *boxed;
     println!("{null:?}");
diff --git a/tests/ui/type-alias-impl-trait/issue-98608.stderr b/tests/ui/type-alias-impl-trait/issue-98608.stderr
index d5c56636f66..872a6ed4350 100644
--- a/tests/ui/type-alias-impl-trait/issue-98608.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-98608.stderr
@@ -1,4 +1,4 @@
-error[E0271]: expected `hi` to be a fn item that returns `Box<u8>`, but it returns `impl Sized`
+error[E0271]: expected `hi` to return `Box<u8>`, but it returns `impl Sized`
   --> $DIR/issue-98608.rs:6:39
    |
 LL | fn hi() -> impl Sized {
diff --git a/tests/ui/type/pattern_types/assoc_const.default.stderr b/tests/ui/type/pattern_types/assoc_const.default.stderr
new file mode 100644
index 00000000000..abda40e4681
--- /dev/null
+++ b/tests/ui/type/pattern_types/assoc_const.default.stderr
@@ -0,0 +1,36 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/assoc_const.rs:17:19
+   |
+LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
+  --> $DIR/assoc_const.rs:17:19
+   |
+LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: constant expression depends on a generic parameter
+  --> $DIR/assoc_const.rs:20:19
+   |
+LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
+  --> $DIR/assoc_const.rs:20:19
+   |
+LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/type/pattern_types/assoc_const.rs b/tests/ui/type/pattern_types/assoc_const.rs
new file mode 100644
index 00000000000..af0f7e4cbf3
--- /dev/null
+++ b/tests/ui/type/pattern_types/assoc_const.rs
@@ -0,0 +1,24 @@
+#![feature(pattern_types)]
+#![feature(pattern_type_macro)]
+#![cfg_attr(const_arg, feature(generic_const_exprs))]
+#![expect(incomplete_features)]
+
+//@ revisions: default const_arg
+
+//@[const_arg] check-pass
+
+use std::pat::pattern_type;
+
+trait Foo {
+    const START: u32;
+    const END: u32;
+}
+
+fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
+//[default]~^ ERROR: constant expression depends on a generic parameter
+//[default]~| ERROR: constant expression depends on a generic parameter
+fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
+//[default]~^ ERROR: constant expression depends on a generic parameter
+//[default]~| ERROR: constant expression depends on a generic parameter
+
+fn main() {}
diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs
index c5f8b2764ec..0f10bf8ce62 100644
--- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs
+++ b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs
@@ -1,10 +1,14 @@
+//@known-bug: #127972
+//@ failure-status: 101
+//@ normalize-stderr: "note: .*\n\n" -> ""
+//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
+//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
+//@ rustc-env:RUST_BACKTRACE=0
+
 #![feature(pattern_types, pattern_type_macro)]
 #![allow(internal_features)]
 
 type Pat<const START: u32, const END: u32> =
     std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
-//~^ ERROR type and const arguments are not allowed on const parameter `START`
-//~| ERROR generic arguments are not allowed on const parameter `END`
-//~| ERROR associated item constraints are not allowed here
 
 fn main() {}
diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr
index f31809bf397..fbe80a19863 100644
--- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr
+++ b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr
@@ -1,38 +1,14 @@
-error[E0109]: type and const arguments are not allowed on const parameter `START`
-  --> $DIR/bad_const_generics_args_on_const_param.rs:5:44
+error: internal compiler error: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs:LL:CC: try_lower_anon_const_lit: received const param which shouldn't be possible
+  --> $DIR/bad_const_generics_args_on_const_param.rs:12:36
    |
 LL |     std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
-   |                                    -----   ^^  ^^^  ^ type and const arguments not allowed
-   |                                    |
-   |                                    not allowed on const parameter `START`
-   |
-note: const parameter `START` defined here
-  --> $DIR/bad_const_generics_args_on_const_param.rs:4:16
-   |
-LL | type Pat<const START: u32, const END: u32> =
-   |                ^^^^^
+   |                                    ^^^^^^^^^^^^^^^^^^^
 
-error[E0109]: generic arguments are not allowed on const parameter `END`
-  --> $DIR/bad_const_generics_args_on_const_param.rs:5:64
-   |
-LL |     std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
-   |                                                          ---   ^ generic argument not allowed
-   |                                                          |
-   |                                                          not allowed on const parameter `END`
-   |
-note: const parameter `END` defined here
-  --> $DIR/bad_const_generics_args_on_const_param.rs:4:34
-   |
-LL | type Pat<const START: u32, const END: u32> =
-   |                                  ^^^
-
-error[E0229]: associated item constraints are not allowed here
-  --> $DIR/bad_const_generics_args_on_const_param.rs:5:67
-   |
-LL |     std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
-   |                                                                   ^^^^^^^^^^ associated item constraint not allowed here
 
-error: aborting due to 3 previous errors
+Box<dyn Any>
+query stack during panic:
+#0 [type_of] expanding type alias `Pat`
+#1 [check_well_formed] checking that `Pat` is well-formed
+... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0109, E0229.
-For more information about an error, try `rustc --explain E0109`.
diff --git a/tests/ui/type/pattern_types/bad_pat.rs b/tests/ui/type/pattern_types/bad_pat.rs
index 6cb2a0f1f8e..549b0d11dd1 100644
--- a/tests/ui/type/pattern_types/bad_pat.rs
+++ b/tests/ui/type/pattern_types/bad_pat.rs
@@ -8,6 +8,6 @@ type NonNullU32_2 = pattern_type!(u32 is 1..=);
 type Positive2 = pattern_type!(i32 is 0..=);
 //~^ ERROR: inclusive range with no end
 type Wild = pattern_type!(() is _);
-//~^ ERROR: wildcard patterns are not permitted for pattern types
+//~^ ERROR: pattern not supported in pattern types
 
 fn main() {}
diff --git a/tests/ui/type/pattern_types/bad_pat.stderr b/tests/ui/type/pattern_types/bad_pat.stderr
index c857cc3c3ad..d2a5a20bf89 100644
--- a/tests/ui/type/pattern_types/bad_pat.stderr
+++ b/tests/ui/type/pattern_types/bad_pat.stderr
@@ -24,7 +24,7 @@ LL - type Positive2 = pattern_type!(i32 is 0..=);
 LL + type Positive2 = pattern_type!(i32 is 0..);
    |
 
-error: wildcard patterns are not permitted for pattern types
+error: pattern not supported in pattern types
   --> $DIR/bad_pat.rs:10:33
    |
 LL | type Wild = pattern_type!(() is _);
diff --git a/tests/ui/type/pattern_types/chars.rs b/tests/ui/type/pattern_types/chars.rs
new file mode 100644
index 00000000000..9073998b387
--- /dev/null
+++ b/tests/ui/type/pattern_types/chars.rs
@@ -0,0 +1,12 @@
+//! Check that chars can be used in ranges
+
+//@ check-pass
+
+#![feature(pattern_types)]
+#![feature(pattern_type_macro)]
+
+use std::pat::pattern_type;
+
+const LOWERCASE: pattern_type!(char is 'a'..='z') = unsafe { std::mem::transmute('b') };
+
+fn main() {}
diff --git a/tests/ui/type/pattern_types/const_block.rs b/tests/ui/type/pattern_types/const_block.rs
new file mode 100644
index 00000000000..49c87f4fa0d
--- /dev/null
+++ b/tests/ui/type/pattern_types/const_block.rs
@@ -0,0 +1,10 @@
+#![feature(pattern_types)]
+#![feature(pattern_type_macro)]
+#![feature(inline_const_pat)]
+
+use std::pat::pattern_type;
+
+fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+//~^ ERROR: cycle
+
+fn main() {}
diff --git a/tests/ui/type/pattern_types/const_block.stderr b/tests/ui/type/pattern_types/const_block.stderr
new file mode 100644
index 00000000000..82b616105af
--- /dev/null
+++ b/tests/ui/type/pattern_types/const_block.stderr
@@ -0,0 +1,72 @@
+error[E0391]: cycle detected when evaluating type-level constant
+  --> $DIR/const_block.rs:7:36
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                    ^^^^^^^^^^^^^^
+   |
+note: ...which requires const-evaluating + checking `bar::{constant#2}`...
+  --> $DIR/const_block.rs:7:36
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                    ^^^^^^^^^^^^^^
+note: ...which requires caching mir of `bar::{constant#2}` for CTFE...
+  --> $DIR/const_block.rs:7:36
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                    ^^^^^^^^^^^^^^
+note: ...which requires elaborating drops for `bar::{constant#2}`...
+  --> $DIR/const_block.rs:7:36
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                    ^^^^^^^^^^^^^^
+note: ...which requires borrow-checking `bar::{constant#2}`...
+  --> $DIR/const_block.rs:7:36
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                    ^^^^^^^^^^^^^^
+note: ...which requires borrow-checking `bar::{constant#0}`...
+  --> $DIR/const_block.rs:7:41
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                         ^^^^^^^^^
+note: ...which requires promoting constants in MIR for `bar::{constant#0}`...
+  --> $DIR/const_block.rs:7:41
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                         ^^^^^^^^^
+note: ...which requires const checking `bar::{constant#0}`...
+  --> $DIR/const_block.rs:7:41
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                         ^^^^^^^^^
+note: ...which requires building MIR for `bar::{constant#0}`...
+  --> $DIR/const_block.rs:7:41
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                         ^^^^^^^^^
+note: ...which requires match-checking `bar::{constant#0}`...
+  --> $DIR/const_block.rs:7:41
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                         ^^^^^^^^^
+note: ...which requires type-checking `bar::{constant#0}`...
+  --> $DIR/const_block.rs:7:41
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   |                                         ^^^^^^^^^
+note: ...which requires type-checking `bar`...
+  --> $DIR/const_block.rs:7:1
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...which again requires evaluating type-level constant, completing the cycle
+note: cycle used when checking that `bar` is well-formed
+  --> $DIR/const_block.rs:7:1
+   |
+LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = 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/type/pattern_types/free_const.rs b/tests/ui/type/pattern_types/free_const.rs
new file mode 100644
index 00000000000..2e29fce2379
--- /dev/null
+++ b/tests/ui/type/pattern_types/free_const.rs
@@ -0,0 +1,13 @@
+//@ check-pass
+
+#![feature(pattern_types)]
+#![feature(pattern_type_macro)]
+
+use std::pat::pattern_type;
+
+const START: u32 = 0;
+const END: u32 = 10;
+
+fn foo(_: pattern_type!(u32 is START..=END)) {}
+
+fn main() {}
diff --git a/tests/ui/type/pattern_types/nested.rs b/tests/ui/type/pattern_types/nested.rs
new file mode 100644
index 00000000000..9ca9c7923de
--- /dev/null
+++ b/tests/ui/type/pattern_types/nested.rs
@@ -0,0 +1,30 @@
+//! Check that pattern types can only have specific base types
+
+#![feature(pattern_types)]
+#![feature(pattern_type_macro)]
+
+use std::pat::pattern_type;
+
+// Undoing an inner pattern type's restrictions should either be forbidden,
+// or still validate correctly.
+const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
+//~^ ERROR: not a valid base type for range patterns
+//~| ERROR: mismatched types
+
+// We want to get the most narrowest version that a pattern could be
+const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
+//~^ ERROR: not a valid base type for range patterns
+//~| ERROR: mismatched types
+
+const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
+//~^ ERROR: not a valid base type for range patterns
+//~| ERROR: mismatched types
+
+const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
+//~^ ERROR: not a valid base type for range patterns
+//~| ERROR: mismatched types
+
+const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
+//~^ ERROR: not a valid base type for range patterns
+
+fn main() {}
diff --git a/tests/ui/type/pattern_types/nested.stderr b/tests/ui/type/pattern_types/nested.stderr
new file mode 100644
index 00000000000..b753b0a9c9b
--- /dev/null
+++ b/tests/ui/type/pattern_types/nested.stderr
@@ -0,0 +1,96 @@
+error: `(u32) is 1..=` is not a valid base type for range patterns
+  --> $DIR/nested.rs:10:34
+   |
+LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: range patterns only support integers
+  --> $DIR/nested.rs:10:63
+   |
+LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
+   |                                                               ^^^
+
+error: `(i32) is 1..=` is not a valid base type for range patterns
+  --> $DIR/nested.rs:15:35
+   |
+LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: range patterns only support integers
+  --> $DIR/nested.rs:15:64
+   |
+LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
+   |                                                                ^^^^^
+
+error: `(i32) is 1..=` is not a valid base type for range patterns
+  --> $DIR/nested.rs:19:35
+   |
+LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: range patterns only support integers
+  --> $DIR/nested.rs:19:64
+   |
+LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
+   |                                                                ^^^
+
+error: `()` is not a valid base type for range patterns
+  --> $DIR/nested.rs:23:35
+   |
+LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
+   |                                   ^^
+   |
+note: range patterns only support integers
+  --> $DIR/nested.rs:23:41
+   |
+LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
+   |                                         ^^^
+
+error: `f32` is not a valid base type for range patterns
+  --> $DIR/nested.rs:27:35
+   |
+LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
+   |                                   ^^^
+   |
+note: range patterns only support integers
+  --> $DIR/nested.rs:27:42
+   |
+LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
+   |                                          ^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/nested.rs:10:63
+   |
+LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
+   |                                                               ^ expected `(u32) is 1..=`, found integer
+   |
+   = note: expected pattern type `(u32) is 1..=`
+                      found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/nested.rs:15:67
+   |
+LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
+   |                                                                   ^^ expected `(i32) is 1..=`, found integer
+   |
+   = note: expected pattern type `(i32) is 1..=`
+                      found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/nested.rs:19:66
+   |
+LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
+   |                                                                  ^ expected `(i32) is 1..=`, found integer
+   |
+   = note: expected pattern type `(i32) is 1..=`
+                      found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/nested.rs:23:43
+   |
+LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
+   |                                           ^ expected `()`, found integer
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type/pattern_types/pattern_type_mismatch.rs b/tests/ui/type/pattern_types/pattern_type_mismatch.rs
new file mode 100644
index 00000000000..0c88f27d836
--- /dev/null
+++ b/tests/ui/type/pattern_types/pattern_type_mismatch.rs
@@ -0,0 +1,16 @@
+//! Check that pattern types patterns must be of the type of the base type
+
+#![feature(pattern_types)]
+#![feature(pattern_type_macro)]
+
+use std::pat::pattern_type;
+
+const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
+//~^ ERROR: mismatched types
+//~| ERROR: mismatched types
+
+const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
+//~^ ERROR: mismatched types
+//~| ERROR: mismatched types
+
+fn main() {}
diff --git a/tests/ui/type/pattern_types/pattern_type_mismatch.stderr b/tests/ui/type/pattern_types/pattern_type_mismatch.stderr
new file mode 100644
index 00000000000..19b0c1059c8
--- /dev/null
+++ b/tests/ui/type/pattern_types/pattern_type_mismatch.stderr
@@ -0,0 +1,37 @@
+error[E0308]: mismatched types
+  --> $DIR/pattern_type_mismatch.rs:8:41
+   |
+LL | const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
+   |                                         ^^^ expected `u8`, found `char`
+   |
+help: if you meant to write a byte literal, prefix with `b`
+   |
+LL | const BAD_NESTING4: pattern_type!(u8 is b'a'..='a') = todo!();
+   |                                         ~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern_type_mismatch.rs:8:47
+   |
+LL | const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
+   |                                               ^^^ expected `u8`, found `char`
+   |
+help: if you meant to write a byte literal, prefix with `b`
+   |
+LL | const BAD_NESTING4: pattern_type!(u8 is 'a'..=b'a') = todo!();
+   |                                               ~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/pattern_type_mismatch.rs:12:43
+   |
+LL | const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
+   |                                           ^ expected `char`, found `u8`
+
+error[E0308]: mismatched types
+  --> $DIR/pattern_type_mismatch.rs:12:47
+   |
+LL | const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
+   |                                               ^ expected `char`, found `u8`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type/pattern_types/reverse_range.rs b/tests/ui/type/pattern_types/reverse_range.rs
new file mode 100644
index 00000000000..6a245615f1a
--- /dev/null
+++ b/tests/ui/type/pattern_types/reverse_range.rs
@@ -0,0 +1,14 @@
+//! Check that the range start must be smaller than the range end
+//@ known-bug: unknown
+//@ failure-status: 101
+//@ normalize-stderr: "note: .*\n\n" -> ""
+//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
+//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
+//@ rustc-env:RUST_BACKTRACE=0
+
+#![feature(pattern_types)]
+#![feature(pattern_type_macro)]
+
+use std::pat::pattern_type;
+
+const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) };
diff --git a/tests/ui/type/pattern_types/reverse_range.stderr b/tests/ui/type/pattern_types/reverse_range.stderr
new file mode 100644
index 00000000000..b714ca7d9ab
--- /dev/null
+++ b/tests/ui/type/pattern_types/reverse_range.stderr
@@ -0,0 +1,17 @@
+error[E0601]: `main` function not found in crate `reverse_range`
+  --> $DIR/reverse_range.rs:14:78
+   |
+LL | const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) };
+   |                                                                              ^ consider adding a `main` function to `$DIR/reverse_range.rs`
+
+
+assertion failed: end <= max_value
+error: the compiler unexpectedly panicked. this is a bug.
+
+query stack during panic:
+#0 [eval_to_allocation_raw] const-evaluating + checking `NONE`
+#1 [eval_to_const_value_raw] simplifying constant for the type system `NONE`
+... and 1 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/tests/ui/type/pattern_types/unimplemented_pat.rs b/tests/ui/type/pattern_types/unimplemented_pat.rs
index b2398cec7c9..44851ec1a10 100644
--- a/tests/ui/type/pattern_types/unimplemented_pat.rs
+++ b/tests/ui/type/pattern_types/unimplemented_pat.rs
@@ -1,14 +1,14 @@
 //! This test ensures we do not ICE for unimplemented
-//! patterns unless the feature gate is enabled.
+//! patterns even if the feature gate is enabled.
 
-#![feature(pattern_type_macro)]
+#![feature(pattern_type_macro, pattern_types)]
 
 use std::pat::pattern_type;
 
 type Always = pattern_type!(Option<u32> is Some(_));
-//~^ ERROR: pattern types are unstable
+//~^ ERROR: pattern not supported
 
 type Binding = pattern_type!(Option<u32> is x);
-//~^ ERROR: pattern types are unstable
+//~^ ERROR: pattern not supported
 
 fn main() {}
diff --git a/tests/ui/type/pattern_types/unimplemented_pat.stderr b/tests/ui/type/pattern_types/unimplemented_pat.stderr
index 7b0f9cbaa6a..a1e55ed02c4 100644
--- a/tests/ui/type/pattern_types/unimplemented_pat.stderr
+++ b/tests/ui/type/pattern_types/unimplemented_pat.stderr
@@ -1,23 +1,14 @@
-error[E0658]: pattern types are unstable
-  --> $DIR/unimplemented_pat.rs:8:15
+error: pattern not supported in pattern types
+  --> $DIR/unimplemented_pat.rs:8:44
    |
 LL | type Always = pattern_type!(Option<u32> is Some(_));
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
-   = help: add `#![feature(pattern_types)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   |                                            ^^^^^^^
 
-error[E0658]: pattern types are unstable
-  --> $DIR/unimplemented_pat.rs:11:16
+error: pattern not supported in pattern types
+  --> $DIR/unimplemented_pat.rs:11:45
    |
 LL | type Binding = pattern_type!(Option<u32> is x);
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
-   = help: add `#![feature(pattern_types)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   |                                             ^
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/type/pattern_types/validity.rs b/tests/ui/type/pattern_types/validity.rs
new file mode 100644
index 00000000000..77a4e72f675
--- /dev/null
+++ b/tests/ui/type/pattern_types/validity.rs
@@ -0,0 +1,37 @@
+//! Check that pattern types have their validity checked
+
+#![feature(pattern_types)]
+#![feature(pattern_type_macro)]
+
+use std::pat::pattern_type;
+
+const BAD: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) };
+//~^ ERROR: it is undefined behavior to use this value
+
+const BAD_UNINIT: pattern_type!(u32 is 1..) =
+    //~^ ERROR: evaluation of constant value failed
+    unsafe { std::mem::transmute(std::mem::MaybeUninit::<u32>::uninit()) };
+
+const BAD_PTR: pattern_type!(usize is 1..) = unsafe { std::mem::transmute(&42) };
+//~^ ERROR: evaluation of constant value failed
+
+const BAD_AGGREGATE: (pattern_type!(u32 is 1..), u32) = (unsafe { std::mem::transmute(0) }, 0);
+//~^ ERROR: it is undefined behavior to use this value
+
+struct Foo(Bar);
+struct Bar(pattern_type!(u32 is 1..));
+
+const BAD_FOO: Foo = Foo(Bar(unsafe { std::mem::transmute(0) }));
+//~^ ERROR: it is undefined behavior to use this value
+
+const CHAR_UNINIT: pattern_type!(char is 'A'..'Z') =
+    //~^ ERROR: evaluation of constant value failed
+    unsafe { std::mem::transmute(std::mem::MaybeUninit::<u32>::uninit()) };
+
+const CHAR_OOB_PAT: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute('a') };
+//~^ ERROR: it is undefined behavior to use this value
+
+const CHAR_OOB: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute(u32::MAX) };
+//~^ ERROR: it is undefined behavior to use this value
+
+fn main() {}
diff --git a/tests/ui/type/pattern_types/validity.stderr b/tests/ui/type/pattern_types/validity.stderr
new file mode 100644
index 00000000000..5bc18cfba3f
--- /dev/null
+++ b/tests/ui/type/pattern_types/validity.stderr
@@ -0,0 +1,79 @@
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/validity.rs:8:1
+   |
+LL | const BAD: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the raw bytes of the constant (size: 4, align: 4) {
+               00 00 00 00                                     │ ....
+           }
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/validity.rs:11:1
+   |
+LL | const BAD_UNINIT: pattern_type!(u32 is 1..) =
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/validity.rs:15:1
+   |
+LL | const BAD_PTR: pattern_type!(usize is 1..) = unsafe { std::mem::transmute(&42) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer
+   |
+   = help: this code performed an operation that depends on the underlying bytes representing a pointer
+   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/validity.rs:18:1
+   |
+LL | const BAD_AGGREGATE: (pattern_type!(u32 is 1..), u32) = (unsafe { std::mem::transmute(0) }, 0);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the raw bytes of the constant (size: 8, align: 4) {
+               00 00 00 00 00 00 00 00                         │ ........
+           }
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/validity.rs:24:1
+   |
+LL | const BAD_FOO: Foo = Foo(Bar(unsafe { std::mem::transmute(0) }));
+   | ^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the raw bytes of the constant (size: 4, align: 4) {
+               00 00 00 00                                     │ ....
+           }
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/validity.rs:27:1
+   |
+LL | const CHAR_UNINIT: pattern_type!(char is 'A'..'Z') =
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/validity.rs:31:1
+   |
+LL | const CHAR_OOB_PAT: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute('a') };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 97, but expected something in the range 65..=89
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the raw bytes of the constant (size: 4, align: 4) {
+               61 00 00 00                                     │ a...
+           }
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/validity.rs:34:1
+   |
+LL | const CHAR_OOB: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute(u32::MAX) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the raw bytes of the constant (size: 4, align: 4) {
+               ff ff ff ff                                     │ ....
+           }
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/typeck/issue-105946.rs b/tests/ui/typeck/issue-105946.rs
index f53f31138f8..0ee70f9346c 100644
--- a/tests/ui/typeck/issue-105946.rs
+++ b/tests/ui/typeck/issue-105946.rs
@@ -1,4 +1,5 @@
 fn digit() -> str {
+    //~^ ERROR the size for values of type
     return {};
     //~^ ERROR: mismatched types [E0308]
 }
diff --git a/tests/ui/typeck/issue-105946.stderr b/tests/ui/typeck/issue-105946.stderr
index 33d4e0b141a..30fe2000a46 100644
--- a/tests/ui/typeck/issue-105946.stderr
+++ b/tests/ui/typeck/issue-105946.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find value `_y` in this scope
-  --> $DIR/issue-105946.rs:6:10
+  --> $DIR/issue-105946.rs:7:10
    |
 LL |     let [_y..] = [Box::new(1), Box::new(2)];
    |          ^^ not found in this scope
@@ -10,7 +10,7 @@ LL |     let [_y @ ..] = [Box::new(1), Box::new(2)];
    |             +
 
 error[E0658]: `X..` patterns in slices are experimental
-  --> $DIR/issue-105946.rs:6:10
+  --> $DIR/issue-105946.rs:7:10
    |
 LL |     let [_y..] = [Box::new(1), Box::new(2)];
    |          ^^^^
@@ -19,19 +19,28 @@ LL |     let [_y..] = [Box::new(1), Box::new(2)];
    = help: add `#![feature(half_open_range_patterns_in_slices)]` 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[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/issue-105946.rs:1:15
+   |
+LL | fn digit() -> str {
+   |               ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: the return type of a function must have a statically known size
+
 error[E0308]: mismatched types
-  --> $DIR/issue-105946.rs:2:12
+  --> $DIR/issue-105946.rs:3:12
    |
 LL |     return {};
    |            ^^ expected `str`, found `()`
 
 error[E0527]: pattern requires 1 element but array has 2
-  --> $DIR/issue-105946.rs:6:9
+  --> $DIR/issue-105946.rs:7:9
    |
 LL |     let [_y..] = [Box::new(1), Box::new(2)];
    |         ^^^^^^ expected 2 elements
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0308, E0425, E0527, E0658.
-For more information about an error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0277, E0308, E0425, E0527, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/typeck/issue-107775.stderr b/tests/ui/typeck/issue-107775.stderr
index dad7e1581e7..1be26897469 100644
--- a/tests/ui/typeck/issue-107775.stderr
+++ b/tests/ui/typeck/issue-107775.stderr
@@ -6,7 +6,7 @@ LL |         map.insert(1, Struct::do_something);
    |         |
    |         ... which causes `map` to have type `HashMap<{integer}, fn(u8) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}>`
 LL |         Self { map }
-   |                ^^^ expected `HashMap<u16, fn(u8) -> Pin<...>>`, found `HashMap<{integer}, ...>`
+   |                ^^^ expected `HashMap<u16, fn(u8) -> Pin<Box<...>>>`, found `HashMap<{integer}, ...>`
    |
    = note: expected struct `HashMap<u16, fn(_) -> Pin<Box<(dyn Future<Output = ()> + Send + 'static)>>>`
               found struct `HashMap<{integer}, fn(_) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}>`
diff --git a/tests/ui/typeck/issue-43189.rs b/tests/ui/typeck/issue-43189.rs
index 9c8cc70e63a..ee0fe15eeba 100644
--- a/tests/ui/typeck/issue-43189.rs
+++ b/tests/ui/typeck/issue-43189.rs
@@ -1,7 +1,6 @@
 // Issue 46112: An extern crate pub re-exporting libcore was causing
 // paths rooted from `std` to be misrendered in the diagnostic output.
 
-//@ ignore-windows
 //@ aux-build:xcrate-issue-43189-a.rs
 //@ aux-build:xcrate-issue-43189-b.rs
 
diff --git a/tests/ui/typeck/issue-43189.stderr b/tests/ui/typeck/issue-43189.stderr
index 8432cbeca2a..3cc1ba9ddfe 100644
--- a/tests/ui/typeck/issue-43189.stderr
+++ b/tests/ui/typeck/issue-43189.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `a` found for unit type `()` in the current scope
-  --> $DIR/issue-43189.rs:10:8
+  --> $DIR/issue-43189.rs:9:8
    |
 LL |     ().a();
    |        ^ method not found in `()`
diff --git a/tests/ui/typeck/issue-46112.rs b/tests/ui/typeck/issue-46112.rs
index 4671ddd06c8..cc8029771d6 100644
--- a/tests/ui/typeck/issue-46112.rs
+++ b/tests/ui/typeck/issue-46112.rs
@@ -1,7 +1,6 @@
 // Issue 46112: An extern crate pub re-exporting libcore was causing
 // paths rooted from `std` to be misrendered in the diagnostic output.
 
-//@ ignore-windows
 //@ aux-build:xcrate-issue-46112-rexport-core.rs
 
 extern crate xcrate_issue_46112_rexport_core;
diff --git a/tests/ui/typeck/issue-46112.stderr b/tests/ui/typeck/issue-46112.stderr
index 16beaea75db..9d439d10f1e 100644
--- a/tests/ui/typeck/issue-46112.stderr
+++ b/tests/ui/typeck/issue-46112.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-46112.rs:9:21
+  --> $DIR/issue-46112.rs:8:21
    |
 LL | fn main() { test(Ok(())); }
    |                  -- ^^ expected `Option<()>`, found `()`
@@ -9,7 +9,7 @@ LL | fn main() { test(Ok(())); }
    = note:   expected enum `Option<()>`
            found unit type `()`
 help: the type constructed contains `()` due to the type of the argument passed
-  --> $DIR/issue-46112.rs:9:18
+  --> $DIR/issue-46112.rs:8:18
    |
 LL | fn main() { test(Ok(())); }
    |                  ^^^--^
diff --git a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs
index 7b4f62fea0c..e095850879c 100644
--- a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs
+++ b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs
@@ -5,6 +5,6 @@ fn main() {
     let page_size = page_size::get();
     //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `page_size`
     //~| NOTE use of unresolved module or unlinked crate `page_size`
-    //@[cargo-invoked]~^^^ HELP if you wanted to use a crate named `page_size`, use `cargo add
-    //@[only-rustc]~^^^^ HELP you might be missing a crate named `page_size`
+    //[cargo-invoked]~^^^ HELP if you wanted to use a crate named `page_size`, use `cargo add
+    //[only-rustc]~^^^^ HELP you might be missing a crate named `page_size`
 }
diff --git a/tests/ui/typeck/return_type_containing_closure.rs b/tests/ui/typeck/return_type_containing_closure.rs
index b81cac0a58a..a9bb89bae2d 100644
--- a/tests/ui/typeck/return_type_containing_closure.rs
+++ b/tests/ui/typeck/return_type_containing_closure.rs
@@ -2,7 +2,7 @@
 fn foo() { //~ HELP try adding a return type
     vec!['a'].iter().map(|c| c)
     //~^ ERROR mismatched types [E0308]
-    //~| NOTE expected `()`, found `Map<Iter<'_, char>, ...>`
+    //~| NOTE expected `()`, found `Map<Iter<'_, char>, {closure@...}>`
     //~| NOTE expected unit type `()`
     //~| HELP consider using a semicolon here
 }
diff --git a/tests/ui/typeck/return_type_containing_closure.stderr b/tests/ui/typeck/return_type_containing_closure.stderr
index 3f14650a82c..a60bf79a57b 100644
--- a/tests/ui/typeck/return_type_containing_closure.stderr
+++ b/tests/ui/typeck/return_type_containing_closure.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/return_type_containing_closure.rs:3:5
    |
 LL |     vec!['a'].iter().map(|c| c)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Map<Iter<'_, char>, ...>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Map<Iter<'_, char>, {closure@...}>`
    |
    = note: expected unit type `()`
                  found struct `Map<std::slice::Iter<'_, char>, {closure@$DIR/return_type_containing_closure.rs:3:26: 3:29}>`
diff --git a/tests/ui/unsafe-binders/expr.rs b/tests/ui/unsafe-binders/expr.rs
index 0fe68751f0a..d437d8f8ac0 100644
--- a/tests/ui/unsafe-binders/expr.rs
+++ b/tests/ui/unsafe-binders/expr.rs
@@ -1,3 +1,5 @@
+//@ check-pass
+
 #![feature(unsafe_binders)]
 //~^ WARN the feature `unsafe_binders` is incomplete
 
@@ -7,8 +9,6 @@ fn main() {
     unsafe {
     let x = 1;
         let binder: unsafe<'a> &'a i32 = wrap_binder!(&x);
-        //~^ ERROR unsafe binder casts are not fully implemented
         let rx = *unwrap_binder!(binder);
-        //~^ ERROR unsafe binder casts are not fully implemented
     }
 }
diff --git a/tests/ui/unsafe-binders/expr.stderr b/tests/ui/unsafe-binders/expr.stderr
index 78a288e10a3..07026e18e12 100644
--- a/tests/ui/unsafe-binders/expr.stderr
+++ b/tests/ui/unsafe-binders/expr.stderr
@@ -1,5 +1,5 @@
 warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/expr.rs:1:12
+  --> $DIR/expr.rs:3:12
    |
 LL | #![feature(unsafe_binders)]
    |            ^^^^^^^^^^^^^^
@@ -7,17 +7,5 @@ LL | #![feature(unsafe_binders)]
    = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/expr.rs:9:55
-   |
-LL |         let binder: unsafe<'a> &'a i32 = wrap_binder!(&x);
-   |                                                       ^^
-
-error: unsafe binder casts are not fully implemented
-  --> $DIR/expr.rs:11:34
-   |
-LL |         let rx = *unwrap_binder!(binder);
-   |                                  ^^^^^^
-
-error: aborting due to 2 previous errors; 1 warning emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/unsafe-binders/mismatch.rs b/tests/ui/unsafe-binders/mismatch.rs
index 731fe2d1ce9..840d938cbe9 100644
--- a/tests/ui/unsafe-binders/mismatch.rs
+++ b/tests/ui/unsafe-binders/mismatch.rs
@@ -5,38 +5,31 @@ use std::unsafe_binder::{wrap_binder, unwrap_binder};
 
 fn a() {
     let _: unsafe<'a> &'a i32 = wrap_binder!(&());
-    //~^ ERROR unsafe binder casts are not fully implemented
-    //~| ERROR mismatched types
+    //~^ ERROR mismatched types
 }
 
 fn b() {
     let _: i32 = wrap_binder!(&());
-    //~^ ERROR unsafe binder casts are not fully implemented
-    //~| ERROR `wrap_binder!()` can only wrap into unsafe binder
+    //~^ ERROR `wrap_binder!()` can only wrap into unsafe binder
 }
 
 fn c() {
     let y = 1;
     unwrap_binder!(y);
-    //~^ ERROR unsafe binder casts are not fully implemented
-    //~| ERROR expected unsafe binder, found integer as input
+    //~^ ERROR expected unsafe binder, found integer as input
 }
 
 fn d() {
     let unknown = Default::default();
+    //~^ ERROR type annotations needed
     unwrap_binder!(unknown);
-    //~^ ERROR unsafe binder casts are not fully implemented
-    // FIXME(unsafe_binders): This should report ambiguity once we've removed
-    // the error above which taints the infcx.
 }
 
 fn e() {
     let x = wrap_binder!(&42);
-    //~^ ERROR unsafe binder casts are not fully implemented
+    //~^ ERROR type annotations needed
     // Currently, type inference doesn't flow backwards for unsafe binders.
     // It could, perhaps, but that may cause even more surprising corners.
-    // FIXME(unsafe_binders): This should report ambiguity once we've removed
-    // the error above which taints the infcx.
     let _: unsafe<'a> &'a i32 = x;
 }
 
diff --git a/tests/ui/unsafe-binders/mismatch.stderr b/tests/ui/unsafe-binders/mismatch.stderr
index a720e5dbdc1..f64db92eb65 100644
--- a/tests/ui/unsafe-binders/mismatch.stderr
+++ b/tests/ui/unsafe-binders/mismatch.stderr
@@ -7,12 +7,6 @@ LL | #![feature(unsafe_binders)]
    = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:7:46
-   |
-LL |     let _: unsafe<'a> &'a i32 = wrap_binder!(&());
-   |                                              ^^^
-
 error[E0308]: mismatched types
   --> $DIR/mismatch.rs:7:46
    |
@@ -22,14 +16,8 @@ LL |     let _: unsafe<'a> &'a i32 = wrap_binder!(&());
    = note: expected reference `&i32`
               found reference `&()`
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:13:31
-   |
-LL |     let _: i32 = wrap_binder!(&());
-   |                               ^^^
-
 error: `wrap_binder!()` can only wrap into unsafe binder, not `i32`
-  --> $DIR/mismatch.rs:13:18
+  --> $DIR/mismatch.rs:12:18
    |
 LL |     let _: i32 = wrap_binder!(&());
    |                  ^^^^^^^^^^^^^^^^^
@@ -37,32 +25,35 @@ LL |     let _: i32 = wrap_binder!(&());
    = note: unsafe binders are the only valid output of wrap
    = note: this error originates in the macro `wrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:20:20
-   |
-LL |     unwrap_binder!(y);
-   |                    ^
-
 error: expected unsafe binder, found integer as input of `unwrap_binder!()`
-  --> $DIR/mismatch.rs:20:20
+  --> $DIR/mismatch.rs:18:20
    |
 LL |     unwrap_binder!(y);
    |                    ^
    |
    = note: only an unsafe binder type can be unwrapped
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:27:20
+error[E0282]: type annotations needed
+  --> $DIR/mismatch.rs:23:9
    |
+LL |     let unknown = Default::default();
+   |         ^^^^^^^
+LL |
 LL |     unwrap_binder!(unknown);
-   |                    ^^^^^^^
+   |                    ------- type must be known at this point
+   |
+help: consider giving `unknown` an explicit type
+   |
+LL |     let unknown: /* Type */ = Default::default();
+   |                ++++++++++++
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:34:26
+error[E0282]: type annotations needed
+  --> $DIR/mismatch.rs:29:26
    |
 LL |     let x = wrap_binder!(&42);
-   |                          ^^^
+   |                          ^^^ cannot infer type
 
-error: aborting due to 8 previous errors; 1 warning emitted
+error: aborting due to 5 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0282, E0308.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/unsafe-binders/moves.rs b/tests/ui/unsafe-binders/moves.rs
new file mode 100644
index 00000000000..5bfcee62402
--- /dev/null
+++ b/tests/ui/unsafe-binders/moves.rs
@@ -0,0 +1,41 @@
+//@ known-bug: unknown
+
+#![feature(unsafe_binders)]
+// FIXME(unsafe_binders) ~^ WARN the feature `unsafe_binders` is incomplete
+
+use std::unsafe_binder::{wrap_binder, unwrap_binder};
+use std::mem::{drop, ManuallyDrop};
+
+struct NotCopyInner;
+type NotCopy = ManuallyDrop<NotCopyInner>;
+
+fn use_after_wrap() {
+    unsafe {
+        let base = NotCopy;
+        let binder: unsafe<> NotCopy = wrap_binder!(base);
+        drop(base);
+        // FIXME(unsafe_binders) ~^ ERROR use of moved value: `base`
+    }
+}
+
+fn move_out_of_wrap() {
+    unsafe {
+        let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
+        drop(unwrap_binder!(binder));
+        drop(unwrap_binder!(binder));
+        // FIXME(unsafe_binders) ~^ ERROR use of moved value: `binder`
+    }
+}
+
+fn not_conflicting() {
+    unsafe {
+        let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
+        drop(unwrap_binder!(binder).0);
+        drop(unwrap_binder!(binder).1);
+        // ^ NOT a problem.
+        drop(unwrap_binder!(binder).0);
+        // FIXME(unsafe_binders) ~^ ERROR use of moved value: `binder.0`
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/unsafe-binders/moves.stderr b/tests/ui/unsafe-binders/moves.stderr
new file mode 100644
index 00000000000..ca507964008
--- /dev/null
+++ b/tests/ui/unsafe-binders/moves.stderr
@@ -0,0 +1,85 @@
+error[E0423]: expected value, found type alias `NotCopy`
+  --> $DIR/moves.rs:14:20
+   |
+LL |         let base = NotCopy;
+   |                    ^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+error[E0423]: expected value, found type alias `NotCopy`
+  --> $DIR/moves.rs:23:53
+   |
+LL |         let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
+   |                                                     ^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+error[E0423]: expected value, found type alias `NotCopy`
+  --> $DIR/moves.rs:32:65
+   |
+LL |         let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
+   |                                                                 ^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+error[E0423]: expected value, found type alias `NotCopy`
+  --> $DIR/moves.rs:32:74
+   |
+LL |         let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
+   |                                                                          ^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/moves.rs:3:12
+   |
+LL | #![feature(unsafe_binders)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
+  --> $DIR/moves.rs:15:21
+   |
+LL |         let binder: unsafe<> NotCopy = wrap_binder!(base);
+   |                     ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
+   |
+   = note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
+help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct NotCopyInner;
+   |
+
+error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
+  --> $DIR/moves.rs:23:21
+   |
+LL |         let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
+   |                     ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
+   |
+   = note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
+help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct NotCopyInner;
+   |
+
+error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
+  --> $DIR/moves.rs:32:21
+   |
+LL |         let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
+   |
+   = note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
+   = note: required because it appears within the type `(ManuallyDrop<NotCopyInner>, ManuallyDrop<NotCopyInner>)`
+help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct NotCopyInner;
+   |
+
+error: aborting due to 7 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0277, E0423.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized/box-instead-of-dyn-fn.rs b/tests/ui/unsized/box-instead-of-dyn-fn.rs
index 321c2ebf5a1..720176081d6 100644
--- a/tests/ui/unsized/box-instead-of-dyn-fn.rs
+++ b/tests/ui/unsized/box-instead-of-dyn-fn.rs
@@ -3,7 +3,7 @@ use std::fmt::Debug;
 // Test to suggest boxing the return type, and the closure branch of the `if`
 
 fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> dyn Fn() + 'a {
-    //~^ ERROR return type cannot have an unboxed trait object
+    //~^ ERROR return type cannot be a trait object without pointer indirection
     if a % 2 == 0 {
         move || println!("{a}")
     } else {
diff --git a/tests/ui/unsized/box-instead-of-dyn-fn.stderr b/tests/ui/unsized/box-instead-of-dyn-fn.stderr
index 1f1845569ef..1836d5dfffe 100644
--- a/tests/ui/unsized/box-instead-of-dyn-fn.stderr
+++ b/tests/ui/unsized/box-instead-of-dyn-fn.stderr
@@ -1,4 +1,4 @@
-error[E0746]: return type cannot have an unboxed trait object
+error[E0746]: return type cannot be a trait object without pointer indirection
   --> $DIR/box-instead-of-dyn-fn.rs:5:56
    |
 LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> dyn Fn() + 'a {
diff --git a/tests/ui/unsized/issue-91801.rs b/tests/ui/unsized/issue-91801.rs
index 096b1a93574..d906a08a55a 100644
--- a/tests/ui/unsized/issue-91801.rs
+++ b/tests/ui/unsized/issue-91801.rs
@@ -6,7 +6,7 @@ pub static ALL_VALIDATORS: &[(&'static str, &'static Validator)] =
     &[("validate that credits and debits balance", &validate_something)];
 
 fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> {
-    //~^ ERROR return type cannot have an unboxed trait object
+    //~^ ERROR return type cannot be a trait object without pointer indirection
     return Box::new(move |something: &'_ Something| -> Result<(), ()> {
         first(something).or_else(|_| second(something))
     });
diff --git a/tests/ui/unsized/issue-91801.stderr b/tests/ui/unsized/issue-91801.stderr
index e13cabbb81d..28e10f9caa4 100644
--- a/tests/ui/unsized/issue-91801.stderr
+++ b/tests/ui/unsized/issue-91801.stderr
@@ -1,4 +1,4 @@
-error[E0746]: return type cannot have an unboxed trait object
+error[E0746]: return type cannot be a trait object without pointer indirection
   --> $DIR/issue-91801.rs:8:77
    |
 LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> {
diff --git a/tests/ui/unsized/issue-91803.rs b/tests/ui/unsized/issue-91803.rs
index c74897cc4bc..8d35c7582b8 100644
--- a/tests/ui/unsized/issue-91803.rs
+++ b/tests/ui/unsized/issue-91803.rs
@@ -1,7 +1,7 @@
 trait Foo<'a> {}
 
 fn or<'a>(first: &'static dyn Foo<'a>) -> dyn Foo<'a> {
-    //~^ ERROR return type cannot have an unboxed trait object
+    //~^ ERROR return type cannot be a trait object without pointer indirection
     return Box::new(panic!());
 }
 
diff --git a/tests/ui/unsized/issue-91803.stderr b/tests/ui/unsized/issue-91803.stderr
index 3b89066499d..e0fde4b1c1b 100644
--- a/tests/ui/unsized/issue-91803.stderr
+++ b/tests/ui/unsized/issue-91803.stderr
@@ -1,4 +1,4 @@
-error[E0746]: return type cannot have an unboxed trait object
+error[E0746]: return type cannot be a trait object without pointer indirection
   --> $DIR/issue-91803.rs:3:43
    |
 LL | fn or<'a>(first: &'static dyn Foo<'a>) -> dyn Foo<'a> {
diff --git a/tests/ui/where-clauses/ignore-err-clauses.rs b/tests/ui/where-clauses/ignore-err-clauses.rs
index c76f0e1a8b2..428ebf4b408 100644
--- a/tests/ui/where-clauses/ignore-err-clauses.rs
+++ b/tests/ui/where-clauses/ignore-err-clauses.rs
@@ -1,6 +1,7 @@
 use std::ops::Add;
 
 fn dbl<T>(x: T) -> <T as Add>::Output
+//~^ ERROR type annotations needed
 where
     T: Copy + Add,
     UUU: Copy,
diff --git a/tests/ui/where-clauses/ignore-err-clauses.stderr b/tests/ui/where-clauses/ignore-err-clauses.stderr
index 4cf553da4c5..fbf1b99334f 100644
--- a/tests/ui/where-clauses/ignore-err-clauses.stderr
+++ b/tests/ui/where-clauses/ignore-err-clauses.stderr
@@ -1,9 +1,16 @@
 error[E0412]: cannot find type `UUU` in this scope
-  --> $DIR/ignore-err-clauses.rs:6:5
+  --> $DIR/ignore-err-clauses.rs:7:5
    |
 LL |     UUU: Copy,
    |     ^^^ not found in this scope
 
-error: aborting due to 1 previous error
+error[E0282]: type annotations needed
+  --> $DIR/ignore-err-clauses.rs:3:14
+   |
+LL | fn dbl<T>(x: T) -> <T as Add>::Output
+   |              ^ cannot infer type for type parameter `T`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0282, E0412.
+For more information about an error, try `rustc --explain E0282`.