about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--Cargo.lock55
-rw-r--r--compiler/rustc_abi/src/canon_abi.rs19
-rw-r--r--compiler/rustc_abi/src/extern_abi.rs99
-rw-r--r--compiler/rustc_abi/src/layout.rs20
-rw-r--r--compiler/rustc_abi/src/layout/ty.rs15
-rw-r--r--compiler/rustc_abi/src/lib.rs100
-rw-r--r--compiler/rustc_ast/src/ast.rs9
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs2
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs796
-rw-r--r--compiler/rustc_ast/src/ptr.rs210
-rw-r--r--compiler/rustc_ast/src/visit.rs1554
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs10
-rw-r--r--compiler/rustc_attr_data_structures/src/attributes.rs44
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/mod.rs2
-rw-r--r--compiler/rustc_attr_parsing/src/lib.rs72
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs22
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/pattern_type.rs20
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs36
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs13
-rw-r--r--compiler/rustc_codegen_cranelift/example/neon.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs16
-rw-r--r--compiler/rustc_codegen_cranelift/src/inline_asm.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs10
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs10
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs40
-rw-r--r--compiler/rustc_codegen_cranelift/src/main_shim.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/num.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/unsize.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/vtable.rs5
-rw-r--r--compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_gcc/example/alloc_system.rs1
-rw-r--r--compiler/rustc_codegen_gcc/messages.ftl3
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs10
-rw-r--r--compiler/rustc_codegen_gcc/src/errors.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_llvm/messages.ftl6
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs38
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs33
-rw-r--r--compiler/rustc_codegen_ssa/src/common.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs328
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/size_of_val.rs3
-rw-r--r--compiler/rustc_const_eval/messages.ftl8
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs7
-rw-r--r--compiler/rustc_const_eval/src/check_consts/ops.rs6
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs4
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs21
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs4
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs9
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/discriminant.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs15
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs15
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs18
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/traits.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/visitor.rs21
-rw-r--r--compiler/rustc_const_eval/src/util/caller_location.rs14
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/vec_cache.rs30
-rw-r--r--compiler/rustc_data_structures/src/vec_cache/tests.rs19
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0092.md15
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0093.md17
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0622.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0783.md2
-rw-r--r--compiler/rustc_error_messages/Cargo.toml1
-rw-r--r--compiler/rustc_error_messages/src/lib.rs6
-rw-r--r--compiler/rustc_errors/src/lib.rs4
-rw-r--r--compiler/rustc_expand/messages.ftl1
-rw-r--r--compiler/rustc_expand/src/base.rs2
-rw-r--r--compiler/rustc_expand/src/config.rs11
-rw-r--r--compiler/rustc_expand/src/errors.rs4
-rw-r--r--compiler/rustc_expand/src/expand.rs37
-rw-r--r--compiler/rustc_expand/src/lib.rs1
-rw-r--r--compiler/rustc_feature/src/accepted.rs4
-rw-r--r--compiler/rustc_feature/src/removed.rs184
-rw-r--r--compiler/rustc_feature/src/unstable.rs4
-rw-r--r--compiler/rustc_fluent_macro/src/lib.rs1
-rw-r--r--compiler/rustc_hir/src/def.rs7
-rw-r--r--compiler/rustc_hir/src/hir.rs74
-rw-r--r--compiler/rustc_hir/src/hir/tests.rs2
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_hir_analysis/Cargo.toml1
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl4
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs125
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs959
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs35
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs90
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs9
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl63
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs112
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs184
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/inline_asm.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/loops.rs (renamed from compiler/rustc_passes/src/loops.rs)39
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/naked_functions.rs (renamed from compiler/rustc_passes/src/naked_functions.rs)77
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs7
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/table.rs2
-rw-r--r--compiler/rustc_infer/src/lib.rs1
-rw-r--r--compiler/rustc_interface/src/interface.rs5
-rw-r--r--compiler/rustc_interface/src/passes.rs9
-rw-r--r--compiler/rustc_interface/src/util.rs21
-rw-r--r--compiler/rustc_lexer/src/cursor.rs2
-rw-r--r--compiler/rustc_lexer/src/lib.rs20
-rw-r--r--compiler/rustc_lint/messages.ftl27
-rw-r--r--compiler/rustc_lint/src/autorefs.rs4
-rw-r--r--compiler/rustc_lint/src/builtin.rs5
-rw-r--r--compiler/rustc_lint/src/early/diagnostics.rs17
-rw-r--r--compiler/rustc_lint/src/lib.rs5
-rw-r--r--compiler/rustc_lint/src/lifetime_syntax.rs503
-rw-r--r--compiler/rustc_lint/src/lints.rs181
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs81
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs12
-rw-r--r--compiler/rustc_macros/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/messages.ftl9
-rw-r--r--compiler/rustc_metadata/src/errors.rs11
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs12
-rw-r--r--compiler/rustc_middle/src/error.rs2
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs9
-rw-r--r--compiler/rustc_middle/src/lib.rs2
-rw-r--r--compiler/rustc_middle/src/middle/lang_items.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs26
-rw-r--r--compiler/rustc_middle/src/mir/statement.rs2
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs9
-rw-r--r--compiler/rustc_middle/src/ty/adjustment.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs22
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs6
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs14
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs2
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs2
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/into.rs2
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/test.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs7
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs7
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs31
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/drop.rs39
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs7
-rw-r--r--compiler/rustc_mir_transform/src/early_otherwise_branch.rs32
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drop.rs13
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs8
-rw-r--r--compiler/rustc_mir_transform/src/jump_threading.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs3
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs2
-rw-r--r--compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs12
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs50
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs4
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs2
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs10
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs105
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs13
-rw-r--r--compiler/rustc_parse/src/lib.rs1
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs4
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs8
-rw-r--r--compiler/rustc_parse/src/parser/item.rs4
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs2
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs26
-rw-r--r--compiler/rustc_passes/messages.ftl59
-rw-r--r--compiler/rustc_passes/src/check_attr.rs38
-rw-r--r--compiler/rustc_passes/src/dead.rs13
-rw-r--r--compiler/rustc_passes/src/errors.rs180
-rw-r--r--compiler/rustc_passes/src/lang_items.rs20
-rw-r--r--compiler/rustc_passes/src/lib.rs8
-rw-r--r--compiler/rustc_query_system/src/lib.rs1
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs53
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs9
-rw-r--r--compiler/rustc_resolve/src/late.rs61
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs4
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs8
-rw-r--r--compiler/rustc_session/src/filesearch.rs62
-rw-r--r--compiler/rustc_session/src/session.rs6
-rw-r--r--compiler/rustc_span/src/lib.rs1
-rw-r--r--compiler/rustc_span/src/symbol.rs16
-rw-r--r--compiler/rustc_target/Cargo.toml2
-rw-r--r--compiler/rustc_target/src/asm/mod.rs14
-rw-r--r--compiler/rustc_target/src/callconv/mod.rs4
-rw-r--r--compiler/rustc_target/src/lib.rs2
-rw-r--r--compiler/rustc_target/src/spec/abi_map.rs4
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs8
-rw-r--r--compiler/rustc_target/src/spec/json.rs21
-rw-r--r--compiler/rustc_target/src/spec/mod.rs13
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs9
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs29
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs30
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs4
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs4
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/target_features.rs16
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs6
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs26
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs2
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs8
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/delegate.rs21
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs86
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalize.rs91
-rw-r--r--compiler/rustc_trait_selection/src/solve/select.rs30
-rw-r--r--compiler/rustc_trait_selection/src/traits/effects.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs34
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_normalize.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs4
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs13
-rw-r--r--compiler/rustc_ty_utils/src/common_traits.rs3
-rw-r--r--compiler/rustc_ty_utils/src/structural_match.rs3
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs4
-rw-r--r--compiler/rustc_type_ir/src/canonical.rs9
-rw-r--r--compiler/rustc_type_ir/src/interner.rs9
-rw-r--r--library/Cargo.lock5
-rw-r--r--library/Cargo.toml1
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/slice.rs2
-rw-r--r--library/alloc/src/str.rs4
-rw-r--r--library/alloctests/lib.rs1
-rw-r--r--library/compiler-builtins/.github/workflows/main.yaml39
-rw-r--r--library/compiler-builtins/.gitignore3
-rw-r--r--library/compiler-builtins/.gitmodules4
-rw-r--r--library/compiler-builtins/Cargo.toml2
-rw-r--r--library/compiler-builtins/README.md2
-rw-r--r--library/compiler-builtins/builtins-test-intrinsics/Cargo.toml4
-rw-r--r--library/compiler-builtins/builtins-test-intrinsics/src/main.rs12
-rw-r--r--library/compiler-builtins/builtins-test/Cargo.toml8
-rw-r--r--library/compiler-builtins/builtins-test/benches/float_cmp.rs43
-rw-r--r--library/compiler-builtins/builtins-test/src/bench.rs4
-rw-r--r--library/compiler-builtins/builtins-test/src/lib.rs78
-rw-r--r--library/compiler-builtins/builtins-test/tests/aeabi_memclr.rs3
-rw-r--r--library/compiler-builtins/builtins-test/tests/aeabi_memcpy.rs3
-rw-r--r--library/compiler-builtins/builtins-test/tests/aeabi_memset.rs3
-rw-r--r--library/compiler-builtins/builtins-test/tests/float_pow.rs2
-rwxr-xr-xlibrary/compiler-builtins/ci/bench-icount.sh33
-rwxr-xr-xlibrary/compiler-builtins/ci/ci-util.py101
-rwxr-xr-xlibrary/compiler-builtins/ci/run.sh149
-rwxr-xr-xlibrary/compiler-builtins/ci/update-musl.sh15
-rw-r--r--library/compiler-builtins/compiler-builtins/CHANGELOG.md15
-rw-r--r--library/compiler-builtins/compiler-builtins/Cargo.toml13
-rw-r--r--library/compiler-builtins/compiler-builtins/build.rs10
-rw-r--r--library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/arm.rs7
-rw-r--r--library/compiler-builtins/compiler-builtins/src/arm_linux.rs40
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/add.rs24
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/cmp.rs25
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/conv.rs28
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/div.rs4
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/mul.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/pow.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/traits.rs4
-rw-r--r--library/compiler-builtins/compiler-builtins/src/float/trunc.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/int/addsub.rs6
-rw-r--r--library/compiler-builtins/compiler-builtins/src/int/big.rs4
-rw-r--r--library/compiler-builtins/compiler-builtins/src/int/leading_zeros.rs64
-rw-r--r--library/compiler-builtins/compiler-builtins/src/int/specialized_div_rem/mod.rs16
-rw-r--r--library/compiler-builtins/compiler-builtins/src/int/trailing_zeros.rs25
-rw-r--r--library/compiler-builtins/compiler-builtins/src/int/traits.rs314
-rw-r--r--library/compiler-builtins/compiler-builtins/src/lib.rs1
-rw-r--r--library/compiler-builtins/compiler-builtins/src/macros.rs4
-rw-r--r--library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs6
-rw-r--r--library/compiler-builtins/compiler-builtins/src/probestack.rs438
-rw-r--r--library/compiler-builtins/crates/josh-sync/Cargo.toml7
-rw-r--r--library/compiler-builtins/crates/josh-sync/src/main.rs45
-rw-r--r--library/compiler-builtins/crates/josh-sync/src/sync.rs371
-rw-r--r--library/compiler-builtins/crates/libm-macros/Cargo.toml4
-rw-r--r--library/compiler-builtins/crates/musl-math-sys/Cargo.toml2
-rw-r--r--library/compiler-builtins/crates/musl-math-sys/build.rs2
m---------library/compiler-builtins/crates/musl-math-sys/musl0
-rw-r--r--library/compiler-builtins/crates/panic-handler/src/lib.rs7
-rw-r--r--library/compiler-builtins/crates/symbol-check/Cargo.toml13
-rw-r--r--library/compiler-builtins/crates/symbol-check/src/main.rs232
-rw-r--r--library/compiler-builtins/libm-test/Cargo.toml16
-rw-r--r--library/compiler-builtins/libm-test/benches/icount.rs102
-rw-r--r--library/compiler-builtins/libm-test/examples/plot_domains.rs2
-rw-r--r--library/compiler-builtins/libm-test/src/generate/edge_cases.rs1
-rw-r--r--library/compiler-builtins/libm-test/src/precision.rs17
-rw-r--r--library/compiler-builtins/libm-test/src/run_cfg.rs74
-rw-r--r--library/compiler-builtins/libm-test/src/test_traits.rs25
-rw-r--r--library/compiler-builtins/libm-test/tests/compare_built_musl.rs2
-rw-r--r--library/compiler-builtins/libm-test/tests/multiprecision.rs2
-rw-r--r--library/compiler-builtins/libm-test/tests/z_extensive/run.rs3
-rw-r--r--library/compiler-builtins/libm/README.md2
-rw-r--r--library/compiler-builtins/libm/src/math/arch/aarch64.rs6
-rw-r--r--library/compiler-builtins/libm/src/math/copysign.rs10
-rw-r--r--library/compiler-builtins/libm/src/math/copysignf.rs8
-rw-r--r--library/compiler-builtins/libm/src/math/copysignf128.rs8
-rw-r--r--library/compiler-builtins/libm/src/math/copysignf16.rs8
-rw-r--r--library/compiler-builtins/libm/src/math/fabsf.rs39
-rw-r--r--library/compiler-builtins/libm/src/math/fabsf128.rs31
-rw-r--r--library/compiler-builtins/libm/src/math/fabsf16.rs31
-rw-r--r--library/compiler-builtins/libm/src/math/fdimf.rs12
-rw-r--r--library/compiler-builtins/libm/src/math/fdimf128.rs12
-rw-r--r--library/compiler-builtins/libm/src/math/fdimf16.rs12
-rw-r--r--library/compiler-builtins/libm/src/math/floorf.rs13
-rw-r--r--library/compiler-builtins/libm/src/math/floorf128.rs7
-rw-r--r--library/compiler-builtins/libm/src/math/floorf16.rs7
-rw-r--r--library/compiler-builtins/libm/src/math/fmodf.rs5
-rw-r--r--library/compiler-builtins/libm/src/math/fmodf128.rs5
-rw-r--r--library/compiler-builtins/libm/src/math/fmodf16.rs5
-rw-r--r--library/compiler-builtins/libm/src/math/generic/fmaximum.rs2
-rw-r--r--library/compiler-builtins/libm/src/math/generic/fmaximum_num.rs11
-rw-r--r--library/compiler-builtins/libm/src/math/generic/fminimum.rs2
-rw-r--r--library/compiler-builtins/libm/src/math/generic/fminimum_num.rs11
-rw-r--r--library/compiler-builtins/libm/src/math/ldexpf.rs4
-rw-r--r--library/compiler-builtins/libm/src/math/ldexpf128.rs4
-rw-r--r--library/compiler-builtins/libm/src/math/ldexpf16.rs4
-rw-r--r--library/compiler-builtins/libm/src/math/roundf.rs5
-rw-r--r--library/compiler-builtins/libm/src/math/roundf128.rs5
-rw-r--r--library/compiler-builtins/libm/src/math/roundf16.rs5
-rw-r--r--library/compiler-builtins/libm/src/math/scalbnf.rs4
-rw-r--r--library/compiler-builtins/libm/src/math/scalbnf128.rs4
-rw-r--r--library/compiler-builtins/libm/src/math/scalbnf16.rs4
-rw-r--r--library/compiler-builtins/libm/src/math/sqrtf.rs15
-rw-r--r--library/compiler-builtins/libm/src/math/sqrtf128.rs5
-rw-r--r--library/compiler-builtins/libm/src/math/sqrtf16.rs11
-rw-r--r--library/compiler-builtins/libm/src/math/support/float_traits.rs1
-rw-r--r--library/compiler-builtins/libm/src/math/support/hex_float.rs207
-rw-r--r--library/compiler-builtins/libm/src/math/support/int_traits.rs15
-rw-r--r--library/compiler-builtins/libm/src/math/support/macros.rs6
-rw-r--r--library/compiler-builtins/libm/src/math/support/mod.rs6
-rw-r--r--library/compiler-builtins/libm/src/math/truncf.rs23
-rw-r--r--library/compiler-builtins/libm/src/math/truncf128.rs7
-rw-r--r--library/compiler-builtins/libm/src/math/truncf16.rs7
-rw-r--r--library/compiler-builtins/rust-version1
-rw-r--r--library/core/Cargo.toml2
-rw-r--r--library/core/src/cell.rs16
-rw-r--r--library/core/src/fmt/num.rs4
-rw-r--r--library/core/src/intrinsics/mod.rs935
-rw-r--r--library/core/src/iter/sources/generator.rs5
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/core/src/macros/mod.rs13
-rw-r--r--library/core/src/num/f128.rs23
-rw-r--r--library/core/src/num/f16.rs25
-rw-r--r--library/core/src/num/f32.rs2
-rw-r--r--library/core/src/num/f64.rs2
-rw-r--r--library/core/src/num/niche_types.rs2
-rw-r--r--library/core/src/num/nonzero.rs34
-rw-r--r--library/core/src/option.rs2
-rw-r--r--library/core/src/pin/unsafe_pinned.rs50
-rw-r--r--library/core/src/ptr/const_ptr.rs64
-rw-r--r--library/core/src/ptr/docs/as_uninit_slice.md44
-rw-r--r--library/core/src/ptr/docs/is_null.md18
-rw-r--r--library/core/src/ptr/mut_ptr.rs68
-rw-r--r--library/core/src/ptr/non_null.rs7
-rw-r--r--library/core/src/slice/ascii.rs2
-rw-r--r--library/core/src/slice/mod.rs1
-rw-r--r--library/core/src/str/mod.rs2
-rw-r--r--library/core/src/sync/atomic.rs280
-rw-r--r--library/coretests/tests/floats/f32.rs9
-rw-r--r--library/coretests/tests/floats/f64.rs2
-rw-r--r--library/coretests/tests/floats/mod.rs548
-rw-r--r--library/coretests/tests/num/dec2flt/float.rs6
-rw-r--r--library/coretests/tests/num/mod.rs362
-rw-r--r--library/coretests/tests/num/niche_types.rs12
-rw-r--r--library/panic_abort/Cargo.toml2
-rw-r--r--library/panic_unwind/Cargo.toml2
-rw-r--r--library/panic_unwind/src/seh.rs12
-rw-r--r--library/rustc-std-workspace-core/Cargo.toml1
-rw-r--r--library/rustc-std-workspace-core/lib.rs4
-rw-r--r--library/std/Cargo.toml4
-rw-r--r--library/std/src/env.rs1
-rw-r--r--library/std/src/ffi/mod.rs2
-rw-r--r--library/std/src/ffi/os_str.rs2
-rw-r--r--library/std/src/fs.rs36
-rw-r--r--library/std/src/io/mod.rs66
-rw-r--r--library/std/src/keyword_docs.rs27
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/num/f128.rs69
-rw-r--r--library/std/src/num/f16.rs67
-rw-r--r--library/std/src/num/f32.rs34
-rw-r--r--library/std/src/num/f64.rs6
-rw-r--r--library/std/src/os/android/net.rs2
-rw-r--r--library/std/src/os/linux/net.rs2
-rw-r--r--library/std/src/os/linux/raw.rs1
-rw-r--r--library/std/src/os/net/linux_ext/mod.rs2
-rw-r--r--library/std/src/os/net/linux_ext/tcp.rs12
-rw-r--r--library/std/src/path.rs2
-rw-r--r--library/std/src/sys/alloc/mod.rs1
-rw-r--r--library/std/src/sys/fs/hermit.rs4
-rw-r--r--library/std/src/sys/fs/solid.rs4
-rw-r--r--library/std/src/sys/fs/uefi.rs4
-rw-r--r--library/std/src/sys/fs/unix.rs9
-rw-r--r--library/std/src/sys/fs/unsupported.rs4
-rw-r--r--library/std/src/sys/fs/wasi.rs4
-rw-r--r--library/std/src/sys/fs/windows.rs8
-rw-r--r--library/std/src/sys/pal/unix/os.rs2
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt1
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs1
-rw-r--r--library/std/src/sys/personality/gcc.rs2
-rw-r--r--library/std/tests/floats/f32.rs33
-rw-r--r--library/std/tests/floats/f64.rs8
-rw-r--r--library/std/tests/path.rs1
-rw-r--r--library/std/tests/sync/mpmc.rs11
-rw-r--r--library/std/tests/sync/mpsc.rs11
m---------library/stdarch0
-rw-r--r--library/unwind/Cargo.toml4
-rw-r--r--library/unwind/src/libunwind.rs2
-rw-r--r--src/bootstrap/bootstrap.py1
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs7
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs3
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs3
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs15
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs9
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs65
-rw-r--r--src/bootstrap/src/core/builder/mod.rs17
-rw-r--r--src/bootstrap/src/core/builder/tests.rs2
-rw-r--r--src/bootstrap/src/core/config/config.rs2261
-rw-r--r--src/bootstrap/src/core/config/flags.rs11
-rw-r--r--src/bootstrap/src/core/config/mod.rs409
-rw-r--r--src/bootstrap/src/core/config/target_selection.rs147
-rw-r--r--src/bootstrap/src/core/config/tests.rs8
-rw-r--r--src/bootstrap/src/core/config/toml/build.rs72
-rw-r--r--src/bootstrap/src/core/config/toml/change_id.rs34
-rw-r--r--src/bootstrap/src/core/config/toml/dist.rs52
-rw-r--r--src/bootstrap/src/core/config/toml/gcc.rs34
-rw-r--r--src/bootstrap/src/core/config/toml/install.rs43
-rw-r--r--src/bootstrap/src/core/config/toml/llvm.rs284
-rw-r--r--src/bootstrap/src/core/config/toml/mod.rs184
-rw-r--r--src/bootstrap/src/core/config/toml/rust.rs664
-rw-r--r--src/bootstrap/src/core/config/toml/target.rs174
-rw-r--r--src/bootstrap/src/core/download.rs77
-rw-r--r--src/bootstrap/src/core/sanity.rs4
-rw-r--r--src/bootstrap/src/lib.rs200
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/channel.rs13
-rw-r--r--src/bootstrap/src/utils/exec.rs16
-rw-r--r--src/bootstrap/src/utils/execution_context.rs202
-rw-r--r--src/bootstrap/src/utils/mod.rs1
-rw-r--r--src/bootstrap/src/utils/render_tests.rs3
-rw-r--r--src/ci/citool/src/jobs.rs6
-rw-r--r--src/ci/citool/src/main.rs1
-rw-r--r--src/ci/citool/tests/jobs.rs24
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile15
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/dist-alt.sh8
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh13
-rw-r--r--src/ci/docker/host-x86_64/mingw-check-2/Dockerfile1
-rwxr-xr-xsrc/ci/docker/scripts/rfl-build.sh3
-rw-r--r--src/ci/github-actions/jobs.yml35
-rwxr-xr-xsrc/ci/run.sh8
-rwxr-xr-xsrc/ci/scripts/checkout-submodules.sh4
-rwxr-xr-xsrc/ci/scripts/create-doc-artifacts.sh3
-rw-r--r--src/doc/rustc-dev-guide/rust-version2
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md4
-rw-r--r--src/doc/rustc-dev-guide/src/autodiff/flags.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/suggested.md8
-rw-r--r--src/doc/rustc-dev-guide/src/coroutine-closures.md28
-rw-r--r--src/doc/rustc-dev-guide/src/getting-started.md4
-rw-r--r--src/doc/rustc-dev-guide/src/normalization.md4
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/about.md14
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md90
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/llvm.md38
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals.md29
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-gui-test-suite.md14
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md3
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md191
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc.md42
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ci.md4
-rw-r--r--src/doc/rustc-dev-guide/src/tests/compiletest.md32
-rw-r--r--src/doc/rustc-dev-guide/src/tests/directives.md15
-rw-r--r--src/doc/rustc-dev-guide/src/tests/minicore.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/running.md4
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ui.md8
-rw-r--r--src/doc/rustc-dev-guide/triagebot.toml17
-rw-r--r--src/doc/rustc/src/platform-support.md40
-rw-r--r--src/doc/rustc/src/platform-support/loongarch-none.md43
-rw-r--r--src/doc/rustdoc/src/write-documentation/the-doc-attribute.md32
-rw-r--r--src/etc/completions/x.fish25
-rw-r--r--src/etc/completions/x.ps123
-rw-r--r--src/etc/completions/x.py.fish25
-rw-r--r--src/etc/completions/x.py.ps123
-rw-r--r--src/etc/completions/x.py.sh46
-rw-r--r--src/etc/completions/x.py.zsh23
-rw-r--r--src/etc/completions/x.sh46
-rw-r--r--src/etc/completions/x.zsh23
-rw-r--r--src/librustdoc/clean/auto_trait.rs4
-rw-r--r--src/librustdoc/clean/blanket_impl.rs6
-rw-r--r--src/librustdoc/clean/cfg.rs1
-rw-r--r--src/librustdoc/clean/inline.rs69
-rw-r--r--src/librustdoc/clean/mod.rs164
-rw-r--r--src/librustdoc/clean/simplify.rs7
-rw-r--r--src/librustdoc/clean/types.rs14
-rw-r--r--src/librustdoc/doctest.rs49
-rw-r--r--src/librustdoc/doctest/extracted.rs5
-rw-r--r--src/librustdoc/doctest/make.rs21
-rw-r--r--src/librustdoc/doctest/markdown.rs2
-rw-r--r--src/librustdoc/doctest/runner.rs11
-rw-r--r--src/librustdoc/doctest/rust.rs29
-rw-r--r--src/librustdoc/doctest/tests.rs68
-rw-r--r--src/librustdoc/html/format.rs45
-rw-r--r--src/librustdoc/html/markdown.rs1
-rw-r--r--src/librustdoc/json/conversions.rs23
-rw-r--r--src/rustdoc-json-types/Cargo.toml3
-rw-r--r--src/rustdoc-json-types/lib.rs2
-rw-r--r--src/tools/build-manifest/src/main.rs4
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.fixed4
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.rs4
-rw-r--r--src/tools/clippy/tests/ui/iter_next_loop.rs2
-rw-r--r--src/tools/clippy/tests/ui/iter_not_returning_iterator.rs2
-rw-r--r--src/tools/clippy/tests/ui/methods.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.rs2
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.rs2
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.stderr25
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs12
-rw-r--r--src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.fixed1
-rw-r--r--src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs1
-rw-r--r--src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr36
-rw-r--r--src/tools/clippy/tests/ui/use_self.fixed2
-rw-r--r--src/tools/clippy/tests/ui/use_self.rs2
-rw-r--r--src/tools/compiletest/src/common.rs1
-rw-r--r--src/tools/compiletest/src/directive-list.rs2
-rw-r--r--src/tools/jsondocck/src/config.rs2
-rw-r--r--src/tools/jsondocck/src/directive.rs232
-rw-r--r--src/tools/jsondocck/src/error.rs4
-rw-r--r--src/tools/jsondocck/src/main.rs251
-rw-r--r--src/tools/miri/Cargo.lock1
-rw-r--r--src/tools/miri/Cargo.toml7
-rw-r--r--src/tools/miri/README.md26
-rw-r--r--src/tools/miri/cargo-miri/Cargo.lock43
-rw-r--r--src/tools/miri/cargo-miri/Cargo.toml2
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs4
-rw-r--r--src/tools/miri/src/bin/miri.rs39
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs29
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs87
-rw-r--r--src/tools/miri/src/diagnostics.rs5
-rw-r--r--src/tools/miri/src/eval.rs15
-rw-r--r--src/tools/miri/src/helpers.rs7
-rw-r--r--src/tools/miri/src/intrinsics/atomic.rs153
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs262
-rw-r--r--src/tools/miri/src/lib.rs5
-rw-r--r--src/tools/miri/src/machine.rs14
-rw-r--r--src/tools/miri/src/math.rs14
-rw-r--r--src/tools/miri/src/shims/alloc.rs12
-rw-r--r--src/tools/miri/src/shims/backtrace.rs18
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs2
-rw-r--r--src/tools/miri/src/shims/native_lib.rs58
-rw-r--r--src/tools/miri/src/shims/panic.rs2
-rw-r--r--src/tools/miri/src/shims/unix/env.rs7
-rw-r--r--src/tools/miri/src/shims/unix/freebsd/sync.rs8
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs113
-rw-r--r--src/tools/miri/src/shims/unix/linux_like/epoll.rs7
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs6
-rw-r--r--src/tools/miri/tests/fail/async-shared-mutable.rs25
-rw-r--r--src/tools/miri/tests/fail/async-shared-mutable.stack.stderr43
-rw-r--r--src/tools/miri/tests/fail/async-shared-mutable.tree.stderr47
-rw-r--r--src/tools/miri/tests/fail/const-ub-checks.stderr2
-rw-r--r--src/tools/miri/tests/fail/erroneous_const2.stderr2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-fs.rs5
-rw-r--r--src/tools/miri/tests/pass/both_borrows/smallvec.rs99
-rw-r--r--src/tools/miri/tests/pass/both_borrows/unsafe_pinned.rs16
-rw-r--r--src/tools/miri/tests/pass/fat_ptr.rs4
-rw-r--r--src/tools/miri/tests/pass/float.rs161
-rw-r--r--src/tools/miri/tests/pass/shims/fs.rs33
-rw-r--r--src/tools/miri/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs2
-rw-r--r--src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs2
-rw-r--r--src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs1
-rw-r--r--src/tools/miri/tests/pass/shims/x86/intrinsics-x86-vpclmulqdq.rs1
-rw-r--r--src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.rs34
-rw-r--r--src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.stderr6
-rw-r--r--src/tools/rust-analyzer/.github/workflows/autopublish.yaml6
-rw-r--r--src/tools/rust-analyzer/.github/workflows/publish-libs.yaml2
-rw-r--r--src/tools/rust-analyzer/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs11
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/db.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs20
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs253
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs48
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/diagnostics.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs379
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs28
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs37
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs102
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs102
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs147
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs77
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs60
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs78
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs14
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/rename.rs200
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs157
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/expand_macro.rs61
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs64
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs15
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs133
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/rename.rs238
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs11
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs7
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/types.rs14
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs8
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/err/0024_many_type_parens.rast15
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast42
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast112
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast46
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rast36
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast30
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast62
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast9
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast31
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0036_fully_qualified.rast31
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast15
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0067_where_for_pred.rast31
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs133
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs137
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs168
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs14
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs10
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs1
-rw-r--r--src/tools/rust-analyzer/crates/syntax/rust.ungram7
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs66
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs23
-rw-r--r--src/tools/rust-analyzer/crates/test-fixture/src/lib.rs69
-rw-r--r--src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md2
-rw-r--r--src/tools/rust-analyzer/editors/code/package-lock.json6
-rw-r--r--src/tools/rust-analyzer/rust-version2
-rw-r--r--src/tools/rustfmt/src/modules.rs2
-rw-r--r--src/tools/rustfmt/src/parse/macros/cfg_if.rs2
-rw-r--r--tests/assembly/targets/targets-elf.rs6
-rw-r--r--tests/crashes/121429.rs14
-rw-r--r--tests/crashes/135863.rs10
-rw-r--r--tests/crashes/139825.rs5
-rw-r--r--tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff5
-rw-r--r--tests/mir-opt/early_otherwise_branch.opt4.EarlyOtherwiseBranch.diff5
-rw-r--r--tests/mir-opt/early_otherwise_branch.opt5.EarlyOtherwiseBranch.diff3
-rw-r--r--tests/mir-opt/early_otherwise_branch.rs33
-rw-r--r--tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff28
-rw-r--r--tests/mir-opt/early_otherwise_branch_3_element_tuple.opt2.EarlyOtherwiseBranch.diff5
-rw-r--r--tests/run-make/atomic-lock-free/atomic_lock_free.rs42
-rw-r--r--tests/run-make/doctests-keep-binaries-2024/rmake.rs17
-rw-r--r--tests/run-make/linker-warning/short-error.txt2
-rw-r--r--tests/rustdoc-ui/const-evalutation-ice.stderr2
-rw-r--r--tests/rustdoc-ui/doctest/dead-code-items.rs116
-rw-r--r--tests/rustdoc-ui/doctest/dead-code-items.stdout146
-rw-r--r--tests/rustdoc-ui/doctest/dead-code-module-2.rs27
-rw-r--r--tests/rustdoc-ui/doctest/dead-code-module-2.stdout35
-rw-r--r--tests/rustdoc-ui/doctest/dead-code-module.rs18
-rw-r--r--tests/rustdoc-ui/doctest/dead-code-module.stdout29
-rw-r--r--tests/rustdoc-ui/doctest/doc-test-attr-pass-module.rs11
-rw-r--r--tests/rustdoc/inline_cross/assoc-const-equality.rs1
-rw-r--r--tests/ui/abi/c-zst.aarch64-darwin.stderr6
-rw-r--r--tests/ui/abi/c-zst.powerpc-linux.stderr6
-rw-r--r--tests/ui/abi/c-zst.s390x-linux.stderr6
-rw-r--r--tests/ui/abi/c-zst.sparc64-linux.stderr6
-rw-r--r--tests/ui/abi/c-zst.x86_64-linux.stderr6
-rw-r--r--tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr6
-rw-r--r--tests/ui/abi/debug.stderr72
-rw-r--r--tests/ui/abi/sysv64-zst.stderr6
-rw-r--r--tests/ui/abi/unsupported.aarch64.stderr213
-rw-r--r--tests/ui/abi/unsupported.arm.stderr205
-rw-r--r--tests/ui/abi/unsupported.i686.stderr54
-rw-r--r--tests/ui/abi/unsupported.riscv32.stderr205
-rw-r--r--tests/ui/abi/unsupported.riscv64.stderr205
-rw-r--r--tests/ui/abi/unsupported.rs158
-rw-r--r--tests/ui/abi/unsupported.x64.stderr173
-rw-r--r--tests/ui/abi/unsupported.x64_win.stderr453
-rw-r--r--tests/ui/array-slice-vec/array_const_index-0.stderr2
-rw-r--r--tests/ui/array-slice-vec/array_const_index-1.stderr2
-rw-r--r--tests/ui/asm/x86_64/evex512-implicit-feature.rs2
-rw-r--r--tests/ui/associated-inherent-types/issue-109299-1.stderr16
-rw-r--r--tests/ui/associated-type-bounds/duplicate.stderr168
-rw-r--r--tests/ui/associated-types/associated-types-impl-redirect.rs2
-rw-r--r--tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs4
-rw-r--r--tests/ui/associated-types/associated-types-normalize-in-bounds.rs22
-rw-r--r--tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs2
-rw-r--r--tests/ui/associated-types/cache/elision.rs2
-rw-r--r--tests/ui/associated-types/project-defer-unification.rs2
-rw-r--r--tests/ui/async-await/async-block-control-flow-static-semantics.stderr32
-rw-r--r--tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr10
-rw-r--r--tests/ui/async-await/drop-track-bad-field-in-fru.stderr10
-rw-r--r--tests/ui/async-await/issue-101715.stderr9
-rw-r--r--tests/ui/async-await/issues/issue-63388-1.rs2
-rw-r--r--tests/ui/async-await/issues/issue-63388-1.stderr13
-rw-r--r--tests/ui/async-await/unnecessary-await.stderr20
-rw-r--r--tests/ui/attributes/attr_unknown_custom_attr.rs (renamed from tests/ui/custom_attribute.rs)2
-rw-r--r--tests/ui/attributes/attr_unknown_custom_attr.stderr (renamed from tests/ui/custom_attribute.stderr)6
-rw-r--r--tests/ui/attributes/crate-name-attr-validation.rs (renamed from tests/ui/crate-name-attr-used.rs)2
-rw-r--r--tests/ui/attributes/crate-name-mismatch.rs (renamed from tests/ui/crate-name-mismatch.rs)2
-rw-r--r--tests/ui/attributes/crate-name-mismatch.stderr (renamed from tests/ui/crate-name-mismatch.stderr)2
-rw-r--r--tests/ui/attributes/custom_attr_multisegment_error.rs (renamed from tests/ui/custom-attribute-multisegment.rs)2
-rw-r--r--tests/ui/attributes/custom_attr_multisegment_error.stderr (renamed from tests/ui/custom-attribute-multisegment.stderr)2
-rw-r--r--tests/ui/borrowck/copy-suggestion-region-vid.fixed2
-rw-r--r--tests/ui/borrowck/copy-suggestion-region-vid.rs2
-rw-r--r--tests/ui/borrowck/issue-81899.stderr2
-rw-r--r--tests/ui/borrowck/issue-88434-minimal-example.stderr2
-rw-r--r--tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr2
-rw-r--r--tests/ui/borrowck/rvalue-borrow-scope-error.rs (renamed from tests/ui/cleanup-rvalue-scopes-cf.rs)14
-rw-r--r--tests/ui/borrowck/rvalue-borrow-scope-error.stderr (renamed from tests/ui/cleanup-rvalue-scopes-cf.stderr)14
-rw-r--r--tests/ui/break-diverging-value.rs37
-rw-r--r--tests/ui/cancel-clean-via-immediate-rvalue-ref.rs9
-rw-r--r--tests/ui/cannot-mutate-captured-non-mut-var.rs15
-rw-r--r--tests/ui/cast/cast-to-slice.stderr18
-rw-r--r--tests/ui/cast/cast-to-unsized-trait-object-suggestion.stderr18
-rw-r--r--tests/ui/char.rs13
-rw-r--r--tests/ui/check-cfg/hrtb-crash.rs7
-rw-r--r--tests/ui/check-cfg/hrtb-crash.stderr13
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr2
-rw-r--r--tests/ui/class-cast-to-trait.rs54
-rw-r--r--tests/ui/class-cast-to-trait.stderr9
-rw-r--r--tests/ui/class-method-missing.rs21
-rw-r--r--tests/ui/class-method-missing.stderr12
-rw-r--r--tests/ui/cleanup-rvalue-for-scope.rs60
-rw-r--r--tests/ui/cleanup-rvalue-scopes.rs128
-rw-r--r--tests/ui/close-over-big-then-small-data.rs39
-rw-r--r--tests/ui/closures/closure-immut-capture-error.rs23
-rw-r--r--tests/ui/closures/closure-immut-capture-error.stderr (renamed from tests/ui/cannot-mutate-captured-non-mut-var.stderr)12
-rw-r--r--tests/ui/codegen/rvalue-mut-ref-box-drop.rs13
-rw-r--r--tests/ui/coercion/issue-73886.stderr3
-rw-r--r--tests/ui/coercion/non-primitive-cast-135412.stderr6
-rw-r--r--tests/ui/coherence/const-errs-dont-conflict-103369.stderr4
-rw-r--r--tests/ui/complex.rs38
-rw-r--r--tests/ui/const-generics/defaults/default-param-wf-concrete.next.stderr2
-rw-r--r--tests/ui/const-generics/defaults/default-param-wf-concrete.old.stderr2
-rw-r--r--tests/ui/const-generics/defaults/wfness.stderr2
-rw-r--r--tests/ui/const-generics/early/invalid-const-arguments.stderr10
-rw-r--r--tests/ui/const-generics/issues/issue-100313.stderr2
-rw-r--r--tests/ui/const-generics/kind_mismatch.stderr20
-rw-r--r--tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr4
-rw-r--r--tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr4
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.full.stderr15
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.min.stderr10
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.rs2
-rw-r--r--tests/ui/const-ptr/forbidden_slices.stderr10
-rw-r--r--tests/ui/const-ptr/out_of_bounds_read.stderr6
-rw-r--r--tests/ui/constructor-lifetime-args.rs26
-rw-r--r--tests/ui/consts/assert-type-intrinsics.stderr6
-rw-r--r--tests/ui/consts/const-array-oob.stderr4
-rw-r--r--tests/ui/consts/const-assert-unchecked-ub.stderr2
-rw-r--r--tests/ui/consts/const-blocks/fn-call-in-non-const.stderr5
-rw-r--r--tests/ui/consts/const-blocks/trait-error.stderr9
-rw-r--r--tests/ui/consts/const-compare-bytes-ub.stderr16
-rw-r--r--tests/ui/consts/const-deref-ptr.stderr2
-rw-r--r--tests/ui/consts/const-err-early.stderr10
-rw-r--r--tests/ui/consts/const-err-enum-discriminant.stderr2
-rw-r--r--tests/ui/consts/const-err-multi.rs8
-rw-r--r--tests/ui/consts/const-err-multi.stderr2
-rw-r--r--tests/ui/consts/const-eval-fail-too-big.stderr2
-rw-r--r--tests/ui/consts/const-eval/assign-to-static-within-other-static.stderr2
-rw-r--r--tests/ui/consts/const-eval/conditional_array_execution.stderr2
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-2.stderr2
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-3.stderr2
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-4.stderr2
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-4b.stderr2
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow2.stderr16
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow2b.stderr16
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow2c.stderr16
-rw-r--r--tests/ui/consts/const-eval/const-eval-query-stack.stderr2
-rw-r--r--tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr58
-rw-r--r--tests/ui/consts/const-eval/const_fn_ptr_fail2.rs4
-rw-r--r--tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr4
-rw-r--r--tests/ui/consts/const-eval/const_panic-normalize-tabs-115498.stderr2
-rw-r--r--tests/ui/consts/const-eval/const_panic.stderr24
-rw-r--r--tests/ui/consts/const-eval/const_panic_2021.stderr20
-rw-r--r--tests/ui/consts/const-eval/const_panic_libcore_bin.stderr6
-rw-r--r--tests/ui/consts/const-eval/const_panic_track_caller.rs2
-rw-r--r--tests/ui/consts/const-eval/const_panic_track_caller.stderr2
-rw-r--r--tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr4
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr2
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr2
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr2
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.stderr8
-rw-r--r--tests/ui/consts/const-eval/index_out_of_bounds.stderr2
-rw-r--r--tests/ui/consts/const-eval/issue-43197.stderr4
-rw-r--r--tests/ui/consts/const-eval/issue-49296.stderr2
-rw-r--r--tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr2
-rw-r--r--tests/ui/consts/const-eval/mod-static-with-const-fn.stderr2
-rw-r--r--tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr2
-rw-r--r--tests/ui/consts/const-eval/panic-assoc-never-type.stderr2
-rw-r--r--tests/ui/consts/const-eval/panic-never-type.stderr2
-rw-r--r--tests/ui/consts/const-eval/parse_ints.stderr4
-rw-r--r--tests/ui/consts/const-eval/partial_ptr_overwrite.stderr2
-rw-r--r--tests/ui/consts/const-eval/raw-pointer-ub.rs10
-rw-r--r--tests/ui/consts/const-eval/raw-pointer-ub.stderr10
-rw-r--r--tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr2
-rw-r--r--tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr2
-rw-r--r--tests/ui/consts/const-eval/shift_overflow.stderr2
-rw-r--r--tests/ui/consts/const-eval/transmute-size-mismatch.rs4
-rw-r--r--tests/ui/consts/const-eval/transmute-size-mismatch.stderr4
-rw-r--r--tests/ui/consts/const-eval/ub-enum-overwrite.stderr2
-rw-r--r--tests/ui/consts/const-eval/ub-enum.stderr18
-rw-r--r--tests/ui/consts/const-eval/ub-invalid-values.rs2
-rw-r--r--tests/ui/consts/const-eval/ub-invalid-values.stderr2
-rw-r--r--tests/ui/consts/const-eval/ub-nonnull.stderr4
-rw-r--r--tests/ui/consts/const-eval/ub-ref-ptr.stderr12
-rw-r--r--tests/ui/consts/const-eval/ub-uninhabit.stderr6
-rw-r--r--tests/ui/consts/const-eval/ub-wide-ptr.stderr12
-rw-r--r--tests/ui/consts/const-eval/ub-write-through-immutable.stderr4
-rw-r--r--tests/ui/consts/const-eval/union-const-eval-field.stderr2
-rw-r--r--tests/ui/consts/const-eval/union-ice.stderr6
-rw-r--r--tests/ui/consts/const-eval/union-ub.32bit.stderr2
-rw-r--r--tests/ui/consts/const-eval/union-ub.64bit.stderr2
-rw-r--r--tests/ui/consts/const-eval/unused-broken-const.stderr2
-rw-r--r--tests/ui/consts/const-eval/unwind-abort.stderr2
-rw-r--r--tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr4
-rw-r--r--tests/ui/consts/const-eval/validation-ice-extern-type-field.stderr2
-rw-r--r--tests/ui/consts/const-external-macro-const-err.stderr2
-rw-r--r--tests/ui/consts/const-fn-in-vec.stderr27
-rw-r--r--tests/ui/consts/const-int-unchecked.stderr98
-rw-r--r--tests/ui/consts/const-len-underflow-separate-spans.next.stderr2
-rw-r--r--tests/ui/consts/const-len-underflow-separate-spans.old.stderr2
-rw-r--r--tests/ui/consts/const-len-underflow-separate-spans.rs2
-rw-r--r--tests/ui/consts/const-len-underflow-subspans.stderr2
-rw-r--r--tests/ui/consts/const-ptr-is-null.stderr2
-rw-r--r--tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr4
-rw-r--r--tests/ui/consts/const-slice-oob.stderr2
-rw-r--r--tests/ui/consts/const-unwrap.stderr4
-rw-r--r--tests/ui/consts/const_refs_to_static_fail.stderr2
-rw-r--r--tests/ui/consts/const_unsafe_unreachable_ub.rs2
-rw-r--r--tests/ui/consts/const_unsafe_unreachable_ub.stderr2
-rw-r--r--tests/ui/consts/control-flow/assert.stderr2
-rw-r--r--tests/ui/consts/copy-intrinsic.stderr8
-rw-r--r--tests/ui/consts/eval-enum.stderr4
-rw-r--r--tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr16
-rw-r--r--tests/ui/consts/issue-32829.stderr2
-rw-r--r--tests/ui/consts/issue-64506.stderr2
-rw-r--r--tests/ui/consts/issue-66693-panic-in-array-len.stderr2
-rw-r--r--tests/ui/consts/issue-66693.stderr4
-rw-r--r--tests/ui/consts/issue-76064.stderr2
-rw-r--r--tests/ui/consts/issue-miri-1910.stderr2
-rw-r--r--tests/ui/consts/large_const_alloc.stderr4
-rw-r--r--tests/ui/consts/miri_unleashed/abi-mismatch.rs2
-rw-r--r--tests/ui/consts/miri_unleashed/abi-mismatch.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/assoc_const.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/box.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/const_refers_to_static.stderr6
-rw-r--r--tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/drop.rs2
-rw-r--r--tests/ui/consts/miri_unleashed/drop.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/extern-static.stderr4
-rw-r--r--tests/ui/consts/miri_unleashed/inline_asm.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/mutable_references.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/mutating_global.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/non_const_fn.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/ptr_arith.stderr4
-rw-r--r--tests/ui/consts/miri_unleashed/tls.stderr4
-rw-r--r--tests/ui/consts/missing_span_in_backtrace.stderr2
-rw-r--r--tests/ui/consts/no-ice-from-static-in-const-issue-52060.stderr2
-rw-r--r--tests/ui/consts/offset_from_ub.stderr28
-rw-r--r--tests/ui/consts/offset_ub.stderr22
-rw-r--r--tests/ui/consts/overflowing-consts.noopt.stderr340
-rw-r--r--tests/ui/consts/overflowing-consts.opt.stderr340
-rw-r--r--tests/ui/consts/overflowing-consts.opt_with_overflow_checks.stderr340
-rw-r--r--tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr2
-rw-r--r--tests/ui/consts/promoted_size_overflow.stderr2
-rw-r--r--tests/ui/consts/qualif-indirect-mutation-fail.stderr4
-rw-r--r--tests/ui/consts/recursive-zst-static.default.stderr2
-rw-r--r--tests/ui/consts/recursive-zst-static.unleash.stderr2
-rw-r--r--tests/ui/consts/recursive.stderr2
-rw-r--r--tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr2
-rw-r--r--tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr2
-rw-r--r--tests/ui/consts/slice-index-overflow-issue-130284.stderr2
-rw-r--r--tests/ui/consts/static_mut_containing_mut_ref2.stderr2
-rw-r--r--tests/ui/consts/static_mut_containing_mut_ref3.stderr2
-rw-r--r--tests/ui/consts/uninhabited-const-issue-61744.rs1
-rw-r--r--tests/ui/consts/uninhabited-const-issue-61744.stderr2
-rw-r--r--tests/ui/consts/write-to-static-mut-in-static.stderr4
-rw-r--r--tests/ui/coroutine/unresolved-ct-var.stderr11
-rw-r--r--tests/ui/cross-crate/auxiliary/method_reexport_aux.rs (renamed from tests/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs)4
-rw-r--r--tests/ui/cross-crate/cross-crate-method-reexport.rs (renamed from tests/ui/crate-method-reexport-grrrrrrr.rs)8
-rw-r--r--tests/ui/default-method-parsing.rs7
-rw-r--r--tests/ui/deprecation/deprecated_no_stack_check.rs2
-rw-r--r--tests/ui/deprecation/deprecated_no_stack_check.stderr4
-rw-r--r--tests/ui/diagnostic-width/command-line-error-format-human.rs (renamed from tests/ui/command-line-diagnostics.rs)3
-rw-r--r--tests/ui/diagnostic-width/command-line-error-format-human.stderr (renamed from tests/ui/command-line-diagnostics.stderr)2
-rw-r--r--tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.rs (renamed from tests/ui/conservative_impl_trait.rs)2
-rw-r--r--tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.stderr (renamed from tests/ui/conservative_impl_trait.stderr)2
-rw-r--r--tests/ui/drop/drop-order-comparisons.e2021.fixed2
-rw-r--r--tests/ui/drop/drop-order-comparisons.rs2
-rw-r--r--tests/ui/drop/drop_order.rs4
-rw-r--r--tests/ui/drop/drop_order_if_let_rescope.rs2
-rw-r--r--tests/ui/drop/for-expr-temporary-drop-scope.rs33
-rw-r--r--tests/ui/drop/issue-2735-2.rs13
-rw-r--r--tests/ui/drop/issue-2735-3.rs11
-rw-r--r--tests/ui/drop/issue-2735.rs12
-rw-r--r--tests/ui/drop/issue-979.rs11
-rw-r--r--tests/ui/drop/or-pattern-drop-order.rs109
-rw-r--r--tests/ui/drop/tail-expr-drop-order.rs4
-rw-r--r--tests/ui/dropck/eager-by-ref-binding-for-guards.rs31
-rw-r--r--tests/ui/dropck/eager-by-ref-binding-for-guards.stderr28
-rw-r--r--tests/ui/dropck/let-else-more-permissive.rs30
-rw-r--r--tests/ui/dropck/let-else-more-permissive.stderr35
-rw-r--r--tests/ui/enum-discriminant/eval-error.stderr2
-rw-r--r--tests/ui/enum/enum-drop-cast-error.rs (renamed from tests/ui/cenum_impl_drop_cast.rs)4
-rw-r--r--tests/ui/enum/enum-drop-cast-error.stderr (renamed from tests/ui/cenum_impl_drop_cast.stderr)2
-rw-r--r--tests/ui/error-codes/E0080.stderr4
-rw-r--r--tests/ui/error-codes/E0092.rs6
-rw-r--r--tests/ui/error-codes/E0092.stderr9
-rw-r--r--tests/ui/error-codes/E0604.stderr11
-rw-r--r--tests/ui/error-codes/E0620.stderr9
-rw-r--r--tests/ui/error-emitter/error-festival.stderr11
-rw-r--r--tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr2
-rw-r--r--tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs2
-rw-r--r--tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr2
-rw-r--r--tests/ui/extern/issue-28324.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-coverage-attribute.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-coverage-attribute.stderr5
-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-sha512_sm_x86.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-sha512_sm_x86.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr2
-rw-r--r--tests/ui/feature-gates/gated-bad-feature.rs1
-rw-r--r--tests/ui/feature-gates/gated-bad-feature.stderr16
-rw-r--r--tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs6
-rw-r--r--tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr20
-rw-r--r--tests/ui/frontmatter/frontmatter-inner-hyphens-1.rs10
-rw-r--r--tests/ui/frontmatter/frontmatter-inner-hyphens-2.rs11
-rw-r--r--tests/ui/future-incompatible-lint-group.rs10
-rw-r--r--tests/ui/future-incompatible-lint-group.stderr40
-rw-r--r--tests/ui/generic-const-items/def-site-eval.fail.stderr2
-rw-r--r--tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr2
-rw-r--r--tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr2
-rw-r--r--tests/ui/generics/export-name-on-generics.fixed2
-rw-r--r--tests/ui/generics/export-name-on-generics.rs2
-rw-r--r--tests/ui/generics/generic-no-mangle.fixed2
-rw-r--r--tests/ui/generics/generic-no-mangle.rs2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs2
-rw-r--r--tests/ui/impl-trait/impl-fn-hrtb-bounds.rs1
-rw-r--r--tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr12
-rw-r--r--tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs1
-rw-r--r--tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr13
-rw-r--r--tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs2
-rw-r--r--tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr12
-rw-r--r--tests/ui/imports/global-path-resolution-drop.rs (renamed from tests/ui/crate-leading-sep.rs)2
-rw-r--r--tests/ui/infinite/infinite-recursion-const-fn.stderr2
-rw-r--r--tests/ui/inline-const/break-inside-inline-const-issue-128604.rs6
-rw-r--r--tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr32
-rw-r--r--tests/ui/inline-const/cross-const-control-flow-125846.stderr20
-rw-r--r--tests/ui/intrinsics/auxiliary/cci_intrinsic.rs11
-rw-r--r--tests/ui/intrinsics/intrinsic-alignment.rs25
-rw-r--r--tests/ui/intrinsics/intrinsic-atomics-cc.rs12
-rw-r--r--tests/ui/intrinsics/intrinsic-atomics.rs40
-rw-r--r--tests/ui/intrinsics/intrinsic-inline-cc.rs9
-rw-r--r--tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr6
-rw-r--r--tests/ui/intrinsics/non-integer-atomic.rs52
-rw-r--r--tests/ui/intrinsics/non-integer-atomic.stderr88
-rw-r--r--tests/ui/issues/issue-16048.stderr8
-rw-r--r--tests/ui/issues/issue-17441.stderr18
-rw-r--r--tests/ui/issues/issue-2502.rs2
-rw-r--r--tests/ui/issues/issue-42552.rs2
-rw-r--r--tests/ui/issues/issue-5708.rs2
-rw-r--r--tests/ui/issues/issue-76191.stderr2
-rw-r--r--tests/ui/lang-items/lang-item-generic-requirements.rs3
-rw-r--r--tests/ui/lang-items/lang-item-generic-requirements.stderr8
-rw-r--r--tests/ui/layout/debug.stderr54
-rw-r--r--tests/ui/layout/enum.stderr2
-rw-r--r--tests/ui/layout/hexagon-enum.stderr30
-rw-r--r--tests/ui/layout/invalid-unsized-const-eval.stderr2
-rw-r--r--tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr2
-rw-r--r--tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr51
-rw-r--r--tests/ui/layout/issue-96185-overaligned-enum.stderr18
-rw-r--r--tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr2
-rw-r--r--tests/ui/layout/thumb-enum.stderr30
-rw-r--r--tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr2
-rw-r--r--tests/ui/layout/unknown-when-no-type-parameter.rs2
-rw-r--r--tests/ui/layout/unknown-when-no-type-parameter.stderr2
-rw-r--r--tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr2
-rw-r--r--tests/ui/layout/zero-sized-array-enum-niche.stderr39
-rw-r--r--tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr2
-rw-r--r--tests/ui/lifetimes/constructor-lifetime-early-binding-error.rs22
-rw-r--r--tests/ui/lifetimes/constructor-lifetime-early-binding-error.stderr (renamed from tests/ui/constructor-lifetime-args.stderr)16
-rw-r--r--tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed1
-rw-r--r--tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs1
-rw-r--r--tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr2
-rw-r--r--tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs1
-rw-r--r--tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs4
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr15
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs (renamed from tests/ui/lint/elided-named-lifetimes/example-from-issue48686.rs)4
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr20
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs27
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr60
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs20
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr38
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs (renamed from tests/ui/lint/elided-named-lifetimes/static.rs)10
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr60
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs315
-rw-r--r--tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr473
-rw-r--r--tests/ui/lifetimes/rvalue-cleanup-shortcircuit.rs (renamed from tests/ui/cleanup-shortcircuit.rs)9
-rw-r--r--tests/ui/lifetimes/rvalue-lifetime-drop-timing.rs104
-rw-r--r--tests/ui/limits/huge-static.stderr4
-rw-r--r--tests/ui/limits/issue-55878.stderr2
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs2
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr37
-rw-r--r--tests/ui/linking/crate-type-invalid-flag-error.rs (renamed from tests/ui/crate_type_flag.rs)2
-rw-r--r--tests/ui/linking/crate-type-invalid-flag-error.stderr (renamed from tests/ui/crate_type_flag.stderr)0
-rw-r--r--tests/ui/lint/dead-code/const-underscore-issue-142104.rs15
-rw-r--r--tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr18
-rw-r--r--tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs27
-rw-r--r--tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr40
-rw-r--r--tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs17
-rw-r--r--tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr34
-rw-r--r--tests/ui/lint/elided-named-lifetimes/static.stderr52
-rw-r--r--tests/ui/lint/force-warn/ice-free.rs9
-rw-r--r--tests/ui/lint/force-warn/ice-free.stderr32
-rw-r--r--tests/ui/lint/implicit_autorefs.fixed53
-rw-r--r--tests/ui/lint/implicit_autorefs.rs53
-rw-r--r--tests/ui/lint/implicit_autorefs.stderr84
-rw-r--r--tests/ui/lint/unused/useless-comment.rs7
-rw-r--r--tests/ui/lint/unused/useless-comment.stderr73
-rw-r--r--tests/ui/loops/issue-43162.stderr12
-rw-r--r--tests/ui/loops/loop-break-never-type-mismatch.rs56
-rw-r--r--tests/ui/loops/loop-break-never-type-mismatch.stderr (renamed from tests/ui/break-diverging-value.stderr)4
-rw-r--r--tests/ui/macros/format-args-temporaries.rs2
-rw-r--r--tests/ui/macros/macro-reexport-removed.rs1
-rw-r--r--tests/ui/macros/macro-reexport-removed.stderr5
-rw-r--r--tests/ui/mir/mir_fat_ptr.rs4
-rw-r--r--tests/ui/mismatched_types/cast-rfc0401.stderr11
-rw-r--r--tests/ui/nll/issue-53570.rs2
-rw-r--r--tests/ui/nll/issue-54556-niconii.rs2
-rw-r--r--tests/ui/nonscalar-cast.stderr8
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-elision.rs2
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-elision.stderr14
-rw-r--r--tests/ui/panics/rvalue-cleanup-during-box-panic.rs (renamed from tests/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs)10
-rw-r--r--tests/ui/privacy/trait-object-method-error.rs20
-rw-r--r--tests/ui/privacy/trait-object-method-error.stderr15
-rw-r--r--tests/ui/query-system/issue-83479.rs1
-rw-r--r--tests/ui/query-system/issue-83479.stderr19
-rw-r--r--tests/ui/recursion/recursive-static-definition.stderr4
-rw-r--r--tests/ui/regions/init-res-into-things.rs2
-rw-r--r--tests/ui/regions/regions-nullary-variant.rs2
-rw-r--r--tests/ui/repeat-expr/copy-check-when-count-inferred-later.stderr9
-rw-r--r--tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr24
-rw-r--r--tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr24
-rw-r--r--tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr24
-rw-r--r--tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr24
-rw-r--r--tests/ui/repr/repr-c-int-dead-variants.stderr24
-rw-r--r--tests/ui/resource-assign-is-not-copy.rs2
-rw-r--r--tests/ui/resource-destruct.rs2
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/temporary-early-drop.rs2
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs2
-rw-r--r--tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs2
-rw-r--r--tests/ui/runtime/deep_recursion.rs (renamed from tests/ui/deep.rs)2
-rw-r--r--tests/ui/rustdoc/doc-test-attr-pass.rs42
-rw-r--r--tests/ui/rustdoc/renamed-features-rustdoc_internals.rs2
-rw-r--r--tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr6
-rw-r--r--tests/ui/self/elision/ignore-non-reference-lifetimes.rs4
-rw-r--r--tests/ui/self/elision/ignore-non-reference-lifetimes.stderr27
-rw-r--r--tests/ui/self/elision/lt-ref-self-async.fixed2
-rw-r--r--tests/ui/self/elision/lt-ref-self-async.rs2
-rw-r--r--tests/ui/self/self_lifetime-async.rs4
-rw-r--r--tests/ui/self/self_lifetime-async.stderr29
-rw-r--r--tests/ui/self/self_lifetime.rs4
-rw-r--r--tests/ui/self/self_lifetime.stderr29
-rw-r--r--tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr2
-rw-r--r--tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr2
-rw-r--r--tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs (renamed from tests/crashes/140571.rs)11
-rw-r--r--tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr21
-rw-r--r--tests/ui/statics/issue-14227.stderr2
-rw-r--r--tests/ui/statics/uninhabited-static.stderr4
-rw-r--r--tests/ui/structs/default-field-values/invalid-const.stderr2
-rw-r--r--tests/ui/suggestions/abi-typo.fixed4
-rw-r--r--tests/ui/suggestions/abi-typo.rs4
-rw-r--r--tests/ui/suggestions/abi-typo.stderr12
-rw-r--r--tests/ui/suggestions/double-reference-ty-in-self-ty.rs12
-rw-r--r--tests/ui/suggestions/double-reference-ty-in-self-ty.stderr19
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs1
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr10
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs1
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr10
-rw-r--r--tests/ui/tag-variant-cast-non-nullary.stderr8
-rw-r--r--tests/ui/test-attrs/custom_test_frameworks_simple.rs (renamed from tests/ui/custom-test-frameworks-simple.rs)2
-rw-r--r--tests/ui/track-diagnostics/track.stderr2
-rw-r--r--tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr34
-rw-r--r--tests/ui/traits/clone-unwind-rc-cleanup.rs (renamed from tests/ui/builtin-clone-unwind.rs)33
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.stderr26
-rw-r--r--tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs1
-rw-r--r--tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr5
-rw-r--r--tests/ui/traits/copy-trait-implicit-copy.rs (renamed from tests/ui/can-copy-pod.rs)6
-rw-r--r--tests/ui/traits/default_method_simple.rs (renamed from tests/ui/default-method-simple.rs)10
-rw-r--r--tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr7
-rw-r--r--tests/ui/traits/trait-impl-missing-method.rs13
-rw-r--r--tests/ui/traits/trait-impl-missing-method.stderr12
-rw-r--r--tests/ui/transmutability/uninhabited.stderr6
-rw-r--r--tests/ui/treat-err-as-bug/err.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr7
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr12
-rw-r--r--tests/ui/type-id-higher-rank-2.rs2
-rw-r--r--tests/ui/type/pattern_types/literals.stderr10
-rw-r--r--tests/ui/type/pattern_types/matching.rs1
-rw-r--r--tests/ui/type/pattern_types/or_patterns.stderr6
-rw-r--r--tests/ui/type/pattern_types/range_patterns.stderr35
-rw-r--r--tests/ui/type/pattern_types/reverse_range.stderr2
-rw-r--r--tests/ui/type/pattern_types/validity.stderr6
-rw-r--r--tests/ui/typeck/issue-114529-illegal-break-with-value.stderr36
-rw-r--r--tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs39
-rw-r--r--tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr14
-rw-r--r--tests/ui/underscore-lifetimes.rs2
-rw-r--r--tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr12
-rw-r--r--triagebot.toml1
1171 files changed, 20203 insertions, 15847 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 81fb39cdc56..e5054a07567 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,6 +11,10 @@ name: CI
 on:
   push:
     branches:
+      # CI on master only serves for caching citool builds for the `calculate_matrix` job.
+      # In order to use GHA cache on PR CI (and auto/try) jobs, we need to write to it
+      # from the default branch.
+      - master
       - auto
       - try
       - try-perf
diff --git a/Cargo.lock b/Cargo.lock
index 43f5f40925b..93abab8469a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -162,7 +162,7 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4"
 dependencies = [
- "object",
+ "object 0.36.7",
 ]
 
 [[package]]
@@ -235,7 +235,7 @@ dependencies = [
  "cfg-if",
  "libc",
  "miniz_oxide",
- "object",
+ "object 0.36.7",
  "rustc-demangle",
  "windows-targets 0.52.6",
 ]
@@ -2326,7 +2326,6 @@ dependencies = [
  "tempfile",
  "tikv-jemalloc-sys",
  "ui_test",
- "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -2509,7 +2508,19 @@ dependencies = [
  "indexmap",
  "memchr",
  "ruzstd",
- "wasmparser 0.222.1",
+]
+
+[[package]]
+name = "object"
+version = "0.37.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6273adb7096cf9ab4335f258e627d8230e69d40d45567d678f552dcec6245215"
+dependencies = [
+ "crc32fast",
+ "hashbrown",
+ "indexmap",
+ "memchr",
+ "wasmparser 0.232.0",
 ]
 
 [[package]]
@@ -3109,7 +3120,7 @@ dependencies = [
  "build_helper",
  "gimli",
  "libc",
- "object",
+ "object 0.36.7",
  "regex",
  "serde_json",
  "similar",
@@ -3118,11 +3129,12 @@ dependencies = [
 
 [[package]]
 name = "rustc-build-sysroot"
-version = "0.5.7"
+version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10edc2e4393515193bd766e2f6c050b0536a68e56f2b6d56c07ababfdc114ff0"
+checksum = "16d115ad7e26e0d1337f64ae6598f758194696afc2e9f34c8a6f24582529c3dc"
 dependencies = [
  "anyhow",
+ "regex",
  "rustc_version",
  "tempfile",
  "walkdir",
@@ -3422,7 +3434,7 @@ dependencies = [
  "itertools",
  "libc",
  "measureme",
- "object",
+ "object 0.37.0",
  "rustc-demangle",
  "rustc_abi",
  "rustc_ast",
@@ -3463,7 +3475,7 @@ dependencies = [
  "either",
  "itertools",
  "libc",
- "object",
+ "object 0.37.0",
  "pathdiff",
  "regex",
  "rustc_abi",
@@ -3640,6 +3652,7 @@ dependencies = [
  "rustc_macros",
  "rustc_serialize",
  "rustc_span",
+ "smallvec",
  "tracing",
  "unic-langid",
 ]
@@ -3786,6 +3799,7 @@ dependencies = [
  "rustc_middle",
  "rustc_session",
  "rustc_span",
+ "rustc_target",
  "rustc_trait_selection",
  "smallvec",
  "tracing",
@@ -4495,7 +4509,7 @@ name = "rustc_target"
 version = "0.0.0"
 dependencies = [
  "bitflags",
- "object",
+ "object 0.37.0",
  "rustc_abi",
  "rustc_data_structures",
  "rustc_fs_util",
@@ -4673,6 +4687,7 @@ dependencies = [
  "bincode",
  "rustc-hash 2.1.1",
  "serde",
+ "serde_derive",
  "serde_json",
 ]
 
@@ -5246,7 +5261,7 @@ checksum = "9e9c1e705f82a260173f3eec93f2ff6d7807f23ad5a8cc2e7316a891733ea7a1"
 dependencies = [
  "gimli",
  "hashbrown",
- "object",
+ "object 0.36.7",
  "tracing",
 ]
 
@@ -5909,15 +5924,6 @@ dependencies = [
 
 [[package]]
 name = "wasmparser"
-version = "0.222.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa210fd1788e6b37a1d1930f3389c48e1d6ebd1a013d34fa4b7f9e3e3bf03146"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "wasmparser"
 version = "0.229.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0cc3b1f053f5d41aa55640a1fa9b6d1b8a9e4418d118ce308d20e24ff3575a8c"
@@ -5941,6 +5947,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "wasmparser"
+version = "0.232.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "917739b33bb1eb0e9a49bcd2637a351931be4578d0cc4d37b908d7a797784fbb"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
 name = "wast"
 version = "230.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_abi/src/canon_abi.rs b/compiler/rustc_abi/src/canon_abi.rs
index 2cf7648a859..03eeb645489 100644
--- a/compiler/rustc_abi/src/canon_abi.rs
+++ b/compiler/rustc_abi/src/canon_abi.rs
@@ -50,18 +50,10 @@ pub enum CanonAbi {
 
 impl fmt::Display for CanonAbi {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.to_erased_extern_abi().as_str().fmt(f)
-    }
-}
-
-impl CanonAbi {
-    /// convert to the ExternAbi that *shares a string* with this CanonAbi
-    ///
-    /// A target-insensitive mapping of CanonAbi to ExternAbi, convenient for "forwarding" impls.
-    /// Importantly, the set of CanonAbi values is a logical *subset* of ExternAbi values,
-    /// so this is injective: if you take an ExternAbi to a CanonAbi and back, you have lost data.
-    const fn to_erased_extern_abi(self) -> ExternAbi {
-        match self {
+        // convert to the ExternAbi that *shares a string* with this CanonAbi.
+        // FIXME: ideally we'd avoid printing `CanonAbi`, and preserve `ExternAbi` everywhere
+        // that we need to generate error messages.
+        let erased_abi = match self {
             CanonAbi::C => ExternAbi::C { unwind: false },
             CanonAbi::Rust => ExternAbi::Rust,
             CanonAbi::RustCold => ExternAbi::RustCold,
@@ -87,7 +79,8 @@ impl CanonAbi {
                 X86Call::Vectorcall => ExternAbi::Vectorcall { unwind: false },
                 X86Call::Win64 => ExternAbi::Win64 { unwind: false },
             },
-        }
+        };
+        erased_abi.as_str().fmt(f)
     }
 }
 
diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs
index c48920e5f1b..0bc1c8a0930 100644
--- a/compiler/rustc_abi/src/extern_abi.rs
+++ b/compiler/rustc_abi/src/extern_abi.rs
@@ -12,66 +12,93 @@ use crate::AbiFromStrErr;
 #[cfg(test)]
 mod tests;
 
-use ExternAbi as Abi;
-
+/// ABI we expect to see within `extern "{abi}"`
 #[derive(Clone, Copy, Debug)]
 #[cfg_attr(feature = "nightly", derive(Encodable, Decodable))]
 pub enum ExternAbi {
-    // Some of the ABIs come first because every time we add a new ABI, we have to re-bless all the
-    // hashing tests. These are used in many places, so giving them stable values reduces test
-    // churn. The specific values are meaningless.
-    Rust,
+    /* universal */
+    /// presumed C ABI for the platform
     C {
         unwind: bool,
     },
-    Cdecl {
+    /// ABI of the "system" interface, e.g. the Win32 API, always "aliasing"
+    System {
         unwind: bool,
     },
-    Stdcall {
+
+    /// that's us!
+    Rust,
+    /// the mostly-unused `unboxed_closures` ABI, effectively now an impl detail unless someone
+    /// puts in the work to make it viable again... but would we need a special ABI?
+    RustCall,
+    /// For things unlikely to be called, where reducing register pressure in
+    /// `extern "Rust"` callers is worth paying extra cost in the callee.
+    /// Stronger than just `#[cold]` because `fn` pointers might be incompatible.
+    RustCold,
+
+    /// Unstable impl detail that directly uses Rust types to describe the ABI to LLVM.
+    /// Even normally-compatible Rust types can become ABI-incompatible with this ABI!
+    Unadjusted,
+
+    /// UEFI ABI, usually an alias of C, but sometimes an arch-specific alias
+    /// and only valid on platforms that have a UEFI standard
+    EfiApi,
+
+    /* arm */
+    /// Arm Architecture Procedure Call Standard, sometimes `ExternAbi::C` is an alias for this
+    Aapcs {
         unwind: bool,
     },
-    Fastcall {
+    /// extremely constrained barely-C ABI for TrustZone
+    CCmseNonSecureCall,
+    /// extremely constrained barely-C ABI for TrustZone
+    CCmseNonSecureEntry,
+
+    /* gpu */
+    /// An entry-point function called by the GPU's host
+    // FIXME: should not be callable from Rust on GPU targets, is for host's use only
+    GpuKernel,
+    /// An entry-point function called by the GPU's host
+    // FIXME: why do we have two of these?
+    PtxKernel,
+
+    /* interrupt */
+    AvrInterrupt,
+    AvrNonBlockingInterrupt,
+    Msp430Interrupt,
+    RiscvInterruptM,
+    RiscvInterruptS,
+    X86Interrupt,
+
+    /* x86 */
+    /// `ExternAbi::C` but spelled funny because x86
+    Cdecl {
         unwind: bool,
     },
-    Vectorcall {
+    /// gnu-stdcall on "unix" and win-stdcall on "windows"
+    Stdcall {
         unwind: bool,
     },
-    Thiscall {
+    /// gnu-fastcall on "unix" and win-fastcall on "windows"
+    Fastcall {
         unwind: bool,
     },
-    Aapcs {
+    /// windows C++ ABI
+    Thiscall {
         unwind: bool,
     },
-    Win64 {
+    /// uses AVX and stuff
+    Vectorcall {
         unwind: bool,
     },
+
+    /* x86_64 */
     SysV64 {
         unwind: bool,
     },
-    PtxKernel,
-    Msp430Interrupt,
-    X86Interrupt,
-    /// An entry-point function called by the GPU's host
-    // FIXME: should not be callable from Rust on GPU targets, is for host's use only
-    GpuKernel,
-    EfiApi,
-    AvrInterrupt,
-    AvrNonBlockingInterrupt,
-    CCmseNonSecureCall,
-    CCmseNonSecureEntry,
-    System {
+    Win64 {
         unwind: bool,
     },
-    RustCall,
-    /// *Not* a stable ABI, just directly use the Rust types to describe the ABI for LLVM. Even
-    /// normally ABI-compatible Rust types can become ABI-incompatible with this ABI!
-    Unadjusted,
-    /// For things unlikely to be called, where reducing register pressure in
-    /// `extern "Rust"` callers is worth paying extra cost in the callee.
-    /// Stronger than just `#[cold]` because `fn` pointers might be incompatible.
-    RustCold,
-    RiscvInterruptM,
-    RiscvInterruptS,
 }
 
 macro_rules! abi_impls {
@@ -224,7 +251,7 @@ pub fn all_names() -> Vec<&'static str> {
 
 impl ExternAbi {
     /// Default ABI chosen for `extern fn` declarations without an explicit ABI.
-    pub const FALLBACK: Abi = Abi::C { unwind: false };
+    pub const FALLBACK: ExternAbi = ExternAbi::C { unwind: false };
 
     pub fn name(self) -> &'static str {
         self.as_str()
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 21fd6be39fa..58a7fcae9f6 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -8,7 +8,7 @@ use rustc_index::bit_set::BitMatrix;
 use tracing::debug;
 
 use crate::{
-    AbiAndPrefAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer,
+    AbiAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer,
     LayoutData, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding,
     Variants, WrappingRange,
 };
@@ -173,13 +173,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             // Non-power-of-two vectors have padding up to the next power-of-two.
             // If we're a packed repr, remove the padding while keeping the alignment as close
             // to a vector as possible.
-            (
-                BackendRepr::Memory { sized: true },
-                AbiAndPrefAlign {
-                    abi: Align::max_aligned_factor(size),
-                    pref: dl.llvmlike_vector_align(size).pref,
-                },
-            )
+            (BackendRepr::Memory { sized: true }, AbiAlign { abi: Align::max_aligned_factor(size) })
         } else {
             (BackendRepr::SimdVector { element: e_repr, count }, dl.llvmlike_vector_align(size))
         };
@@ -435,13 +429,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         }
 
         if let Some(pack) = repr.pack {
-            align = align.min(AbiAndPrefAlign::new(pack));
+            align = align.min(AbiAlign::new(pack));
         }
         // The unadjusted ABI alignment does not include repr(align), but does include repr(pack).
         // See documentation on `LayoutS::unadjusted_abi_align`.
         let unadjusted_abi_align = align.abi;
         if let Some(repr_align) = repr.align {
-            align = align.max(AbiAndPrefAlign::new(repr_align));
+            align = align.max(AbiAlign::new(repr_align));
         }
         // `align` must not be modified after this, or `unadjusted_abi_align` could be inaccurate.
         let align = align;
@@ -1289,7 +1283,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
             let prefix_align =
                 if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align };
-            align = align.max(AbiAndPrefAlign::new(prefix_align));
+            align = align.max(AbiAlign::new(prefix_align));
             offset = prefix_size.align_to(prefix_align);
         }
         for &i in &inverse_memory_index {
@@ -1308,7 +1302,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
 
             // Invariant: offset < dl.obj_size_bound() <= 1<<61
             let field_align = if let Some(pack) = pack {
-                field.align.min(AbiAndPrefAlign::new(pack))
+                field.align.min(AbiAlign::new(pack))
             } else {
                 field.align
             };
@@ -1342,7 +1336,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         // See documentation on `LayoutS::unadjusted_abi_align`.
         let unadjusted_abi_align = align.abi;
         if let Some(repr_align) = repr.align {
-            align = align.max(AbiAndPrefAlign::new(repr_align));
+            align = align.max(AbiAlign::new(repr_align));
         }
         // `align` must not be modified after this point, or `unadjusted_abi_align` could be inaccurate.
         let align = align;
diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs
index 4f43c0e6f8e..bb880a58e52 100644
--- a/compiler/rustc_abi/src/layout/ty.rs
+++ b/compiler/rustc_abi/src/layout/ty.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::intern::Interned;
 use rustc_macros::HashStable_Generic;
 
 use crate::{
-    AbiAndPrefAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche,
+    AbiAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche,
     PointeeInfo, Primitive, Scalar, Size, TargetDataLayout, Variants,
 };
 
@@ -39,6 +39,13 @@ rustc_index::newtype_index! {
     pub struct FieldIdx {}
 }
 
+impl FieldIdx {
+    /// The second field, at index 1.
+    ///
+    /// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.
+    pub const ONE: FieldIdx = FieldIdx::from_u32(1);
+}
+
 rustc_index::newtype_index! {
     /// The *source-order* index of a variant in a type.
     ///
@@ -93,7 +100,7 @@ impl<'a> Layout<'a> {
         self.0.0.largest_niche
     }
 
-    pub fn align(self) -> AbiAndPrefAlign {
+    pub fn align(self) -> AbiAlign {
         self.0.0.align
     }
 
@@ -274,7 +281,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
 
     /// Finds the one field that is not a 1-ZST.
     /// Returns `None` if there are multiple non-1-ZST fields or only 1-ZST-fields.
-    pub fn non_1zst_field<C>(&self, cx: &C) -> Option<(usize, Self)>
+    pub fn non_1zst_field<C>(&self, cx: &C) -> Option<(FieldIdx, Self)>
     where
         Ty: TyAbiInterface<'a, C> + Copy,
     {
@@ -288,7 +295,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
                 // More than one non-1-ZST field.
                 return None;
             }
-            found = Some((field_idx, field));
+            found = Some((FieldIdx::from_usize(field_idx), field));
         }
         found
     }
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 46b7a0c1e77..4268e68b2e4 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -43,7 +43,7 @@ use std::fmt;
 #[cfg(feature = "nightly")]
 use std::iter::Step;
 use std::num::{NonZeroUsize, ParseIntError};
-use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub};
+use std::ops::{Add, AddAssign, Deref, Mul, RangeInclusive, Sub};
 use std::str::FromStr;
 
 use bitflags::bitflags;
@@ -226,22 +226,22 @@ pub const MAX_SIMD_LANES: u64 = 1 << 0xF;
 #[derive(Debug, PartialEq, Eq)]
 pub struct TargetDataLayout {
     pub endian: Endian,
-    pub i1_align: AbiAndPrefAlign,
-    pub i8_align: AbiAndPrefAlign,
-    pub i16_align: AbiAndPrefAlign,
-    pub i32_align: AbiAndPrefAlign,
-    pub i64_align: AbiAndPrefAlign,
-    pub i128_align: AbiAndPrefAlign,
-    pub f16_align: AbiAndPrefAlign,
-    pub f32_align: AbiAndPrefAlign,
-    pub f64_align: AbiAndPrefAlign,
-    pub f128_align: AbiAndPrefAlign,
+    pub i1_align: AbiAlign,
+    pub i8_align: AbiAlign,
+    pub i16_align: AbiAlign,
+    pub i32_align: AbiAlign,
+    pub i64_align: AbiAlign,
+    pub i128_align: AbiAlign,
+    pub f16_align: AbiAlign,
+    pub f32_align: AbiAlign,
+    pub f64_align: AbiAlign,
+    pub f128_align: AbiAlign,
     pub pointer_size: Size,
-    pub pointer_align: AbiAndPrefAlign,
-    pub aggregate_align: AbiAndPrefAlign,
+    pub pointer_align: AbiAlign,
+    pub aggregate_align: AbiAlign,
 
     /// Alignments for vector types.
-    pub vector_align: Vec<(Size, AbiAndPrefAlign)>,
+    pub vector_align: Vec<(Size, AbiAlign)>,
 
     pub instruction_address_space: AddressSpace,
 
@@ -257,22 +257,22 @@ impl Default for TargetDataLayout {
         let align = |bits| Align::from_bits(bits).unwrap();
         TargetDataLayout {
             endian: Endian::Big,
-            i1_align: AbiAndPrefAlign::new(align(8)),
-            i8_align: AbiAndPrefAlign::new(align(8)),
-            i16_align: AbiAndPrefAlign::new(align(16)),
-            i32_align: AbiAndPrefAlign::new(align(32)),
-            i64_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
-            i128_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
-            f16_align: AbiAndPrefAlign::new(align(16)),
-            f32_align: AbiAndPrefAlign::new(align(32)),
-            f64_align: AbiAndPrefAlign::new(align(64)),
-            f128_align: AbiAndPrefAlign::new(align(128)),
+            i1_align: AbiAlign::new(align(8)),
+            i8_align: AbiAlign::new(align(8)),
+            i16_align: AbiAlign::new(align(16)),
+            i32_align: AbiAlign::new(align(32)),
+            i64_align: AbiAlign::new(align(32)),
+            i128_align: AbiAlign::new(align(32)),
+            f16_align: AbiAlign::new(align(16)),
+            f32_align: AbiAlign::new(align(32)),
+            f64_align: AbiAlign::new(align(64)),
+            f128_align: AbiAlign::new(align(128)),
             pointer_size: Size::from_bits(64),
-            pointer_align: AbiAndPrefAlign::new(align(64)),
-            aggregate_align: AbiAndPrefAlign { abi: align(0), pref: align(64) },
+            pointer_align: AbiAlign::new(align(64)),
+            aggregate_align: AbiAlign { abi: align(8) },
             vector_align: vec![
-                (Size::from_bits(64), AbiAndPrefAlign::new(align(64))),
-                (Size::from_bits(128), AbiAndPrefAlign::new(align(128))),
+                (Size::from_bits(64), AbiAlign::new(align(64))),
+                (Size::from_bits(128), AbiAlign::new(align(128))),
             ],
             instruction_address_space: AddressSpace::DATA,
             c_enum_min_size: Integer::I32,
@@ -330,8 +330,7 @@ impl TargetDataLayout {
                     .map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err })
             };
             let abi = parse_bits(s[0], "alignment", cause)?;
-            let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?;
-            Ok(AbiAndPrefAlign { abi: align_from_bits(abi)?, pref: align_from_bits(pref)? })
+            Ok(AbiAlign::new(align_from_bits(abi)?))
         };
 
         let mut dl = TargetDataLayout::default();
@@ -426,7 +425,7 @@ impl TargetDataLayout {
 
     /// psABI-mandated alignment for a vector type, if any
     #[inline]
-    fn cabi_vector_align(&self, vec_size: Size) -> Option<AbiAndPrefAlign> {
+    fn cabi_vector_align(&self, vec_size: Size) -> Option<AbiAlign> {
         self.vector_align
             .iter()
             .find(|(size, _align)| *size == vec_size)
@@ -435,8 +434,8 @@ impl TargetDataLayout {
 
     /// an alignment resembling the one LLVM would pick for a vector
     #[inline]
-    pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAndPrefAlign {
-        self.cabi_vector_align(vec_size).unwrap_or(AbiAndPrefAlign::new(
+    pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAlign {
+        self.cabi_vector_align(vec_size).unwrap_or(AbiAlign::new(
             Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap(),
         ))
     }
@@ -864,25 +863,32 @@ impl Align {
 /// It is of effectively no consequence for layout in structs and on the stack.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 #[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
-pub struct AbiAndPrefAlign {
+pub struct AbiAlign {
     pub abi: Align,
-    pub pref: Align,
 }
 
-impl AbiAndPrefAlign {
+impl AbiAlign {
     #[inline]
-    pub fn new(align: Align) -> AbiAndPrefAlign {
-        AbiAndPrefAlign { abi: align, pref: align }
+    pub fn new(align: Align) -> AbiAlign {
+        AbiAlign { abi: align }
     }
 
     #[inline]
-    pub fn min(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign {
-        AbiAndPrefAlign { abi: self.abi.min(other.abi), pref: self.pref.min(other.pref) }
+    pub fn min(self, other: AbiAlign) -> AbiAlign {
+        AbiAlign { abi: self.abi.min(other.abi) }
     }
 
     #[inline]
-    pub fn max(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign {
-        AbiAndPrefAlign { abi: self.abi.max(other.abi), pref: self.pref.max(other.pref) }
+    pub fn max(self, other: AbiAlign) -> AbiAlign {
+        AbiAlign { abi: self.abi.max(other.abi) }
+    }
+}
+
+impl Deref for AbiAlign {
+    type Target = Align;
+
+    fn deref(&self) -> &Self::Target {
+        &self.abi
     }
 }
 
@@ -945,7 +951,7 @@ impl Integer {
         }
     }
 
-    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
+    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
         use Integer::*;
         let dl = cx.data_layout();
 
@@ -1058,7 +1064,7 @@ impl Float {
         }
     }
 
-    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
+    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
         use Float::*;
         let dl = cx.data_layout();
 
@@ -1102,7 +1108,7 @@ impl Primitive {
         }
     }
 
-    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
+    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
         use Primitive::*;
         let dl = cx.data_layout();
 
@@ -1225,7 +1231,7 @@ impl Scalar {
         }
     }
 
-    pub fn align(self, cx: &impl HasDataLayout) -> AbiAndPrefAlign {
+    pub fn align(self, cx: &impl HasDataLayout) -> AbiAlign {
         self.primitive().align(cx)
     }
 
@@ -1731,7 +1737,7 @@ pub struct LayoutData<FieldIdx: Idx, VariantIdx: Idx> {
     /// especially in the case of by-pointer struct returns, which allocate stack even when unused.
     pub uninhabited: bool,
 
-    pub align: AbiAndPrefAlign,
+    pub align: AbiAlign,
     pub size: Size,
 
     /// The largest alignment explicitly requested with `repr(align)` on this type or any field.
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index c9a8adec31a..cf40c3f7f6f 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1119,10 +1119,9 @@ impl Stmt {
     pub fn add_trailing_semicolon(mut self) -> Self {
         self.kind = match self.kind {
             StmtKind::Expr(expr) => StmtKind::Semi(expr),
-            StmtKind::MacCall(mac) => {
-                StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
-                    MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
-                }))
+            StmtKind::MacCall(mut mac) => {
+                mac.style = MacStmtStyle::Semicolon;
+                StmtKind::MacCall(mac)
             }
             kind => kind,
         };
@@ -1724,7 +1723,7 @@ pub enum ExprKind {
     ///
     /// Usually not written directly in user code but
     /// indirectly via the macro `core::mem::offset_of!(...)`.
-    OffsetOf(P<Ty>, P<[Ident]>),
+    OffsetOf(P<Ty>, Vec<Ident>),
 
     /// A macro invocation; pre-expansion.
     MacCall(P<MacCall>),
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index f165c4ddcdd..621e3042b62 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -63,7 +63,7 @@ impl Attribute {
 
     pub fn unwrap_normal_item(self) -> AttrItem {
         match self.kind {
-            AttrKind::Normal(normal) => normal.into_inner().item,
+            AttrKind::Normal(normal) => normal.item,
             AttrKind::DocComment(..) => panic!("unexpected doc comment"),
         }
     }
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 08726ee6b41..71a47dcfcba 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -11,7 +11,7 @@ use std::ops::DerefMut;
 use std::panic;
 
 use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
-use rustc_data_structures::stack::ensure_sufficient_stack;
+use rustc_span::source_map::Spanned;
 use rustc_span::{Ident, Span};
 use smallvec::{Array, SmallVec, smallvec};
 use thin_vec::ThinVec;
@@ -19,7 +19,7 @@ use thin_vec::ThinVec;
 use crate::ast::*;
 use crate::ptr::P;
 use crate::tokenstream::*;
-use crate::visit::{AssocCtxt, BoundKind, FnCtxt, try_visit, visit_opt, walk_list};
+use crate::visit::{AssocCtxt, BoundKind, FnCtxt, VisitorResult, try_visit, visit_opt, walk_list};
 
 pub trait ExpectOne<A: Array> {
     fn expect_one(self, err: &'static str) -> A::Item;
@@ -32,7 +32,22 @@ impl<A: Array> ExpectOne<A> for SmallVec<A> {
     }
 }
 
-pub trait MutVisitor: Sized {
+mod sealed {
+    use rustc_ast_ir::visit::VisitorResult;
+
+    /// This is for compatibility with the regular `Visitor`.
+    pub trait MutVisitorResult {
+        type Result: VisitorResult;
+    }
+
+    impl<T> MutVisitorResult for T {
+        type Result = ();
+    }
+}
+
+use sealed::MutVisitorResult;
+
+pub trait MutVisitor: Sized + MutVisitorResult<Result = ()> {
     // Methods in this trait have one of three forms:
     //
     //   fn visit_t(&mut self, t: &mut T);                      // common
@@ -208,11 +223,7 @@ pub trait MutVisitor: Sized {
     }
 
     fn visit_ident(&mut self, i: &mut Ident) {
-        walk_ident(self, i);
-    }
-
-    fn visit_modifiers(&mut self, m: &mut TraitBoundModifiers) {
-        walk_modifiers(self, m);
+        self.visit_span(&mut i.span);
     }
 
     fn visit_path(&mut self, p: &mut Path) {
@@ -231,14 +242,6 @@ pub trait MutVisitor: Sized {
         walk_generic_args(self, p);
     }
 
-    fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) {
-        walk_angle_bracketed_parameter_data(self, p);
-    }
-
-    fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) {
-        walk_parenthesized_parameter_data(self, p);
-    }
-
     fn visit_local(&mut self, l: &mut Local) {
         walk_local(self, l);
     }
@@ -307,10 +310,6 @@ pub trait MutVisitor: Sized {
         walk_flat_map_expr_field(self, f)
     }
 
-    fn visit_where_clause(&mut self, where_clause: &mut WhereClause) {
-        walk_where_clause(self, where_clause);
-    }
-
     fn flat_map_where_predicate(
         &mut self,
         where_predicate: WherePredicate,
@@ -367,32 +366,44 @@ pub trait MutVisitor: Sized {
 
 super::common_visitor_and_walkers!((mut) MutVisitor);
 
-#[inline]
-fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F)
-where
-    F: FnMut(&mut T),
-{
-    for elem in elems {
-        visit_elem(elem);
+macro_rules! generate_flat_map_visitor_fns {
+    ($($name:ident, $Ty:ty, $flat_map_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => {
+        $(
+            fn $name<V: MutVisitor>(
+                vis: &mut V,
+                values: &mut ThinVec<$Ty>,
+                $(
+                    $param: $ParamTy,
+                )*
+            ) {
+                values.flat_map_in_place(|value| vis.$flat_map_fn(value$(,$param)*));
+            }
+        )+
     }
 }
 
-#[inline]
-fn visit_thin_vec<T, F>(elems: &mut ThinVec<T>, mut visit_elem: F)
-where
-    F: FnMut(&mut T),
-{
-    for elem in elems {
-        visit_elem(elem);
-    }
+generate_flat_map_visitor_fns! {
+    visit_items, P<Item>, flat_map_item;
+    visit_foreign_items, P<ForeignItem>, flat_map_foreign_item;
+    visit_generic_params, GenericParam, flat_map_generic_param;
+    visit_stmts, Stmt, flat_map_stmt;
+    visit_exprs, P<Expr>, filter_map_expr;
+    visit_expr_fields, ExprField, flat_map_expr_field;
+    visit_pat_fields, PatField, flat_map_pat_field;
+    visit_variants, Variant, flat_map_variant;
+    visit_assoc_items, P<AssocItem>, flat_map_assoc_item, ctxt: AssocCtxt;
+    visit_where_predicates, WherePredicate, flat_map_where_predicate;
+    visit_params, Param, flat_map_param;
+    visit_field_defs, FieldDef, flat_map_field_def;
+    visit_arms, Arm, flat_map_arm;
 }
 
 #[inline]
-fn visit_opt<T, F>(opt: &mut Option<T>, mut visit_elem: F)
+fn visit_thin_vec<T, F>(elems: &mut ThinVec<T>, mut visit_elem: F)
 where
     F: FnMut(&mut T),
 {
-    if let Some(elem) = opt {
+    for elem in elems {
         visit_elem(elem);
     }
 }
@@ -403,42 +414,6 @@ fn visit_attrs<T: MutVisitor>(vis: &mut T, attrs: &mut AttrVec) {
     }
 }
 
-#[allow(unused)]
-fn visit_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut Vec<P<Expr>>) {
-    exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
-}
-
-fn visit_thin_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut ThinVec<P<Expr>>) {
-    exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
-}
-
-fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) {
-    match args {
-        AttrArgs::Empty => {}
-        AttrArgs::Delimited(args) => visit_delim_args(vis, args),
-        AttrArgs::Eq { eq_span, expr } => {
-            vis.visit_expr(expr);
-            vis.visit_span(eq_span);
-        }
-    }
-}
-
-fn visit_delim_args<T: MutVisitor>(vis: &mut T, args: &mut DelimArgs) {
-    let DelimArgs { dspan, delim: _, tokens: _ } = args;
-    let DelimSpan { open, close } = dspan;
-    vis.visit_span(open);
-    vis.visit_span(close);
-}
-
-pub fn walk_pat_field<T: MutVisitor>(vis: &mut T, fp: &mut PatField) {
-    let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = fp;
-    vis.visit_id(id);
-    visit_attrs(vis, attrs);
-    vis.visit_ident(ident);
-    vis.visit_pat(pat);
-    vis.visit_span(span);
-}
-
 pub fn walk_flat_map_pat_field<T: MutVisitor>(
     vis: &mut T,
     mut fp: PatField,
@@ -447,31 +422,13 @@ pub fn walk_flat_map_pat_field<T: MutVisitor>(
     smallvec![fp]
 }
 
-fn walk_use_tree<T: MutVisitor>(vis: &mut T, use_tree: &mut UseTree) {
-    let UseTree { prefix, kind, span } = use_tree;
-    vis.visit_path(prefix);
-    match kind {
-        UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)),
-        UseTreeKind::Nested { items, span } => {
-            for (tree, id) in items {
-                vis.visit_id(id);
-                vis.visit_use_tree(tree);
-            }
-            vis.visit_span(span);
-        }
-        UseTreeKind::Glob => {}
-    }
-    vis.visit_span(span);
-}
-
-pub fn walk_arm<T: MutVisitor>(vis: &mut T, arm: &mut Arm) {
-    let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm;
-    vis.visit_id(id);
-    visit_attrs(vis, attrs);
-    vis.visit_pat(pat);
-    visit_opt(guard, |guard| vis.visit_expr(guard));
-    visit_opt(body, |body| vis.visit_expr(body));
-    vis.visit_span(span);
+fn visit_nested_use_tree<V: MutVisitor>(
+    vis: &mut V,
+    nested_tree: &mut UseTree,
+    nested_id: &mut NodeId,
+) {
+    vis.visit_id(nested_id);
+    vis.visit_use_tree(nested_tree);
 }
 
 pub fn walk_flat_map_arm<T: MutVisitor>(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> {
@@ -479,50 +436,6 @@ pub fn walk_flat_map_arm<T: MutVisitor>(vis: &mut T, mut arm: Arm) -> SmallVec<[
     smallvec![arm]
 }
 
-fn walk_assoc_item_constraint<T: MutVisitor>(
-    vis: &mut T,
-    AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint,
-) {
-    vis.visit_id(id);
-    vis.visit_ident(ident);
-    if let Some(gen_args) = gen_args {
-        vis.visit_generic_args(gen_args);
-    }
-    match kind {
-        AssocItemConstraintKind::Equality { term } => match term {
-            Term::Ty(ty) => vis.visit_ty(ty),
-            Term::Const(c) => vis.visit_anon_const(c),
-        },
-        AssocItemConstraintKind::Bound { bounds } => visit_bounds(vis, bounds, BoundKind::Bound),
-    }
-    vis.visit_span(span);
-}
-
-pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut TyPat) {
-    let TyPat { id, kind, span, tokens: _ } = ty;
-    vis.visit_id(id);
-    match kind {
-        TyPatKind::Range(start, end, _include_end) => {
-            visit_opt(start, |c| vis.visit_anon_const(c));
-            visit_opt(end, |c| vis.visit_anon_const(c));
-        }
-        TyPatKind::Or(variants) => visit_thin_vec(variants, |p| vis.visit_ty_pat(p)),
-        TyPatKind::Err(_) => {}
-    }
-    vis.visit_span(span);
-}
-
-pub fn walk_variant<T: MutVisitor>(visitor: &mut T, variant: &mut Variant) {
-    let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant;
-    visitor.visit_id(id);
-    visit_attrs(visitor, attrs);
-    visitor.visit_vis(vis);
-    visitor.visit_ident(ident);
-    visitor.visit_variant_data(data);
-    visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
-    visitor.visit_span(span);
-}
-
 pub fn walk_flat_map_variant<T: MutVisitor>(
     vis: &mut T,
     mut variant: Variant,
@@ -531,104 +444,6 @@ pub fn walk_flat_map_variant<T: MutVisitor>(
     smallvec![variant]
 }
 
-fn walk_ident<T: MutVisitor>(vis: &mut T, Ident { name: _, span }: &mut Ident) {
-    vis.visit_span(span);
-}
-
-fn walk_path<T: MutVisitor>(vis: &mut T, Path { segments, span, tokens: _ }: &mut Path) {
-    for segment in segments {
-        vis.visit_path_segment(segment);
-    }
-    vis.visit_span(span);
-}
-
-fn walk_qself<T: MutVisitor>(vis: &mut T, qself: &mut Option<P<QSelf>>) {
-    visit_opt(qself, |qself| {
-        let QSelf { ty, path_span, position: _ } = &mut **qself;
-        vis.visit_ty(ty);
-        vis.visit_span(path_span);
-    })
-}
-
-fn walk_generic_args<T: MutVisitor>(vis: &mut T, generic_args: &mut GenericArgs) {
-    match generic_args {
-        GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data),
-        GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data),
-        GenericArgs::ParenthesizedElided(span) => vis.visit_span(span),
-    }
-}
-
-fn walk_generic_arg<T: MutVisitor>(vis: &mut T, arg: &mut GenericArg) {
-    match arg {
-        GenericArg::Lifetime(lt) => vis.visit_lifetime(lt),
-        GenericArg::Type(ty) => vis.visit_ty(ty),
-        GenericArg::Const(ct) => vis.visit_anon_const(ct),
-    }
-}
-
-fn walk_angle_bracketed_parameter_data<T: MutVisitor>(vis: &mut T, data: &mut AngleBracketedArgs) {
-    let AngleBracketedArgs { args, span } = data;
-    visit_thin_vec(args, |arg| match arg {
-        AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg),
-        AngleBracketedArg::Constraint(constraint) => vis.visit_assoc_item_constraint(constraint),
-    });
-    vis.visit_span(span);
-}
-
-fn walk_parenthesized_parameter_data<T: MutVisitor>(vis: &mut T, args: &mut ParenthesizedArgs) {
-    let ParenthesizedArgs { inputs, output, span, inputs_span } = args;
-    visit_thin_vec(inputs, |input| vis.visit_ty(input));
-    vis.visit_fn_ret_ty(output);
-    vis.visit_span(span);
-    vis.visit_span(inputs_span);
-}
-
-fn walk_local<T: MutVisitor>(vis: &mut T, local: &mut Local) {
-    let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local;
-    visit_opt(super_, |sp| vis.visit_span(sp));
-    vis.visit_id(id);
-    visit_attrs(vis, attrs);
-    vis.visit_pat(pat);
-    visit_opt(ty, |ty| vis.visit_ty(ty));
-    match kind {
-        LocalKind::Decl => {}
-        LocalKind::Init(init) => {
-            vis.visit_expr(init);
-        }
-        LocalKind::InitElse(init, els) => {
-            vis.visit_expr(init);
-            vis.visit_block(els);
-        }
-    }
-    visit_opt(colon_sp, |sp| vis.visit_span(sp));
-    vis.visit_span(span);
-}
-
-fn walk_attribute<T: MutVisitor>(vis: &mut T, attr: &mut Attribute) {
-    let Attribute { kind, id: _, style: _, span } = attr;
-    match kind {
-        AttrKind::Normal(normal) => {
-            let NormalAttr { item: AttrItem { unsafety: _, path, args, tokens: _ }, tokens: _ } =
-                &mut **normal;
-            vis.visit_path(path);
-            visit_attr_args(vis, args);
-        }
-        AttrKind::DocComment(_kind, _sym) => {}
-    }
-    vis.visit_span(span);
-}
-
-fn walk_mac<T: MutVisitor>(vis: &mut T, mac: &mut MacCall) {
-    let MacCall { path, args } = mac;
-    vis.visit_path(path);
-    visit_delim_args(vis, args);
-}
-
-fn walk_macro_def<T: MutVisitor>(vis: &mut T, macro_def: &mut MacroDef) {
-    let MacroDef { body, macro_rules: _ } = macro_def;
-    visit_delim_args(vis, body);
-}
-
 fn walk_meta_list_item<T: MutVisitor>(vis: &mut T, li: &mut MetaItemInner) {
     match li {
         MetaItemInner::MetaItem(mi) => vis.visit_meta_item(mi),
@@ -646,138 +461,11 @@ fn walk_meta_item<T: MutVisitor>(vis: &mut T, mi: &mut MetaItem) {
     vis.visit_span(span);
 }
 
-pub fn walk_param<T: MutVisitor>(vis: &mut T, param: &mut Param) {
-    let Param { attrs, id, pat, span, ty, is_placeholder: _ } = param;
-    vis.visit_id(id);
-    visit_attrs(vis, attrs);
-    vis.visit_pat(pat);
-    vis.visit_ty(ty);
-    vis.visit_span(span);
-}
-
 pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> {
     vis.visit_param(&mut param);
     smallvec![param]
 }
 
-fn walk_closure_binder<T: MutVisitor>(vis: &mut T, binder: &mut ClosureBinder) {
-    match binder {
-        ClosureBinder::NotPresent => {}
-        ClosureBinder::For { span: _, generic_params } => {
-            generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
-        }
-    }
-}
-
-fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
-    match kind {
-        FnKind::Fn(
-            _ctxt,
-            _vis,
-            Fn {
-                defaultness,
-                ident,
-                generics,
-                contract,
-                body,
-                sig: FnSig { header, decl, span },
-                define_opaque,
-            },
-        ) => {
-            // Visibility is visited as a part of the item.
-            visit_defaultness(vis, defaultness);
-            vis.visit_ident(ident);
-            vis.visit_fn_header(header);
-            vis.visit_generics(generics);
-            vis.visit_fn_decl(decl);
-            if let Some(contract) = contract {
-                vis.visit_contract(contract);
-            }
-            if let Some(body) = body {
-                vis.visit_block(body);
-            }
-            vis.visit_span(span);
-
-            walk_define_opaques(vis, define_opaque);
-        }
-        FnKind::Closure(binder, coroutine_kind, decl, body) => {
-            vis.visit_closure_binder(binder);
-            coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind));
-            vis.visit_fn_decl(decl);
-            vis.visit_expr(body);
-        }
-    }
-}
-
-fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut FnContract) {
-    let FnContract { requires, ensures } = contract;
-    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 FnDecl) {
-    let FnDecl { inputs, output } = decl;
-    inputs.flat_map_in_place(|param| vis.flat_map_param(param));
-    vis.visit_fn_ret_ty(output);
-}
-
-fn walk_fn_ret_ty<T: MutVisitor>(vis: &mut T, fn_ret_ty: &mut FnRetTy) {
-    match fn_ret_ty {
-        FnRetTy::Default(span) => vis.visit_span(span),
-        FnRetTy::Ty(ty) => vis.visit_ty(ty),
-    }
-}
-
-fn walk_param_bound<T: MutVisitor>(vis: &mut T, pb: &mut GenericBound) {
-    match pb {
-        GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref),
-        GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime),
-        GenericBound::Use(args, span) => {
-            for arg in args {
-                vis.visit_precise_capturing_arg(arg);
-            }
-            vis.visit_span(span);
-        }
-    }
-}
-
-fn walk_precise_capturing_arg<T: MutVisitor>(vis: &mut T, arg: &mut PreciseCapturingArg) {
-    match arg {
-        PreciseCapturingArg::Lifetime(lt) => {
-            vis.visit_lifetime(lt);
-        }
-        PreciseCapturingArg::Arg(path, id) => {
-            vis.visit_id(id);
-            vis.visit_path(path);
-        }
-    }
-}
-
-pub fn walk_generic_param<T: MutVisitor>(vis: &mut T, param: &mut GenericParam) {
-    let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = param;
-    vis.visit_id(id);
-    visit_attrs(vis, attrs);
-    vis.visit_ident(ident);
-    visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
-    match kind {
-        GenericParamKind::Lifetime => {}
-        GenericParamKind::Type { default } => {
-            visit_opt(default, |default| vis.visit_ty(default));
-        }
-        GenericParamKind::Const { ty, kw_span: _, default } => {
-            vis.visit_ty(ty);
-            visit_opt(default, |default| vis.visit_anon_const(default));
-        }
-    }
-    if let Some(colon_span) = colon_span {
-        vis.visit_span(colon_span);
-    }
-}
-
 pub fn walk_flat_map_generic_param<T: MutVisitor>(
     vis: &mut T,
     mut param: GenericParam,
@@ -786,13 +474,6 @@ pub fn walk_flat_map_generic_param<T: MutVisitor>(
     smallvec![param]
 }
 
-fn walk_generics<T: MutVisitor>(vis: &mut T, generics: &mut Generics) {
-    let Generics { params, where_clause, span } = generics;
-    params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
-    vis.visit_where_clause(where_clause);
-    vis.visit_span(span);
-}
-
 fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWhereClauses) {
     let TyAliasWhereClauses { before, after, split: _ } = tawcs;
     let TyAliasWhereClause { has_where_token: _, span: span_before } = before;
@@ -801,99 +482,14 @@ fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWh
     vis.visit_span(span_after);
 }
 
-fn walk_where_clause<T: MutVisitor>(vis: &mut T, wc: &mut WhereClause) {
-    let WhereClause { has_where_token: _, predicates, span } = wc;
-    predicates.flat_map_in_place(|predicate| vis.flat_map_where_predicate(predicate));
-    vis.visit_span(span);
-}
-
 pub fn walk_flat_map_where_predicate<T: MutVisitor>(
     vis: &mut T,
     mut pred: WherePredicate,
 ) -> SmallVec<[WherePredicate; 1]> {
-    let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = &mut pred;
-    vis.visit_id(id);
-    visit_attrs(vis, attrs);
-    vis.visit_where_predicate_kind(kind);
-    vis.visit_span(span);
+    walk_where_predicate(vis, &mut pred);
     smallvec![pred]
 }
 
-pub fn walk_where_predicate_kind<T: MutVisitor>(vis: &mut T, kind: &mut WherePredicateKind) {
-    match kind {
-        WherePredicateKind::BoundPredicate(bp) => {
-            let WhereBoundPredicate { bound_generic_params, bounded_ty, bounds } = bp;
-            bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
-            vis.visit_ty(bounded_ty);
-            visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
-        }
-        WherePredicateKind::RegionPredicate(rp) => {
-            let WhereRegionPredicate { lifetime, bounds } = rp;
-            vis.visit_lifetime(lifetime);
-            visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound));
-        }
-        WherePredicateKind::EqPredicate(ep) => {
-            let WhereEqPredicate { lhs_ty, rhs_ty } = ep;
-            vis.visit_ty(lhs_ty);
-            vis.visit_ty(rhs_ty);
-        }
-    }
-}
-
-fn walk_variant_data<T: MutVisitor>(vis: &mut T, vdata: &mut VariantData) {
-    match vdata {
-        VariantData::Struct { fields, recovered: _ } => {
-            fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
-        }
-        VariantData::Tuple(fields, id) => {
-            vis.visit_id(id);
-            fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
-        }
-        VariantData::Unit(id) => vis.visit_id(id),
-    }
-}
-
-fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut TraitRef) {
-    vis.visit_id(ref_id);
-    vis.visit_path(path);
-}
-
-fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
-    let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p;
-    vis.visit_modifiers(modifiers);
-    bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
-    vis.visit_trait_ref(trait_ref);
-    vis.visit_span(span);
-}
-
-fn walk_modifiers<V: MutVisitor>(vis: &mut V, m: &mut TraitBoundModifiers) {
-    let TraitBoundModifiers { constness, asyncness, polarity } = m;
-    match constness {
-        BoundConstness::Never => {}
-        BoundConstness::Always(span) | BoundConstness::Maybe(span) => vis.visit_span(span),
-    }
-    match asyncness {
-        BoundAsyncness::Normal => {}
-        BoundAsyncness::Async(span) => vis.visit_span(span),
-    }
-    match polarity {
-        BoundPolarity::Positive => {}
-        BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => vis.visit_span(span),
-    }
-}
-
-pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) {
-    let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety, default } = fd;
-    visitor.visit_id(id);
-    visit_attrs(visitor, attrs);
-    visitor.visit_vis(vis);
-    visit_safety(visitor, safety);
-    visit_opt(ident, |ident| visitor.visit_ident(ident));
-    visitor.visit_ty(ty);
-    visit_opt(default, |default| visitor.visit_anon_const(default));
-    visitor.visit_span(span);
-}
-
 pub fn walk_flat_map_field_def<T: MutVisitor>(
     vis: &mut T,
     mut fd: FieldDef,
@@ -902,15 +498,6 @@ pub fn walk_flat_map_field_def<T: MutVisitor>(
     smallvec![fd]
 }
 
-pub fn walk_expr_field<T: MutVisitor>(vis: &mut T, f: &mut ExprField) {
-    let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = f;
-    vis.visit_id(id);
-    visit_attrs(vis, attrs);
-    vis.visit_ident(ident);
-    vis.visit_expr(expr);
-    vis.visit_span(span);
-}
-
 pub fn walk_flat_map_expr_field<T: MutVisitor>(
     vis: &mut T,
     mut f: ExprField,
@@ -930,16 +517,6 @@ pub fn walk_item_kind<K: WalkItemKind>(
     kind.walk(span, id, visibility, ctxt, vis)
 }
 
-pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) {
-    let Crate { attrs, items, spans, id, is_placeholder: _ } = krate;
-    vis.visit_id(id);
-    visit_attrs(vis, attrs);
-    items.flat_map_in_place(|item| vis.flat_map_item(item));
-    let ModSpans { inner_span, inject_use_span } = spans;
-    vis.visit_span(inner_span);
-    vis.visit_span(inject_use_span);
-}
-
 pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P<Item>) -> SmallVec<[P<Item>; 1]> {
     vis.visit_item(&mut item);
     smallvec![item]
@@ -962,255 +539,6 @@ pub fn walk_flat_map_assoc_item(
     smallvec![item]
 }
 
-fn walk_inline_asm<T: MutVisitor>(vis: &mut T, asm: &mut InlineAsm) {
-    // FIXME: Visit spans inside all this currently ignored stuff.
-    let InlineAsm {
-        asm_macro: _,
-        template: _,
-        template_strs: _,
-        operands,
-        clobber_abis: _,
-        options: _,
-        line_spans: _,
-    } = asm;
-    for (op, span) in operands {
-        match op {
-            InlineAsmOperand::In { expr, reg: _ }
-            | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ }
-            | InlineAsmOperand::InOut { expr, reg: _, late: _ } => vis.visit_expr(expr),
-            InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {}
-            InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
-                vis.visit_expr(in_expr);
-                if let Some(out_expr) = out_expr {
-                    vis.visit_expr(out_expr);
-                }
-            }
-            InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const),
-            InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym),
-            InlineAsmOperand::Label { block } => vis.visit_block(block),
-        }
-        vis.visit_span(span);
-    }
-}
-
-fn walk_inline_asm_sym<T: MutVisitor>(
-    vis: &mut T,
-    InlineAsmSym { id, qself, path }: &mut InlineAsmSym,
-) {
-    vis.visit_id(id);
-    vis.visit_qself(qself);
-    vis.visit_path(path);
-}
-
-fn walk_format_args<T: MutVisitor>(vis: &mut T, fmt: &mut FormatArgs) {
-    // FIXME: visit the template exhaustively.
-    let FormatArgs { span, template: _, arguments, uncooked_fmt_str: _ } = fmt;
-    for FormatArgument { kind, expr } in arguments.all_args_mut() {
-        match kind {
-            FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => {
-                vis.visit_ident(ident)
-            }
-            FormatArgumentKind::Normal => {}
-        }
-        vis.visit_expr(expr);
-    }
-    vis.visit_span(span);
-}
-
-pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, tokens: _ }: &mut Expr) {
-    vis.visit_id(id);
-    visit_attrs(vis, attrs);
-    match kind {
-        ExprKind::Array(exprs) => visit_thin_exprs(vis, exprs),
-        ExprKind::ConstBlock(anon_const) => {
-            vis.visit_anon_const(anon_const);
-        }
-        ExprKind::Repeat(expr, count) => {
-            vis.visit_expr(expr);
-            vis.visit_anon_const(count);
-        }
-        ExprKind::Tup(exprs) => visit_thin_exprs(vis, exprs),
-        ExprKind::Call(f, args) => {
-            vis.visit_expr(f);
-            visit_thin_exprs(vis, args);
-        }
-        ExprKind::MethodCall(box MethodCall {
-            seg: PathSegment { ident, id, args: seg_args },
-            receiver,
-            args: call_args,
-            span,
-        }) => {
-            vis.visit_method_receiver_expr(receiver);
-            vis.visit_id(id);
-            vis.visit_ident(ident);
-            visit_opt(seg_args, |args| vis.visit_generic_args(args));
-            visit_thin_exprs(vis, call_args);
-            vis.visit_span(span);
-        }
-        ExprKind::Binary(binop, lhs, rhs) => {
-            vis.visit_expr(lhs);
-            vis.visit_expr(rhs);
-            vis.visit_span(&mut binop.span);
-        }
-        ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs),
-        ExprKind::Cast(expr, ty) => {
-            vis.visit_expr(expr);
-            vis.visit_ty(ty);
-        }
-        ExprKind::Type(expr, ty) => {
-            vis.visit_expr(expr);
-            vis.visit_ty(ty);
-        }
-        ExprKind::AddrOf(_kind, _mut, ohs) => vis.visit_expr(ohs),
-        ExprKind::Let(pat, scrutinee, span, _recovered) => {
-            vis.visit_pat(pat);
-            vis.visit_expr(scrutinee);
-            vis.visit_span(span);
-        }
-        ExprKind::If(cond, tr, fl) => {
-            vis.visit_expr(cond);
-            vis.visit_block(tr);
-            visit_opt(fl, |fl| ensure_sufficient_stack(|| vis.visit_expr(fl)));
-        }
-        ExprKind::While(cond, body, label) => {
-            visit_opt(label, |label| vis.visit_label(label));
-            vis.visit_expr(cond);
-            vis.visit_block(body);
-        }
-        ExprKind::ForLoop { pat, iter, body, label, kind: _ } => {
-            visit_opt(label, |label| vis.visit_label(label));
-            vis.visit_pat(pat);
-            vis.visit_expr(iter);
-            vis.visit_block(body);
-        }
-        ExprKind::Loop(body, label, span) => {
-            visit_opt(label, |label| vis.visit_label(label));
-            vis.visit_block(body);
-            vis.visit_span(span);
-        }
-        ExprKind::Match(expr, arms, _kind) => {
-            vis.visit_expr(expr);
-            arms.flat_map_in_place(|arm| vis.flat_map_arm(arm));
-        }
-        ExprKind::Closure(box Closure {
-            binder,
-            capture_clause,
-            constness,
-            coroutine_kind,
-            movability: _,
-            fn_decl,
-            body,
-            fn_decl_span,
-            fn_arg_span,
-        }) => {
-            visit_constness(vis, constness);
-            vis.visit_capture_by(capture_clause);
-            vis.visit_fn(FnKind::Closure(binder, coroutine_kind, fn_decl, body), *span, *id);
-            vis.visit_span(fn_decl_span);
-            vis.visit_span(fn_arg_span);
-        }
-        ExprKind::Block(blk, label) => {
-            visit_opt(label, |label| vis.visit_label(label));
-            vis.visit_block(blk);
-        }
-        ExprKind::Gen(_capture_by, body, _kind, decl_span) => {
-            vis.visit_block(body);
-            vis.visit_span(decl_span);
-        }
-        ExprKind::Await(expr, await_kw_span) => {
-            vis.visit_expr(expr);
-            vis.visit_span(await_kw_span);
-        }
-        ExprKind::Use(expr, use_kw_span) => {
-            vis.visit_expr(expr);
-            vis.visit_span(use_kw_span);
-        }
-        ExprKind::Assign(el, er, span) => {
-            vis.visit_expr(el);
-            vis.visit_expr(er);
-            vis.visit_span(span);
-        }
-        ExprKind::AssignOp(_op, el, er) => {
-            vis.visit_expr(el);
-            vis.visit_expr(er);
-        }
-        ExprKind::Field(el, ident) => {
-            vis.visit_expr(el);
-            vis.visit_ident(ident);
-        }
-        ExprKind::Index(el, er, brackets_span) => {
-            vis.visit_expr(el);
-            vis.visit_expr(er);
-            vis.visit_span(brackets_span);
-        }
-        ExprKind::Range(e1, e2, _lim) => {
-            visit_opt(e1, |e1| vis.visit_expr(e1));
-            visit_opt(e2, |e2| vis.visit_expr(e2));
-        }
-        ExprKind::Underscore => {}
-        ExprKind::Path(qself, path) => {
-            vis.visit_qself(qself);
-            vis.visit_path(path);
-        }
-        ExprKind::Break(label, expr) => {
-            visit_opt(label, |label| vis.visit_label(label));
-            visit_opt(expr, |expr| vis.visit_expr(expr));
-        }
-        ExprKind::Continue(label) => {
-            visit_opt(label, |label| vis.visit_label(label));
-        }
-        ExprKind::Ret(expr) => {
-            visit_opt(expr, |expr| vis.visit_expr(expr));
-        }
-        ExprKind::Yeet(expr) => {
-            visit_opt(expr, |expr| vis.visit_expr(expr));
-        }
-        ExprKind::Become(expr) => vis.visit_expr(expr),
-        ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm),
-        ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt),
-        ExprKind::OffsetOf(container, fields) => {
-            vis.visit_ty(container);
-            for field in fields.iter_mut() {
-                vis.visit_ident(field);
-            }
-        }
-        ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
-        ExprKind::Struct(se) => {
-            let StructExpr { qself, path, fields, rest } = se.deref_mut();
-            vis.visit_qself(qself);
-            vis.visit_path(path);
-            fields.flat_map_in_place(|field| vis.flat_map_expr_field(field));
-            match rest {
-                StructRest::Base(expr) => vis.visit_expr(expr),
-                StructRest::Rest(_span) => {}
-                StructRest::None => {}
-            }
-        }
-        ExprKind::Paren(expr) => {
-            vis.visit_expr(expr);
-        }
-        ExprKind::Yield(kind) => {
-            let expr = kind.expr_mut();
-            if let Some(expr) = expr {
-                vis.visit_expr(expr);
-            }
-        }
-        ExprKind::Try(expr) => vis.visit_expr(expr),
-        ExprKind::TryBlock(body) => vis.visit_block(body),
-        ExprKind::Lit(_token) => {}
-        ExprKind::IncludedBytes(_bytes) => {}
-        ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
-            vis.visit_expr(expr);
-            if let Some(ty) = ty {
-                vis.visit_ty(ty);
-            }
-        }
-        ExprKind::Err(_guar) => {}
-        ExprKind::Dummy => {}
-    }
-    vis.visit_span(span);
-}
-
 pub fn walk_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Option<P<Expr>> {
     vis.visit_expr(&mut e);
     Some(e)
@@ -1255,18 +583,6 @@ fn walk_flat_map_stmt_kind<T: MutVisitor>(vis: &mut T, kind: StmtKind) -> SmallV
     }
 }
 
-fn walk_vis<T: MutVisitor>(vis: &mut T, visibility: &mut Visibility) {
-    let Visibility { kind, span, tokens: _ } = visibility;
-    match kind {
-        VisibilityKind::Public | VisibilityKind::Inherited => {}
-        VisibilityKind::Restricted { path, id, shorthand: _ } => {
-            vis.visit_id(id);
-            vis.visit_path(path);
-        }
-    }
-    vis.visit_span(span);
-}
-
 fn walk_capture_by<T: MutVisitor>(vis: &mut T, capture_by: &mut CaptureBy) {
     match capture_by {
         CaptureBy::Ref => {}
diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs
index dd923305cdf..fffeab8bbca 100644
--- a/compiler/rustc_ast/src/ptr.rs
+++ b/compiler/rustc_ast/src/ptr.rs
@@ -1,209 +1,11 @@
-//! The AST pointer.
-//!
-//! Provides [`P<T>`][struct@P], an owned smart pointer.
-//!
-//! # Motivations and benefits
-//!
-//! * **Identity**: sharing AST nodes is problematic for the various analysis
-//!   passes (e.g., one may be able to bypass the borrow checker with a shared
-//!   `ExprKind::AddrOf` node taking a mutable borrow).
-//!
-//! * **Efficiency**: folding can reuse allocation space for `P<T>` and `Vec<T>`,
-//!   the latter even when the input and output types differ (as it would be the
-//!   case with arenas or a GADT AST using type parameters to toggle features).
-//!
-//! * **Maintainability**: `P<T>` provides an interface, which can remain fully
-//!   functional even if the implementation changes (using a special thread-local
-//!   heap, for example). Moreover, a switch to, e.g., `P<'a, T>` would be easy
-//!   and mostly automated.
-
-use std::fmt::{self, Debug, Display};
-use std::ops::{Deref, DerefMut};
-use std::{slice, vec};
-
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
-/// An owned smart pointer.
+/// A pointer type that uniquely owns a heap allocation of type T.
 ///
-/// See the [module level documentation][crate::ptr] for details.
-pub struct P<T: ?Sized> {
-    ptr: Box<T>,
-}
+/// This used to be its own type, but now it's just a typedef for `Box` and we are planning to
+/// remove it soon.
+pub type P<T> = Box<T>;
 
 /// Construct a `P<T>` from a `T` value.
 #[allow(non_snake_case)]
-pub fn P<T: 'static>(value: T) -> P<T> {
-    P { ptr: Box::new(value) }
-}
-
-impl<T: 'static> P<T> {
-    /// Move out of the pointer.
-    /// Intended for chaining transformations not covered by `map`.
-    pub fn and_then<U, F>(self, f: F) -> U
-    where
-        F: FnOnce(T) -> U,
-    {
-        f(*self.ptr)
-    }
-
-    /// Equivalent to `and_then(|x| x)`.
-    pub fn into_inner(self) -> T {
-        *self.ptr
-    }
-
-    /// Produce a new `P<T>` from `self` without reallocating.
-    pub fn map<F>(mut self, f: F) -> P<T>
-    where
-        F: FnOnce(T) -> T,
-    {
-        let x = f(*self.ptr);
-        *self.ptr = x;
-
-        self
-    }
-
-    /// Optionally produce a new `P<T>` from `self` without reallocating.
-    pub fn filter_map<F>(mut self, f: F) -> Option<P<T>>
-    where
-        F: FnOnce(T) -> Option<T>,
-    {
-        *self.ptr = f(*self.ptr)?;
-        Some(self)
-    }
-}
-
-impl<T: ?Sized> Deref for P<T> {
-    type Target = T;
-
-    fn deref(&self) -> &T {
-        &self.ptr
-    }
-}
-
-impl<T: ?Sized> DerefMut for P<T> {
-    fn deref_mut(&mut self) -> &mut T {
-        &mut self.ptr
-    }
-}
-
-impl<T: 'static + Clone> Clone for P<T> {
-    fn clone(&self) -> P<T> {
-        P((**self).clone())
-    }
-}
-
-impl<T: ?Sized + Debug> Debug for P<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Debug::fmt(&self.ptr, f)
-    }
-}
-
-impl<T: Display> Display for P<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Display::fmt(&**self, f)
-    }
-}
-
-impl<T> fmt::Pointer for P<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Pointer::fmt(&self.ptr, f)
-    }
-}
-
-impl<D: Decoder, T: 'static + Decodable<D>> Decodable<D> for P<T> {
-    fn decode(d: &mut D) -> P<T> {
-        P(Decodable::decode(d))
-    }
-}
-
-impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<T> {
-    fn encode(&self, s: &mut S) {
-        (**self).encode(s);
-    }
-}
-
-impl<T> P<[T]> {
-    // FIXME(const-hack) make this const again
-    pub fn new() -> P<[T]> {
-        P { ptr: Box::default() }
-    }
-
-    #[inline(never)]
-    pub fn from_vec(v: Vec<T>) -> P<[T]> {
-        P { ptr: v.into_boxed_slice() }
-    }
-
-    #[inline(never)]
-    pub fn into_vec(self) -> Vec<T> {
-        self.ptr.into_vec()
-    }
-}
-
-impl<T> Default for P<[T]> {
-    /// Creates an empty `P<[T]>`.
-    fn default() -> P<[T]> {
-        P::new()
-    }
-}
-
-impl<T: Clone> Clone for P<[T]> {
-    fn clone(&self) -> P<[T]> {
-        P::from_vec(self.to_vec())
-    }
-}
-
-impl<T> From<Vec<T>> for P<[T]> {
-    fn from(v: Vec<T>) -> Self {
-        P::from_vec(v)
-    }
-}
-
-impl<T> From<P<[T]>> for Vec<T> {
-    fn from(val: P<[T]>) -> Self {
-        val.into_vec()
-    }
-}
-
-impl<T> FromIterator<T> for P<[T]> {
-    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> P<[T]> {
-        P::from_vec(iter.into_iter().collect())
-    }
-}
-
-impl<T> IntoIterator for P<[T]> {
-    type Item = T;
-    type IntoIter = vec::IntoIter<T>;
-
-    fn into_iter(self) -> Self::IntoIter {
-        self.into_vec().into_iter()
-    }
-}
-
-impl<'a, T> IntoIterator for &'a P<[T]> {
-    type Item = &'a T;
-    type IntoIter = slice::Iter<'a, T>;
-    fn into_iter(self) -> Self::IntoIter {
-        self.ptr.iter()
-    }
-}
-
-impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<[T]> {
-    fn encode(&self, s: &mut S) {
-        Encodable::encode(&**self, s);
-    }
-}
-
-impl<D: Decoder, T: Decodable<D>> Decodable<D> for P<[T]> {
-    fn decode(d: &mut D) -> P<[T]> {
-        P::from_vec(Decodable::decode(d))
-    }
-}
-
-impl<CTX, T> HashStable<CTX> for P<T>
-where
-    T: ?Sized + HashStable<CTX>,
-{
-    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        (**self).hash_stable(hcx, hasher);
-    }
+pub fn P<T>(value: T) -> P<T> {
+    Box::new(value)
 }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 1f7c97380dc..c88aa5c33ea 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -15,11 +15,13 @@
 
 pub use rustc_ast_ir::visit::VisitorResult;
 pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list};
+use rustc_span::source_map::Spanned;
 use rustc_span::{Ident, Span};
 use thin_vec::ThinVec;
 
 use crate::ast::*;
 use crate::ptr::P;
+use crate::tokenstream::DelimSpan;
 
 #[derive(Copy, Clone, Debug, PartialEq)]
 pub enum AssocCtxt {
@@ -219,9 +221,6 @@ pub trait Visitor<'ast>: Sized {
     fn visit_field_def(&mut self, s: &'ast FieldDef) -> Self::Result {
         walk_field_def(self, s)
     }
-    fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef) -> Self::Result {
-        walk_enum_def(self, enum_definition)
-    }
     fn visit_variant(&mut self, v: &'ast Variant) -> Self::Result {
         walk_variant(self, v)
     }
@@ -240,19 +239,18 @@ pub trait Visitor<'ast>: Sized {
     fn visit_id(&mut self, _id: NodeId) -> Self::Result {
         Self::Result::output()
     }
-    fn visit_macro_def(&mut self, _mac: &'ast MacroDef) -> Self::Result {
-        Self::Result::output()
+    fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) -> Self::Result {
+        walk_macro_def(self, macro_def)
     }
     fn visit_path(&mut self, path: &'ast Path) -> Self::Result {
         walk_path(self, path)
     }
-    fn visit_use_tree(
-        &mut self,
-        use_tree: &'ast UseTree,
-        id: NodeId,
-        _nested: bool,
-    ) -> Self::Result {
-        walk_use_tree(self, use_tree, id)
+    fn visit_use_tree(&mut self, use_tree: &'ast UseTree) -> Self::Result {
+        walk_use_tree(self, use_tree)
+    }
+    fn visit_nested_use_tree(&mut self, use_tree: &'ast UseTree, id: NodeId) -> Self::Result {
+        try_visit!(self.visit_id(id));
+        self.visit_use_tree(use_tree)
     }
     fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) -> Self::Result {
         walk_path_segment(self, path_segment)
@@ -324,8 +322,8 @@ macro_rules! common_visitor_and_walkers {
                 id: NodeId,
                 visibility: &$($lt)? $($mut)? Visibility,
                 ctxt: Self::Ctxt,
-                visitor: &mut V,
-            ) $(-> <V as Visitor<$lt>>::Result)?;
+                vis: &mut V,
+            ) -> V::Result;
         }
 
         // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier
@@ -333,12 +331,12 @@ macro_rules! common_visitor_and_walkers {
             #[expect(unused, rustc::pass_by_value)]
             #[inline]
         )?
-        fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, span: &$($lt)? $($mut)? Span) $(-> <V as Visitor<$lt>>::Result)? {
+        fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, span: &$($lt)? $($mut)? Span) -> V::Result {
             $(
                 ${ignore($mut)}
-                visitor.visit_span(span);
+                vis.visit_span(span);
             )?
-            $(${ignore($lt)}V::Result::output())?
+            V::Result::output()
         }
 
         /// helper since `Visitor` wants `NodeId` but `MutVisitor` wants `&mut NodeId`
@@ -346,62 +344,88 @@ macro_rules! common_visitor_and_walkers {
             #[expect(rustc::pass_by_value)]
         )?
         #[inline]
-        fn visit_id<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, id: &$($lt)? $($mut)? NodeId) $(-> <V as Visitor<$lt>>::Result)? {
+        fn visit_id<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, id: &$($lt)? $($mut)? NodeId) -> V::Result {
             // deref `&NodeId` into `NodeId` only for `Visitor`
-            visitor.visit_id( $(${ignore($lt)} * )? id)
+            vis.visit_id( $(${ignore($lt)} * )? id)
         }
 
         // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier
-        fn visit_safety<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, safety: &$($lt)? $($mut)? Safety) $(-> <V as Visitor<$lt>>::Result)? {
+        fn visit_safety<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, safety: &$($lt)? $($mut)? Safety) -> V::Result {
             match safety {
                 Safety::Unsafe(span) => visit_span(vis, span),
                 Safety::Safe(span) => visit_span(vis, span),
-                Safety::Default => { $(${ignore($lt)}V::Result::output())? }
+                Safety::Default => { V::Result::output() }
             }
         }
 
-        fn visit_constness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, constness: &$($lt)? $($mut)? Const) $(-> <V as Visitor<$lt>>::Result)? {
+        fn visit_constness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, constness: &$($lt)? $($mut)? Const) -> V::Result {
             match constness {
                 Const::Yes(span) => visit_span(vis, span),
                 Const::No => {
-                    $(<V as Visitor<$lt>>::Result::output())?
+                    V::Result::output()
                 }
             }
         }
 
-        fn visit_defaultness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, defaultness: &$($lt)? $($mut)? Defaultness) $(-> <V as Visitor<$lt>>::Result)? {
+        fn visit_defaultness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, defaultness: &$($lt)? $($mut)? Defaultness) -> V::Result {
             match defaultness {
                 Defaultness::Default(span) => visit_span(vis, span),
                 Defaultness::Final => {
-                    $(<V as Visitor<$lt>>::Result::output())?
+                    V::Result::output()
                 }
             }
         }
 
-        fn visit_polarity<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, polarity: &$($lt)? $($mut)? ImplPolarity) $(-> <V as Visitor<$lt>>::Result)? {
+        fn visit_polarity<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            polarity: &$($lt)? $($mut)? ImplPolarity,
+        ) -> V::Result {
             match polarity {
-                ImplPolarity::Positive => { $(<V as Visitor<$lt>>::Result::output())? }
+                ImplPolarity::Positive => { V::Result::output() }
                 ImplPolarity::Negative(span) => visit_span(vis, span),
             }
         }
 
-        fn visit_bounds<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, bounds: &$($lt)? $($mut)? GenericBounds, ctxt: BoundKind) $(-> <V as Visitor<$lt>>::Result)? {
+        $(${ignore($lt)}
+            #[inline]
+        )?
+        fn visit_modifiers<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            m: &$($lt)? $($mut)? TraitBoundModifiers
+        ) -> V::Result {
+            let TraitBoundModifiers { constness, asyncness, polarity } = m;
+            match constness {
+                BoundConstness::Never => {}
+                BoundConstness::Always(span) | BoundConstness::Maybe(span) => try_visit!(visit_span(vis, span)),
+            }
+            match asyncness {
+                BoundAsyncness::Normal => {}
+                BoundAsyncness::Async(span) => try_visit!(visit_span(vis, span)),
+            }
+            match polarity {
+                BoundPolarity::Positive => {}
+                BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => try_visit!(visit_span(vis, span)),
+            }
+            V::Result::output()
+        }
+
+        fn visit_bounds<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, bounds: &$($lt)? $($mut)? GenericBounds, ctxt: BoundKind) -> V::Result {
             walk_list!(visitor, visit_param_bound, bounds, ctxt);
-            $(<V as Visitor<$lt>>::Result::output())?
+            V::Result::output()
         }
 
-        pub fn walk_label<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Label { ident }: &$($lt)? $($mut)? Label) $(-> <V as Visitor<$lt>>::Result)? {
+        pub fn walk_label<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Label { ident }: &$($lt)? $($mut)? Label) -> V::Result {
             visitor.visit_ident(ident)
         }
 
-        pub fn walk_fn_header<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, header: &$($lt)? $($mut)? FnHeader) $(-> <V as Visitor<$lt>>::Result)? {
+        pub fn walk_fn_header<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, header: &$($lt)? $($mut)? FnHeader) -> V::Result {
             let FnHeader { safety, coroutine_kind, constness, ext: _ } = header;
             try_visit!(visit_constness(visitor, constness));
             visit_opt!(visitor, visit_coroutine_kind, coroutine_kind);
             visit_safety(visitor, safety)
         }
 
-        pub fn walk_lifetime<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Lifetime { id, ident }: &$($lt)? $($mut)? Lifetime) $(-> <V as Visitor<$lt>>::Result)? {
+        pub fn walk_lifetime<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Lifetime { id, ident }: &$($lt)? $($mut)? Lifetime) -> V::Result {
             try_visit!(visit_id(visitor, id));
             visitor.visit_ident(ident)
         }
@@ -410,7 +434,7 @@ macro_rules! common_visitor_and_walkers {
             visitor: &mut V,
             item: &$($mut)? $($lt)? Item<K>,
             ctxt: K::Ctxt,
-        ) $(-> <V as Visitor<$lt>>::Result)? {
+        ) -> V::Result {
             let Item { attrs, id, kind, vis, span, tokens: _ } = item;
             try_visit!(visit_id(visitor, id));
             walk_list!(visitor, visit_attribute, attrs);
@@ -422,7 +446,7 @@ macro_rules! common_visitor_and_walkers {
         pub fn walk_item<$($lt,)? V: $Visitor$(<$lt>)?, K: WalkItemKind<Ctxt = ()>>(
             visitor: &mut V,
             item: &$($mut)? $($lt)? Item<K>,
-        ) $(-> <V as Visitor<$lt>>::Result)? {
+        ) -> V::Result {
             walk_item_ctxt(visitor, item, ())
         }
 
@@ -430,7 +454,7 @@ macro_rules! common_visitor_and_walkers {
             visitor: &mut V,
             item: &$($mut)? $($lt)? AssocItem,
             ctxt: AssocCtxt,
-        ) $(-> <V as Visitor<$lt>>::Result)? {
+        ) -> V::Result {
             walk_item_ctxt(visitor, item, ctxt)
         }
 
@@ -443,11 +467,10 @@ macro_rules! common_visitor_and_walkers {
                 visibility: &$($lt)? $($mut)? Visibility,
                 _ctxt: Self::Ctxt,
                 vis: &mut V,
-            ) $(-> <V as Visitor<$lt>>::Result)? {
+            ) -> V::Result {
                 match self {
                     ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident),
-                    // FIXME(fee1-dead): look into this weird assymetry
-                    ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree$(${ignore($lt)}, id, false)?),
+                    ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
                     ItemKind::Static(box StaticItem {
                         ident,
                         ty,
@@ -478,18 +501,13 @@ macro_rules! common_visitor_and_walkers {
                                 ModSpans { inner_span, inject_use_span },
                                 _,
                             ) => {
-                                $(${ignore($mut)}
-                                    items.flat_map_in_place(|item| vis.flat_map_item(item));
-                                )?
-                                $(${ignore($lt)}
-                                    walk_list!(vis, visit_item, items);
-                                )?
+                                try_visit!(visit_items(vis, items));
                                 try_visit!(visit_span(vis, inner_span));
                                 try_visit!(visit_span(vis, inject_use_span));
                             }
                             ModKind::Unloaded => {}
                         }
-                        $(<V as Visitor<$lt>>::Result::output())?
+                        V::Result::output()
                     }
                     ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
                     ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
@@ -510,15 +528,12 @@ macro_rules! common_visitor_and_walkers {
                         $(${ignore($mut)}
                             walk_ty_alias_where_clauses(vis, where_clauses);
                         )?
-                        $(<V as Visitor<$lt>>::Result::output())?
+                        V::Result::output()
                     }
                     ItemKind::Enum(ident, generics, enum_definition) => {
                         try_visit!(vis.visit_ident(ident));
                         try_visit!(vis.visit_generics(generics));
-                        $(${ignore($mut)}
-                            enum_definition.variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
-                        )?
-                        $(${ignore($lt)}vis.visit_enum_def(enum_definition))?
+                        visit_variants(vis, &$($mut)? enum_definition.variants)
                     }
                     ItemKind::Struct(ident, generics, variant_data)
                     | ItemKind::Union(ident, generics, variant_data) => {
@@ -543,35 +558,14 @@ macro_rules! common_visitor_and_walkers {
                         try_visit!(visit_polarity(vis, polarity));
                         visit_opt!(vis, visit_trait_ref, of_trait);
                         try_visit!(vis.visit_ty(self_ty));
-                        $(${ignore($mut)}
-                            items.flat_map_in_place(|item| {
-                                vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
-                            });
-                        )?
-                        $(${ignore($lt)}
-                            walk_list!(
-                                vis,
-                                visit_assoc_item,
-                                items,
-                                AssocCtxt::Impl { of_trait: of_trait.is_some() }
-                            );
-                            <V as Visitor<$lt>>::Result::output()
-                        )?
+                        visit_assoc_items(vis, items, AssocCtxt::Impl { of_trait: of_trait.is_some() })
                     }
                     ItemKind::Trait(box Trait { safety, is_auto: _, ident, generics, bounds, items }) => {
                         try_visit!(visit_safety(vis, safety));
                         try_visit!(vis.visit_ident(ident));
                         try_visit!(vis.visit_generics(generics));
                         try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
-                        $(${ignore($mut)}
-                            items.flat_map_in_place(|item| {
-                                vis.flat_map_assoc_item(item, AssocCtxt::Trait)
-                            });
-                        )?
-                        $(${ignore($lt)}
-                            walk_list!(vis, visit_assoc_item, items, AssocCtxt::Trait);
-                            <V as Visitor<$lt>>::Result::output()
-                        )?
+                        visit_assoc_items(vis, items, AssocCtxt::Trait)
                     }
                     ItemKind::TraitAlias(ident, generics, bounds) => {
                         try_visit!(vis.visit_ident(ident));
@@ -598,7 +592,7 @@ macro_rules! common_visitor_and_walkers {
                         try_visit!(vis.visit_ident(ident));
                         visit_opt!(vis, visit_ident, rename);
                         visit_opt!(vis, visit_block, body);
-                        $(<V as Visitor<$lt>>::Result::output())?
+                        V::Result::output()
                     }
                     ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
                         try_visit!(vis.visit_qself(qself));
@@ -610,13 +604,16 @@ macro_rules! common_visitor_and_walkers {
                             }
                         }
                         visit_opt!(vis, visit_block, body);
-                        $(<V as Visitor<$lt>>::Result::output())?
+                        V::Result::output()
                     }
                 }
             }
         }
 
-        fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, item: &$($lt)? $($mut)? ConstItem) $(-> <V as Visitor<$lt>>::Result)? {
+        fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            item: &$($lt)? $($mut)? ConstItem,
+        ) -> V::Result {
             let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item;
             try_visit!(visit_defaultness(vis, defaultness));
             try_visit!(vis.visit_ident(ident));
@@ -626,29 +623,23 @@ macro_rules! common_visitor_and_walkers {
             walk_define_opaques(vis, define_opaque)
         }
 
-        fn walk_foreign_mod<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, foreign_mod: &$($lt)? $($mut)? ForeignMod) $(-> <V as Visitor<$lt>>::Result)? {
+        fn walk_foreign_mod<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, foreign_mod: &$($lt)? $($mut)? ForeignMod) -> V::Result {
             let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
             try_visit!(visit_safety(vis, safety));
-            $(${ignore($mut)}
-                items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
-            )?
-            $(
-                walk_list!(vis, visit_foreign_item, items);
-                <V as Visitor<$lt>>::Result::output()
-            )?
+            visit_foreign_items(vis, items)
         }
 
         fn walk_define_opaques<$($lt,)? V: $Visitor$(<$lt>)?>(
             visitor: &mut V,
             define_opaque: &$($lt)? $($mut)? Option<ThinVec<(NodeId, Path)>>,
-        ) $(-> <V as Visitor<$lt>>::Result)? {
+        ) -> V::Result {
             if let Some(define_opaque) = define_opaque {
                 for (id, path) in define_opaque {
                     try_visit!(visit_id(visitor, id));
                     try_visit!(visitor.visit_path(path));
                 }
             }
-            $(<V as Visitor<$lt>>::Result::output())?
+            V::Result::output()
         }
 
         impl WalkItemKind for AssocItemKind {
@@ -660,7 +651,7 @@ macro_rules! common_visitor_and_walkers {
                 visibility: &$($lt)? $($mut)? Visibility,
                 ctxt: Self::Ctxt,
                 vis: &mut V,
-            ) $(-> <V as Visitor<$lt>>::Result)? {
+            ) -> V::Result {
                 match self {
                     AssocItemKind::Const(item) => {
                         walk_const_item(vis, item)
@@ -685,7 +676,7 @@ macro_rules! common_visitor_and_walkers {
                         $(${ignore($mut)}
                             walk_ty_alias_where_clauses(vis, where_clauses);
                         )?
-                        $(<V as Visitor<$lt>>::Result::output())?
+                        V::Result::output()
                     }
                     AssocItemKind::MacCall(mac) => {
                         vis.visit_mac_call(mac)
@@ -705,7 +696,7 @@ macro_rules! common_visitor_and_walkers {
                         try_visit!(vis.visit_ident(ident));
                         visit_opt!(vis, visit_ident, rename);
                         visit_opt!(vis, visit_block, body);
-                        $(<V as Visitor<$lt>>::Result::output())?
+                        V::Result::output()
                     }
                     AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
                         try_visit!(vis.visit_qself(qself));
@@ -717,7 +708,7 @@ macro_rules! common_visitor_and_walkers {
                             }
                         }
                         visit_opt!(vis, visit_block, body);
-                        $(<V as Visitor<$lt>>::Result::output())?
+                        V::Result::output()
                     }
                 }
             }
@@ -732,7 +723,7 @@ macro_rules! common_visitor_and_walkers {
                 visibility: &$($lt)? $($mut)? Visibility,
                 _ctxt: Self::Ctxt,
                 vis: &mut V,
-            ) $(-> <V as Visitor<$lt>>::Result)? {
+            ) -> V::Result {
                 match self {
                     ForeignItemKind::Static(box StaticItem {
                         ident,
@@ -767,7 +758,7 @@ macro_rules! common_visitor_and_walkers {
                         $(${ignore($mut)}
                             walk_ty_alias_where_clauses(vis, where_clauses);
                         )?
-                        $(<V as Visitor<$lt>>::Result::output())?
+                        V::Result::output()
                     }
                     ForeignItemKind::MacCall(mac) => {
                         vis.visit_mac_call(mac)
@@ -779,22 +770,20 @@ macro_rules! common_visitor_and_walkers {
         fn walk_coroutine_kind<$($lt,)? V: $Visitor$(<$lt>)?>(
             vis: &mut V,
             coroutine_kind: &$($lt)? $($mut)? CoroutineKind,
-        ) $(-> <V as Visitor<$lt>>::Result)? {
-            match coroutine_kind {
-                CoroutineKind::Async { span, closure_id, return_impl_trait_id }
+        ) -> V::Result {
+            let (CoroutineKind::Async { span, closure_id, return_impl_trait_id }
                 | CoroutineKind::Gen { span, closure_id, return_impl_trait_id }
-                | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id } => {
-                    try_visit!(visit_id(vis, closure_id));
-                    try_visit!(visit_id(vis, return_impl_trait_id));
-                    visit_span(vis, span)
-                }
-            }
+                | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id })
+                = coroutine_kind;
+            try_visit!(visit_id(vis, closure_id));
+            try_visit!(visit_id(vis, return_impl_trait_id));
+            visit_span(vis, span)
         }
 
         pub fn walk_pat<$($lt,)? V: $Visitor$(<$lt>)?>(
             vis: &mut V,
             pattern: &$($lt)? $($mut)? Pat
-        ) $(-> <V as Visitor<$lt>>::Result)? {
+        ) -> V::Result {
             let Pat { id, kind, span, tokens: _ } = pattern;
             try_visit!(visit_id(vis, id));
             match kind {
@@ -817,15 +806,7 @@ macro_rules! common_visitor_and_walkers {
                 PatKind::Struct(opt_qself, path, fields, _rest) => {
                     try_visit!(vis.visit_qself(opt_qself));
                     try_visit!(vis.visit_path(path));
-
-                    $(
-                        ${ignore($lt)}
-                        walk_list!(vis, visit_pat_field, fields);
-                    )?
-                    $(
-                        ${ignore($mut)}
-                        fields.flat_map_in_place(|field| vis.flat_map_pat_field(field));
-                    )?
+                    try_visit!(visit_pat_fields(vis, fields));
                 }
                 PatKind::Box(subpattern) | PatKind::Deref(subpattern) | PatKind::Paren(subpattern) => {
                     try_visit!(vis.visit_pat(subpattern));
@@ -853,7 +834,7 @@ macro_rules! common_visitor_and_walkers {
         pub fn walk_anon_const<$($lt,)? V: $Visitor$(<$lt>)?>(
             vis: &mut V,
             constant: &$($lt)? $($mut)? AnonConst,
-        ) $(-> <V as Visitor<$lt>>::Result)? {
+        ) -> V::Result {
             let AnonConst { id, value } = constant;
             try_visit!(visit_id(vis, id));
             vis.visit_expr(value)
@@ -862,35 +843,28 @@ macro_rules! common_visitor_and_walkers {
         pub fn walk_path_segment<$($lt,)? V: $Visitor$(<$lt>)?>(
             vis: &mut V,
             segment: &$($lt)? $($mut)? PathSegment,
-        ) $(-> <V as Visitor<$lt>>::Result)? {
+        ) -> V::Result {
             let PathSegment { ident, id, args } = segment;
             try_visit!(visit_id(vis, id));
             try_visit!(vis.visit_ident(ident));
             visit_opt!(vis, visit_generic_args, args);
-            $(<V as Visitor<$lt>>::Result::output())?
+            V::Result::output()
         }
 
         pub fn walk_block<$($lt,)? V: $Visitor$(<$lt>)?>(
             vis: &mut V,
             block: &$($lt)? $($mut)? Block
-        ) $(-> <V as Visitor<$lt>>::Result)? {
+        ) -> V::Result {
             let Block { stmts, id, rules: _, span, tokens: _ } = block;
             try_visit!(visit_id(vis, id));
-            $(
-                ${ignore($lt)}
-                walk_list!(vis, visit_stmt, stmts);
-            )?
-            $(
-                ${ignore($mut)}
-                stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
-            )?
+            try_visit!(visit_stmts(vis, stmts));
             visit_span(vis, span)
         }
 
 
         pub fn walk_ty<$($lt,)? V: $Visitor$(<$lt>)?>(
             vis: &mut V, ty: &$($lt)? $($mut)? Ty
-        ) $(-> <V as Visitor<$lt>>::Result)? {
+        ) -> V::Result {
             let Ty { id, kind, span, tokens: _ } = ty;
             try_visit!(visit_id(vis, id));
             match kind {
@@ -911,28 +885,13 @@ macro_rules! common_visitor_and_walkers {
                     let BareFnTy { safety, ext: _, generic_params, decl, decl_span } =
                         &$($mut)? **function_declaration;
                     visit_safety(vis, safety);
-                    $(
-                        ${ignore($lt)}
-                        walk_list!(vis, visit_generic_param, generic_params);
-                    )?
-                    $(
-                        ${ignore($mut)}
-                        generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
-                    )?
-
+                    try_visit!(visit_generic_params(vis, generic_params));
                     try_visit!(vis.visit_fn_decl(decl));
                     try_visit!(visit_span(vis, decl_span));
                 }
                 TyKind::UnsafeBinder(binder) => {
-                    $(
-                        ${ignore($lt)}
-                        walk_list!(vis, visit_generic_param, &binder.generic_params);
-                    )?
-                    $(
-                        ${ignore($mut)}
-                        binder.generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
-                    )?
-                    try_visit!(vis.visit_ty(&$($mut)?binder.inner_ty));
+                    try_visit!(visit_generic_params(vis, &$($mut)? binder.generic_params));
+                    try_visit!(vis.visit_ty(&$($mut)? binder.inner_ty));
                 }
                 TyKind::Path(maybe_qself, path) => {
                     try_visit!(vis.visit_qself(maybe_qself));
@@ -959,658 +918,799 @@ macro_rules! common_visitor_and_walkers {
             }
             visit_span(vis, span)
         }
-    };
-}
-
-common_visitor_and_walkers!(Visitor<'a>);
 
-pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result {
-    let Crate { attrs, items, spans: _, id: _, is_placeholder: _ } = krate;
-    walk_list!(visitor, visit_attribute, attrs);
-    walk_list!(visitor, visit_item, items);
-    V::Result::output()
-}
-
-pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::Result {
-    let Local { id: _, super_: _, pat, ty, kind, span: _, colon_sp: _, attrs, tokens: _ } = local;
-    walk_list!(visitor, visit_attribute, attrs);
-    try_visit!(visitor.visit_pat(pat));
-    visit_opt!(visitor, visit_ty, ty);
-    if let Some((init, els)) = kind.init_else_opt() {
-        try_visit!(visitor.visit_expr(init));
-        visit_opt!(visitor, visit_block, els);
-    }
-    V::Result::output()
-}
+        pub fn walk_crate<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            krate: &$($lt)? $($mut)? Crate,
+        ) -> V::Result {
+            let Crate { attrs, items, spans, id, is_placeholder: _ } = krate;
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            try_visit!(visit_items(vis, items));
+            let ModSpans { inner_span, inject_use_span } = spans;
+            try_visit!(visit_span(vis, inner_span));
+            visit_span(vis, inject_use_span)
+        }
 
-pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result
-where
-    V: Visitor<'a>,
-{
-    let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span: _ } = trait_ref;
-    walk_list!(visitor, visit_generic_param, bound_generic_params);
-    visitor.visit_trait_ref(trait_ref)
-}
+        pub fn walk_local<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            local: &$($lt)? $($mut)? Local,
+        ) -> V::Result {
+            let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local;
+            if let Some(sp) = super_ {
+                try_visit!(visit_span(vis, sp));
+            }
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            try_visit!(vis.visit_pat(pat));
+            visit_opt!(vis, visit_ty, ty);
+            match kind {
+                LocalKind::Decl => {}
+                LocalKind::Init(init) => {
+                    try_visit!(vis.visit_expr(init))
+                }
+                LocalKind::InitElse(init, els) => {
+                    try_visit!(vis.visit_expr(init));
+                    try_visit!(vis.visit_block(els));
+                }
+            }
+            if let Some(sp) = colon_sp {
+                try_visit!(visit_span(vis, sp));
+            }
+            visit_span(vis, span)
+        }
 
-pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitRef) -> V::Result {
-    let TraitRef { path, ref_id } = trait_ref;
-    try_visit!(visitor.visit_path(path));
-    visitor.visit_id(*ref_id)
-}
+        pub fn walk_poly_trait_ref<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            p: &$($lt)? $($mut)? PolyTraitRef,
+        ) -> V::Result {
+            let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p;
+            try_visit!(visit_modifiers(vis, modifiers));
+            try_visit!(visit_generic_params(vis, bound_generic_params));
+            try_visit!(vis.visit_trait_ref(trait_ref));
+            visit_span(vis, span)
+        }
 
-pub fn walk_enum_def<'a, V: Visitor<'a>>(
-    visitor: &mut V,
-    EnumDef { variants }: &'a EnumDef,
-) -> V::Result {
-    walk_list!(visitor, visit_variant, variants);
-    V::Result::output()
-}
+        pub fn walk_trait_ref<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            TraitRef { path, ref_id }: &$($lt)? $($mut)? TraitRef,
+        ) -> V::Result {
+            try_visit!(vis.visit_path(path));
+            visit_id(vis, ref_id)
+        }
 
-pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant) -> V::Result
-where
-    V: Visitor<'a>,
-{
-    let Variant { attrs, id: _, span: _, vis, ident, data, disr_expr, is_placeholder: _ } = variant;
-    walk_list!(visitor, visit_attribute, attrs);
-    try_visit!(visitor.visit_vis(vis));
-    try_visit!(visitor.visit_ident(ident));
-    try_visit!(visitor.visit_variant_data(data));
-    visit_opt!(visitor, visit_variant_discr, disr_expr);
-    V::Result::output()
-}
+        pub fn walk_variant<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            variant: &$($lt)? $($mut)? Variant,
+        ) -> V::Result {
+            let Variant { attrs, id, span, vis: visibility, ident, data, disr_expr, is_placeholder: _ } = variant;
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            try_visit!(vis.visit_vis(visibility));
+            try_visit!(vis.visit_ident(ident));
+            try_visit!(vis.visit_variant_data(data));
+            $(${ignore($lt)} visit_opt!(vis, visit_variant_discr, disr_expr); )?
+            $(${ignore($mut)} visit_opt!(vis, visit_anon_const, disr_expr); )?
+            visit_span(vis, span)
+        }
 
-pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> V::Result {
-    let ExprField { attrs, id: _, span: _, ident, expr, is_shorthand: _, is_placeholder: _ } = f;
-    walk_list!(visitor, visit_attribute, attrs);
-    try_visit!(visitor.visit_ident(ident));
-    try_visit!(visitor.visit_expr(expr));
-    V::Result::output()
-}
+        pub fn walk_expr_field<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            f: &$($lt)? $($mut)? ExprField,
+        ) -> V::Result {
+            let ExprField { attrs, id, span, ident, expr, is_shorthand: _, is_placeholder: _ } = f;
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            try_visit!(vis.visit_ident(ident));
+            try_visit!(vis.visit_expr(expr));
+            visit_span(vis, span)
+        }
 
-pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result {
-    let PatField { ident, pat, is_shorthand: _, attrs, id: _, span: _, is_placeholder: _ } = fp;
-    walk_list!(visitor, visit_attribute, attrs);
-    try_visit!(visitor.visit_ident(ident));
-    try_visit!(visitor.visit_pat(pat));
-    V::Result::output()
-}
+        pub fn walk_pat_field<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            fp: &$($lt)? $($mut)? PatField,
+        ) -> V::Result {
+            let PatField { ident, pat, is_shorthand: _, attrs, id, span, is_placeholder: _ } = fp;
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            try_visit!(vis.visit_ident(ident));
+            try_visit!(vis.visit_pat(pat));
+            visit_span(vis, span)
+        }
 
-pub fn walk_ty_pat<'a, V: Visitor<'a>>(visitor: &mut V, tp: &'a TyPat) -> V::Result {
-    let TyPat { id: _, kind, span: _, tokens: _ } = tp;
-    match kind {
-        TyPatKind::Range(start, end, _include_end) => {
-            visit_opt!(visitor, visit_anon_const, start);
-            visit_opt!(visitor, visit_anon_const, end);
+        pub fn walk_ty_pat<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            tp: &$($lt)? $($mut)? TyPat,
+        ) -> V::Result {
+            let TyPat { id, kind, span, tokens: _ } = tp;
+            try_visit!(visit_id(vis, id));
+            match kind {
+                TyPatKind::Range(start, end, _include_end) => {
+                    visit_opt!(vis, visit_anon_const, start);
+                    visit_opt!(vis, visit_anon_const, end);
+                }
+                TyPatKind::Or(variants) => walk_list!(vis, visit_ty_pat, variants),
+                TyPatKind::Err(_) => {}
+            }
+            visit_span(vis, span)
         }
-        TyPatKind::Or(variants) => walk_list!(visitor, visit_ty_pat, variants),
-        TyPatKind::Err(_) => {}
-    }
-    V::Result::output()
-}
 
-fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option<P<QSelf>>) -> V::Result {
-    if let Some(qself) = qself {
-        let QSelf { ty, path_span: _, position: _ } = &**qself;
-        try_visit!(visitor.visit_ty(ty));
-    }
-    V::Result::output()
-}
+        fn walk_qself<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            qself: &$($lt)? $($mut)? Option<P<QSelf>>,
+        ) -> V::Result {
+            if let Some(qself) = qself {
+                let QSelf { ty, path_span, position: _ } = &$($mut)? **qself;
+                try_visit!(vis.visit_ty(ty));
+                try_visit!(visit_span(vis, path_span));
+            }
+            V::Result::output()
+        }
 
-pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) -> V::Result {
-    let Path { span: _, segments, tokens: _ } = path;
-    walk_list!(visitor, visit_path_segment, segments);
-    V::Result::output()
-}
+        pub fn walk_path<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            path: &$($lt)? $($mut)? Path,
+        ) -> V::Result {
+            let Path { span, segments, tokens: _ } = path;
+            walk_list!(vis, visit_path_segment, segments);
+            visit_span(vis, span)
+        }
 
-pub fn walk_use_tree<'a, V: Visitor<'a>>(
-    visitor: &mut V,
-    use_tree: &'a UseTree,
-    id: NodeId,
-) -> V::Result {
-    let UseTree { prefix, kind, span: _ } = use_tree;
-    try_visit!(visitor.visit_id(id));
-    try_visit!(visitor.visit_path(prefix));
-    match kind {
-        UseTreeKind::Simple(rename) => {
-            // The extra IDs are handled during AST lowering.
-            visit_opt!(visitor, visit_ident, rename);
-        }
-        UseTreeKind::Glob => {}
-        UseTreeKind::Nested { items, span: _ } => {
-            for &(ref nested_tree, nested_id) in items {
-                try_visit!(visitor.visit_use_tree(nested_tree, nested_id, true));
+        pub fn walk_use_tree<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            use_tree: &$($lt)? $($mut)? UseTree,
+        ) -> V::Result {
+            let UseTree { prefix, kind, span } = use_tree;
+            try_visit!(vis.visit_path(prefix));
+            match kind {
+                UseTreeKind::Simple(rename) => {
+                    // The extra IDs are handled during AST lowering.
+                    visit_opt!(vis, visit_ident, rename);
+                }
+                UseTreeKind::Glob => {}
+                UseTreeKind::Nested { items, span } => {
+                    for (nested_tree, nested_id) in items {
+                        try_visit!(visit_nested_use_tree(vis, nested_tree, nested_id));
+                    }
+                    try_visit!(visit_span(vis, span));
+                }
             }
+            visit_span(vis, span)
         }
-    }
-    V::Result::output()
-}
 
-pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs) -> V::Result
-where
-    V: Visitor<'a>,
-{
-    match generic_args {
-        GenericArgs::AngleBracketed(AngleBracketedArgs { span: _, args }) => {
-            for arg in args {
-                match arg {
-                    AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)),
-                    AngleBracketedArg::Constraint(c) => {
-                        try_visit!(visitor.visit_assoc_item_constraint(c))
+        pub fn walk_generic_args<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            generic_args: &$($lt)? $($mut)? GenericArgs
+        ) -> V::Result {
+            match generic_args {
+                GenericArgs::AngleBracketed(AngleBracketedArgs { span, args }) => {
+                    for arg in args {
+                        match arg {
+                            AngleBracketedArg::Arg(a) => try_visit!(vis.visit_generic_arg(a)),
+                            AngleBracketedArg::Constraint(c) => {
+                                try_visit!(vis.visit_assoc_item_constraint(c))
+                            }
+                        }
                     }
+                    visit_span(vis, span)
                 }
+                GenericArgs::Parenthesized(data) => {
+                    let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
+                    walk_list!(vis, visit_ty, inputs);
+                    try_visit!(vis.visit_fn_ret_ty(output));
+                    try_visit!(visit_span(vis, span));
+                    visit_span(vis, inputs_span)
+                }
+                GenericArgs::ParenthesizedElided(span) => visit_span(vis, span)
             }
         }
-        GenericArgs::Parenthesized(data) => {
-            let ParenthesizedArgs { span: _, inputs, inputs_span: _, output } = data;
-            walk_list!(visitor, visit_ty, inputs);
-            try_visit!(visitor.visit_fn_ret_ty(output));
+
+        pub fn walk_generic_arg<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            generic_arg: &$($lt)? $($mut)? GenericArg,
+        ) -> V::Result {
+            match generic_arg {
+                GenericArg::Lifetime(lt) => vis.visit_lifetime(lt, $(${ignore($lt)} LifetimeCtxt::GenericArg)? ),
+                GenericArg::Type(ty) => vis.visit_ty(ty),
+                GenericArg::Const(ct) => vis.visit_anon_const(ct),
+            }
         }
-        GenericArgs::ParenthesizedElided(_span) => {}
-    }
-    V::Result::output()
-}
 
-pub fn walk_generic_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) -> V::Result
-where
-    V: Visitor<'a>,
-{
-    match generic_arg {
-        GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg),
-        GenericArg::Type(ty) => visitor.visit_ty(ty),
-        GenericArg::Const(ct) => visitor.visit_anon_const(ct),
-    }
-}
+        pub fn walk_assoc_item_constraint<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            constraint: &$($lt)? $($mut)? AssocItemConstraint,
+        ) -> V::Result {
+            let AssocItemConstraint { id, ident, gen_args, kind, span } = constraint;
+            try_visit!(visit_id(vis, id));
+            try_visit!(vis.visit_ident(ident));
+            visit_opt!(vis, visit_generic_args, gen_args);
+            match kind {
+                AssocItemConstraintKind::Equality { term } => match term {
+                    Term::Ty(ty) => try_visit!(vis.visit_ty(ty)),
+                    Term::Const(c) => try_visit!(vis.visit_anon_const(c)),
+                },
+                AssocItemConstraintKind::Bound { bounds } => {
+                    try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
+                }
+            }
+            visit_span(vis, span)
+        }
 
-pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>(
-    visitor: &mut V,
-    constraint: &'a AssocItemConstraint,
-) -> V::Result {
-    let AssocItemConstraint { id: _, ident, gen_args, kind, span: _ } = constraint;
-    try_visit!(visitor.visit_ident(ident));
-    visit_opt!(visitor, visit_generic_args, gen_args);
-    match kind {
-        AssocItemConstraintKind::Equality { term } => match term {
-            Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)),
-            Term::Const(c) => try_visit!(visitor.visit_anon_const(c)),
-        },
-        AssocItemConstraintKind::Bound { bounds } => {
-            walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
+        pub fn walk_param_bound<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, bound: &$($lt)? $($mut)? GenericBound) -> V::Result {
+            match bound {
+                GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref),
+                GenericBound::Outlives(lifetime) => vis.visit_lifetime(lifetime, $(${ignore($lt)} LifetimeCtxt::Bound)?),
+                GenericBound::Use(args, span) => {
+                    walk_list!(vis, visit_precise_capturing_arg, args);
+                    visit_span(vis, span)
+                }
+            }
+        }
+
+        pub fn walk_precise_capturing_arg<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            arg: &$($lt)? $($mut)? PreciseCapturingArg,
+        ) -> V::Result {
+            match arg {
+                PreciseCapturingArg::Lifetime(lt) => vis.visit_lifetime(lt, $(${ignore($lt)} LifetimeCtxt::GenericArg)?),
+                PreciseCapturingArg::Arg(path, id) => {
+                    try_visit!(visit_id(vis, id));
+                    vis.visit_path(path)
+                }
+            }
         }
-    }
-    V::Result::output()
-}
 
-pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result {
-    match bound {
-        GenericBound::Trait(trait_ref) => visitor.visit_poly_trait_ref(trait_ref),
-        GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
-        GenericBound::Use(args, _span) => {
-            walk_list!(visitor, visit_precise_capturing_arg, args);
+        pub fn walk_generic_param<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            param: &$($lt)? $($mut)? GenericParam,
+        ) -> V::Result {
+            let GenericParam { id, ident, attrs, bounds, is_placeholder: _, kind, colon_span } =
+                param;
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            try_visit!(vis.visit_ident(ident));
+            walk_list!(vis, visit_param_bound, bounds, BoundKind::Bound);
+            match kind {
+                GenericParamKind::Lifetime => (),
+                GenericParamKind::Type { default } => visit_opt!(vis, visit_ty, default),
+                GenericParamKind::Const { ty, default, kw_span: _ } => {
+                    try_visit!(vis.visit_ty(ty));
+                    visit_opt!(vis, visit_anon_const, default);
+                }
+            }
+            if let Some(sp) = colon_span {
+                try_visit!(visit_span(vis, sp))
+            }
             V::Result::output()
         }
-    }
-}
 
-pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>(
-    visitor: &mut V,
-    arg: &'a PreciseCapturingArg,
-) -> V::Result {
-    match arg {
-        PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg),
-        PreciseCapturingArg::Arg(path, id) => {
-            try_visit!(visitor.visit_id(*id));
-            visitor.visit_path(path)
+        pub fn walk_generics<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, generics: &$($lt)? $($mut)? Generics) -> V::Result {
+            let Generics { params, where_clause, span } = generics;
+            let WhereClause { has_where_token: _, predicates, span: where_clause_span } = where_clause;
+            try_visit!(visit_generic_params(vis, params));
+            try_visit!(visit_where_predicates(vis, predicates));
+            try_visit!(visit_span(vis, span));
+            visit_span(vis, where_clause_span)
         }
-    }
-}
 
-pub fn walk_generic_param<'a, V: Visitor<'a>>(
-    visitor: &mut V,
-    param: &'a GenericParam,
-) -> V::Result {
-    let GenericParam { id: _, ident, attrs, bounds, is_placeholder: _, kind, colon_span: _ } =
-        param;
-    walk_list!(visitor, visit_attribute, attrs);
-    try_visit!(visitor.visit_ident(ident));
-    walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
-    match kind {
-        GenericParamKind::Lifetime => (),
-        GenericParamKind::Type { default } => visit_opt!(visitor, visit_ty, default),
-        GenericParamKind::Const { ty, default, kw_span: _ } => {
-            try_visit!(visitor.visit_ty(ty));
-            visit_opt!(visitor, visit_anon_const, default);
+        pub fn walk_contract<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, c: &$($lt)? $($mut)? FnContract) -> V::Result {
+            let FnContract { requires, ensures } = c;
+            visit_opt!(vis, visit_expr, requires);
+            visit_opt!(vis, visit_expr, ensures);
+            V::Result::output()
         }
-    }
-    V::Result::output()
-}
 
-pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) -> V::Result {
-    let Generics { params, where_clause, span: _ } = generics;
-    let WhereClause { has_where_token: _, predicates, span: _ } = where_clause;
-    walk_list!(visitor, visit_generic_param, params);
-    walk_list!(visitor, visit_where_predicate, predicates);
-    V::Result::output()
-}
+        pub fn walk_where_predicate<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            predicate: &$($lt)? $($mut)? WherePredicate,
+        ) -> V::Result {
+            let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = predicate;
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            try_visit!(visit_span(vis, span));
+            vis.visit_where_predicate_kind(kind)
+        }
 
-pub fn walk_closure_binder<'a, V: Visitor<'a>>(
-    visitor: &mut V,
-    binder: &'a ClosureBinder,
-) -> V::Result {
-    match binder {
-        ClosureBinder::NotPresent => {}
-        ClosureBinder::For { generic_params, span: _ } => {
-            walk_list!(visitor, visit_generic_param, generic_params)
+        pub fn walk_closure_binder<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            binder: &$($lt)? $($mut)? ClosureBinder,
+        ) -> V::Result {
+            match binder {
+                ClosureBinder::NotPresent => {}
+                ClosureBinder::For { generic_params, span } => {
+                    try_visit!(visit_generic_params(vis, generic_params));
+                    try_visit!(visit_span(vis, span));
+                }
+            }
+            V::Result::output()
         }
-    }
-    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_kind<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            kind: &$($lt)? $($mut)? WherePredicateKind,
+        ) -> V::Result {
+            match kind {
+                WherePredicateKind::BoundPredicate(WhereBoundPredicate {
+                    bounded_ty,
+                    bounds,
+                    bound_generic_params,
+                }) => {
+                    visit_generic_params(vis, bound_generic_params);
+                    try_visit!(vis.visit_ty(bounded_ty));
+                    walk_list!(vis, visit_param_bound, bounds, BoundKind::Bound);
+                }
+                WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
+                    try_visit!(vis.visit_lifetime(lifetime, $(${ignore($lt)} LifetimeCtxt::Bound )?));
+                    walk_list!(vis, visit_param_bound, bounds, BoundKind::Bound);
+                }
+                WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
+                    try_visit!(vis.visit_ty(lhs_ty));
+                    try_visit!(vis.visit_ty(rhs_ty));
+                }
+            }
+            V::Result::output()
+        }
 
-pub fn walk_where_predicate<'a, V: Visitor<'a>>(
-    visitor: &mut V,
-    predicate: &'a WherePredicate,
-) -> V::Result {
-    let WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate;
-    walk_list!(visitor, visit_attribute, attrs);
-    visitor.visit_where_predicate_kind(kind)
-}
+        pub fn walk_fn_decl<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            FnDecl { inputs, output }: &$($lt)? $($mut)? FnDecl,
+        ) -> V::Result {
+            try_visit!(visit_params(vis, inputs));
+            vis.visit_fn_ret_ty(output)
+        }
 
-pub fn walk_where_predicate_kind<'a, V: Visitor<'a>>(
-    visitor: &mut V,
-    kind: &'a WherePredicateKind,
-) -> V::Result {
-    match kind {
-        WherePredicateKind::BoundPredicate(WhereBoundPredicate {
-            bounded_ty,
-            bounds,
-            bound_generic_params,
-        }) => {
-            walk_list!(visitor, visit_generic_param, bound_generic_params);
-            try_visit!(visitor.visit_ty(bounded_ty));
-            walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
+        pub fn walk_fn_ret_ty<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, ret_ty: &$($lt)? $($mut)? FnRetTy) -> V::Result {
+            match ret_ty {
+                FnRetTy::Default(span) => visit_span(vis, span),
+                FnRetTy::Ty(output_ty) => vis.visit_ty(output_ty),
+            }
         }
-        WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
-            try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound));
-            walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
+
+        pub fn walk_fn<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, kind: FnKind<$($lt)? $(${ignore($mut)} '_)?>) -> V::Result {
+            match kind {
+                FnKind::Fn(
+                    _ctxt,
+                    _vis,
+                    Fn {
+                        defaultness,
+                        ident,
+                        sig: FnSig { header, decl, span },
+                        generics,
+                        contract,
+                        body,
+                        define_opaque,
+                    },
+                ) => {
+                    // Visibility is visited as a part of the item.
+                    try_visit!(visit_defaultness(vis, defaultness));
+                    try_visit!(vis.visit_ident(ident));
+                    try_visit!(vis.visit_fn_header(header));
+                    try_visit!(vis.visit_generics(generics));
+                    try_visit!(vis.visit_fn_decl(decl));
+                    visit_opt!(vis, visit_contract, contract);
+                    visit_opt!(vis, visit_block, body);
+                    try_visit!(visit_span(vis, span));
+                    walk_define_opaques(vis, define_opaque)
+                }
+                FnKind::Closure(binder, coroutine_kind, decl, body) => {
+                    try_visit!(vis.visit_closure_binder(binder));
+                    visit_opt!(vis, visit_coroutine_kind, coroutine_kind);
+                    try_visit!(vis.visit_fn_decl(decl));
+                    vis.visit_expr(body)
+                }
+            }
         }
-        WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
-            try_visit!(visitor.visit_ty(lhs_ty));
-            try_visit!(visitor.visit_ty(rhs_ty));
+
+        pub fn walk_variant_data<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, data: &$($lt)? $($mut)? VariantData) -> V::Result {
+            match data {
+                VariantData::Struct { fields, recovered: _ } => {
+                    visit_field_defs(vis, fields)
+                }
+                VariantData::Tuple(fields, id) => {
+                    try_visit!(visit_id(vis, id));
+                    visit_field_defs(vis, fields)
+                }
+                VariantData::Unit(id) => visit_id(vis, id),
+            }
         }
-    }
-    V::Result::output()
-}
 
-pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) -> V::Result {
-    match ret_ty {
-        FnRetTy::Default(_span) => {}
-        FnRetTy::Ty(output_ty) => try_visit!(visitor.visit_ty(output_ty)),
-    }
-    V::Result::output()
-}
+        pub fn walk_field_def<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, field: &$($lt)? $($mut)? FieldDef) -> V::Result {
+            let FieldDef { attrs, id, span, vis: visibility, ident, ty, is_placeholder: _, safety: _, default } =
+                field;
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            try_visit!(vis.visit_vis(visibility));
+            visit_opt!(vis, visit_ident, ident);
+            try_visit!(vis.visit_ty(ty));
+            visit_opt!(vis, visit_anon_const, default);
+            visit_span(vis, span)
+        }
 
-pub fn walk_fn_decl<'a, V: Visitor<'a>>(
-    visitor: &mut V,
-    FnDecl { inputs, output }: &'a FnDecl,
-) -> V::Result {
-    walk_list!(visitor, visit_param, inputs);
-    visitor.visit_fn_ret_ty(output)
-}
+        fn visit_delim_args<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, args: &$($lt)? $($mut)? DelimArgs) -> V::Result {
+            let DelimArgs { dspan, delim: _, tokens: _ } = args;
+            let DelimSpan { open, close } = dspan;
+            try_visit!(visit_span(vis, open));
+            visit_span(vis, close)
+        }
+
+        pub fn walk_mac<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, mac: &$($lt)? $($mut)? MacCall) -> V::Result {
+            let MacCall { path, args } = mac;
+            try_visit!(vis.visit_path(path));
+            visit_delim_args(vis, args)
+        }
+
+        fn walk_macro_def<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, macro_def: &$($lt)? $($mut)? MacroDef) -> V::Result {
+            let MacroDef { body, macro_rules: _ } = macro_def;
+            visit_delim_args(vis, body)
+        }
+
+        pub fn walk_inline_asm<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, asm: &$($lt)? $($mut)? InlineAsm) -> V::Result {
+            // FIXME: Visit spans inside all this currently ignored stuff.
+            let InlineAsm {
+                asm_macro: _,
+                template: _,
+                template_strs: _,
+                operands,
+                clobber_abis: _,
+                options: _,
+                line_spans: _,
+            } = asm;
+            for (op, span) in operands {
+                match op {
+                    InlineAsmOperand::In { expr, reg: _ }
+                    | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ }
+                    | InlineAsmOperand::InOut { expr, reg: _, late: _ } => {
+                        try_visit!(vis.visit_expr(expr))
+                    }
+                    InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {}
+                    InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
+                        try_visit!(vis.visit_expr(in_expr));
+                        visit_opt!(vis, visit_expr, out_expr);
+                    }
+                    InlineAsmOperand::Const { anon_const } => {
+                        try_visit!(vis.visit_anon_const(anon_const))
+                    }
+                    InlineAsmOperand::Sym { sym } => try_visit!(vis.visit_inline_asm_sym(sym)),
+                    InlineAsmOperand::Label { block } => try_visit!(vis.visit_block(block)),
+                }
+                try_visit!(visit_span(vis, span));
+            }
+            V::Result::output()
+        }
 
-pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result {
-    match kind {
-        FnKind::Fn(
-            _ctxt,
-            _vis,
-            Fn {
-                defaultness: _,
-                ident,
-                sig: FnSig { header, decl, span: _ },
-                generics,
-                contract,
-                body,
-                define_opaque,
-            },
-        ) => {
-            // Visibility is visited as a part of the item.
-            try_visit!(visitor.visit_ident(ident));
-            try_visit!(visitor.visit_fn_header(header));
-            try_visit!(visitor.visit_generics(generics));
-            try_visit!(visitor.visit_fn_decl(decl));
-            visit_opt!(visitor, visit_contract, contract);
-            visit_opt!(visitor, visit_block, body);
-            try_visit!(walk_define_opaques(visitor, define_opaque));
-        }
-        FnKind::Closure(binder, coroutine_kind, decl, body) => {
-            try_visit!(visitor.visit_closure_binder(binder));
-            visit_opt!(visitor, visit_coroutine_kind, coroutine_kind.as_ref());
-            try_visit!(visitor.visit_fn_decl(decl));
-            try_visit!(visitor.visit_expr(body));
+        pub fn walk_inline_asm_sym<$($lt,)? V: $Visitor$(<$lt>)?>(
+            vis: &mut V,
+            InlineAsmSym { id, qself, path }: &$($lt)? $($mut)? InlineAsmSym,
+        ) -> V::Result {
+            try_visit!(visit_id(vis, id));
+            try_visit!(vis.visit_qself(qself));
+            vis.visit_path(path)
+        }
+
+        // FIXME: visit the template exhaustively.
+        pub fn walk_format_args<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, fmt: &$($lt)? $($mut)? FormatArgs) -> V::Result {
+            let FormatArgs { span, template: _, arguments, uncooked_fmt_str: _ } = fmt;
+            let args = $(${ignore($mut)} arguments.all_args_mut())? $(${ignore($lt)} arguments.all_args())? ;
+            for FormatArgument { kind, expr } in args {
+                match kind {
+                    FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => {
+                        try_visit!(vis.visit_ident(ident))
+                    }
+                    FormatArgumentKind::Normal => {}
+                }
+                try_visit!(vis.visit_expr(expr));
+            }
+            visit_span(vis, span)
         }
-    }
-    V::Result::output()
-}
 
-pub fn walk_variant_data<'a, V: Visitor<'a>>(visitor: &mut V, data: &'a VariantData) -> V::Result {
-    visit_opt!(visitor, visit_id, data.ctor_node_id());
-    walk_list!(visitor, visit_field_def, data.fields());
-    V::Result::output()
-}
+        pub fn walk_expr<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, expression: &$($lt)? $($mut)? Expr) -> V::Result {
+            let Expr { id, kind, span, attrs, tokens: _ } = expression;
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            match kind {
+                ExprKind::Array(exprs) => {
+                    try_visit!(visit_exprs(vis, exprs));
+                }
+                ExprKind::ConstBlock(anon_const) => try_visit!(vis.visit_anon_const(anon_const)),
+                ExprKind::Repeat(element, count) => {
+                    try_visit!(vis.visit_expr(element));
+                    try_visit!(vis.visit_anon_const(count));
+                }
+                ExprKind::Struct(se) => {
+                    let StructExpr { qself, path, fields, rest } = &$($mut)?**se;
+                    try_visit!(vis.visit_qself(qself));
+                    try_visit!(vis.visit_path(path));
+                    visit_expr_fields(vis, fields);
+                    match rest {
+                        StructRest::Base(expr) => try_visit!(vis.visit_expr(expr)),
+                        StructRest::Rest(_span) => {}
+                        StructRest::None => {}
+                    }
+                }
+                ExprKind::Tup(exprs) => {
+                    try_visit!(visit_exprs(vis, exprs));
+                }
+                ExprKind::Call(callee_expression, arguments) => {
+                    try_visit!(vis.visit_expr(callee_expression));
+                    try_visit!(visit_exprs(vis, arguments));
+                }
+                ExprKind::MethodCall(box MethodCall { seg, receiver, args, span }) => {
+                    try_visit!(vis.visit_method_receiver_expr(receiver));
+                    try_visit!(vis.visit_path_segment(seg));
+                    try_visit!(visit_exprs(vis, args));
+                    try_visit!(visit_span(vis, span));
+                }
+                ExprKind::Binary(Spanned { span, node: _ }, left_expression, right_expression) => {
+                    try_visit!(vis.visit_expr(left_expression));
+                    try_visit!(vis.visit_expr(right_expression));
+                    try_visit!(visit_span(vis, span))
+                }
+                ExprKind::AddrOf(_kind, _mutbl, subexpression) => {
+                    try_visit!(vis.visit_expr(subexpression));
+                }
+                ExprKind::Unary(_op, subexpression) => {
+                    try_visit!(vis.visit_expr(subexpression));
+                }
+                ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => {
+                    try_visit!(vis.visit_expr(subexpression));
+                    try_visit!(vis.visit_ty(typ));
+                }
+                ExprKind::Let(pat, expr, span, _recovered) => {
+                    try_visit!(vis.visit_pat(pat));
+                    try_visit!(vis.visit_expr(expr));
+                    try_visit!(visit_span(vis, span))
+                }
+                ExprKind::If(head_expression, if_block, optional_else) => {
+                    try_visit!(vis.visit_expr(head_expression));
+                    try_visit!(vis.visit_block(if_block));
+                    visit_opt!(vis, visit_expr, optional_else);
+                }
+                ExprKind::While(subexpression, block, opt_label) => {
+                    visit_opt!(vis, visit_label, opt_label);
+                    try_visit!(vis.visit_expr(subexpression));
+                    try_visit!(vis.visit_block(block));
+                }
+                ExprKind::ForLoop { pat, iter, body, label, kind: _ } => {
+                    visit_opt!(vis, visit_label, label);
+                    try_visit!(vis.visit_pat(pat));
+                    try_visit!(vis.visit_expr(iter));
+                    try_visit!(vis.visit_block(body));
+                }
+                ExprKind::Loop(block, opt_label, span) => {
+                    visit_opt!(vis, visit_label, opt_label);
+                    try_visit!(vis.visit_block(block));
+                    try_visit!(visit_span(vis, span))
+                }
+                ExprKind::Match(subexpression, arms, _kind) => {
+                    try_visit!(vis.visit_expr(subexpression));
+                    try_visit!(visit_arms(vis, arms));
+                }
+                ExprKind::Closure(box Closure {
+                    binder,
+                    capture_clause,
+                    coroutine_kind,
+                    constness,
+                    movability: _,
+                    fn_decl,
+                    body,
+                    fn_decl_span,
+                    fn_arg_span,
+                }) => {
+                    try_visit!(visit_constness(vis, constness));
+                    try_visit!(vis.visit_capture_by(capture_clause));
+                    try_visit!(vis.visit_fn(
+                        FnKind::Closure(binder, coroutine_kind, fn_decl, body),
+                        *span,
+                        *id
+                    ));
+                    try_visit!(visit_span(vis, fn_decl_span));
+                    try_visit!(visit_span(vis, fn_arg_span));
+                }
+                ExprKind::Block(block, opt_label) => {
+                    visit_opt!(vis, visit_label, opt_label);
+                    try_visit!(vis.visit_block(block));
+                }
+                ExprKind::Gen(_capt, body, _kind, decl_span) => {
+                    try_visit!(vis.visit_block(body));
+                    try_visit!(visit_span(vis, decl_span));
+                }
+                ExprKind::Await(expr, span) => {
+                    try_visit!(vis.visit_expr(expr));
+                    try_visit!(visit_span(vis, span));
+                }
+                ExprKind::Use(expr, span) => {
+                    try_visit!(vis.visit_expr(expr));
+                    try_visit!(visit_span(vis, span));
+                }
+                ExprKind::Assign(lhs, rhs, span) => {
+                    try_visit!(vis.visit_expr(lhs));
+                    try_visit!(vis.visit_expr(rhs));
+                    try_visit!(visit_span(vis, span));
+                }
+                ExprKind::AssignOp(_op, left_expression, right_expression) => {
+                    try_visit!(vis.visit_expr(left_expression));
+                    try_visit!(vis.visit_expr(right_expression));
+                }
+                ExprKind::Field(subexpression, ident) => {
+                    try_visit!(vis.visit_expr(subexpression));
+                    try_visit!(vis.visit_ident(ident));
+                }
+                ExprKind::Index(main_expression, index_expression, span) => {
+                    try_visit!(vis.visit_expr(main_expression));
+                    try_visit!(vis.visit_expr(index_expression));
+                    try_visit!(visit_span(vis, span));
+                }
+                ExprKind::Range(start, end, _limit) => {
+                    visit_opt!(vis, visit_expr, start);
+                    visit_opt!(vis, visit_expr, end);
+                }
+                ExprKind::Underscore => {}
+                ExprKind::Path(maybe_qself, path) => {
+                    try_visit!(vis.visit_qself(maybe_qself));
+                    try_visit!(vis.visit_path(path));
+                }
+                ExprKind::Break(opt_label, opt_expr) => {
+                    visit_opt!(vis, visit_label, opt_label);
+                    visit_opt!(vis, visit_expr, opt_expr);
+                }
+                ExprKind::Continue(opt_label) => {
+                    visit_opt!(vis, visit_label, opt_label);
+                }
+                ExprKind::Ret(optional_expression) => {
+                    visit_opt!(vis, visit_expr, optional_expression);
+                }
+                ExprKind::Yeet(optional_expression) => {
+                    visit_opt!(vis, visit_expr, optional_expression);
+                }
+                ExprKind::Become(expr) => try_visit!(vis.visit_expr(expr)),
+                ExprKind::MacCall(mac) => try_visit!(vis.visit_mac_call(mac)),
+                ExprKind::Paren(subexpression) => try_visit!(vis.visit_expr(subexpression)),
+                ExprKind::InlineAsm(asm) => try_visit!(vis.visit_inline_asm(asm)),
+                ExprKind::FormatArgs(f) => try_visit!(vis.visit_format_args(f)),
+                ExprKind::OffsetOf(container, fields) => {
+                    try_visit!(vis.visit_ty(container));
+                    walk_list!(vis, visit_ident, fields);
+                }
+                ExprKind::Yield(kind) => {
+                    match kind {
+                        YieldKind::Postfix(expr) => {
+                            try_visit!(vis.visit_expr(expr));
+                        }
+                        YieldKind::Prefix(expr) => {
+                            visit_opt!(vis, visit_expr, expr);
+                        }
+                    }
+                }
+                ExprKind::Try(subexpression) => try_visit!(vis.visit_expr(subexpression)),
+                ExprKind::TryBlock(body) => try_visit!(vis.visit_block(body)),
+                ExprKind::Lit(_token) => {}
+                ExprKind::IncludedBytes(_bytes) => {}
+                ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
+                    try_visit!(vis.visit_expr(expr));
+                    visit_opt!(vis, visit_ty, ty);
+                }
+                ExprKind::Err(_guar) => {}
+                ExprKind::Dummy => {}
+            }
 
-pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result {
-    let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _, safety: _, default } =
-        field;
-    walk_list!(visitor, visit_attribute, attrs);
-    try_visit!(visitor.visit_vis(vis));
-    visit_opt!(visitor, visit_ident, ident);
-    try_visit!(visitor.visit_ty(ty));
-    visit_opt!(visitor, visit_anon_const, &*default);
-    V::Result::output()
-}
+            visit_span(vis, span)
+        }
 
-pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result {
-    let Stmt { id: _, kind, span: _ } = statement;
-    match kind {
-        StmtKind::Let(local) => try_visit!(visitor.visit_local(local)),
-        StmtKind::Item(item) => try_visit!(visitor.visit_item(item)),
-        StmtKind::Expr(expr) | StmtKind::Semi(expr) => try_visit!(visitor.visit_expr(expr)),
-        StmtKind::Empty => {}
-        StmtKind::MacCall(mac) => {
-            let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac;
-            walk_list!(visitor, visit_attribute, attrs);
-            try_visit!(visitor.visit_mac_call(mac));
+        pub fn walk_param<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, param: &$($lt)? $($mut)? Param) -> V::Result {
+            let Param { attrs, ty, pat, id, span, is_placeholder: _ } = param;
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            try_visit!(vis.visit_pat(pat));
+            try_visit!(vis.visit_ty(ty));
+            visit_span(vis, span)
         }
-    }
-    V::Result::output()
-}
 
-pub fn walk_mac<'a, V: Visitor<'a>>(visitor: &mut V, mac: &'a MacCall) -> V::Result {
-    let MacCall { path, args: _ } = mac;
-    visitor.visit_path(path)
-}
+        pub fn walk_arm<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, arm: &$($lt)? $($mut)? Arm) -> V::Result {
+            let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm;
+            try_visit!(visit_id(vis, id));
+            walk_list!(vis, visit_attribute, attrs);
+            try_visit!(vis.visit_pat(pat));
+            visit_opt!(vis, visit_expr, guard);
+            visit_opt!(vis, visit_expr, body);
+            visit_span(vis, span)
+        }
 
-pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) -> V::Result {
-    let InlineAsm {
-        asm_macro: _,
-        template: _,
-        template_strs: _,
-        operands,
-        clobber_abis: _,
-        options: _,
-        line_spans: _,
-    } = asm;
-    for (op, _span) in operands {
-        match op {
-            InlineAsmOperand::In { expr, reg: _ }
-            | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ }
-            | InlineAsmOperand::InOut { expr, reg: _, late: _ } => {
-                try_visit!(visitor.visit_expr(expr))
-            }
-            InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {}
-            InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
-                try_visit!(visitor.visit_expr(in_expr));
-                visit_opt!(visitor, visit_expr, out_expr);
-            }
-            InlineAsmOperand::Const { anon_const } => {
-                try_visit!(visitor.visit_anon_const(anon_const))
+        pub fn walk_vis<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, visibility: &$($lt)? $($mut)? Visibility) -> V::Result {
+            let Visibility { kind, span, tokens: _ } = visibility;
+            match kind {
+                VisibilityKind::Restricted { path, id, shorthand: _ } => {
+                    try_visit!(visit_id(vis, id));
+                    try_visit!(vis.visit_path(path));
+                }
+                VisibilityKind::Public | VisibilityKind::Inherited => {}
             }
-            InlineAsmOperand::Sym { sym } => try_visit!(visitor.visit_inline_asm_sym(sym)),
-            InlineAsmOperand::Label { block } => try_visit!(visitor.visit_block(block)),
+            visit_span(vis, span)
         }
-    }
-    V::Result::output()
-}
 
-pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(
-    visitor: &mut V,
-    InlineAsmSym { id, qself, path }: &'a InlineAsmSym,
-) -> V::Result {
-    try_visit!(visitor.visit_qself(qself));
-    try_visit!(visitor.visit_id(*id));
-    visitor.visit_path(path)
-}
-
-pub fn walk_format_args<'a, V: Visitor<'a>>(visitor: &mut V, fmt: &'a FormatArgs) -> V::Result {
-    let FormatArgs { span: _, template: _, arguments, uncooked_fmt_str: _ } = fmt;
-    for FormatArgument { kind, expr } in arguments.all_args() {
-        match kind {
-            FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => {
-                try_visit!(visitor.visit_ident(ident))
+        pub fn walk_attribute<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, attr: &$($lt)? $($mut)? Attribute) -> V::Result {
+            let Attribute { kind, id: _, style: _, span } = attr;
+            match kind {
+                AttrKind::Normal(normal) => {
+                    let NormalAttr { item, tokens: _ } = &$($mut)?**normal;
+                    let AttrItem { unsafety: _, path, args, tokens: _ } = item;
+                    try_visit!(vis.visit_path(path));
+                    try_visit!(walk_attr_args(vis, args));
+                }
+                AttrKind::DocComment(_kind, _sym) => {}
             }
-            FormatArgumentKind::Normal => {}
+            visit_span(vis, span)
         }
-        try_visit!(visitor.visit_expr(expr));
-    }
-    V::Result::output()
-}
 
-pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V::Result {
-    let Expr { id, kind, span, attrs, tokens: _ } = expression;
-    walk_list!(visitor, visit_attribute, attrs);
-    match kind {
-        ExprKind::Array(subexpressions) => {
-            walk_list!(visitor, visit_expr, subexpressions);
-        }
-        ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)),
-        ExprKind::Repeat(element, count) => {
-            try_visit!(visitor.visit_expr(element));
-            try_visit!(visitor.visit_anon_const(count));
-        }
-        ExprKind::Struct(se) => {
-            let StructExpr { qself, path, fields, rest } = &**se;
-            try_visit!(visitor.visit_qself(qself));
-            try_visit!(visitor.visit_id(*id));
-            try_visit!(visitor.visit_path(path));
-            walk_list!(visitor, visit_expr_field, fields);
-            match rest {
-                StructRest::Base(expr) => try_visit!(visitor.visit_expr(expr)),
-                StructRest::Rest(_span) => {}
-                StructRest::None => {}
+        pub fn walk_attr_args<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, args: &$($lt)? $($mut)? AttrArgs) -> V::Result {
+            match args {
+                AttrArgs::Empty => {}
+                AttrArgs::Delimited(args) => try_visit!(visit_delim_args(vis, args)),
+                AttrArgs::Eq { eq_span, expr } => {
+                    try_visit!(vis.visit_expr(expr));
+                    try_visit!(visit_span(vis, eq_span));
+                }
             }
+            V::Result::output()
         }
-        ExprKind::Tup(subexpressions) => {
-            walk_list!(visitor, visit_expr, subexpressions);
-        }
-        ExprKind::Call(callee_expression, arguments) => {
-            try_visit!(visitor.visit_expr(callee_expression));
-            walk_list!(visitor, visit_expr, arguments);
-        }
-        ExprKind::MethodCall(box MethodCall { seg, receiver, args, span: _ }) => {
-            try_visit!(visitor.visit_expr(receiver));
-            try_visit!(visitor.visit_path_segment(seg));
-            walk_list!(visitor, visit_expr, args);
-        }
-        ExprKind::Binary(_op, left_expression, right_expression) => {
-            try_visit!(visitor.visit_expr(left_expression));
-            try_visit!(visitor.visit_expr(right_expression));
-        }
-        ExprKind::AddrOf(_kind, _mutbl, subexpression) => {
-            try_visit!(visitor.visit_expr(subexpression));
-        }
-        ExprKind::Unary(_op, subexpression) => {
-            try_visit!(visitor.visit_expr(subexpression));
-        }
-        ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => {
-            try_visit!(visitor.visit_expr(subexpression));
-            try_visit!(visitor.visit_ty(typ));
-        }
-        ExprKind::Let(pat, expr, _span, _recovered) => {
-            try_visit!(visitor.visit_pat(pat));
-            try_visit!(visitor.visit_expr(expr));
-        }
-        ExprKind::If(head_expression, if_block, optional_else) => {
-            try_visit!(visitor.visit_expr(head_expression));
-            try_visit!(visitor.visit_block(if_block));
-            visit_opt!(visitor, visit_expr, optional_else);
-        }
-        ExprKind::While(subexpression, block, opt_label) => {
-            visit_opt!(visitor, visit_label, opt_label);
-            try_visit!(visitor.visit_expr(subexpression));
-            try_visit!(visitor.visit_block(block));
-        }
-        ExprKind::ForLoop { pat, iter, body, label, kind: _ } => {
-            visit_opt!(visitor, visit_label, label);
-            try_visit!(visitor.visit_pat(pat));
-            try_visit!(visitor.visit_expr(iter));
-            try_visit!(visitor.visit_block(body));
-        }
-        ExprKind::Loop(block, opt_label, _span) => {
-            visit_opt!(visitor, visit_label, opt_label);
-            try_visit!(visitor.visit_block(block));
-        }
-        ExprKind::Match(subexpression, arms, _kind) => {
-            try_visit!(visitor.visit_expr(subexpression));
-            walk_list!(visitor, visit_arm, arms);
-        }
-        ExprKind::Closure(box Closure {
-            binder,
-            capture_clause,
-            coroutine_kind,
-            constness: _,
-            movability: _,
-            fn_decl,
-            body,
-            fn_decl_span: _,
-            fn_arg_span: _,
-        }) => {
-            try_visit!(visitor.visit_capture_by(capture_clause));
-            try_visit!(visitor.visit_fn(
-                FnKind::Closure(binder, coroutine_kind, fn_decl, body),
-                *span,
-                *id
-            ));
-        }
-        ExprKind::Block(block, opt_label) => {
-            visit_opt!(visitor, visit_label, opt_label);
-            try_visit!(visitor.visit_block(block));
-        }
-        ExprKind::Gen(_capt, body, _kind, _decl_span) => try_visit!(visitor.visit_block(body)),
-        ExprKind::Await(expr, _span) => try_visit!(visitor.visit_expr(expr)),
-        ExprKind::Use(expr, _span) => try_visit!(visitor.visit_expr(expr)),
-        ExprKind::Assign(lhs, rhs, _span) => {
-            try_visit!(visitor.visit_expr(lhs));
-            try_visit!(visitor.visit_expr(rhs));
-        }
-        ExprKind::AssignOp(_op, left_expression, right_expression) => {
-            try_visit!(visitor.visit_expr(left_expression));
-            try_visit!(visitor.visit_expr(right_expression));
-        }
-        ExprKind::Field(subexpression, ident) => {
-            try_visit!(visitor.visit_expr(subexpression));
-            try_visit!(visitor.visit_ident(ident));
-        }
-        ExprKind::Index(main_expression, index_expression, _span) => {
-            try_visit!(visitor.visit_expr(main_expression));
-            try_visit!(visitor.visit_expr(index_expression));
-        }
-        ExprKind::Range(start, end, _limit) => {
-            visit_opt!(visitor, visit_expr, start);
-            visit_opt!(visitor, visit_expr, end);
-        }
-        ExprKind::Underscore => {}
-        ExprKind::Path(maybe_qself, path) => {
-            try_visit!(visitor.visit_qself(maybe_qself));
-            try_visit!(visitor.visit_id(*id));
-            try_visit!(visitor.visit_path(path));
-        }
-        ExprKind::Break(opt_label, opt_expr) => {
-            visit_opt!(visitor, visit_label, opt_label);
-            visit_opt!(visitor, visit_expr, opt_expr);
-        }
-        ExprKind::Continue(opt_label) => {
-            visit_opt!(visitor, visit_label, opt_label);
-        }
-        ExprKind::Ret(optional_expression) => {
-            visit_opt!(visitor, visit_expr, optional_expression);
-        }
-        ExprKind::Yeet(optional_expression) => {
-            visit_opt!(visitor, visit_expr, optional_expression);
-        }
-        ExprKind::Become(expr) => try_visit!(visitor.visit_expr(expr)),
-        ExprKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
-        ExprKind::Paren(subexpression) => try_visit!(visitor.visit_expr(subexpression)),
-        ExprKind::InlineAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
-        ExprKind::FormatArgs(f) => try_visit!(visitor.visit_format_args(f)),
-        ExprKind::OffsetOf(container, fields) => {
-            try_visit!(visitor.visit_ty(container));
-            walk_list!(visitor, visit_ident, fields.iter());
-        }
-        ExprKind::Yield(kind) => {
-            visit_opt!(visitor, visit_expr, kind.expr());
-        }
-        ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)),
-        ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)),
-        ExprKind::Lit(_token) => {}
-        ExprKind::IncludedBytes(_bytes) => {}
-        ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
-            try_visit!(visitor.visit_expr(expr));
-            visit_opt!(visitor, visit_ty, ty);
-        }
-        ExprKind::Err(_guar) => {}
-        ExprKind::Dummy => {}
-    }
-
-    V::Result::output()
+    };
 }
 
-pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) -> V::Result {
-    let Param { attrs, ty, pat, id: _, span: _, is_placeholder: _ } = param;
-    walk_list!(visitor, visit_attribute, attrs);
-    try_visit!(visitor.visit_pat(pat));
-    try_visit!(visitor.visit_ty(ty));
-    V::Result::output()
+common_visitor_and_walkers!(Visitor<'a>);
+
+macro_rules! generate_list_visit_fns {
+    ($($name:ident, $Ty:ty, $visit_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => {
+        $(
+            fn $name<'a, V: Visitor<'a>>(
+                vis: &mut V,
+                values: &'a ThinVec<$Ty>,
+                $(
+                    $param: $ParamTy,
+                )*
+            ) -> V::Result {
+                walk_list!(vis, $visit_fn, values$(,$param)*);
+                V::Result::output()
+            }
+        )+
+    }
 }
 
-pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) -> V::Result {
-    let Arm { attrs, pat, guard, body, span: _, id: _, is_placeholder: _ } = arm;
-    walk_list!(visitor, visit_attribute, attrs);
-    try_visit!(visitor.visit_pat(pat));
-    visit_opt!(visitor, visit_expr, guard);
-    visit_opt!(visitor, visit_expr, body);
-    V::Result::output()
+generate_list_visit_fns! {
+    visit_items, P<Item>, visit_item;
+    visit_foreign_items, P<ForeignItem>, visit_foreign_item;
+    visit_generic_params, GenericParam, visit_generic_param;
+    visit_stmts, Stmt, visit_stmt;
+    visit_exprs, P<Expr>, visit_expr;
+    visit_expr_fields, ExprField, visit_expr_field;
+    visit_pat_fields, PatField, visit_pat_field;
+    visit_variants, Variant, visit_variant;
+    visit_assoc_items, P<AssocItem>, visit_assoc_item, ctxt: AssocCtxt;
+    visit_where_predicates, WherePredicate, visit_where_predicate;
+    visit_params, Param, visit_param;
+    visit_field_defs, FieldDef, visit_field_def;
+    visit_arms, Arm, visit_arm;
 }
 
-pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) -> V::Result {
-    let Visibility { kind, span: _, tokens: _ } = vis;
-    match kind {
-        VisibilityKind::Restricted { path, id, shorthand: _ } => {
-            try_visit!(visitor.visit_id(*id));
-            try_visit!(visitor.visit_path(path));
-        }
-        VisibilityKind::Public | VisibilityKind::Inherited => {}
-    }
-    V::Result::output()
+#[expect(rustc::pass_by_value)] // needed for symmetry with mut_visit
+fn visit_nested_use_tree<'a, V: Visitor<'a>>(
+    vis: &mut V,
+    nested_tree: &'a UseTree,
+    &nested_id: &NodeId,
+) -> V::Result {
+    vis.visit_nested_use_tree(nested_tree, nested_id)
 }
 
-pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) -> V::Result {
-    let Attribute { kind, id: _, style: _, span: _ } = attr;
+pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result {
+    let Stmt { id: _, kind, span: _ } = statement;
     match kind {
-        AttrKind::Normal(normal) => {
-            let NormalAttr { item, tokens: _ } = &**normal;
-            let AttrItem { unsafety: _, path, args, tokens: _ } = item;
-            try_visit!(visitor.visit_path(path));
-            try_visit!(walk_attr_args(visitor, args));
+        StmtKind::Let(local) => try_visit!(visitor.visit_local(local)),
+        StmtKind::Item(item) => try_visit!(visitor.visit_item(item)),
+        StmtKind::Expr(expr) | StmtKind::Semi(expr) => try_visit!(visitor.visit_expr(expr)),
+        StmtKind::Empty => {}
+        StmtKind::MacCall(mac) => {
+            let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac;
+            walk_list!(visitor, visit_attribute, attrs);
+            try_visit!(visitor.visit_mac_call(mac));
         }
-        AttrKind::DocComment(_kind, _sym) => {}
-    }
-    V::Result::output()
-}
-
-pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -> V::Result {
-    match args {
-        AttrArgs::Empty => {}
-        AttrArgs::Delimited(_args) => {}
-        AttrArgs::Eq { expr, .. } => try_visit!(visitor.visit_expr(expr)),
     }
     V::Result::output()
 }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index f41627e479f..b99df8bd7e5 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -33,9 +33,7 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![doc(rust_logo)]
-#![feature(assert_matches)]
 #![feature(box_patterns)]
-#![feature(exact_size_is_empty)]
 #![feature(if_let_guard)]
 #![feature(rustdoc_internals)]
 // tidy-alphabetical-end
@@ -732,7 +730,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         span: Span,
         args: Option<&'hir hir::GenericArgs<'hir>>,
     ) -> &'hir hir::Path<'hir> {
-        let def_id = self.tcx.require_lang_item(lang_item, Some(span));
+        let def_id = self.tcx.require_lang_item(lang_item, span);
         let def_kind = self.tcx.def_kind(def_id);
         let res = Res::Def(def_kind, def_id);
         self.arena.alloc(hir::Path {
@@ -1406,7 +1404,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 };
                 let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
                 let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
-                (region, LifetimeSyntax::Hidden)
+                (region, LifetimeSyntax::Implicit)
             }
         };
         self.lower_lifetime(&region, LifetimeSource::Reference, syntax)
@@ -1790,7 +1788,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             id,
             Ident::new(kw::UnderscoreLifetime, span),
             LifetimeSource::Path { angle_brackets },
-            LifetimeSyntax::Hidden,
+            LifetimeSyntax::Implicit,
         )
     }
 
@@ -2422,7 +2420,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
             hir::LifetimeKind::ImplicitObjectLifetimeDefault,
             LifetimeSource::Other,
-            LifetimeSyntax::Hidden,
+            LifetimeSyntax::Implicit,
         );
         debug!("elided_dyn_bound: r={:?}", r);
         self.arena.alloc(r)
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs
index d2d1285b075..845e4d5e5d0 100644
--- a/compiler/rustc_attr_data_structures/src/attributes.rs
+++ b/compiler/rustc_attr_data_structures/src/attributes.rs
@@ -57,14 +57,6 @@ impl OptimizeAttr {
     }
 }
 
-#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic, PrintAttribute)]
-pub enum DiagnosticAttribute {
-    // tidy-alphabetical-start
-    DoNotRecommend,
-    OnUnimplemented,
-    // tidy-alphabetical-end
-}
-
 #[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone, HashStable_Generic, PrintAttribute)]
 pub enum ReprAttr {
     ReprInt(IntType),
@@ -160,40 +152,52 @@ impl Deprecation {
 #[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
 pub enum AttributeKind {
     // tidy-alphabetical-start
+    /// Represents `#[rustc_allow_const_fn_unstable]`.
     AllowConstFnUnstable(ThinVec<Symbol>),
+
+    /// Represents `#[allow_internal_unstable]`.
     AllowInternalUnstable(ThinVec<(Symbol, Span)>),
+
+    /// Represents `#[rustc_default_body_unstable]`.
     BodyStability {
         stability: DefaultBodyStability,
         /// Span of the `#[rustc_default_body_unstable(...)]` attribute
         span: Span,
     },
+
+    /// Represents `#[rustc_confusables]`.
     Confusables {
         symbols: ThinVec<Symbol>,
         // FIXME(jdonszelmann): remove when target validation code is moved
         first_span: Span,
     },
+
+    /// Represents `#[rustc_const_stable]` and `#[rustc_const_unstable]`.
     ConstStability {
         stability: PartialConstStability,
         /// Span of the `#[rustc_const_stable(...)]` or `#[rustc_const_unstable(...)]` attribute
         span: Span,
     },
+
+    /// Represents `#[rustc_const_stable_indirect]`.
     ConstStabilityIndirect,
-    Deprecation {
-        deprecation: Deprecation,
-        span: Span,
-    },
-    Diagnostic(DiagnosticAttribute),
-    DocComment {
-        style: AttrStyle,
-        kind: CommentKind,
-        span: Span,
-        comment: Symbol,
-    },
+
+    /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute).
+    Deprecation { deprecation: Deprecation, span: Span },
+
+    /// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html).
+    DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol },
+
+    /// Represents `#[rustc_macro_transparency]`.
     MacroTransparency(Transparency),
+
+    /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
     Repr(ThinVec<(ReprAttr, Span)>),
+
+    /// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`.
     Stability {
         stability: Stability,
-        /// Span of the `#[stable(...)]` or `#[unstable(...)]` attribute
+        /// Span of the attribute.
         span: Span,
     },
     // tidy-alphabetical-end
diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
index f45cf984f71..bf18e10e19f 100644
--- a/compiler/rustc_attr_parsing/src/attributes/mod.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
@@ -74,7 +74,7 @@ pub(crate) trait AttributeParser: Default + 'static {
 pub(crate) trait SingleAttributeParser: 'static {
     const PATH: &'static [Symbol];
 
-    /// Caled when a duplicate attribute is found.
+    /// Called when a duplicate attribute is found.
     ///
     /// `first_span` is the span of the first occurrence of this attribute.
     // FIXME(jdonszelmann): default error
diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs
index 63bccf52018..15037e802ff 100644
--- a/compiler/rustc_attr_parsing/src/lib.rs
+++ b/compiler/rustc_attr_parsing/src/lib.rs
@@ -1,31 +1,38 @@
 //! Centralized logic for parsing and attributes.
 //!
-//! Part of a series of crates:
-//! - rustc_attr_data_structures: contains types that the parsers parse into
-//! - rustc_attr_parsing: this crate
-//! - (in the future): rustc_attr_validation
+//! ## Architecture
+//! This crate is part of a series of crates that handle attribute processing.
+//! - [rustc_attr_data_structures](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_data_structures/index.html): Defines the data structures that store parsed attributes
+//! - [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html): This crate, handles the parsing of attributes
+//! - (planned) rustc_attr_validation: Will handle attribute validation
 //!
-//! History: Check out [#131229](https://github.com/rust-lang/rust/issues/131229).
-//! There used to be only one definition of attributes in the compiler: `ast::Attribute`.
-//! These were then parsed or validated or both in places distributed all over the compiler.
-//! This was a mess...
+//! The separation between data structures and parsing follows the principle of separation of concerns.
+//! Data structures (`rustc_attr_data_structures`) define what attributes look like after parsing.
+//! This crate (`rustc_attr_parsing`) handles how to convert raw tokens into those structures.
+//! This split allows other parts of the compiler to use the data structures without needing
+//! the parsing logic, making the codebase more modular and maintainable.
 //!
-//! Attributes are markers on items.
-//! Many of them are actually attribute-like proc-macros, and are expanded to some other rust syntax.
-//! This could either be a user provided proc macro, or something compiler provided.
-//! `derive` is an example of one that the compiler provides.
-//! These are built-in, but they have a valid expansion to Rust tokens and are thus called "active".
-//! I personally like calling these *active* compiler-provided attributes, built-in *macros*,
-//! because they still expand, and this helps to differentiate them from built-in *attributes*.
-//! However, I'll be the first to admit that the naming here can be confusing.
+//! ## Background
+//! Previously, the compiler had a single attribute definition (`ast::Attribute`) with parsing and
+//! validation scattered throughout the codebase. This was reorganized for better maintainability
+//! (see [#131229](https://github.com/rust-lang/rust/issues/131229)).
 //!
-//! The alternative to active attributes, are inert attributes.
-//! These can occur in user code (proc-macro helper attributes).
-//! But what's important is, many built-in attributes are inert like this.
-//! There is nothing they expand to during the macro expansion process,
-//! sometimes because they literally cannot expand to something that is valid Rust.
-//! They are really just markers to guide the compilation process.
-//! An example is `#[inline(...)]` which changes how code for functions is generated.
+//! ## Types of Attributes
+//! In Rust, attributes are markers that can be attached to items. They come in two main categories.
+//!
+//! ### 1. Active Attributes
+//! These are attribute-like proc-macros that expand into other Rust code.
+//! They can be either user-defined or compiler-provided. Examples of compiler-provided active attributes:
+//!   - `#[derive(...)]`: Expands into trait implementations
+//!   - `#[cfg()]`: Expands based on configuration
+//!   - `#[cfg_attr()]`: Conditional attribute application
+//!
+//! ### 2. Inert Attributes
+//! These are pure markers that don't expand into other code. They guide the compilation process.
+//! They can be user-defined (in proc-macro helpers) or built-in. Examples of built-in inert attributes:
+//!   - `#[stable()]`: Marks stable API items
+//!   - `#[inline()]`: Suggests function inlining
+//!   - `#[repr()]`: Controls type representation
 //!
 //! ```text
 //!                      Active                 Inert
@@ -33,27 +40,21 @@
 //!              │     (mostly in)      │    these are parsed  │
 //!              │ rustc_builtin_macros │        here!         │
 //!              │                      │                      │
-//!              │                      │                      │
 //!              │    #[derive(...)]    │    #[stable()]       │
 //!     Built-in │    #[cfg()]          │    #[inline()]       │
 //!              │    #[cfg_attr()]     │    #[repr()]         │
 //!              │                      │                      │
-//!              │                      │                      │
-//!              │                      │                      │
 //!              ├──────────────────────┼──────────────────────┤
 //!              │                      │                      │
-//!              │                      │                      │
 //!              │                      │       `b` in         │
 //!              │                      │ #[proc_macro_derive( │
 //! User created │ #[proc_macro_attr()] │    a,                │
 //!              │                      │    attributes(b)     │
 //!              │                      │ ]                    │
-//!              │                      │                      │
-//!              │                      │                      │
-//!              │                      │                      │
 //!              └──────────────────────┴──────────────────────┘
 //! ```
 //!
+//! ## How This Crate Works
 //! In this crate, syntactical attributes (sequences of tokens that look like
 //! `#[something(something else)]`) are parsed into more semantic attributes, markers on items.
 //! Multiple syntactic attributes might influence a single semantic attribute. For example,
@@ -63,18 +64,17 @@
 //! and `#[unstable()]` syntactic attributes, and at the end produce a single
 //! [`AttributeKind::Stability`](rustc_attr_data_structures::AttributeKind::Stability).
 //!
-//! As a rule of thumb, when a syntactical attribute can be applied more than once, they should be
-//! combined into a single semantic attribute. For example:
+//! When multiple instances of the same attribute are allowed, they're combined into a single
+//! semantic attribute. For example:
 //!
-//! ```
+//! ```rust
 //! #[repr(C)]
 //! #[repr(packed)]
 //! struct Meow {}
 //! ```
 //!
-//! should result in a single `AttributeKind::Repr` containing a list of repr annotations, in this
-//! case `C` and `packed`. This is equivalent to writing `#[repr(C, packed)]` in a single
-//! syntactical annotation.
+//! This is equivalent to `#[repr(C, packed)]` and results in a single `AttributeKind::Repr`
+//! containing both `C` and `packed` annotations.
 
 // tidy-alphabetical-start
 #![allow(internal_features)]
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index b7b6a2da549..1b4bb11d87b 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -263,7 +263,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 // something that already has `Fn`-like bounds (or is a closure), so we can't
                 // restrict anyways.
             } else {
-                let copy_did = self.infcx.tcx.require_lang_item(LangItem::Copy, Some(span));
+                let copy_did = self.infcx.tcx.require_lang_item(LangItem::Copy, span);
                 self.suggest_adding_bounds(&mut err, ty, copy_did, span);
             }
 
@@ -1915,7 +1915,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
 
         let local_ty = self.body.local_decls[place.local].ty;
         let typeck_results = tcx.typeck(self.mir_def_id());
-        let clone = tcx.require_lang_item(LangItem::Clone, Some(body.span));
+        let clone = tcx.require_lang_item(LangItem::Clone, body.span);
         for expr in expr_finder.clones {
             if let hir::ExprKind::MethodCall(_, rcvr, _, span) = expr.kind
                 && let Some(rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id)
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 4f5baeff7c3..4f75dd7e992 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -688,7 +688,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 if !self.unsized_feature_enabled() {
                     let trait_ref = ty::TraitRef::new(
                         tcx,
-                        tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
+                        tcx.require_lang_item(LangItem::Sized, self.last_span),
                         [place_ty],
                     );
                     self.prove_trait_ref(
@@ -1010,7 +1010,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                             let ty = place.ty(self.body, tcx).ty;
                             let trait_ref = ty::TraitRef::new(
                                 tcx,
-                                tcx.require_lang_item(LangItem::Copy, Some(span)),
+                                tcx.require_lang_item(LangItem::Copy, span),
                                 [ty],
                             );
 
@@ -1025,11 +1025,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             }
 
             &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
-                let trait_ref = ty::TraitRef::new(
-                    tcx,
-                    tcx.require_lang_item(LangItem::Sized, Some(span)),
-                    [ty],
-                );
+                let trait_ref =
+                    ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [ty]);
 
                 self.prove_trait_ref(
                     trait_ref,
@@ -1041,11 +1038,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             &Rvalue::NullaryOp(NullOp::UbChecks, _) => {}
 
             Rvalue::ShallowInitBox(_operand, ty) => {
-                let trait_ref = ty::TraitRef::new(
-                    tcx,
-                    tcx.require_lang_item(LangItem::Sized, Some(span)),
-                    [*ty],
-                );
+                let trait_ref =
+                    ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [*ty]);
 
                 self.prove_trait_ref(
                     trait_ref,
@@ -1222,7 +1216,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         let &ty = ty;
                         let trait_ref = ty::TraitRef::new(
                             tcx,
-                            tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)),
+                            tcx.require_lang_item(LangItem::CoerceUnsized, span),
                             [op.ty(self.body, tcx), ty],
                         );
 
@@ -1811,7 +1805,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
         if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
             let trait_ref = ty::TraitRef::new(
                 tcx,
-                tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
+                tcx.require_lang_item(LangItem::Copy, self.last_span),
                 [place_ty.ty],
             );
 
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index c11e14d214c..846299711be 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -544,10 +544,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         // (as it's created inside the body itself, not passed in from outside).
         if let DefiningTy::FnDef(def_id, _) = defining_ty {
             if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() {
-                let va_list_did = self.infcx.tcx.require_lang_item(
-                    LangItem::VaList,
-                    Some(self.infcx.tcx.def_span(self.mir_def)),
-                );
+                let va_list_did = self
+                    .infcx
+                    .tcx
+                    .require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def));
 
                 let reg_vid = self
                     .infcx
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index 50e7b989ed8..e45d09b5796 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -57,7 +57,7 @@ impl MultiItemModifier for BuiltinDerive {
         let mut items = Vec::new();
         match item {
             Annotatable::Stmt(stmt) => {
-                if let ast::StmtKind::Item(item) = stmt.into_inner().kind {
+                if let ast::StmtKind::Item(item) = stmt.kind {
                     (self.0)(
                         ecx,
                         span,
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index aa52c3bd281..9e7d0ec9e81 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -15,7 +15,6 @@
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
 #![feature(rustdoc_internals)]
-#![feature(string_from_utf8_lossy_owned)]
 #![feature(try_blocks)]
 #![recursion_limit = "256"]
 // tidy-alphabetical-end
diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs
index 3529e5525fc..b61af0b0aaa 100644
--- a/compiler/rustc_builtin_macros/src/pattern_type.rs
+++ b/compiler/rustc_builtin_macros/src/pattern_type.rs
@@ -30,14 +30,12 @@ fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P
 
     let pat = pat_to_ty_pat(
         cx,
-        parser
-            .parse_pat_no_top_guard(
-                None,
-                RecoverComma::No,
-                RecoverColon::No,
-                CommaRecoveryMode::EitherTupleOrPipe,
-            )?
-            .into_inner(),
+        *parser.parse_pat_no_top_guard(
+            None,
+            RecoverComma::No,
+            RecoverColon::No,
+            CommaRecoveryMode::EitherTupleOrPipe,
+        )?,
     );
 
     if parser.token != token::Eof {
@@ -58,9 +56,9 @@ fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> P<TyPat> {
             end.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
             include_end,
         ),
-        ast::PatKind::Or(variants) => TyPatKind::Or(
-            variants.into_iter().map(|pat| pat_to_ty_pat(cx, pat.into_inner())).collect(),
-        ),
+        ast::PatKind::Or(variants) => {
+            TyPatKind::Or(variants.into_iter().map(|pat| pat_to_ty_pat(cx, *pat)).collect())
+        }
         ast::PatKind::Err(guar) => TyPatKind::Err(guar),
         _ => TyPatKind::Err(cx.dcx().span_err(pat.span, "pattern not supported in pattern types")),
     };
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index a91f2d38a93..daf480a9ce4 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -354,30 +354,28 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
         })
         .collect();
 
-    let decls_static = cx
-        .item_static(
+    let mut decls_static = cx.item_static(
+        span,
+        Ident::new(sym::_DECLS, span),
+        cx.ty_ref(
             span,
-            Ident::new(sym::_DECLS, span),
-            cx.ty_ref(
+            cx.ty(
                 span,
-                cx.ty(
-                    span,
-                    ast::TyKind::Slice(
-                        cx.ty_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty])),
-                    ),
+                ast::TyKind::Slice(
+                    cx.ty_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty])),
                 ),
-                None,
-                ast::Mutability::Not,
             ),
+            None,
             ast::Mutability::Not,
-            cx.expr_array_ref(span, decls),
-        )
-        .map(|mut i| {
-            i.attrs.push(cx.attr_word(sym::rustc_proc_macro_decls, span));
-            i.attrs.push(cx.attr_word(sym::used, span));
-            i.attrs.push(cx.attr_nested_word(sym::allow, sym::deprecated, span));
-            i
-        });
+        ),
+        ast::Mutability::Not,
+        cx.expr_array_ref(span, decls),
+    );
+    decls_static.attrs.extend([
+        cx.attr_word(sym::rustc_proc_macro_decls, span),
+        cx.attr_word(sym::used, span),
+        cx.attr_nested_word(sym::allow, sym::deprecated, span),
+    ]);
 
     let block = cx.expr_block(
         cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]),
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 1cef4f9514c..b439fa34f5b 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -40,7 +40,7 @@ pub(crate) fn expand_test_case(
     let (mut item, is_stmt) = match anno_item {
         Annotatable::Item(item) => (item, false),
         Annotatable::Stmt(stmt) if let ast::StmtKind::Item(_) = stmt.kind => {
-            if let ast::StmtKind::Item(i) = stmt.into_inner().kind {
+            if let ast::StmtKind::Item(i) = stmt.kind {
                 (i, true)
             } else {
                 unreachable!()
@@ -120,11 +120,7 @@ pub(crate) fn expand_test_or_bench(
         Annotatable::Item(i) => (i, false),
         Annotatable::Stmt(stmt) if matches!(stmt.kind, ast::StmtKind::Item(_)) => {
             // FIXME: Use an 'if let' guard once they are implemented
-            if let ast::StmtKind::Item(i) = stmt.into_inner().kind {
-                (i, true)
-            } else {
-                unreachable!()
-            }
+            if let ast::StmtKind::Item(i) = stmt.kind { (i, true) } else { unreachable!() }
         }
         other => {
             not_testable_error(cx, attr_sp, None);
@@ -381,10 +377,7 @@ pub(crate) fn expand_test_or_bench(
                 .into(),
             ),
         );
-    test_const = test_const.map(|mut tc| {
-        tc.vis.kind = ast::VisibilityKind::Public;
-        tc
-    });
+    test_const.vis.kind = ast::VisibilityKind::Public;
 
     // extern crate test
     let test_extern =
diff --git a/compiler/rustc_codegen_cranelift/example/neon.rs b/compiler/rustc_codegen_cranelift/example/neon.rs
index 69ce17d3d75..704f866e2c4 100644
--- a/compiler/rustc_codegen_cranelift/example/neon.rs
+++ b/compiler/rustc_codegen_cranelift/example/neon.rs
@@ -233,7 +233,7 @@ unsafe fn test_vaddvq_f32() {
 
 #[cfg(target_arch = "aarch64")]
 unsafe fn test_vrndnq_f32() {
-    // AArch64 llvm intrinsic: llvm.aarch64.neon.frintn.v4f32
+    // llvm intrinsic: llvm.roundeven.v4f32
     let a = f32x4::from([0.1, -1.9, 4.5, 5.5]);
     let e = f32x4::from([0., -2., 4., 6.]);
     let r: f32x4 = transmute(vrndnq_f32(transmute(a)));
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 4617304105a..0b641ba64b7 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -380,7 +380,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                             rustc_hir::LangItem::PanicBoundsCheck,
                             &[index, len, location],
                             *unwind,
-                            Some(source_info.span),
+                            source_info.span,
                         );
                     }
                     AssertKind::MisalignedPointerDereference { ref required, ref found } => {
@@ -393,7 +393,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                             rustc_hir::LangItem::PanicMisalignedPointerDereference,
                             &[required, found, location],
                             *unwind,
-                            Some(source_info.span),
+                            source_info.span,
                         );
                     }
                     AssertKind::NullPointerDereference => {
@@ -404,7 +404,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                             rustc_hir::LangItem::PanicNullPointerDereference,
                             &[location],
                             *unwind,
-                            Some(source_info.span),
+                            source_info.span,
                         )
                     }
                     _ => {
@@ -415,7 +415,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                             msg.panic_function(),
                             &[location],
                             *unwind,
-                            Some(source_info.span),
+                            source_info.span,
                         );
                     }
                 }
@@ -531,7 +531,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                 );
             }
             TerminatorKind::UnwindTerminate(reason) => {
-                codegen_unwind_terminate(fx, Some(source_info.span), *reason);
+                codegen_unwind_terminate(fx, source_info.span, *reason);
             }
             TerminatorKind::UnwindResume => {
                 // FIXME implement unwinding
@@ -1074,7 +1074,7 @@ pub(crate) fn codegen_operand<'tcx>(
 pub(crate) fn codegen_panic_nounwind<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     msg_str: &str,
-    span: Option<Span>,
+    span: Span,
 ) {
     let msg_ptr = fx.anonymous_str(msg_str);
     let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
@@ -1091,7 +1091,7 @@ pub(crate) fn codegen_panic_nounwind<'tcx>(
 
 pub(crate) fn codegen_unwind_terminate<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
-    span: Option<Span>,
+    span: Span,
     reason: UnwindTerminateReason,
 ) {
     codegen_panic_inner(fx, reason.lang_item(), &[], UnwindAction::Unreachable, span);
@@ -1102,7 +1102,7 @@ fn codegen_panic_inner<'tcx>(
     lang_item: rustc_hir::LangItem,
     args: &[Value],
     _unwind: UnwindAction,
-    span: Option<Span>,
+    span: Span,
 ) {
     fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
 
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index afee5095549..120d6ff9e38 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -850,7 +850,7 @@ fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option<ty
         // Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151
         ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => {
             let fields = &adt.non_enum_variant().fields;
-            let ty = fields[FieldIdx::from_u32(1)].ty(fx.tcx, args);
+            let ty = fields[FieldIdx::ONE].ty(fx.tcx, args);
             let ty::Adt(ty, args) = ty.kind() else {
                 unreachable!("expected first field of `MaybeUninit` to be an ADT")
             };
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
index 2e02e85a997..2dee9176936 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
@@ -62,6 +62,14 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
             });
         }
 
+        _ if intrinsic.starts_with("llvm.roundeven.v") => {
+            intrinsic_args!(fx, args => (v); intrinsic);
+
+            simd_for_each_lane(fx, v, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
+                fx.bcx.ins().nearest(lane)
+            });
+        }
+
         _ => {
             fx.tcx
                 .dcx()
@@ -71,7 +79,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
                  See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\
                  Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues"
             );
-            crate::base::codegen_panic_nounwind(fx, &msg, None);
+            crate::base::codegen_panic_nounwind(fx, &msg, span);
             return;
         }
     }
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
index d22483cf177..3cd7ebb88f4 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
@@ -264,14 +264,6 @@ pub(super) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
             simd_reduce(fx, v, None, ret, &|fx, _ty, a, b| fx.bcx.ins().fadd(a, b));
         }
 
-        _ if intrinsic.starts_with("llvm.aarch64.neon.frintn.v") => {
-            intrinsic_args!(fx, args => (v); intrinsic);
-
-            simd_for_each_lane(fx, v, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
-                fx.bcx.ins().nearest(lane)
-            });
-        }
-
         _ if intrinsic.starts_with("llvm.aarch64.neon.smaxv.i") => {
             intrinsic_args!(fx, args => (v); intrinsic);
 
@@ -512,7 +504,7 @@ pub(super) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
                  See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\
                  Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues"
             );
-            crate::base::codegen_panic_nounwind(fx, &msg, None);
+            crate::base::codegen_panic_nounwind(fx, &msg, fx.mir.span);
             return;
         }
     }
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
index 3d67913a8ff..615f6c47d90 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -1321,7 +1321,7 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>(
                  See https://github.com/rust-lang/rustc_codegen_cranelift/issues/171\n\
                  Please open an issue at https://github.com/rust-lang/rustc_codegen_cranelift/issues"
             );
-            crate::base::codegen_panic_nounwind(fx, &msg, None);
+            crate::base::codegen_panic_nounwind(fx, &msg, span);
             return;
         }
     }
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 0de23e55e81..1d1cf884e48 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -785,7 +785,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                             }
                         })
                     });
-                    crate::base::codegen_panic_nounwind(fx, &msg_str, Some(source_info.span));
+                    crate::base::codegen_panic_nounwind(fx, &msg_str, source_info.span);
                     return Ok(());
                 }
             }
@@ -812,11 +812,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             dest.write_cvalue(fx, val);
         }
 
-        sym::pref_align_of
-        | sym::needs_drop
-        | sym::type_id
-        | sym::type_name
-        | sym::variant_count => {
+        sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
             intrinsic_args!(fx, args => (); intrinsic);
 
             let const_val = fx
@@ -875,7 +871,6 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let ptr = ptr.load_scalar(fx);
 
             let ty = generic_args.type_at(0);
-            let _ord = generic_args.const_at(1).to_value(); // FIXME: forward this to cranelift once they support that
             match ty.kind() {
                 ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
                     // FIXME implement 128bit atomics
@@ -884,7 +879,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                         crate::base::codegen_panic_nounwind(
                             fx,
                             "128bit atomics not yet supported",
-                            None,
+                            source_info.span,
                         );
                         return Ok(());
                     } else {
@@ -906,7 +901,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let val = CValue::by_val(val, fx.layout_of(ty));
             ret.write_cvalue(fx, val);
         }
-        _ if intrinsic.as_str().starts_with("atomic_store") => {
+        sym::atomic_store => {
             intrinsic_args!(fx, args => (ptr, val); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -919,7 +914,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
                         crate::base::codegen_panic_nounwind(
                             fx,
                             "128bit atomics not yet supported",
-                            None,
+                            source_info.span,
                         );
                         return Ok(());
                     } else {
@@ -939,7 +934,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
             fx.bcx.ins().atomic_store(MemFlags::trusted(), val, ptr);
         }
-        _ if intrinsic.as_str().starts_with("atomic_xchg") => {
+        sym::atomic_xchg => {
             intrinsic_args!(fx, args => (ptr, new); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -960,8 +955,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let old = CValue::by_val(old, layout);
             ret.write_cvalue(fx, old);
         }
-        _ if intrinsic.as_str().starts_with("atomic_cxchg") => {
-            // both atomic_cxchg_* and atomic_cxchgweak_*
+        sym::atomic_cxchg | sym::atomic_cxchgweak => {
             intrinsic_args!(fx, args => (ptr, test_old, new); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -984,7 +978,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             ret.write_cvalue(fx, ret_val)
         }
 
-        _ if intrinsic.as_str().starts_with("atomic_xadd") => {
+        sym::atomic_xadd => {
             intrinsic_args!(fx, args => (ptr, amount); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -1006,7 +1000,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let old = CValue::by_val(old, layout);
             ret.write_cvalue(fx, old);
         }
-        _ if intrinsic.as_str().starts_with("atomic_xsub") => {
+        sym::atomic_xsub => {
             intrinsic_args!(fx, args => (ptr, amount); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -1028,7 +1022,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let old = CValue::by_val(old, layout);
             ret.write_cvalue(fx, old);
         }
-        _ if intrinsic.as_str().starts_with("atomic_and") => {
+        sym::atomic_and => {
             intrinsic_args!(fx, args => (ptr, src); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -1049,7 +1043,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let old = CValue::by_val(old, layout);
             ret.write_cvalue(fx, old);
         }
-        _ if intrinsic.as_str().starts_with("atomic_or") => {
+        sym::atomic_or => {
             intrinsic_args!(fx, args => (ptr, src); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -1070,7 +1064,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let old = CValue::by_val(old, layout);
             ret.write_cvalue(fx, old);
         }
-        _ if intrinsic.as_str().starts_with("atomic_xor") => {
+        sym::atomic_xor => {
             intrinsic_args!(fx, args => (ptr, src); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -1091,7 +1085,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let old = CValue::by_val(old, layout);
             ret.write_cvalue(fx, old);
         }
-        _ if intrinsic.as_str().starts_with("atomic_nand") => {
+        sym::atomic_nand => {
             intrinsic_args!(fx, args => (ptr, src); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -1112,7 +1106,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let old = CValue::by_val(old, layout);
             ret.write_cvalue(fx, old);
         }
-        _ if intrinsic.as_str().starts_with("atomic_max") => {
+        sym::atomic_max => {
             intrinsic_args!(fx, args => (ptr, src); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -1133,7 +1127,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let old = CValue::by_val(old, layout);
             ret.write_cvalue(fx, old);
         }
-        _ if intrinsic.as_str().starts_with("atomic_umax") => {
+        sym::atomic_umax => {
             intrinsic_args!(fx, args => (ptr, src); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -1154,7 +1148,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let old = CValue::by_val(old, layout);
             ret.write_cvalue(fx, old);
         }
-        _ if intrinsic.as_str().starts_with("atomic_min") => {
+        sym::atomic_min => {
             intrinsic_args!(fx, args => (ptr, src); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
@@ -1175,7 +1169,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             let old = CValue::by_val(old, layout);
             ret.write_cvalue(fx, old);
         }
-        _ if intrinsic.as_str().starts_with("atomic_umin") => {
+        sym::atomic_umin => {
             intrinsic_args!(fx, args => (ptr, src); intrinsic);
             let ptr = ptr.load_scalar(fx);
 
diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs
index 6eef97c14dd..bf756860b64 100644
--- a/compiler/rustc_codegen_cranelift/src/main_shim.rs
+++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs
@@ -101,7 +101,7 @@ pub(crate) fn maybe_create_entry_wrapper(
                 let call_inst = bcx.ins().call(main_func_ref, &[]);
                 let call_results = bcx.func.dfg.inst_results(call_inst).to_owned();
 
-                let termination_trait = tcx.require_lang_item(LangItem::Termination, None);
+                let termination_trait = tcx.require_lang_item(LangItem::Termination, DUMMY_SP);
                 let report = tcx
                     .associated_items(termination_trait)
                     .find_by_ident_and_kind(
@@ -136,7 +136,7 @@ pub(crate) fn maybe_create_entry_wrapper(
                 }
             } else {
                 // Regular main fn invoked via start lang item.
-                let start_def_id = tcx.require_lang_item(LangItem::Start, None);
+                let start_def_id = tcx.require_lang_item(LangItem::Start, DUMMY_SP);
                 let start_instance = Instance::expect_resolve(
                     tcx,
                     ty::TypingEnv::fully_monomorphized(),
diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs
index f53045df6e7..95d44dfb6d9 100644
--- a/compiler/rustc_codegen_cranelift/src/num.rs
+++ b/compiler/rustc_codegen_cranelift/src/num.rs
@@ -54,7 +54,7 @@ fn codegen_three_way_compare<'tcx>(
     let gt = fx.bcx.ins().icmp(gt_cc, lhs, rhs);
     let lt = fx.bcx.ins().icmp(lt_cc, lhs, rhs);
     let val = fx.bcx.ins().isub(gt, lt);
-    CValue::by_val(val, fx.layout_of(fx.tcx.ty_ordering_enum(Some(fx.mir.span))))
+    CValue::by_val(val, fx.layout_of(fx.tcx.ty_ordering_enum(fx.mir.span)))
 }
 
 fn codegen_compare_bin_op<'tcx>(
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index f8bbb214920..662546e4999 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -240,7 +240,7 @@ pub(crate) fn size_and_align_of<'tcx>(
                 })
             });
 
-            codegen_panic_nounwind(fx, &msg_str, None);
+            codegen_panic_nounwind(fx, &msg_str, fx.mir.span);
 
             fx.bcx.switch_to_block(next_block);
 
diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs
index 9d9e0462a9b..05a8e3c3342 100644
--- a/compiler/rustc_codegen_cranelift/src/vtable.rs
+++ b/compiler/rustc_codegen_cranelift/src/vtable.rs
@@ -53,7 +53,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
                     .layout()
                     .non_1zst_field(fx)
                     .expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type");
-                arg = arg.value_field(fx, FieldIdx::new(idx));
+                arg = arg.value_field(fx, idx);
             }
         }
 
@@ -62,8 +62,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
                 let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap());
                 let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout);
                 let ptr = dyn_star.place_field(fx, FieldIdx::ZERO).to_ptr();
-                let vtable =
-                    dyn_star.place_field(fx, FieldIdx::new(1)).to_cvalue(fx).load_scalar(fx);
+                let vtable = dyn_star.place_field(fx, FieldIdx::ONE).to_cvalue(fx).load_scalar(fx);
                 break 'block (ptr, vtable);
             }
         }
diff --git a/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml b/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml
index 24152070e64..931f6097abc 100644
--- a/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml
+++ b/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml
@@ -6,7 +6,6 @@ resolver = "2"
 
 [dependencies]
 core = { path = "./sysroot_src/library/core" }
-compiler_builtins = "0.1"
 alloc = { path = "./sysroot_src/library/alloc" }
 std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] }
 test = { path = "./sysroot_src/library/test" }
@@ -16,6 +15,7 @@ proc_macro = { path = "./sysroot_src/library/proc_macro" }
 rustc-std-workspace-core = { path = "./sysroot_src/library/rustc-std-workspace-core" }
 rustc-std-workspace-alloc = { path = "./sysroot_src/library/rustc-std-workspace-alloc" }
 rustc-std-workspace-std = { path = "./sysroot_src/library/rustc-std-workspace-std" }
+compiler_builtins = { path = "./sysroot_src/library/compiler-builtins/compiler-builtins" }
 
 # For compiler-builtins we always use a high number of codegen units.
 # The goal here is to place every single intrinsic into its own object
diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs
index 945d34063a6..4d70122496b 100644
--- a/compiler/rustc_codegen_gcc/example/alloc_system.rs
+++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs
@@ -8,6 +8,7 @@
 // add fast paths for low alignment values.
 #[cfg(any(target_arch = "x86",
               target_arch = "arm",
+              target_arch = "loongarch32",
               target_arch = "m68k",
               target_arch = "mips",
               target_arch = "mips32r6",
diff --git a/compiler/rustc_codegen_gcc/messages.ftl b/compiler/rustc_codegen_gcc/messages.ftl
index 882fff8673a..546bfc87b68 100644
--- a/compiler/rustc_codegen_gcc/messages.ftl
+++ b/compiler/rustc_codegen_gcc/messages.ftl
@@ -2,9 +2,6 @@ codegen_gcc_unknown_ctarget_feature_prefix =
     unknown feature specified for `-Ctarget-feature`: `{$feature}`
     .note = features must begin with a `+` to enable or `-` to disable it
 
-codegen_gcc_invalid_minimum_alignment =
-    invalid minimum global alignment: {$err}
-
 codegen_gcc_forbidden_ctarget_feature =
     target feature `{$feature}` cannot be toggled with `-Ctarget-feature`: {$reason}
 
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index deb13ddf755..1690641a5bc 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -18,7 +18,6 @@ use rustc_span::def_id::DefId;
 
 use crate::base;
 use crate::context::CodegenCx;
-use crate::errors::InvalidMinimumAlignment;
 use crate::type_of::LayoutGccExt;
 
 fn set_global_alignment<'gcc, 'tcx>(
@@ -29,13 +28,8 @@ fn set_global_alignment<'gcc, 'tcx>(
     // The target may require greater alignment for globals than the type does.
     // Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
     // which can force it to be smaller. Rust doesn't support this yet.
-    if let Some(min) = cx.sess().target.min_global_align {
-        match Align::from_bits(min) {
-            Ok(min) => align = align.max(min),
-            Err(err) => {
-                cx.sess().dcx().emit_err(InvalidMinimumAlignment { err: err.to_string() });
-            }
-        }
+    if let Some(min_global) = cx.sess().target.min_global_align {
+        align = Ord::max(align, min_global);
     }
     gv.set_alignment(align.bytes() as i32);
 }
diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs
index 1b59b9ac169..ccd9abe3804 100644
--- a/compiler/rustc_codegen_gcc/src/errors.rs
+++ b/compiler/rustc_codegen_gcc/src/errors.rs
@@ -48,12 +48,6 @@ pub(crate) struct UnwindingInlineAsm {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_gcc_invalid_minimum_alignment)]
-pub(crate) struct InvalidMinimumAlignment {
-    pub err: String,
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_gcc_copy_bitcode)]
 pub(crate) struct CopyBitcode {
     pub err: std::io::Error,
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index f79ba2dcfc7..0591ffa42e4 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -16,7 +16,7 @@
 #![allow(internal_features)]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-#![feature(rustc_private, decl_macro, never_type, trusted_len)]
+#![feature(rustc_private)]
 #![allow(broken_intra_doc_links)]
 #![recursion_limit = "256"]
 #![warn(rust_2018_idioms)]
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index bf8ec8c3b91..88efc8ac96b 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -15,7 +15,7 @@ gimli = "0.31"
 itertools = "0.12"
 libc = "0.2"
 measureme = "12.0.1"
-object = { version = "0.36.3", default-features = false, features = ["std", "read"] }
+object = { version = "0.37.0", default-features = false, features = ["std", "read"] }
 rustc-demangle = "0.1.21"
 rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl
index 41391b096cc..bda121c67fb 100644
--- a/compiler/rustc_codegen_llvm/messages.ftl
+++ b/compiler/rustc_codegen_llvm/messages.ftl
@@ -19,12 +19,6 @@ codegen_llvm_from_llvm_diag = {$message}
 
 codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_name} ({$kind}): {$message}
 
-codegen_llvm_invalid_minimum_alignment_not_power_of_two =
-    invalid minimum global alignment: {$align} is not power of 2
-
-codegen_llvm_invalid_minimum_alignment_too_large =
-    invalid minimum global alignment: {$align} is too large
-
 codegen_llvm_load_bitcode = failed to load bitcode of module "{$name}"
 codegen_llvm_load_bitcode_with_llvm_err = failed to load bitcode of module "{$name}": {$llvm_err}
 
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 9e3893d5314..4185aef8b31 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -251,7 +251,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 InlineAsmArch::Nvptx64 => {}
                 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {}
                 InlineAsmArch::Hexagon => {}
-                InlineAsmArch::LoongArch64 => {
+                InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
                     constraints.extend_from_slice(&[
                         "~{$fcc0}".to_string(),
                         "~{$fcc1}".to_string(),
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 443c2eace55..27fd09745ff 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -5,6 +5,7 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet};
+use rustc_symbol_mangling::mangle_internal_symbol;
 use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector};
 use smallvec::SmallVec;
 
@@ -256,11 +257,11 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
         StackProbeType::Inline => "inline-asm",
         // Flag our internal `__rust_probestack` function as the stack probe symbol.
         // This is defined in the `compiler-builtins` crate for each architecture.
-        StackProbeType::Call => "__rust_probestack",
+        StackProbeType::Call => &mangle_internal_symbol(cx.tcx, "__rust_probestack"),
         // Pick from the two above based on the LLVM version.
         StackProbeType::InlineOrCall { min_llvm_version_for_inline } => {
             if llvm_util::get_version() < min_llvm_version_for_inline {
-                "__rust_probestack"
+                &mangle_internal_symbol(cx.tcx, "__rust_probestack")
             } else {
                 "inline-asm"
             }
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 4234352c93a..a4492d76c3c 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -1,8 +1,6 @@
 use std::ops::Range;
 
-use rustc_abi::{
-    Align, AlignFromBytesError, HasDataLayout, Primitive, Scalar, Size, WrappingRange,
-};
+use rustc_abi::{Align, HasDataLayout, Primitive, Scalar, Size, WrappingRange};
 use rustc_codegen_ssa::common;
 use rustc_codegen_ssa::traits::*;
 use rustc_hir::LangItem;
@@ -20,9 +18,7 @@ use rustc_middle::{bug, span_bug};
 use tracing::{debug, instrument, trace};
 
 use crate::common::{AsCCharPtr, CodegenCx};
-use crate::errors::{
-    InvalidMinimumAlignmentNotPowerOfTwo, InvalidMinimumAlignmentTooLarge, SymbolAlreadyDefined,
-};
+use crate::errors::SymbolAlreadyDefined;
 use crate::llvm::{self, True};
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
@@ -149,22 +145,10 @@ fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align:
     // The target may require greater alignment for globals than the type does.
     // Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
     // which can force it to be smaller. Rust doesn't support this yet.
-    if let Some(min) = cx.sess().target.min_global_align {
-        match Align::from_bits(min) {
-            Ok(min) => align = align.max(min),
-            Err(err) => match err {
-                AlignFromBytesError::NotPowerOfTwo(align) => {
-                    cx.sess().dcx().emit_err(InvalidMinimumAlignmentNotPowerOfTwo { align });
-                }
-                AlignFromBytesError::TooLarge(align) => {
-                    cx.sess().dcx().emit_err(InvalidMinimumAlignmentTooLarge { align });
-                }
-            },
-        }
-    }
-    unsafe {
-        llvm::LLVMSetAlignment(gv, align.bytes() as u32);
+    if let Some(min_global) = cx.sess().target.min_global_align {
+        align = Ord::max(align, min_global);
     }
+    llvm::set_alignment(gv, align);
 }
 
 fn check_and_apply_linkage<'ll, 'tcx>(
@@ -541,12 +525,12 @@ impl<'ll> CodegenCx<'ll, '_> {
                 // in the handling of `.init_array` (the static constructor list) in versions of
                 // the gold linker (prior to the one released with binutils 2.36).
                 //
-                // That said, we only ever emit these when compiling for ELF targets, unless
-                // `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage
-                // on other targets, in particular MachO targets have *their* static constructor
-                // lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However,
-                // that check happens when assigning the `CodegenFnAttrFlags` in
-                // `rustc_hir_analysis`, so we don't need to take care of it here.
+                // That said, we only ever emit these when `#[used(compiler)]` is explicitly
+                // requested. This is to avoid similar breakage on other targets, in particular
+                // MachO targets have *their* static constructor lists broken if `llvm.compiler.used`
+                // is emitted rather than `llvm.used`. However, that check happens when assigning
+                // the `CodegenFnAttrFlags` in the `codegen_fn_attrs` query, so we don't need to
+                // take care of it here.
                 self.add_compiler_used_global(g);
             }
             if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) {
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index ecf108f988f..eaafc680712 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -58,18 +58,6 @@ pub(crate) struct SymbolAlreadyDefined<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_llvm_invalid_minimum_alignment_not_power_of_two)]
-pub(crate) struct InvalidMinimumAlignmentNotPowerOfTwo {
-    pub align: u64,
-}
-
-#[derive(Diagnostic)]
-#[diag(codegen_llvm_invalid_minimum_alignment_too_large)]
-pub(crate) struct InvalidMinimumAlignmentTooLarge {
-    pub align: u64,
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_llvm_sanitizer_memtag_requires_mte)]
 pub(crate) struct SanitizerMemtagRequiresMte;
 
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index fd376ea8d80..6890923a594 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -9,7 +9,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(assert_matches)]
-#![feature(exact_size_is_empty)]
 #![feature(extern_types)]
 #![feature(file_buffered)]
 #![feature(if_let_guard)]
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 337c6944177..e9c4c255bce 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -54,7 +54,7 @@ libc = "0.2.50"
 # tidy-alphabetical-end
 
 [dependencies.object]
-version = "0.36.2"
+version = "0.37.0"
 default-features = false
 features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive", "write", "wasm"]
 
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index acb4cbaa13f..91f6af7fb93 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -8,8 +8,6 @@ codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to
 
 codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
 
-codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering
-
 codegen_ssa_autodiff_without_lto = using the autodiff feature requires using fat-lto
 
 codegen_ssa_bare_instruction_set = `#[instruction_set]` requires an argument
@@ -206,8 +204,6 @@ codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be m
 
 codegen_ssa_missing_features = add the missing features in a `target_feature` attribute
 
-codegen_ssa_missing_memory_ordering = Atomic intrinsic missing memory ordering
-
 codegen_ssa_missing_query_depgraph =
     found CGU-reuse attribute but `-Zquery-dep-graph` was not specified
 
@@ -374,10 +370,6 @@ codegen_ssa_unexpected_parameter_name = unexpected parameter name
 codegen_ssa_unknown_archive_kind =
     Don't know how to build archive of type: {$kind}
 
-codegen_ssa_unknown_atomic_operation = unknown atomic operation
-
-codegen_ssa_unknown_atomic_ordering = unknown ordering in atomic intrinsic
-
 codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified
 
 codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]`
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 1a39a0c3fda..168077260a6 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1961,7 +1961,7 @@ fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor
 /// This method creates a synthetic object file, which contains undefined references to all symbols
 /// that are necessary for the linking. They are only present in symbol table but not actually
 /// used in any sections, so the linker will therefore pick relevant rlibs for linking, but
-/// unused `#[no_mangle]` or `#[used]` can still be discard by GC sections.
+/// unused `#[no_mangle]` or `#[used(compiler)]` can still be discard by GC sections.
 ///
 /// There's a few internal crates in the standard library (aka libcore and
 /// libstd) which actually have a circular dependence upon one another. This
@@ -1995,7 +1995,8 @@ fn add_linked_symbol_object(
 
     if file.format() == object::BinaryFormat::MachO {
         // Divide up the sections into sub-sections via symbols for dead code stripping.
-        // Without this flag, unused `#[no_mangle]` or `#[used]` cannot be discard on MachO targets.
+        // Without this flag, unused `#[no_mangle]` or `#[used(compiler)]` cannot be
+        // discard on MachO targets.
         file.set_subsections_via_symbols();
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
index 2c24378afe1..74f39022afb 100644
--- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
@@ -287,6 +287,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
         (Architecture::X86_64, None) => elf::EM_X86_64,
         (Architecture::X86_64_X32, None) => elf::EM_X86_64,
         (Architecture::Hexagon, None) => elf::EM_HEXAGON,
+        (Architecture::LoongArch32, None) => elf::EM_LOONGARCH,
         (Architecture::LoongArch64, None) => elf::EM_LOONGARCH,
         (Architecture::M68k, None) => elf::EM_68K,
         (Architecture::Mips, None) => elf::EM_MIPS,
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index ec46c71b0e4..a16862c41ee 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -348,7 +348,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
 
             e_flags
         }
-        Architecture::LoongArch64 => {
+        Architecture::LoongArch32 | Architecture::LoongArch64 => {
             // Source: https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc#e_flags-identifies-abi-type-and-version
             let mut e_flags: u32 = elf::EF_LARCH_OBJABI_V1;
 
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index f7863fe4ae2..c2d6a26de0f 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -561,7 +561,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
         let EntryFnType::Main { sigpipe } = entry_type;
         let (start_fn, start_ty, args, instance) = {
-            let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
+            let start_def_id = cx.tcx().require_lang_item(LangItem::Start, DUMMY_SP);
             let start_instance = ty::Instance::expect_resolve(
                 cx.tcx(),
                 cx.typing_env(),
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 4bcafa3be36..0b31fa8fa88 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -195,35 +195,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                         tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span() });
                     }
                     None => {
-                        // Unfortunately, unconditionally using `llvm.used` causes
-                        // issues in handling `.init_array` with the gold linker,
-                        // but using `llvm.compiler.used` caused a nontrivial amount
-                        // of unintentional ecosystem breakage -- particularly on
-                        // Mach-O targets.
-                        //
-                        // As a result, we emit `llvm.compiler.used` only on ELF
-                        // targets. This is somewhat ad-hoc, but actually follows
-                        // our pre-LLVM 13 behavior (prior to the ecosystem
-                        // breakage), and seems to match `clang`'s behavior as well
-                        // (both before and after LLVM 13), possibly because they
-                        // have similar compatibility concerns to us. See
-                        // https://github.com/rust-lang/rust/issues/47384#issuecomment-1019080146
-                        // and following comments for some discussion of this, as
-                        // well as the comments in `rustc_codegen_llvm` where these
-                        // flags are handled.
-                        //
-                        // Anyway, to be clear: this is still up in the air
-                        // somewhat, and is subject to change in the future (which
-                        // is a good thing, because this would ideally be a bit
-                        // more firmed up).
-                        let is_like_elf = !(tcx.sess.target.is_like_darwin
-                            || tcx.sess.target.is_like_windows
-                            || tcx.sess.target.is_like_wasm);
-                        codegen_fn_attrs.flags |= if is_like_elf {
-                            CodegenFnAttrFlags::USED_COMPILER
-                        } else {
-                            CodegenFnAttrFlags::USED_LINKER
-                        };
+                        // Unconditionally using `llvm.used` causes issues in handling
+                        // `.init_array` with the gold linker. Luckily gold has been
+                        // deprecated with GCC 15 and rustc now warns about using gold.
+                        codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER
                     }
                 }
             }
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index ef0d565333e..48565e0b4de 100644
--- a/compiler/rustc_codegen_ssa/src/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -110,7 +110,7 @@ mod temp_stable_hash_impls {
 
 pub(crate) fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &Bx,
-    span: Option<Span>,
+    span: Span,
     li: LangItem,
 ) -> (Bx::FnAbiOfResult, Bx::Value, Instance<'tcx>) {
     let tcx = bx.tcx();
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 572d7b1e06a..f843347db92 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -797,22 +797,6 @@ pub(crate) struct ShuffleIndicesEvaluation {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_ssa_missing_memory_ordering)]
-pub(crate) struct MissingMemoryOrdering;
-
-#[derive(Diagnostic)]
-#[diag(codegen_ssa_unknown_atomic_ordering)]
-pub(crate) struct UnknownAtomicOrdering;
-
-#[derive(Diagnostic)]
-#[diag(codegen_ssa_atomic_compare_exchange)]
-pub(crate) struct AtomicCompareExchange;
-
-#[derive(Diagnostic)]
-#[diag(codegen_ssa_unknown_atomic_operation)]
-pub(crate) struct UnknownAtomicOperation;
-
-#[derive(Diagnostic)]
 pub enum InvalidMonomorphization<'tcx> {
     #[diag(codegen_ssa_invalid_monomorphization_basic_integer_type, code = E0511)]
     BasicIntegerType {
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 1baab62ae43..43b87171d51 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -783,7 +783,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
         };
 
-        let (fn_abi, llfn, instance) = common::build_langcall(bx, Some(span), lang_item);
+        let (fn_abi, llfn, instance) = common::build_langcall(bx, span, lang_item);
 
         // Codegen the actual panic invoke/call.
         let merging_succ =
@@ -803,7 +803,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         self.set_debug_loc(bx, terminator.source_info);
 
         // Obtain the panic entry point.
-        let (fn_abi, llfn, instance) = common::build_langcall(bx, Some(span), reason.lang_item());
+        let (fn_abi, llfn, instance) = common::build_langcall(bx, span, reason.lang_item());
 
         // Codegen the actual panic invoke/call.
         let merging_succ = helper.do_call(
@@ -871,7 +871,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         // Obtain the panic entry point.
         let (fn_abi, llfn, instance) =
-            common::build_langcall(bx, Some(source_info.span), LangItem::PanicNounwind);
+            common::build_langcall(bx, source_info.span, LangItem::PanicNounwind);
 
         // Codegen the actual panic invoke/call.
         Some(helper.do_call(
@@ -1077,7 +1077,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             let (idx, _) = op.layout.non_1zst_field(bx).expect(
                                 "not exactly one non-1-ZST field in a `DispatchFromDyn` type",
                             );
-                            op = op.extract_field(self, bx, idx);
+                            op = op.extract_field(self, bx, idx.as_usize());
                         }
 
                         // Now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
@@ -1109,7 +1109,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             let (idx, _) = op.layout.non_1zst_field(bx).expect(
                                 "not exactly one non-1-ZST field in a `DispatchFromDyn` type",
                             );
-                            op = op.extract_field(self, bx, idx);
+                            op = op.extract_field(self, bx, idx.as_usize());
                         }
 
                         // Make sure that we've actually unwrapped the rcvr down
@@ -1830,7 +1830,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span));
 
-        let (fn_abi, fn_ptr, instance) = common::build_langcall(&bx, None, reason.lang_item());
+        let (fn_abi, fn_ptr, instance) =
+            common::build_langcall(&bx, self.mir.span, reason.lang_item());
         if is_call_from_compiler_builtins_to_upstream_monomorphization(bx.tcx(), instance) {
             bx.abort();
         } else {
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 8c6f52084c2..e217c09939e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -8,9 +8,10 @@ use rustc_span::sym;
 use super::FunctionCx;
 use super::operand::OperandRef;
 use super::place::PlaceRef;
+use crate::common::{AtomicRmwBinOp, SynchronizationScope};
 use crate::errors::InvalidMonomorphization;
 use crate::traits::*;
-use crate::{MemFlags, errors, meth, size_of_val};
+use crate::{MemFlags, meth, size_of_val};
 
 fn copy_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
@@ -62,7 +63,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let span = source_info.span;
 
         let name = bx.tcx().item_name(instance.def_id());
-        let name_str = name.as_str();
         let fn_args = instance.args;
 
         // If we're swapping something that's *not* an `OperandValue::Ref`,
@@ -89,14 +89,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
         }
 
-        let ret_llval = |bx: &mut Bx, llval| {
-            if result.layout.ty.is_bool() {
-                let val = bx.from_immediate(llval);
-                bx.store_to_place(val, result.val);
-            } else if !result.layout.ty.is_unit() {
-                bx.store_to_place(llval, result.val);
-            }
-            Ok(())
+        let invalid_monomorphization_int_type = |ty| {
+            bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty });
+        };
+
+        let parse_atomic_ordering = |ord: ty::Value<'tcx>| {
+            let discr = ord.valtree.unwrap_branch()[0].unwrap_leaf();
+            discr.to_atomic_ordering()
         };
 
         let llval = match name {
@@ -151,11 +150,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
                 value
             }
-            sym::pref_align_of
-            | sym::needs_drop
-            | sym::type_id
-            | sym::type_name
-            | sym::variant_count => {
+            sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
                 let value = bx.tcx().const_eval_instance(bx.typing_env(), instance, span).unwrap();
                 OperandRef::from_const(bx, value, result.layout.ty).immediate_or_packed_pair(bx)
             }
@@ -336,184 +331,145 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
             }
 
-            // This requires that atomic intrinsics follow a specific naming pattern:
-            // "atomic_<operation>[_<ordering>]"
-            name if let Some(atomic) = name_str.strip_prefix("atomic_") => {
-                use rustc_middle::ty::AtomicOrdering::*;
-
-                use crate::common::{AtomicRmwBinOp, SynchronizationScope};
+            sym::atomic_load => {
+                let ty = fn_args.type_at(0);
+                if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) {
+                    invalid_monomorphization_int_type(ty);
+                    return Ok(());
+                }
+                let ordering = fn_args.const_at(1).to_value();
+                let layout = bx.layout_of(ty);
+                let source = args[0].immediate();
+                bx.atomic_load(
+                    bx.backend_type(layout),
+                    source,
+                    parse_atomic_ordering(ordering),
+                    layout.size,
+                )
+            }
+            sym::atomic_store => {
+                let ty = fn_args.type_at(0);
+                if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) {
+                    invalid_monomorphization_int_type(ty);
+                    return Ok(());
+                }
+                let ordering = fn_args.const_at(1).to_value();
+                let size = bx.layout_of(ty).size;
+                let val = args[1].immediate();
+                let ptr = args[0].immediate();
+                bx.atomic_store(val, ptr, parse_atomic_ordering(ordering), size);
+                return Ok(());
+            }
+            sym::atomic_cxchg | sym::atomic_cxchgweak => {
+                let ty = fn_args.type_at(0);
+                if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) {
+                    invalid_monomorphization_int_type(ty);
+                    return Ok(());
+                }
+                let succ_ordering = fn_args.const_at(1).to_value();
+                let fail_ordering = fn_args.const_at(2).to_value();
+                let weak = name == sym::atomic_cxchgweak;
+                let dst = args[0].immediate();
+                let cmp = args[1].immediate();
+                let src = args[2].immediate();
+                let (val, success) = bx.atomic_cmpxchg(
+                    dst,
+                    cmp,
+                    src,
+                    parse_atomic_ordering(succ_ordering),
+                    parse_atomic_ordering(fail_ordering),
+                    weak,
+                );
+                let val = bx.from_immediate(val);
+                let success = bx.from_immediate(success);
 
-                let invalid_monomorphization = |ty| {
-                    bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicIntegerType {
-                        span,
-                        name,
-                        ty,
-                    });
-                };
+                let dest = result.project_field(bx, 0);
+                bx.store_to_place(val, dest.val);
+                let dest = result.project_field(bx, 1);
+                bx.store_to_place(success, dest.val);
 
-                let parse_const_generic_ordering = |ord: ty::Value<'tcx>| {
-                    let discr = ord.valtree.unwrap_branch()[0].unwrap_leaf();
-                    discr.to_atomic_ordering()
+                return Ok(());
+            }
+            // These are all AtomicRMW ops
+            sym::atomic_max | sym::atomic_min => {
+                let atom_op = if name == sym::atomic_max {
+                    AtomicRmwBinOp::AtomicMax
+                } else {
+                    AtomicRmwBinOp::AtomicMin
                 };
 
-                // Some intrinsics have the ordering already converted to a const generic parameter, we handle those first.
-                match name {
-                    sym::atomic_load => {
-                        let ty = fn_args.type_at(0);
-                        let ordering = fn_args.const_at(1).to_value();
-                        if !(int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr()) {
-                            invalid_monomorphization(ty);
-                            return Ok(());
-                        }
-                        let layout = bx.layout_of(ty);
-                        let source = args[0].immediate();
-                        let llval = bx.atomic_load(
-                            bx.backend_type(layout),
-                            source,
-                            parse_const_generic_ordering(ordering),
-                            layout.size,
-                        );
-
-                        return ret_llval(bx, llval);
-                    }
-
-                    // The rest falls back to below.
-                    _ => {}
+                let ty = fn_args.type_at(0);
+                if matches!(ty.kind(), ty::Int(_)) {
+                    let ordering = fn_args.const_at(1).to_value();
+                    let ptr = args[0].immediate();
+                    let val = args[1].immediate();
+                    bx.atomic_rmw(atom_op, ptr, val, parse_atomic_ordering(ordering))
+                } else {
+                    invalid_monomorphization_int_type(ty);
+                    return Ok(());
                 }
-
-                let Some((instruction, ordering)) = atomic.split_once('_') else {
-                    bx.sess().dcx().emit_fatal(errors::MissingMemoryOrdering);
+            }
+            sym::atomic_umax | sym::atomic_umin => {
+                let atom_op = if name == sym::atomic_umax {
+                    AtomicRmwBinOp::AtomicUMax
+                } else {
+                    AtomicRmwBinOp::AtomicUMin
                 };
 
-                let parse_ordering = |bx: &Bx, s| match s {
-                    "relaxed" => Relaxed,
-                    "acquire" => Acquire,
-                    "release" => Release,
-                    "acqrel" => AcqRel,
-                    "seqcst" => SeqCst,
-                    _ => bx.sess().dcx().emit_fatal(errors::UnknownAtomicOrdering),
+                let ty = fn_args.type_at(0);
+                if matches!(ty.kind(), ty::Uint(_)) {
+                    let ordering = fn_args.const_at(1).to_value();
+                    let ptr = args[0].immediate();
+                    let val = args[1].immediate();
+                    bx.atomic_rmw(atom_op, ptr, val, parse_atomic_ordering(ordering))
+                } else {
+                    invalid_monomorphization_int_type(ty);
+                    return Ok(());
+                }
+            }
+            sym::atomic_xchg
+            | sym::atomic_xadd
+            | sym::atomic_xsub
+            | sym::atomic_and
+            | sym::atomic_nand
+            | sym::atomic_or
+            | sym::atomic_xor => {
+                let atom_op = match name {
+                    sym::atomic_xchg => AtomicRmwBinOp::AtomicXchg,
+                    sym::atomic_xadd => AtomicRmwBinOp::AtomicAdd,
+                    sym::atomic_xsub => AtomicRmwBinOp::AtomicSub,
+                    sym::atomic_and => AtomicRmwBinOp::AtomicAnd,
+                    sym::atomic_nand => AtomicRmwBinOp::AtomicNand,
+                    sym::atomic_or => AtomicRmwBinOp::AtomicOr,
+                    sym::atomic_xor => AtomicRmwBinOp::AtomicXor,
+                    _ => unreachable!(),
                 };
 
-                match instruction {
-                    "cxchg" | "cxchgweak" => {
-                        let Some((success, failure)) = ordering.split_once('_') else {
-                            bx.sess().dcx().emit_fatal(errors::AtomicCompareExchange);
-                        };
-                        let ty = fn_args.type_at(0);
-                        if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() {
-                            let weak = instruction == "cxchgweak";
-                            let dst = args[0].immediate();
-                            let cmp = args[1].immediate();
-                            let src = args[2].immediate();
-                            let (val, success) = bx.atomic_cmpxchg(
-                                dst,
-                                cmp,
-                                src,
-                                parse_ordering(bx, success),
-                                parse_ordering(bx, failure),
-                                weak,
-                            );
-                            let val = bx.from_immediate(val);
-                            let success = bx.from_immediate(success);
-
-                            let dest = result.project_field(bx, 0);
-                            bx.store_to_place(val, dest.val);
-                            let dest = result.project_field(bx, 1);
-                            bx.store_to_place(success, dest.val);
-                        } else {
-                            invalid_monomorphization(ty);
-                        }
-                        return Ok(());
-                    }
-
-                    "store" => {
-                        let ty = fn_args.type_at(0);
-                        if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() {
-                            let size = bx.layout_of(ty).size;
-                            let val = args[1].immediate();
-                            let ptr = args[0].immediate();
-                            bx.atomic_store(val, ptr, parse_ordering(bx, ordering), size);
-                        } else {
-                            invalid_monomorphization(ty);
-                        }
-                        return Ok(());
-                    }
-
-                    "fence" => {
-                        bx.atomic_fence(
-                            parse_ordering(bx, ordering),
-                            SynchronizationScope::CrossThread,
-                        );
-                        return Ok(());
-                    }
-
-                    "singlethreadfence" => {
-                        bx.atomic_fence(
-                            parse_ordering(bx, ordering),
-                            SynchronizationScope::SingleThread,
-                        );
-                        return Ok(());
-                    }
-
-                    // These are all AtomicRMW ops
-                    "max" | "min" => {
-                        let atom_op = if instruction == "max" {
-                            AtomicRmwBinOp::AtomicMax
-                        } else {
-                            AtomicRmwBinOp::AtomicMin
-                        };
-
-                        let ty = fn_args.type_at(0);
-                        if matches!(ty.kind(), ty::Int(_)) {
-                            let ptr = args[0].immediate();
-                            let val = args[1].immediate();
-                            bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
-                        } else {
-                            invalid_monomorphization(ty);
-                            return Ok(());
-                        }
-                    }
-                    "umax" | "umin" => {
-                        let atom_op = if instruction == "umax" {
-                            AtomicRmwBinOp::AtomicUMax
-                        } else {
-                            AtomicRmwBinOp::AtomicUMin
-                        };
-
-                        let ty = fn_args.type_at(0);
-                        if matches!(ty.kind(), ty::Uint(_)) {
-                            let ptr = args[0].immediate();
-                            let val = args[1].immediate();
-                            bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
-                        } else {
-                            invalid_monomorphization(ty);
-                            return Ok(());
-                        }
-                    }
-                    op => {
-                        let atom_op = match op {
-                            "xchg" => AtomicRmwBinOp::AtomicXchg,
-                            "xadd" => AtomicRmwBinOp::AtomicAdd,
-                            "xsub" => AtomicRmwBinOp::AtomicSub,
-                            "and" => AtomicRmwBinOp::AtomicAnd,
-                            "nand" => AtomicRmwBinOp::AtomicNand,
-                            "or" => AtomicRmwBinOp::AtomicOr,
-                            "xor" => AtomicRmwBinOp::AtomicXor,
-                            _ => bx.sess().dcx().emit_fatal(errors::UnknownAtomicOperation),
-                        };
-
-                        let ty = fn_args.type_at(0);
-                        if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() {
-                            let ptr = args[0].immediate();
-                            let val = args[1].immediate();
-                            bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
-                        } else {
-                            invalid_monomorphization(ty);
-                            return Ok(());
-                        }
-                    }
+                let ty = fn_args.type_at(0);
+                if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_raw_ptr() {
+                    let ordering = fn_args.const_at(1).to_value();
+                    let ptr = args[0].immediate();
+                    let val = args[1].immediate();
+                    bx.atomic_rmw(atom_op, ptr, val, parse_atomic_ordering(ordering))
+                } else {
+                    invalid_monomorphization_int_type(ty);
+                    return Ok(());
                 }
             }
+            sym::atomic_fence => {
+                let ordering = fn_args.const_at(0).to_value();
+                bx.atomic_fence(parse_atomic_ordering(ordering), SynchronizationScope::CrossThread);
+                return Ok(());
+            }
+
+            sym::atomic_singlethreadfence => {
+                let ordering = fn_args.const_at(0).to_value();
+                bx.atomic_fence(
+                    parse_atomic_ordering(ordering),
+                    SynchronizationScope::SingleThread,
+                );
+                return Ok(());
+            }
 
             sym::nontemporal_store => {
                 let dst = args[0].deref(bx.cx());
@@ -556,7 +512,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
         };
 
-        ret_llval(bx, llval)
+        if result.layout.ty.is_bool() {
+            let val = bx.from_immediate(llval);
+            bx.store_to_place(val, result.val);
+        } else if !result.layout.ty.is_unit() {
+            bx.store_to_place(llval, result.val);
+        }
+        Ok(())
     }
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index b7f2277bfda..e9389ddf93b 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -45,9 +45,15 @@ pub enum OperandValue<V> {
     Immediate(V),
     /// A pair of immediate LLVM values. Used by wide pointers too.
     ///
-    /// An `OperandValue` *must* be this variant for any type for which
+    /// # Invariants
+    /// - For `Pair(a, b)`, `a` is always at offset 0, but may have `FieldIdx(1..)`
+    /// - `b` is not at offset 0, because `V` is not a 1ZST type.
+    /// - `a` and `b` will have a different FieldIdx, but otherwise `b`'s may be lower
+    ///   or they may not be adjacent, due to arbitrary numbers of 1ZST fields that
+    ///   will not affect the shape of the data which determines if `Pair` will be used.
+    /// - An `OperandValue` *must* be this variant for any type for which
     /// [`LayoutTypeCodegenMethods::is_backend_scalar_pair`] returns `true`.
-    /// The backend values in this variant must be the *immediate* backend types,
+    /// - The backend values in this variant must be the *immediate* backend types,
     /// as returned by [`LayoutTypeCodegenMethods::scalar_pair_element_backend_type`]
     /// with `immediate: true`.
     Pair(V, V),
diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs
index ac2366340fb..577012151e4 100644
--- a/compiler/rustc_codegen_ssa/src/size_of_val.rs
+++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs
@@ -5,6 +5,7 @@ use rustc_hir::LangItem;
 use rustc_middle::bug;
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Ty};
+use rustc_span::DUMMY_SP;
 use tracing::{debug, trace};
 
 use crate::common::IntPredicate;
@@ -62,7 +63,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
             // Obtain the panic entry point.
             let (fn_abi, llfn, _instance) =
-                common::build_langcall(bx, None, LangItem::PanicNounwind);
+                common::build_langcall(bx, DUMMY_SP, LangItem::PanicNounwind);
 
             // Generate the call. Cannot use `do_call` since we don't have a MIR terminator so we
             // can't create a `TerminationCodegenHelper`. (But we are in good company, this code is
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 5bce6fb7ab2..7f9abe8aa8e 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -88,11 +88,9 @@ const_eval_division_overflow =
 const_eval_dyn_call_not_a_method =
     `dyn` call trying to call something that is not a method
 
-const_eval_error = {$error_kind ->
-    [static] evaluation of static initializer failed here
-    [const] evaluation of constant value failed here
-    [const_with_path] evaluation of `{$instance}` failed here
-    *[other] {""}
+const_eval_error = evaluation of `{$instance}` failed {$num_frames ->
+    [0] here
+    *[other] inside this call
 }
 
 const_eval_exact_div_has_remainder =
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 6167f8cd4b5..4f252f3ccd4 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -356,10 +356,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
             hir::ConstContext::ConstFn => true,
             _ => {
                 // For indirect places, we are not creating a new permanent borrow, it's just as
-                // transient as the already existing one. For reborrowing references this is handled
-                // at the top of `visit_rvalue`, but for raw pointers we handle it here.
-                // Pointers/references to `static mut` and cases where the `*` is not the first
-                // projection also end up here.
+                // transient as the already existing one.
                 // Locals with StorageDead do not live beyond the evaluation and can
                 // thus safely be borrowed without being able to be leaked to the final
                 // value of the constant.
@@ -395,7 +392,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
         }
 
         let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(self.body.typing_env(tcx));
-        let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
+        let ocx = ObligationCtxt::new(&infcx);
 
         let body_id = self.body.source.def_id().expect_local();
         let host_polarity = match self.const_kind() {
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index d701646719a..9c30dbff99e 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -345,11 +345,7 @@ fn build_error_for_const_call<'tcx>(
                 non_or_conditionally,
             });
 
-            note_trait_if_possible(
-                &mut err,
-                self_ty,
-                tcx.require_lang_item(LangItem::Deref, Some(span)),
-            );
+            note_trait_if_possible(&mut err, self_ty, tcx.require_lang_item(LangItem::Deref, span));
             err
         }
         _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::FmtArgumentsNew) => {
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index dfcd1969a73..c1a37ab6a83 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -99,7 +99,7 @@ impl Qualif for HasMutInterior {
         // requires borrowck, which in turn will invoke mir_const_qualifs again, causing a cycle error.
         // Instead we invoke an obligation context manually, and provide the opaque type inference settings
         // that allow the trait solver to just error out instead of cycling.
-        let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span));
+        let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, cx.body.span);
         // FIXME(#132279): Once we've got a typing mode which reveals opaque types using the HIR
         // typeck results without causing query cycles, we should use this here instead of defining
         // opaque types.
@@ -180,7 +180,7 @@ impl Qualif for NeedsNonConstDrop {
         // that the components of this type are also `~const Destruct`. This
         // amounts to verifying that there are no values in this ADT that may have
         // a non-const drop.
-        let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span));
+        let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, cx.body.span);
         let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env);
         let ocx = ObligationCtxt::new(&infcx);
         ocx.register_obligation(Obligation::new(
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 01625b91353..be840191547 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -430,20 +430,7 @@ fn report_eval_error<'tcx>(
     let (error, backtrace) = error.into_parts();
     backtrace.print_backtrace();
 
-    let (kind, instance) = if ecx.tcx.is_static(cid.instance.def_id()) {
-        ("static", String::new())
-    } else {
-        // If the current item has generics, we'd like to enrich the message with the
-        // instance and its args: to show the actual compile-time values, in addition to
-        // the expression, leading to the const eval error.
-        let instance = &cid.instance;
-        if !instance.args.is_empty() {
-            let instance = with_no_trimmed_paths!(instance.to_string());
-            ("const_with_path", instance)
-        } else {
-            ("const", String::new())
-        }
-    };
+    let instance = with_no_trimmed_paths!(cid.instance.to_string());
 
     super::report(
         *ecx.tcx,
@@ -451,14 +438,16 @@ fn report_eval_error<'tcx>(
         DUMMY_SP,
         || super::get_span_and_frames(ecx.tcx, ecx.stack()),
         |diag, span, frames| {
+            let num_frames = frames.len();
             // FIXME(oli-obk): figure out how to use structured diagnostics again.
             diag.code(E0080);
             diag.span_label(span, crate::fluent_generated::const_eval_error);
-            diag.arg("instance", instance);
-            diag.arg("error_kind", kind);
             for frame in frames {
                 diag.subdiagnostic(frame);
             }
+            // Add after the frame rendering above, as it adds its own `instance` args.
+            diag.arg("instance", instance);
+            diag.arg("num_frames", num_frames);
         },
     )
 }
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 3922b33ea84..a68dcf29988 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -249,7 +249,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
             return Err(ConstEvalErrKind::Panic { msg, file, line, col }).into();
         } else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) {
             // For panic_fmt, call const_panic_fmt instead.
-            let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None);
+            let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, self.tcx.span);
             let new_instance = ty::Instance::expect_resolve(
                 *self.tcx,
                 self.typing_env(),
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index c0438fb3ff8..6fd0b9d26e3 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -1,6 +1,6 @@
 // Not in interpret to make sure we do not use private implementation details
 
-use rustc_abi::VariantIdx;
+use rustc_abi::{FieldIdx, VariantIdx};
 use rustc_middle::query::Key;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -60,7 +60,7 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
 
     let fields_iter = (0..field_count)
         .map(|i| {
-            let field_op = ecx.project_field(&down, i).discard_err()?;
+            let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?;
             let val = op_to_const(&ecx, &field_op, /* for diagnostics */ true);
             Some((val, field_op.layout.ty))
         })
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 34239ae1d15..58d230af683 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -1,4 +1,4 @@
-use rustc_abi::{BackendRepr, VariantIdx};
+use rustc_abi::{BackendRepr, FieldIdx, VariantIdx};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ReportedErrorInfo};
 use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
@@ -40,7 +40,7 @@ fn branches<'tcx>(
     }
 
     for i in 0..field_count {
-        let field = ecx.project_field(&place, i).unwrap();
+        let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();
         let valtree = const_to_valtree_inner(ecx, &field, num_nodes)?;
         branches.push(valtree);
     }
@@ -437,7 +437,7 @@ fn valtree_into_mplace<'tcx>(
                     ty::Str | ty::Slice(_) | ty::Array(..) => {
                         ecx.project_index(place, i as u64).unwrap()
                     }
-                    _ => ecx.project_field(&place_adjusted, i).unwrap(),
+                    _ => ecx.project_field(&place_adjusted, FieldIdx::from_usize(i)).unwrap(),
                 };
 
                 debug!(?place_inner);
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index 789baea0734..37677f9e048 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -62,7 +62,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     pub(super) fn fn_arg_field(
         &self,
         arg: &FnArg<'tcx, M::Provenance>,
-        field: usize,
+        field: FieldIdx,
     ) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> {
         interp_ok(match arg {
             FnArg::Copy(op) => FnArg::Copy(self.project_field(op, field)?),
@@ -600,10 +600,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                         Cow::from(
                             args.iter()
                                 .map(|a| interp_ok(a.clone()))
-                                .chain(
-                                    (0..untuple_arg.layout().fields.count())
-                                        .map(|i| self.fn_arg_field(untuple_arg, i)),
-                                )
+                                .chain((0..untuple_arg.layout().fields.count()).map(|i| {
+                                    self.fn_arg_field(untuple_arg, FieldIdx::from_usize(i))
+                                }))
                                 .collect::<InterpResult<'_, Vec<_>>>()?,
                         )
                     } else {
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index 643a5805019..9e15f4572d7 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -1,6 +1,6 @@
 use std::assert_matches::assert_matches;
 
-use rustc_abi::Integer;
+use rustc_abi::{FieldIdx, Integer};
 use rustc_apfloat::ieee::{Double, Half, Quad, Single};
 use rustc_apfloat::{Float, FloatConvert};
 use rustc_middle::mir::CastKind;
@@ -484,6 +484,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let mut found_cast_field = false;
                 for i in 0..src.layout.fields.count() {
                     let cast_ty_field = cast_ty.field(self, i);
+                    let i = FieldIdx::from_usize(i);
                     let src_field = self.project_field(src, i)?;
                     let dst_field = self.project_field(dest, i)?;
                     if src_field.layout.is_1zst() && cast_ty_field.is_1zst() {
diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs
index 020cd65d75d..6c4b000e16b 100644
--- a/compiler/rustc_const_eval/src/interpret/discriminant.rs
+++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs
@@ -26,7 +26,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 // No need to validate that the discriminant here because the
                 // `TyAndLayout::for_variant()` call earlier already checks the
                 // variant is valid.
-                let tag_dest = self.project_field(dest, tag_field.as_usize())?;
+                let tag_dest = self.project_field(dest, tag_field)?;
                 self.write_scalar(tag, &tag_dest)
             }
             None => {
@@ -96,7 +96,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         let tag_layout = self.layout_of(tag_scalar_layout.primitive().to_int_ty(*self.tcx))?;
 
         // Read tag and sanity-check `tag_layout`.
-        let tag_val = self.read_immediate(&self.project_field(op, tag_field.as_usize())?)?;
+        let tag_val = self.read_immediate(&self.project_field(op, tag_field)?)?;
         assert_eq!(tag_layout.size, tag_val.layout.size);
         assert_eq!(tag_layout.backend_repr.is_signed(), tag_val.layout.backend_repr.is_signed());
         trace!("tag value: {}", tag_val);
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 1dd96297d1f..f0f958d069e 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -227,12 +227,11 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
 
     // Keep interning as long as there are things to intern.
     // We show errors if there are dangling pointers, or mutable pointers in immutable contexts
-    // (i.e., everything except for `static mut`). When these errors affect references, it is
-    // unfortunate that we show these errors here and not during validation, since validation can
-    // show much nicer errors. However, we do need these checks to be run on all pointers, including
-    // raw pointers, so we cannot rely on validation to catch them -- and since interning runs
-    // before validation, and interning doesn't know the type of anything, this means we can't show
-    // better errors. Maybe we should consider doing validation before interning in the future.
+    // (i.e., everything except for `static mut`). We only return these errors as a `Result`
+    // so that the caller can run validation, and subsequently only report interning errors
+    // if validation fails. Validation has the better error messages so we prefer those, but
+    // interning has better coverage since it "sees" *all* pointers, including raw pointers and
+    // references stored in unions.
     while let Some(prov) = todo.pop() {
         trace!(?prov);
         let alloc_id = prov.alloc_id();
@@ -279,12 +278,12 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
             // when there is memory there that someone might expect to be mutable, but we make it immutable.
             let dangling = !is_already_global && !ecx.memory.alloc_map.contains_key(&alloc_id);
             if !dangling {
-                // Found a mutable reference inside a const where inner allocations should be
+                // Found a mutable pointer inside a const where inner allocations should be
                 // immutable.
                 if !ecx.tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you {
                     span_bug!(
                         ecx.tcx.span,
-                        "the static const safety checks accepted mutable references they should not have accepted"
+                        "the static const safety checks accepted a mutable pointer they should not have accepted"
                     );
                 }
                 // Prefer dangling pointer errors over mutable pointer errors
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 64467a90136..ab27182c211 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -50,13 +50,6 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
             ensure_monomorphic_enough(tcx, tp_ty)?;
             ConstValue::from_bool(tp_ty.needs_drop(tcx, typing_env))
         }
-        sym::pref_align_of => {
-            // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
-            let layout = tcx
-                .layout_of(typing_env.as_query_input(tp_ty))
-                .map_err(|e| err_inval!(Layout(*e)))?;
-            ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx)
-        }
         sym::type_id => {
             ensure_monomorphic_enough(tcx, tp_ty)?;
             ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128())
@@ -144,14 +137,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 self.write_scalar(Scalar::from_target_usize(result, self), dest)?;
             }
 
-            sym::pref_align_of
-            | sym::needs_drop
-            | sym::type_id
-            | sym::type_name
-            | sym::variant_count => {
+            sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
                 let gid = GlobalId { instance, promoted: None };
                 let ty = match intrinsic_name {
-                    sym::pref_align_of | sym::variant_count => self.tcx.types.usize,
+                    sym::variant_count => self.tcx.types.usize,
                     sym::needs_drop => self.tcx.types.bool,
                     sym::type_id => self.tcx.types.u128,
                     sym::type_name => Ty::new_static_str(self.tcx.tcx),
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 39755169e6c..77667ba823a 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -12,6 +12,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
 use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
 use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
 use rustc_middle::{bug, mir, span_bug, ty};
+use rustc_span::DUMMY_SP;
 use tracing::trace;
 
 use super::{
@@ -307,7 +308,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
     #[inline]
     pub fn from_ordering(c: std::cmp::Ordering, tcx: TyCtxt<'tcx>) -> Self {
         // Can use any typing env, since `Ordering` is always monomorphic.
-        let ty = tcx.ty_ordering_enum(None);
+        let ty = tcx.ty_ordering_enum(DUMMY_SP);
         let layout =
             tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)).unwrap();
         Self::from_scalar(Scalar::Int(c.into()), layout)
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index 8ecb3e13d5c..ad47a19a14d 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -10,7 +10,7 @@
 use std::marker::PhantomData;
 use std::ops::Range;
 
-use rustc_abi::{self as abi, Size, VariantIdx};
+use rustc_abi::{self as abi, FieldIdx, Size, VariantIdx};
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::{bug, mir, span_bug, ty};
@@ -144,22 +144,22 @@ where
     /// always possible without allocating, so it can take `&self`. Also return the field's layout.
     /// This supports both struct and array fields, but not slices!
     ///
-    /// This also works for arrays, but then the `usize` index type is restricting.
-    /// For indexing into arrays, use `mplace_index`.
+    /// This also works for arrays, but then the `FieldIdx` index type is restricting.
+    /// For indexing into arrays, use [`Self::project_index`].
     pub fn project_field<P: Projectable<'tcx, M::Provenance>>(
         &self,
         base: &P,
-        field: usize,
+        field: FieldIdx,
     ) -> InterpResult<'tcx, P> {
         // Slices nominally have length 0, so they will panic somewhere in `fields.offset`.
         debug_assert!(
             !matches!(base.layout().ty.kind(), ty::Slice(..)),
             "`field` projection called on a slice -- call `index` projection instead"
         );
-        let offset = base.layout().fields.offset(field);
+        let offset = base.layout().fields.offset(field.as_usize());
         // Computing the layout does normalization, so we get a normalized type out of this
         // even if the field type is non-normalized (possible e.g. via associated types).
-        let field_layout = base.layout().field(self, field);
+        let field_layout = base.layout().field(self, field.as_usize());
 
         // Offset may need adjustment for unsized fields.
         let (meta, offset) = if field_layout.is_unsized() {
@@ -244,7 +244,7 @@ where
             }
             _ => span_bug!(
                 self.cur_span(),
-                "`mplace_index` called on non-array type {:?}",
+                "`project_index` called on non-array type {:?}",
                 base.layout().ty
             ),
         };
@@ -260,7 +260,7 @@ where
     ) -> InterpResult<'tcx, (P, u64)> {
         assert!(base.layout().ty.ty_adt_def().unwrap().repr().simd());
         // SIMD types must be newtypes around arrays, so all we have to do is project to their only field.
-        let array = self.project_field(base, 0)?;
+        let array = self.project_field(base, FieldIdx::ZERO)?;
         let len = array.len(self)?;
         interp_ok((array, len))
     }
@@ -384,7 +384,7 @@ where
             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())?,
+            Field(field, _) => self.project_field(base, field)?,
             Downcast(_, variant) => self.project_downcast(base, variant)?,
             Deref => self.deref_pointer(&base.to_op(self)?)?.into(),
             Index(local) => {
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 975325b0c1e..833fcc38817 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -333,7 +333,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         }
         for (field_index, operand) in operands.iter_enumerated() {
             let field_index = active_field_index.unwrap_or(field_index);
-            let field_dest = self.project_field(&variant_dest, field_index.as_usize())?;
+            let field_dest = self.project_field(&variant_dest, field_index)?;
             let op = self.eval_operand(operand, Some(field_dest.layout))?;
             self.copy_op(&op, &field_dest)?;
         }
diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs
index a5029eea5a7..7249ef23bf6 100644
--- a/compiler/rustc_const_eval/src/interpret/traits.rs
+++ b/compiler/rustc_const_eval/src/interpret/traits.rs
@@ -1,4 +1,4 @@
-use rustc_abi::{Align, Size};
+use rustc_abi::{Align, FieldIdx, Size};
 use rustc_middle::mir::interpret::{InterpResult, Pointer};
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt, Ty, TyCtxt, VtblEntry};
@@ -137,8 +137,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             matches!(val.layout().ty.kind(), ty::Dynamic(_, _, ty::DynStar)),
             "`unpack_dyn_star` only makes sense on `dyn*` types"
         );
-        let data = self.project_field(val, 0)?;
-        let vtable = self.project_field(val, 1)?;
+        let data = self.project_field(val, FieldIdx::ZERO)?;
+        let vtable = self.project_field(val, FieldIdx::ONE)?;
         let vtable = self.read_pointer(&vtable.to_op(self)?)?;
         let ty = self.get_ptr_vtable_ty(vtable, Some(expected_trait))?;
         // `data` is already the right thing but has the wrong type. So we transmute it.
diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs
index 3647c109a6e..5aea91233bd 100644
--- a/compiler/rustc_const_eval/src/interpret/visitor.rs
+++ b/compiler/rustc_const_eval/src/interpret/visitor.rs
@@ -112,8 +112,10 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
                 // So we transmute it to a raw pointer.
                 let raw_ptr_ty = Ty::new_mut_ptr(*self.ecx().tcx, self.ecx().tcx.types.unit);
                 let raw_ptr_ty = self.ecx().layout_of(raw_ptr_ty)?;
-                let vtable_field =
-                    self.ecx().project_field(v, 1)?.transmute(raw_ptr_ty, self.ecx())?;
+                let vtable_field = self
+                    .ecx()
+                    .project_field(v, FieldIdx::ONE)?
+                    .transmute(raw_ptr_ty, self.ecx())?;
                 self.visit_field(v, 1, &vtable_field)?;
 
                 // Then unpack the first field, and continue.
@@ -140,14 +142,16 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
 
                 // `Box` has two fields: the pointer we care about, and the allocator.
                 assert_eq!(v.layout().fields.count(), 2, "`Box` must have exactly 2 fields");
-                let (unique_ptr, alloc) =
-                    (self.ecx().project_field(v, 0)?, self.ecx().project_field(v, 1)?);
+                let (unique_ptr, alloc) = (
+                    self.ecx().project_field(v, FieldIdx::ZERO)?,
+                    self.ecx().project_field(v, FieldIdx::ONE)?,
+                );
                 // Unfortunately there is some type junk in the way here: `unique_ptr` is a `Unique`...
                 // (which means another 2 fields, the second of which is a `PhantomData`)
                 assert_eq!(unique_ptr.layout().fields.count(), 2);
                 let (nonnull_ptr, phantom) = (
-                    self.ecx().project_field(&unique_ptr, 0)?,
-                    self.ecx().project_field(&unique_ptr, 1)?,
+                    self.ecx().project_field(&unique_ptr, FieldIdx::ZERO)?,
+                    self.ecx().project_field(&unique_ptr, FieldIdx::ONE)?,
                 );
                 assert!(
                     phantom.layout().ty.ty_adt_def().is_some_and(|adt| adt.is_phantom_data()),
@@ -156,7 +160,7 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
                 );
                 // ... that contains a `NonNull`... (gladly, only a single field here)
                 assert_eq!(nonnull_ptr.layout().fields.count(), 1);
-                let raw_ptr = self.ecx().project_field(&nonnull_ptr, 0)?; // the actual raw ptr
+                let raw_ptr = self.ecx().project_field(&nonnull_ptr, FieldIdx::ZERO)?; // the actual raw ptr
                 // ... whose only field finally is a raw ptr we can dereference.
                 self.visit_box(ty, &raw_ptr)?;
 
@@ -188,9 +192,8 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
             }
             FieldsShape::Arbitrary { memory_index, .. } => {
                 for idx in Self::aggregate_field_iter(memory_index) {
-                    let idx = idx.as_usize();
                     let field = self.ecx().project_field(v, idx)?;
-                    self.visit_field(v, idx, &field)?;
+                    self.visit_field(v, idx.as_usize(), &field)?;
                 }
             }
             FieldsShape::Array { .. } => {
diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs
index 9c867cc615e..671214002a0 100644
--- a/compiler/rustc_const_eval/src/util/caller_location.rs
+++ b/compiler/rustc_const_eval/src/util/caller_location.rs
@@ -1,3 +1,4 @@
+use rustc_abi::FieldIdx;
 use rustc_hir::LangItem;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, TyCtxt};
@@ -35,17 +36,20 @@ fn alloc_caller_location<'tcx>(
     // Allocate memory for `CallerLocation` struct.
     let loc_ty = ecx
         .tcx
-        .type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, None))
+        .type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, ecx.tcx.span))
         .instantiate(*ecx.tcx, ecx.tcx.mk_args(&[ecx.tcx.lifetimes.re_erased.into()]));
     let loc_layout = ecx.layout_of(loc_ty).unwrap();
     let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
 
     // Initialize fields.
-    ecx.write_immediate(file_wide_ptr, &ecx.project_field(&location, 0).unwrap())
+    ecx.write_immediate(
+        file_wide_ptr,
+        &ecx.project_field(&location, FieldIdx::from_u32(0)).unwrap(),
+    )
+    .expect("writing to memory we just allocated cannot fail");
+    ecx.write_scalar(line, &ecx.project_field(&location, FieldIdx::from_u32(1)).unwrap())
         .expect("writing to memory we just allocated cannot fail");
-    ecx.write_scalar(line, &ecx.project_field(&location, 1).unwrap())
-        .expect("writing to memory we just allocated cannot fail");
-    ecx.write_scalar(col, &ecx.project_field(&location, 2).unwrap())
+    ecx.write_scalar(col, &ecx.project_field(&location, FieldIdx::from_u32(2)).unwrap())
         .expect("writing to memory we just allocated cannot fail");
 
     location
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index b7447e24731..eb3817a80a7 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -25,7 +25,6 @@
 #![feature(dropck_eyepatch)]
 #![feature(extend_one)]
 #![feature(file_buffered)]
-#![feature(macro_metavar_expr)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
 #![feature(negative_impls)]
diff --git a/compiler/rustc_data_structures/src/vec_cache.rs b/compiler/rustc_data_structures/src/vec_cache.rs
index 2ff60ab7f36..3b448c056b7 100644
--- a/compiler/rustc_data_structures/src/vec_cache.rs
+++ b/compiler/rustc_data_structures/src/vec_cache.rs
@@ -68,22 +68,22 @@ impl SlotIndex {
     // slots (see `slot_index_exhaustive` in tests).
     #[inline]
     const fn from_index(idx: u32) -> Self {
-        let mut bucket = match idx.checked_ilog2() {
-            Some(x) => x as usize,
-            None => 0,
-        };
-        let entries;
-        let running_sum;
-        if bucket <= 11 {
-            entries = 1 << 12;
-            running_sum = 0;
-            bucket = 0;
-        } else {
-            entries = 1 << bucket;
-            running_sum = entries;
-            bucket = bucket - 11;
+        const FIRST_BUCKET_SHIFT: usize = 12;
+        if idx < (1 << FIRST_BUCKET_SHIFT) {
+            return SlotIndex {
+                bucket_idx: 0,
+                entries: 1 << FIRST_BUCKET_SHIFT,
+                index_in_bucket: idx as usize,
+            };
+        }
+        // SAFETY: We already ruled out idx 0, so `checked_ilog2` can't return `None`.
+        let bucket = unsafe { idx.checked_ilog2().unwrap_unchecked() as usize };
+        let entries = 1 << bucket;
+        SlotIndex {
+            bucket_idx: bucket - FIRST_BUCKET_SHIFT + 1,
+            entries,
+            index_in_bucket: idx as usize - entries,
         }
-        SlotIndex { bucket_idx: bucket, entries, index_in_bucket: idx as usize - running_sum }
     }
 
     // SAFETY: Buckets must be managed solely by functions here (i.e., get/put on SlotIndex) and
diff --git a/compiler/rustc_data_structures/src/vec_cache/tests.rs b/compiler/rustc_data_structures/src/vec_cache/tests.rs
index 3b65c14162e..9b60913ec92 100644
--- a/compiler/rustc_data_structures/src/vec_cache/tests.rs
+++ b/compiler/rustc_data_structures/src/vec_cache/tests.rs
@@ -75,24 +75,21 @@ fn slot_index_exhaustive() {
     for idx in 0..=u32::MAX {
         buckets[SlotIndex::from_index(idx).bucket_idx] += 1;
     }
-    let mut prev = None::<SlotIndex>;
-    for idx in 0..=u32::MAX {
+    let slot_idx = SlotIndex::from_index(0);
+    assert_eq!(slot_idx.index_in_bucket, 0);
+    assert_eq!(slot_idx.bucket_idx, 0);
+    let mut prev = slot_idx;
+    for idx in 1..=u32::MAX {
         let slot_idx = SlotIndex::from_index(idx);
-        if let Some(p) = prev {
-            if p.bucket_idx == slot_idx.bucket_idx {
-                assert_eq!(p.index_in_bucket + 1, slot_idx.index_in_bucket);
-            } else {
-                assert_eq!(slot_idx.index_in_bucket, 0);
-            }
+        if prev.bucket_idx == slot_idx.bucket_idx {
+            assert_eq!(prev.index_in_bucket + 1, slot_idx.index_in_bucket);
         } else {
-            assert_eq!(idx, 0);
             assert_eq!(slot_idx.index_in_bucket, 0);
-            assert_eq!(slot_idx.bucket_idx, 0);
         }
 
         assert_eq!(buckets[slot_idx.bucket_idx], slot_idx.entries as u32);
         assert_eq!(ENTRIES_BY_BUCKET[slot_idx.bucket_idx], slot_idx.entries, "{}", idx);
 
-        prev = Some(slot_idx);
+        prev = slot_idx;
     }
 }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0092.md b/compiler/rustc_error_codes/src/error_codes/E0092.md
index be459d040c2..9c63798ded7 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0092.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0092.md
@@ -1,8 +1,10 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 An undefined atomic operation function was declared.
 
 Erroneous code example:
 
-```compile_fail,E0092
+```ignore (no longer emitted)
 #![feature(intrinsics)]
 #![allow(internal_features)]
 
@@ -12,13 +14,4 @@ unsafe fn atomic_foo(); // error: unrecognized atomic operation
 ```
 
 Please check you didn't make a mistake in the function's name. All intrinsic
-functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
-`library/core/src/intrinsics.rs` in the Rust source code. Example:
-
-```
-#![feature(intrinsics)]
-#![allow(internal_features)]
-
-#[rustc_intrinsic]
-unsafe fn atomic_fence_seqcst(); // ok!
-```
+functions are defined in `library/core/src/intrinsics` in the Rust source code.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0093.md b/compiler/rustc_error_codes/src/error_codes/E0093.md
index 9929a069927..3552c2db4cc 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0093.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0093.md
@@ -17,19 +17,4 @@ fn main() {
 ```
 
 Please check you didn't make a mistake in the function's name. All intrinsic
-functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
-`library/core/src/intrinsics.rs` in the Rust source code. Example:
-
-```
-#![feature(intrinsics)]
-#![allow(internal_features)]
-
-#[rustc_intrinsic]
-unsafe fn atomic_fence_seqcst(); // ok!
-
-fn main() {
-    unsafe {
-        atomic_fence_seqcst();
-    }
-}
-```
+functions are defined in `library/core/src/intrinsics` in the Rust source code.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0622.md b/compiler/rustc_error_codes/src/error_codes/E0622.md
index 9b8131a061e..cc66e067990 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0622.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0622.md
@@ -4,7 +4,7 @@ An intrinsic was declared without being a function.
 
 Erroneous code example:
 
-```no_run
+```ignore (no longer emitted)
 #![feature(intrinsics)]
 #![allow(internal_features)]
 
@@ -21,7 +21,7 @@ An intrinsic is a function available for use in a given programming language
 whose implementation is handled specially by the compiler. In order to fix this
 error, just declare a function. Example:
 
-```no_run
+```ignore (no longer emitted)
 #![feature(intrinsics)]
 #![allow(internal_features)]
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0783.md b/compiler/rustc_error_codes/src/error_codes/E0783.md
index 73981e59e0d..ac8641cfc5a 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0783.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0783.md
@@ -9,7 +9,7 @@ match 2u8 {
 }
 ```
 
-Older Rust code using previous editions allowed `...` to stand for exclusive
+Older Rust code using previous editions allowed `...` to stand for inclusive
 ranges which are now signified using `..=`.
 
 To make this code compile replace the `...` with `..=`.
diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml
index 0951859fa53..5dc582b9c3a 100644
--- a/compiler/rustc_error_messages/Cargo.toml
+++ b/compiler/rustc_error_messages/Cargo.toml
@@ -16,6 +16,7 @@ rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 unic-langid = { version = "0.9.0", features = ["macros"] }
 # tidy-alphabetical-end
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 3c6df147b1b..1d3b5b20751 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -21,6 +21,7 @@ use intl_memoizer::concurrent::IntlLangMemoizer;
 use rustc_data_structures::sync::IntoDynSyncSend;
 use rustc_macros::{Decodable, Encodable};
 use rustc_span::Span;
+use smallvec::SmallVec;
 use tracing::{instrument, trace};
 pub use unic_langid::{LanguageIdentifier, langid};
 
@@ -106,8 +107,7 @@ impl From<Vec<FluentError>> for TranslationBundleError {
 /// (overriding any conflicting messages).
 #[instrument(level = "trace")]
 pub fn fluent_bundle(
-    sysroot: PathBuf,
-    sysroot_candidates: Vec<PathBuf>,
+    sysroot_candidates: SmallVec<[PathBuf; 2]>,
     requested_locale: Option<LanguageIdentifier>,
     additional_ftl_path: Option<&Path>,
     with_directionality_markers: bool,
@@ -141,7 +141,7 @@ pub fn fluent_bundle(
     // If the user requests the default locale then don't try to load anything.
     if let Some(requested_locale) = requested_locale {
         let mut found_resources = false;
-        for mut sysroot in Some(sysroot).into_iter().chain(sysroot_candidates.into_iter()) {
+        for mut sysroot in sysroot_candidates {
             sysroot.push("share");
             sysroot.push("locale");
             sysroot.push(requested_locale.to_string());
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index bd421a441f9..133bd361ee7 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -15,12 +15,10 @@
 #![feature(box_patterns)]
 #![feature(default_field_values)]
 #![feature(error_reporter)]
-#![feature(if_let_guard)]
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
 // tidy-alphabetical-end
@@ -1529,7 +1527,7 @@ impl DiagCtxtInner {
             // Future breakages aren't emitted if they're `Level::Allow` or
             // `Level::Expect`, but they still need to be constructed and
             // stashed below, so they'll trigger the must_produce_diag check.
-            assert_matches!(diagnostic.level, Error | Warning | Allow | Expect);
+            assert_matches!(diagnostic.level, Error | ForceWarning | Warning | Allow | Expect);
             self.future_breakage_diagnostics.push(diagnostic.clone());
         }
 
diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl
index f26c7c1ba0b..08b7a362083 100644
--- a/compiler/rustc_expand/messages.ftl
+++ b/compiler/rustc_expand/messages.ftl
@@ -62,6 +62,7 @@ expand_feature_not_allowed =
 expand_feature_removed =
     feature has been removed
     .label = feature has been removed
+    .note = removed in {$removed_rustc_version} (you are using {$current_rustc_version}){$pull_note}
     .reason = {$reason}
 
 expand_glob_delegation_outside_impls =
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 2accfba383e..c7b975d8f3e 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -167,7 +167,7 @@ impl Annotatable {
 
     pub fn expect_stmt(self) -> ast::Stmt {
         match self {
-            Annotatable::Stmt(stmt) => stmt.into_inner(),
+            Annotatable::Stmt(stmt) => *stmt,
             _ => panic!("expected statement"),
         }
     }
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index c50ab5959e2..9a359e9b031 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -80,9 +80,20 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
 
             // If the enabled feature has been removed, issue an error.
             if let Some(f) = REMOVED_LANG_FEATURES.iter().find(|f| name == f.feature.name) {
+                let pull_note = if let Some(pull) = f.pull {
+                    format!(
+                        "; see <https://github.com/rust-lang/rust/pull/{}> for more information",
+                        pull
+                    )
+                } else {
+                    "".to_owned()
+                };
                 sess.dcx().emit_err(FeatureRemoved {
                     span: mi.span(),
                     reason: f.reason.map(|reason| FeatureRemovedReason { reason }),
+                    removed_rustc_version: f.feature.since,
+                    current_rustc_version: sess.cfg_version,
+                    pull_note,
                 });
                 continue;
             }
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index 89bdc7b6dfa..ec0af67c046 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -154,12 +154,16 @@ pub(crate) struct HelperAttributeNameInvalid {
 
 #[derive(Diagnostic)]
 #[diag(expand_feature_removed, code = E0557)]
+#[note]
 pub(crate) struct FeatureRemoved<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
     #[subdiagnostic]
     pub reason: Option<FeatureRemovedReason<'a>>,
+    pub removed_rustc_version: &'a str,
+    pub current_rustc_version: &'a str,
+    pub pull_note: String,
 }
 
 #[derive(Subdiagnostic)]
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 82a2719ca96..569165a64e5 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1183,9 +1183,8 @@ impl InvocationCollectorNode for P<ast::Item> {
         matches!(self.kind, ItemKind::MacCall(..))
     }
     fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
-        let node = self.into_inner();
-        match node.kind {
-            ItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
+        match self.kind {
+            ItemKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
             _ => unreachable!(),
         }
     }
@@ -1339,7 +1338,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag>
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
     }
     fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
-        let item = self.wrapped.into_inner();
+        let item = self.wrapped;
         match item.kind {
             AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
             _ => unreachable!(),
@@ -1380,7 +1379,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
     }
     fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
-        let item = self.wrapped.into_inner();
+        let item = self.wrapped;
         match item.kind {
             AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
             _ => unreachable!(),
@@ -1421,7 +1420,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitImplItem
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
     }
     fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
-        let item = self.wrapped.into_inner();
+        let item = self.wrapped;
         match item.kind {
             AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
             _ => unreachable!(),
@@ -1459,9 +1458,8 @@ impl InvocationCollectorNode for P<ast::ForeignItem> {
         matches!(self.kind, ForeignItemKind::MacCall(..))
     }
     fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
-        let node = self.into_inner();
-        match node.kind {
-            ForeignItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
+        match self.kind {
+            ForeignItemKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
             _ => unreachable!(),
         }
     }
@@ -1596,16 +1594,16 @@ impl InvocationCollectorNode for ast::Stmt {
         // `StmtKind`s and treat them as statement macro invocations, not as items or expressions.
         let (add_semicolon, mac, attrs) = match self.kind {
             StmtKind::MacCall(mac) => {
-                let ast::MacCallStmt { mac, style, attrs, .. } = mac.into_inner();
+                let ast::MacCallStmt { mac, style, attrs, .. } = *mac;
                 (style == MacStmtStyle::Semicolon, mac, attrs)
             }
-            StmtKind::Item(item) => match item.into_inner() {
+            StmtKind::Item(item) => match *item {
                 ast::Item { kind: ItemKind::MacCall(mac), attrs, .. } => {
                     (mac.args.need_semicolon(), mac, attrs)
                 }
                 _ => unreachable!(),
             },
-            StmtKind::Semi(expr) => match expr.into_inner() {
+            StmtKind::Semi(expr) => match *expr {
                 ast::Expr { kind: ExprKind::MacCall(mac), attrs, .. } => {
                     (mac.args.need_semicolon(), mac, attrs)
                 }
@@ -1686,8 +1684,7 @@ impl InvocationCollectorNode for P<ast::Ty> {
         matches!(self.kind, ast::TyKind::MacCall(..))
     }
     fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
-        let node = self.into_inner();
-        match node.kind {
+        match self.kind {
             TyKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
             _ => unreachable!(),
         }
@@ -1710,8 +1707,7 @@ impl InvocationCollectorNode for P<ast::Pat> {
         matches!(self.kind, PatKind::MacCall(..))
     }
     fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
-        let node = self.into_inner();
-        match node.kind {
+        match self.kind {
             PatKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
             _ => unreachable!(),
         }
@@ -1737,9 +1733,8 @@ impl InvocationCollectorNode for P<ast::Expr> {
         matches!(self.kind, ExprKind::MacCall(..))
     }
     fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
-        let node = self.into_inner();
-        match node.kind {
-            ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
+        match self.kind {
+            ExprKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
             _ => unreachable!(),
         }
     }
@@ -1763,7 +1758,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> {
         matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
     }
     fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
-        let node = self.wrapped.into_inner();
+        let node = self.wrapped;
         match node.kind {
             ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
             _ => unreachable!(),
@@ -1797,7 +1792,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, MethodReceiverTag>
         matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
     }
     fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
-        let node = self.wrapped.into_inner();
+        let node = self.wrapped;
         match node.kind {
             ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
             _ => unreachable!(),
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 35b38d99c70..515d82296ca 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -6,7 +6,6 @@
 #![feature(associated_type_defaults)]
 #![feature(if_let_guard)]
 #![feature(macro_metavar_expr)]
-#![feature(map_try_insert)]
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
 #![feature(rustdoc_internals)]
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index ffa6ffb40b6..b1c185220f4 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -259,6 +259,8 @@ declare_features! (
     /// Allows some increased flexibility in the name resolution rules,
     /// especially around globs and shadowing (RFC 1560).
     (accepted, item_like_imports, "1.15.0", Some(35120)),
+    // Allows using the `kl` and `widekl` target features and the associated intrinsics
+    (accepted, keylocker_x86, "CURRENT_RUSTC_VERSION", Some(134813)),
     /// Allows `'a: { break 'a; }`.
     (accepted, label_break_value, "1.65.0", Some(48594)),
     /// Allows `let...else` statements.
@@ -382,6 +384,8 @@ declare_features! (
     (accepted, self_in_typedefs, "1.32.0", Some(49303)),
     /// Allows `Self` struct constructor (RFC 2302).
     (accepted, self_struct_ctor, "1.32.0", Some(51994)),
+    /// Allows use of x86 SHA512, SM3 and SM4 target-features and intrinsics
+    (accepted, sha512_sm_x86, "CURRENT_RUSTC_VERSION", Some(126624)),
     /// Shortern the tail expression lifetime
     (accepted, shorter_tail_lifetimes, "1.84.0", Some(123739)),
     /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`.
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 687d859df53..9738f169595 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -1,5 +1,7 @@
 //! List of the removed feature gates.
 
+use std::num::{NonZero, NonZeroU32};
+
 use rustc_span::sym;
 
 use super::{Feature, to_nonzero};
@@ -7,11 +9,21 @@ use super::{Feature, to_nonzero};
 pub struct RemovedFeature {
     pub feature: Feature,
     pub reason: Option<&'static str>,
+    pub pull: Option<NonZero<u32>>,
+}
+
+macro_rules! opt_nonzero_u32 {
+    () => {
+        None
+    };
+    ($val:expr) => {
+        Some(NonZeroU32::new($val).unwrap())
+    };
 }
 
 macro_rules! declare_features {
     ($(
-        $(#[doc = $doc:tt])* (removed, $feature:ident, $ver:expr, $issue:expr, $reason:expr),
+        $(#[doc = $doc:tt])* (removed, $feature:ident, $ver:expr, $issue:expr, $reason:expr $(, $pull:expr)?),
     )+) => {
         /// Formerly unstable features that have now been removed.
         pub static REMOVED_LANG_FEATURES: &[RemovedFeature] = &[
@@ -21,7 +33,8 @@ macro_rules! declare_features {
                     since: $ver,
                     issue: to_nonzero($issue),
                 },
-                reason: $reason
+                reason: $reason,
+                pull:  opt_nonzero_u32!($($pull)?),
             }),+
         ];
     };
@@ -40,64 +53,64 @@ declare_features! (
     // version they got originally added in.)
 
     /// Allows using the `amdgpu-kernel` ABI.
-    (removed, abi_amdgpu_kernel, "1.77.0", Some(51575), None),
-    (removed, advanced_slice_patterns, "1.0.0", Some(62254),
-     Some("merged into `#![feature(slice_patterns)]`")),
+    (removed, abi_amdgpu_kernel, "1.77.0", Some(51575), None, 120495),
+    (removed, advanced_slice_patterns, "1.42.0", Some(62254),
+     Some("merged into `#![feature(slice_patterns)]`"), 67712),
     (removed, allocator, "1.0.0", None, None),
     /// Allows a test to fail without failing the whole suite.
-    (removed, allow_fail, "1.19.0", Some(46488), Some("removed due to no clear use cases")),
+    (removed, allow_fail, "1.60.0", Some(46488), Some("removed due to no clear use cases"), 93416),
     (removed, await_macro, "1.38.0", Some(50547),
-     Some("subsumed by `.await` syntax")),
+     Some("subsumed by `.await` syntax"), 62293),
     /// Allows using the `box $expr` syntax.
-    (removed, box_syntax, "1.70.0", Some(49733), Some("replaced with `#[rustc_box]`")),
+    (removed, box_syntax, "1.70.0", Some(49733), Some("replaced with `#[rustc_box]`"), 108471),
     /// Allows capturing disjoint fields in a closure/coroutine (RFC 2229).
-    (removed, capture_disjoint_fields, "1.49.0", Some(53488), Some("stabilized in Rust 2021")),
+    (removed, capture_disjoint_fields, "1.69.0", Some(53488), Some("stabilized in Rust 2021"), 108550),
     /// Allows comparing raw pointers during const eval.
     (removed, const_compare_raw_pointers, "1.46.0", Some(53020),
-     Some("cannot be allowed in const eval in any meaningful way")),
+     Some("cannot be allowed in const eval in any meaningful way"), 73398),
     /// Allows limiting the evaluation steps of const expressions
-    (removed, const_eval_limit, "1.43.0", Some(67217), Some("removed the limit entirely")),
+    (removed, const_eval_limit, "1.72.0", Some(67217), Some("removed the limit entirely"), 103877),
     /// Allows non-trivial generic constants which have to be manually propagated upwards.
-    (removed, const_evaluatable_checked, "1.48.0", Some(76560), Some("renamed to `generic_const_exprs`")),
+    (removed, const_evaluatable_checked, "1.56.0", Some(76560), Some("renamed to `generic_const_exprs`"), 88369),
     /// Allows the definition of `const` functions with some advanced features.
     (removed, const_fn, "1.54.0", Some(57563),
-     Some("split into finer-grained feature gates")),
+     Some("split into finer-grained feature gates"), 85109),
     /// Allows const generic types (e.g. `struct Foo<const N: usize>(...);`).
-    (removed, const_generics, "1.34.0", Some(44580),
-     Some("removed in favor of `#![feature(adt_const_params)]` and `#![feature(generic_const_exprs)]`")),
+    (removed, const_generics, "1.56.0", Some(44580),
+     Some("removed in favor of `#![feature(adt_const_params)]` and `#![feature(generic_const_exprs)]`"), 88369),
     /// Allows `[x; N]` where `x` is a constant (RFC 2203).
-    (removed, const_in_array_repeat_expressions,  "1.37.0", Some(49147),
-     Some("removed due to causing promotable bugs")),
+    (removed, const_in_array_repeat_expressions,  "1.51.0", Some(49147),
+     Some("removed due to causing promotable bugs"), 80404),
     /// Allows casting raw pointers to `usize` during const eval.
     (removed, const_raw_ptr_to_usize_cast, "1.55.0", Some(51910),
-     Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported")),
+     Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported"), 87020),
     /// Allows `T: ?const Trait` syntax in bounds.
-    (removed, const_trait_bound_opt_out, "1.42.0", Some(67794),
-     Some("Removed in favor of `~const` bound in #![feature(const_trait_impl)]")),
+    (removed, const_trait_bound_opt_out, "1.56.0", Some(67794),
+     Some("Removed in favor of `~const` bound in #![feature(const_trait_impl)]"), 88328),
     /// Allows using `crate` as visibility modifier, synonymous with `pub(crate)`.
-    (removed, crate_visibility_modifier, "1.63.0", Some(53120), Some("removed in favor of `pub(crate)`")),
+    (removed, crate_visibility_modifier, "1.63.0", Some(53120), Some("removed in favor of `pub(crate)`"), 97254),
     /// Allows using custom attributes (RFC 572).
     (removed, custom_attribute, "1.0.0", Some(29642),
-     Some("removed in favor of `#![register_tool]` and `#![register_attr]`")),
+     Some("removed in favor of `#![register_tool]` and `#![register_attr]`"), 66070),
     /// Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
     (removed, custom_derive, "1.32.0", Some(29644),
      Some("subsumed by `#[proc_macro_derive]`")),
     /// Allows default type parameters to influence type inference.
     (removed, default_type_parameter_fallback, "1.82.0", Some(27336),
-     Some("never properly implemented; requires significant design work")),
+     Some("never properly implemented; requires significant design work"), 127655),
     /// Allows deriving traits as per `SmartPointer` specification
-    (removed, derive_smart_pointer, "1.79.0", Some(123430), Some("replaced by `CoercePointee`")),
+    (removed, derive_smart_pointer, "1.84.0", Some(123430), Some("replaced by `CoercePointee`"), 131284),
     /// Allows using `#[doc(keyword = "...")]`.
-    (removed, doc_keyword, "1.28.0", Some(51315),
-     Some("merged into `#![feature(rustdoc_internals)]`")),
+    (removed, doc_keyword, "1.58.0", Some(51315),
+     Some("merged into `#![feature(rustdoc_internals)]`"), 90420),
     /// Allows using `doc(primitive)` without a future-incompat warning.
-    (removed, doc_primitive, "1.56.0", Some(88070),
-     Some("merged into `#![feature(rustdoc_internals)]`")),
+    (removed, doc_primitive, "1.58.0", Some(88070),
+     Some("merged into `#![feature(rustdoc_internals)]`"), 90420),
     /// Allows `#[doc(spotlight)]`.
     /// The attribute was renamed to `#[doc(notable_trait)]`
     /// and the feature to `doc_notable_trait`.
-    (removed, doc_spotlight, "1.22.0", Some(45040),
-     Some("renamed to `doc_notable_trait`")),
+    (removed, doc_spotlight, "1.53.0", Some(45040),
+     Some("renamed to `doc_notable_trait`"), 80965),
     /// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
     (removed, dropck_parametricity, "1.38.0", Some(28498), None),
     /// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible[^1].
@@ -107,159 +120,162 @@ declare_features! (
     /// Renamed from `object_safe_for_dispatch`.
     ///
     /// [^1]: Formerly known as "object safe".
-    (removed, dyn_compatible_for_dispatch, "1.83.0", Some(43561),
-     Some("removed, not used heavily and represented additional complexity in dyn compatibility")),
+    (removed, dyn_compatible_for_dispatch, "1.87.0", Some(43561),
+     Some("removed, not used heavily and represented additional complexity in dyn compatibility"), 136522),
     /// Uses generic effect parameters for ~const bounds
     (removed, effects, "1.84.0", Some(102090),
-     Some("removed, redundant with `#![feature(const_trait_impl)]`")),
+     Some("removed, redundant with `#![feature(const_trait_impl)]`"), 132479),
     /// Allows defining `existential type`s.
     (removed, existential_type, "1.38.0", Some(63063),
      Some("removed in favor of `#![feature(type_alias_impl_trait)]`")),
     /// Paths of the form: `extern::foo::bar`
     (removed, extern_in_paths, "1.33.0", Some(55600),
-     Some("subsumed by `::foo::bar` paths")),
+     Some("subsumed by `::foo::bar` paths"), 57572),
     /// Allows `#[doc(include = "some-file")]`.
     (removed, external_doc, "1.54.0", Some(44732),
-     Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")),
+     Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations"), 85457),
     /// Allows using `#[ffi_returns_twice]` on foreign functions.
     (removed, ffi_returns_twice, "1.78.0", Some(58314),
-     Some("being investigated by the ffi-unwind project group")),
+     Some("being investigated by the ffi-unwind project group"), 120502),
     /// Allows generators to be cloned.
-    (removed, generator_clone, "1.65.0", Some(95360), Some("renamed to `coroutine_clone`")),
+    (removed, generator_clone, "1.75.0", Some(95360), Some("renamed to `coroutine_clone`"), 116958),
     /// Allows defining generators.
-    (removed, generators, "1.21.0", Some(43122), Some("renamed to `coroutines`")),
+    (removed, generators, "1.75.0", Some(43122), Some("renamed to `coroutines`"), 116958),
     /// An extension to the `generic_associated_types` feature, allowing incomplete features.
     (removed, generic_associated_types_extended, "1.85.0", Some(95451),
         Some(
             "feature needs overhaul and reimplementation pending \
             better implied higher-ranked implied bounds support"
-        )
+        ),
+        133768
     ),
     (removed, import_shadowing, "1.0.0", None, None),
     /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
-    (removed, in_band_lifetimes, "1.23.0", Some(44524),
-     Some("removed due to unsolved ergonomic questions and added lifetime resolution complexity")),
+    (removed, in_band_lifetimes, "1.61.0", Some(44524),
+     Some("removed due to unsolved ergonomic questions and added lifetime resolution complexity"), 93845),
     /// Allows inferring `'static` outlives requirements (RFC 2093).
     (removed, infer_static_outlives_requirements, "1.63.0", Some(54185),
-     Some("removed as it caused some confusion and discussion was inactive for years")),
+     Some("removed as it caused some confusion and discussion was inactive for years"), 97875),
     /// Allow anonymous constants from an inline `const` block in pattern position
     (removed, inline_const_pat, "1.88.0", Some(76001),
-     Some("removed due to implementation concerns as it requires significant refactorings")),
+     Some("removed due to implementation concerns as it requires significant refactorings"), 138492),
     /// Lazily evaluate constants. This allows constants to depend on type parameters.
-    (removed, lazy_normalization_consts, "1.46.0", Some(72219), Some("superseded by `generic_const_exprs`")),
+    (removed, lazy_normalization_consts, "1.56.0", Some(72219), Some("superseded by `generic_const_exprs`"), 88369),
     /// Changes `impl Trait` to capture all lifetimes in scope.
-    (removed, lifetime_capture_rules_2024, "1.76.0", None, Some("unnecessary -- use edition 2024 instead")),
+    (removed, lifetime_capture_rules_2024, "1.87.0", None, Some("unnecessary -- use edition 2024 instead"), 136787),
     /// Allows using the `#[link_args]` attribute.
     (removed, link_args, "1.53.0", Some(29596),
      Some("removed in favor of using `-C link-arg=ARG` on command line, \
-           which is available from cargo build scripts with `cargo:rustc-link-arg` now")),
+           which is available from cargo build scripts with `cargo:rustc-link-arg` now"), 83820),
     (removed, macro_reexport, "1.0.0", Some(29638),
-     Some("subsumed by `pub use`")),
+     Some("subsumed by `pub use`"), 49982),
     /// Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls.
-    (removed, main, "1.53.0", Some(29634), None),
+    (removed, main, "1.53.0", Some(29634), None, 84217),
     (removed, managed_boxes, "1.0.0", None, None),
     /// Allows the use of type alias impl trait in function return positions
     (removed, min_type_alias_impl_trait, "1.56.0", Some(63063),
-     Some("removed in favor of full type_alias_impl_trait")),
+     Some("removed in favor of full type_alias_impl_trait"), 87564),
     /// Make `mut` not reset the binding mode on edition >= 2024.
-    (removed, mut_preserve_binding_mode_2024, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024`")),
+    (removed, mut_preserve_binding_mode_2024, "1.80.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024`"), 125168),
     (removed, needs_allocator, "1.4.0", Some(27389),
      Some("subsumed by `#![feature(allocator_internals)]`")),
     /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8
     (removed, negate_unsigned, "1.0.0", Some(29645), None),
     /// Allows `#[no_coverage]` on functions.
     /// The feature was renamed to `coverage_attribute` and the attribute to `#[coverage(on|off)]`
-    (removed, no_coverage, "1.74.0", Some(84605), Some("renamed to `coverage_attribute`")),
+    (removed, no_coverage, "1.74.0", Some(84605), Some("renamed to `coverage_attribute`"), 114656),
     /// Allows `#[no_debug]`.
-    (removed, no_debug, "1.43.0", Some(29721), Some("removed due to lack of demand")),
+    (removed, no_debug, "1.43.0", Some(29721), Some("removed due to lack of demand"), 69667),
     /// Note: this feature was previously recorded in a separate
     /// `STABLE_REMOVED` list because it, uniquely, was once stable but was
     /// then removed. But there was no utility storing it separately, so now
     /// it's in this list.
-    (removed, no_stack_check, "1.0.0", None, None),
+    (removed, no_stack_check, "1.0.0", None, None, 40110),
     /// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible (object safe).
     /// Renamed to `dyn_compatible_for_dispatch`.
     (removed, object_safe_for_dispatch, "1.83.0", Some(43561),
-     Some("renamed to `dyn_compatible_for_dispatch`")),
+     Some("renamed to `dyn_compatible_for_dispatch`"), 131511),
     /// Allows using `#[on_unimplemented(..)]` on traits.
     /// (Moved to `rustc_attrs`.)
-    (removed, on_unimplemented, "1.40.0", None, None),
+    (removed, on_unimplemented, "1.40.0", None, None, 65794),
     /// A way to temporarily opt out of opt-in copy. This will *never* be accepted.
-    (removed, opt_out_copy, "1.0.0", None, None),
+    (removed, opt_out_copy, "1.0.0", None, None, 20740),
     /// Allows features specific to OIBIT (now called auto traits).
     /// Renamed to `auto_traits`.
-    (removed, optin_builtin_traits, "1.0.0", Some(13231),
-     Some("renamed to `auto_traits`")),
+    (removed, optin_builtin_traits, "1.50.0", Some(13231),
+     Some("renamed to `auto_traits`"), 79336),
     /// Allows overlapping impls of marker traits.
     (removed, overlapping_marker_traits, "1.42.0", Some(29864),
-     Some("removed in favor of `#![feature(marker_trait_attr)]`")),
+     Some("removed in favor of `#![feature(marker_trait_attr)]`"), 68544),
     (removed, panic_implementation, "1.28.0", Some(44489),
-     Some("subsumed by `#[panic_handler]`")),
+     Some("subsumed by `#[panic_handler]`"), 53619),
     /// Allows `extern "platform-intrinsic" { ... }`.
-    (removed, platform_intrinsics, "1.4.0", Some(27731),
-     Some("SIMD intrinsics use the regular intrinsics ABI now")),
+    (removed, platform_intrinsics, "1.78.0", Some(27731),
+     Some("SIMD intrinsics use the regular intrinsics ABI now"), 121516),
     /// Allows using `#![plugin(myplugin)]`.
     (removed, plugin, "1.75.0", Some(29597),
-     Some("plugins are no longer supported")),
+     Some("plugins are no longer supported"), 116412),
     /// Allows using `#[plugin_registrar]` on functions.
-    (removed, plugin_registrar, "1.54.0", Some(29597),
-     Some("plugins are no longer supported")),
+    (removed, plugin_registrar, "1.75.0", Some(29597),
+     Some("plugins are no longer supported"), 116412),
     /// Allows exhaustive integer pattern matching with `usize::MAX`/`isize::MIN`/`isize::MAX`.
-    (removed, precise_pointer_size_matching, "1.32.0", Some(56354),
-     Some("removed in favor of half-open ranges")),
+    (removed, precise_pointer_size_matching, "1.76.0", Some(56354),
+     Some("removed in favor of half-open ranges"), 118598),
+    (removed, pref_align_of, "CURRENT_RUSTC_VERSION", Some(91971),
+     Some("removed due to marginal use and inducing compiler complications")),
     (removed, proc_macro_expr, "1.27.0", Some(54727),
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`"), 52121),
     (removed, proc_macro_gen, "1.27.0", Some(54727),
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`"), 52121),
     (removed, proc_macro_mod, "1.27.0", Some(54727),
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`"), 52121),
     (removed, proc_macro_non_items, "1.27.0", Some(54727),
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`"), 52121),
     (removed, pub_macro_rules, "1.53.0", Some(78855),
      Some("removed due to being incomplete, in particular it does not work across crates")),
     (removed, pushpop_unsafe, "1.2.0", None, None),
     (removed, quad_precision_float, "1.0.0", None, None),
     (removed, quote, "1.33.0", Some(29601), None),
-    (removed, ref_pat_everywhere, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024")),
+    (removed, ref_pat_everywhere, "1.80.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024"), 125168),
     (removed, reflect, "1.0.0", Some(27749), None),
     /// Allows using the `#[register_attr]` attribute.
     (removed, register_attr, "1.65.0", Some(66080),
-     Some("removed in favor of `#![register_tool]`")),
+     Some("removed in favor of `#![register_tool]`"), 66070),
     (removed, rust_2018_preview, "1.76.0", None,
      Some("2018 Edition preview is no longer relevant")),
     /// Allows using the macros:
     /// + `__diagnostic_used`
     /// + `__register_diagnostic`
     /// +`__build_diagnostic_array`
-    (removed, rustc_diagnostic_macros, "1.38.0", None, None),
+    (removed, rustc_diagnostic_macros, "1.38.0", None, None, 64139),
     /// Allows identifying crates that contain sanitizer runtimes.
-    (removed, sanitizer_runtime, "1.17.0", None, None),
+    (removed, sanitizer_runtime, "1.17.0", None, None, 65241),
     (removed, simd, "1.0.0", Some(27731), Some("removed in favor of `#[repr(simd)]`")),
     /// Allows using `#[start]` on a function indicating that it is the program entrypoint.
-    (removed, start, "1.0.0", Some(29633), Some("not portable enough and never RFC'd")),
+    (removed, start, "1.86.0", Some(29633), Some("not portable enough and never RFC'd"), 134299),
     /// Allows `#[link(kind = "static-nobundle", ...)]`.
-    (removed, static_nobundle, "1.16.0", Some(37403),
-     Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#)),
+    (removed, static_nobundle, "1.63.0", Some(37403),
+     Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#), 95818),
     (removed, struct_inherit, "1.0.0", None, None),
     (removed, test_removed_feature, "1.0.0", None, None),
     /// Allows using items which are missing stability attributes
     (removed, unmarked_api, "1.0.0", None, None),
     /// Allows unnamed fields of struct and union type
-    (removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign")),
+    (removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign"), 131045),
     (removed, unsafe_no_drop_flag, "1.0.0", None, None),
     (removed, unsized_tuple_coercion, "1.87.0", Some(42877),
-     Some("The feature restricts possible layouts for tuples, and this restriction is not worth it.")),
+     Some("The feature restricts possible layouts for tuples, and this restriction is not worth it."), 137728),
     /// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue.
-    (removed, untagged_unions, "1.13.0", Some(55149),
-     Some("unions with `Copy` and `ManuallyDrop` fields are stable; there is no intent to stabilize more")),
+    (removed, untagged_unions, "1.64.0", Some(55149),
+     Some("unions with `Copy` and `ManuallyDrop` fields are stable; there is no intent to stabilize more"), 97995),
     /// Allows `#[unwind(..)]`.
     ///
     /// Permits specifying whether a function should permit unwinding or abort on unwind.
-    (removed, unwind_attributes, "1.56.0", Some(58760), Some("use the C-unwind ABI instead")),
+    (removed, unwind_attributes, "1.56.0", Some(58760), Some("use the C-unwind ABI instead"), 86155),
     (removed, visible_private_types, "1.0.0", None, None),
     /// Allows `extern "wasm" fn`
     (removed, wasm_abi, "1.81.0", Some(83788),
-     Some("non-standard wasm ABI is no longer supported")),
+     Some("non-standard wasm ABI is no longer supported"), 127605),
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
     // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index b46eac6d8a6..594021d78d2 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -546,8 +546,6 @@ declare_features! (
     (incomplete, inherent_associated_types, "1.52.0", Some(8995)),
     /// 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, "1.86.0", 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.
@@ -627,8 +625,6 @@ declare_features! (
     (unstable, return_type_notation, "1.70.0", Some(109417)),
     /// Allows `extern "rust-cold"`.
     (unstable, rust_cold_cc, "1.63.0", Some(97544)),
-    /// Allows use of x86 SHA512, SM3 and SM4 target-features and intrinsics
-    (unstable, sha512_sm_x86, "1.82.0", Some(126624)),
     /// Allows the use of SIMD types in functions declared in `extern` blocks.
     (unstable, simd_ffi, "1.0.0", Some(27731)),
     /// Allows specialization of implementations (RFC 1210).
diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs
index c6e0484b921..6f85e05f29a 100644
--- a/compiler/rustc_fluent_macro/src/lib.rs
+++ b/compiler/rustc_fluent_macro/src/lib.rs
@@ -4,7 +4,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(proc_macro_diagnostic)]
-#![feature(proc_macro_span)]
 #![feature(rustdoc_internals)]
 #![feature(track_path)]
 // tidy-alphabetical-end
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 98ec1ccd6ba..459fe5935e0 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -852,12 +852,7 @@ pub enum LifetimeRes {
     /// late resolution. Those lifetimes will be inferred by typechecking.
     Infer,
     /// `'static` lifetime.
-    Static {
-        /// We do not want to emit `elided_named_lifetimes`
-        /// when we are inside of a const item or a static,
-        /// because it would get too annoying.
-        suppress_elision_warning: bool,
-    },
+    Static,
     /// Resolution failure.
     Error,
     /// HACK: This is used to recover the NodeId of an elided lifetime.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 433d5f98829..6f288bb39b9 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -72,13 +72,13 @@ pub enum LifetimeSource {
 #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
 pub enum LifetimeSyntax {
     /// E.g. `&Type`, `ContainsLifetime`
-    Hidden,
+    Implicit,
 
     /// E.g. `&'_ Type`, `ContainsLifetime<'_>`, `impl Trait + '_`, `impl Trait + use<'_>`
-    Anonymous,
+    ExplicitAnonymous,
 
     /// E.g. `&'a Type`, `ContainsLifetime<'a>`, `impl Trait + 'a`, `impl Trait + use<'a>`
-    Named,
+    ExplicitBound,
 }
 
 impl From<Ident> for LifetimeSyntax {
@@ -88,10 +88,10 @@ impl From<Ident> for LifetimeSyntax {
         if name == sym::empty {
             unreachable!("A lifetime name should never be empty");
         } else if name == kw::UnderscoreLifetime {
-            LifetimeSyntax::Anonymous
+            LifetimeSyntax::ExplicitAnonymous
         } else {
             debug_assert!(name.as_str().starts_with('\''));
-            LifetimeSyntax::Named
+            LifetimeSyntax::ExplicitBound
         }
     }
 }
@@ -102,48 +102,48 @@ impl From<Ident> for LifetimeSyntax {
 ///
 /// ```
 /// #[repr(C)]
-/// struct S<'a>(&'a u32);       // res=Param, name='a, source=Reference, syntax=Named
+/// struct S<'a>(&'a u32);       // res=Param, name='a, source=Reference, syntax=ExplicitBound
 /// unsafe extern "C" {
-///     fn f1(s: S);             // res=Param, name='_, source=Path, syntax=Hidden
-///     fn f2(s: S<'_>);         // res=Param, name='_, source=Path, syntax=Anonymous
-///     fn f3<'a>(s: S<'a>);     // res=Param, name='a, source=Path, syntax=Named
+///     fn f1(s: S);             // res=Param, name='_, source=Path, syntax=Implicit
+///     fn f2(s: S<'_>);         // res=Param, name='_, source=Path, syntax=ExplicitAnonymous
+///     fn f3<'a>(s: S<'a>);     // res=Param, name='a, source=Path, syntax=ExplicitBound
 /// }
 ///
-/// struct St<'a> { x: &'a u32 } // res=Param, name='a, source=Reference, syntax=Named
+/// struct St<'a> { x: &'a u32 } // res=Param, name='a, source=Reference, syntax=ExplicitBound
 /// fn f() {
-///     _ = St { x: &0 };        // res=Infer, name='_, source=Path, syntax=Hidden
-///     _ = St::<'_> { x: &0 };  // res=Infer, name='_, source=Path, syntax=Anonymous
+///     _ = St { x: &0 };        // res=Infer, name='_, source=Path, syntax=Implicit
+///     _ = St::<'_> { x: &0 };  // res=Infer, name='_, source=Path, syntax=ExplicitAnonymous
 /// }
 ///
-/// struct Name<'a>(&'a str);    // res=Param,  name='a, source=Reference, syntax=Named
-/// const A: Name = Name("a");   // res=Static, name='_, source=Path, syntax=Hidden
-/// const B: &str = "";          // res=Static, name='_, source=Reference, syntax=Hidden
-/// static C: &'_ str = "";      // res=Static, name='_, source=Reference, syntax=Anonymous
-/// static D: &'static str = ""; // res=Static, name='static, source=Reference, syntax=Named
+/// struct Name<'a>(&'a str);    // res=Param,  name='a, source=Reference, syntax=ExplicitBound
+/// const A: Name = Name("a");   // res=Static, name='_, source=Path, syntax=Implicit
+/// const B: &str = "";          // res=Static, name='_, source=Reference, syntax=Implicit
+/// static C: &'_ str = "";      // res=Static, name='_, source=Reference, syntax=ExplicitAnonymous
+/// static D: &'static str = ""; // res=Static, name='static, source=Reference, syntax=ExplicitBound
 ///
 /// trait Tr {}
-/// fn tr(_: Box<dyn Tr>) {}     // res=ImplicitObjectLifetimeDefault, name='_, source=Other, syntax=Hidden
+/// fn tr(_: Box<dyn Tr>) {}     // res=ImplicitObjectLifetimeDefault, name='_, source=Other, syntax=Implicit
 ///
 /// fn capture_outlives<'a>() ->
-///     impl FnOnce() + 'a       // res=Param, ident='a, source=OutlivesBound, syntax=Named
+///     impl FnOnce() + 'a       // res=Param, ident='a, source=OutlivesBound, syntax=ExplicitBound
 /// {
 ///     || {}
 /// }
 ///
 /// fn capture_precise<'a>() ->
-///     impl FnOnce() + use<'a>  // res=Param, ident='a, source=PreciseCapturing, syntax=Named
+///     impl FnOnce() + use<'a>  // res=Param, ident='a, source=PreciseCapturing, syntax=ExplicitBound
 /// {
 ///     || {}
 /// }
 ///
 /// // (commented out because these cases trigger errors)
-/// // struct S1<'a>(&'a str);   // res=Param, name='a, source=Reference, syntax=Named
-/// // struct S2(S1);            // res=Error, name='_, source=Path, syntax=Hidden
-/// // struct S3(S1<'_>);        // res=Error, name='_, source=Path, syntax=Anonymous
-/// // struct S4(S1<'a>);        // res=Error, name='a, source=Path, syntax=Named
+/// // struct S1<'a>(&'a str);   // res=Param, name='a, source=Reference, syntax=ExplicitBound
+/// // struct S2(S1);            // res=Error, name='_, source=Path, syntax=Implicit
+/// // struct S3(S1<'_>);        // res=Error, name='_, source=Path, syntax=ExplicitAnonymous
+/// // struct S4(S1<'a>);        // res=Error, name='a, source=Path, syntax=ExplicitBound
 /// ```
 ///
-/// Some combinations that cannot occur are `LifetimeSyntax::Hidden` with
+/// Some combinations that cannot occur are `LifetimeSyntax::Implicit` with
 /// `LifetimeSource::OutlivesBound` or `LifetimeSource::PreciseCapturing`
 /// — there's no way to "elide" these lifetimes.
 #[derive(Debug, Copy, Clone, HashStable_Generic)]
@@ -206,7 +206,7 @@ impl ParamName {
     }
 }
 
-#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
 pub enum LifetimeKind {
     /// User-given names or fresh (synthetic) names.
     Param(LocalDefId),
@@ -287,12 +287,8 @@ impl Lifetime {
         self.ident.name == kw::UnderscoreLifetime
     }
 
-    pub fn is_syntactically_hidden(&self) -> bool {
-        matches!(self.syntax, LifetimeSyntax::Hidden)
-    }
-
-    pub fn is_syntactically_anonymous(&self) -> bool {
-        matches!(self.syntax, LifetimeSyntax::Anonymous)
+    pub fn is_implicit(&self) -> bool {
+        matches!(self.syntax, LifetimeSyntax::Implicit)
     }
 
     pub fn is_static(&self) -> bool {
@@ -307,28 +303,28 @@ impl Lifetime {
 
         match (self.syntax, self.source) {
             // The user wrote `'a` or `'_`.
-            (Named | Anonymous, _) => (self.ident.span, format!("{new_lifetime}")),
+            (ExplicitBound | ExplicitAnonymous, _) => (self.ident.span, format!("{new_lifetime}")),
 
             // The user wrote `Path<T>`, and omitted the `'_,`.
-            (Hidden, Path { angle_brackets: AngleBrackets::Full }) => {
+            (Implicit, Path { angle_brackets: AngleBrackets::Full }) => {
                 (self.ident.span, format!("{new_lifetime}, "))
             }
 
             // The user wrote `Path<>`, and omitted the `'_`..
-            (Hidden, Path { angle_brackets: AngleBrackets::Empty }) => {
+            (Implicit, Path { angle_brackets: AngleBrackets::Empty }) => {
                 (self.ident.span, format!("{new_lifetime}"))
             }
 
             // The user wrote `Path` and omitted the `<'_>`.
-            (Hidden, Path { angle_brackets: AngleBrackets::Missing }) => {
+            (Implicit, Path { angle_brackets: AngleBrackets::Missing }) => {
                 (self.ident.span.shrink_to_hi(), format!("<{new_lifetime}>"))
             }
 
             // The user wrote `&type` or `&mut type`.
-            (Hidden, Reference) => (self.ident.span, format!("{new_lifetime} ")),
+            (Implicit, Reference) => (self.ident.span, format!("{new_lifetime} ")),
 
-            (Hidden, source) => {
-                unreachable!("can't suggest for a hidden lifetime of {source:?}")
+            (Implicit, source) => {
+                unreachable!("can't suggest for a implicit lifetime of {source:?}")
             }
         }
     }
diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs
index 8684adee29c..1fd793bc161 100644
--- a/compiler/rustc_hir/src/hir/tests.rs
+++ b/compiler/rustc_hir/src/hir/tests.rs
@@ -55,7 +55,7 @@ fn trait_object_roundtrips_impl(syntax: TraitObjectSyntax) {
         ident: Ident::new(sym::name, DUMMY_SP),
         kind: LifetimeKind::Static,
         source: LifetimeSource::Other,
-        syntax: LifetimeSyntax::Hidden,
+        syntax: LifetimeSyntax::Implicit,
     };
     let unambig = TyKind::TraitObject::<'_, ()>(&[], TaggedRef::new(&lt, syntax));
     let unambig_to_ambig = unsafe { std::mem::transmute::<_, TyKind<'_, AmbigArg>>(unambig) };
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 7a5ff890689..c6fe475b460 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -5,7 +5,6 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![feature(associated_type_defaults)]
-#![feature(box_patterns)]
 #![feature(closure_track_caller)]
 #![feature(debug_closure_helpers)]
 #![feature(exhaustive_patterns)]
diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml
index f2b82c679b9..899370b34e4 100644
--- a/compiler/rustc_hir_analysis/Cargo.toml
+++ b/compiler/rustc_hir_analysis/Cargo.toml
@@ -26,6 +26,7 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index a3a0e276f74..4fcd9f8a646 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -565,10 +565,6 @@ hir_analysis_unconstrained_generic_parameter = the {$param_def_kind} `{$param_na
 hir_analysis_unconstrained_opaque_type = unconstrained opaque type
     .note = `{$name}` must be used in combination with a concrete type within the same {$what}
 
-hir_analysis_unrecognized_atomic_operation =
-    unrecognized atomic operation function: `{$op}`
-    .label = unrecognized atomic operation
-
 hir_analysis_unrecognized_intrinsic_function =
     unrecognized intrinsic function: `{$name}`
     .label = unrecognized intrinsic
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 846eacce9e1..60ca0155bdd 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -4,14 +4,15 @@ use std::ops::ControlFlow;
 use rustc_abi::FieldIdx;
 use rustc_attr_data_structures::ReprAttr::ReprPacked;
 use rustc_data_structures::unord::{UnordMap, UnordSet};
-use rustc_errors::MultiSpan;
 use rustc_errors::codes::*;
+use rustc_errors::{EmissionGuarantee, MultiSpan};
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::{LangItem, Node, intravisit};
 use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
 use rustc_infer::traits::{Obligation, ObligationCauseCode};
 use rustc_lint_defs::builtin::{
-    REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
+    REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS,
+    UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
 };
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
@@ -24,6 +25,7 @@ use rustc_middle::ty::{
     TypeVisitable, TypeVisitableExt, fold_regions,
 };
 use rustc_session::lint::builtin::UNINHABITED_STATIC;
+use rustc_target::spec::{AbiMap, AbiMapping};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective;
 use rustc_trait_selection::traits;
@@ -35,25 +37,66 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir};
 use super::compare_impl_item::check_type_bounds;
 use super::*;
 
-pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: ExternAbi) {
-    if !tcx.sess.target.is_abi_supported(abi) {
-        struct_span_code_err!(
-            tcx.dcx(),
-            span,
-            E0570,
-            "`{abi}` is not a supported ABI for the current target",
-        )
-        .emit();
+fn add_abi_diag_help<T: EmissionGuarantee>(abi: ExternAbi, diag: &mut Diag<'_, T>) {
+    if let ExternAbi::Cdecl { unwind } = abi {
+        let c_abi = ExternAbi::C { unwind };
+        diag.help(format!("use `extern {c_abi}` instead",));
+    } else if let ExternAbi::Stdcall { unwind } = abi {
+        let c_abi = ExternAbi::C { unwind };
+        let system_abi = ExternAbi::System { unwind };
+        diag.help(format!(
+            "if you need `extern {abi}` on win32 and `extern {c_abi}` everywhere else, \
+                use `extern {system_abi}`"
+        ));
+    }
+}
+
+pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) {
+    // FIXME: this should be checked earlier, e.g. in `rustc_ast_lowering`, to fix
+    // things like #86232.
+
+    match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) {
+        AbiMapping::Direct(..) => (),
+        AbiMapping::Invalid => {
+            let mut err = struct_span_code_err!(
+                tcx.dcx(),
+                span,
+                E0570,
+                "`{abi}` is not a supported ABI for the current target",
+            );
+            add_abi_diag_help(abi, &mut err);
+            err.emit();
+        }
+        AbiMapping::Deprecated(..) => {
+            tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
+                lint.primary_message("use of calling convention not supported on this target");
+                add_abi_diag_help(abi, lint);
+            });
+        }
     }
 }
 
 pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) {
-    if !tcx.sess.target.is_abi_supported(abi) {
-        tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
-            lint.primary_message(format!(
-                "the calling convention {abi} is not supported on this target"
-            ));
-        });
+    // This is always an FCW, even for `AbiMapping::Invalid`, since we started linting later than
+    // in `check_abi` above.
+    match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) {
+        AbiMapping::Direct(..) => (),
+        // This is not a redundant match arm: these ABIs started linting after introducing
+        // UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS already existed and we want to
+        // avoid expanding the scope of that lint so it can move to a hard error sooner.
+        AbiMapping::Deprecated(..) => {
+            tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
+                lint.primary_message("use of calling convention not supported on this target");
+                add_abi_diag_help(abi, lint);
+            });
+        }
+        AbiMapping::Invalid => {
+            tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
+                lint.primary_message(format!(
+                    "the calling convention {abi} is not supported on this target"
+                ));
+            });
+        }
     }
 }
 
@@ -97,7 +140,7 @@ fn allowed_union_or_unsafe_field<'tcx>(
     let def_id = tcx
         .lang_items()
         .get(LangItem::BikeshedGuaranteedNoDrop)
-        .unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, Some(span)));
+        .unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, span));
     let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) else {
         tcx.dcx().span_delayed_bug(span, "could not normalize field type");
         return true;
@@ -702,6 +745,29 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 }
 
 pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
+    let generics = tcx.generics_of(def_id);
+
+    for param in &generics.own_params {
+        match param.kind {
+            ty::GenericParamDefKind::Lifetime { .. } => {}
+            ty::GenericParamDefKind::Type { has_default, .. } => {
+                if has_default {
+                    tcx.ensure_ok().type_of(param.def_id);
+                }
+            }
+            ty::GenericParamDefKind::Const { has_default, .. } => {
+                tcx.ensure_ok().type_of(param.def_id);
+                if has_default {
+                    // need to store default and type of default
+                    let ct = tcx.const_param_default(param.def_id).skip_binder();
+                    if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
+                        tcx.ensure_ok().type_of(uv.def);
+                    }
+                }
+            }
+        }
+    }
+
     match tcx.def_kind(def_id) {
         DefKind::Static { .. } => {
             check_static_inhabited(tcx, def_id);
@@ -770,6 +836,16 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
             } else {
                 check_opaque(tcx, def_id);
             }
+
+            tcx.ensure_ok().predicates_of(def_id);
+            tcx.ensure_ok().explicit_item_bounds(def_id);
+            tcx.ensure_ok().explicit_item_self_bounds(def_id);
+            tcx.ensure_ok().item_bounds(def_id);
+            tcx.ensure_ok().item_self_bounds(def_id);
+            if tcx.is_conditionally_const(def_id) {
+                tcx.ensure_ok().explicit_implied_const_bounds(def_id);
+                tcx.ensure_ok().const_conditions(def_id);
+            }
         }
         DefKind::TyAlias => {
             check_type_alias_type_params_are_used(tcx, def_id);
@@ -779,7 +855,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
             let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
                 return;
             };
-            check_abi(tcx, it.span, abi);
+            check_abi(tcx, it.hir_id(), it.span, abi);
 
             for item in items {
                 let def_id = item.id.owner_id.def_id;
@@ -827,6 +903,15 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                 }
             }
         }
+        DefKind::Closure => {
+            // This is guaranteed to be called by metadata encoding,
+            // we still call it in wfcheck eagerly to ensure errors in codegen
+            // attrs prevent lints from spamming the output.
+            tcx.ensure_ok().codegen_fn_attrs(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.
+        }
         _ => {}
     }
 }
@@ -1100,7 +1185,7 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
             return;
         };
 
-        if let Some(second_field) = fields.get(FieldIdx::from_u32(1)) {
+        if let Some(second_field) = fields.get(FieldIdx::ONE) {
             struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot have multiple fields")
                 .with_span_label(tcx.def_span(second_field.did), "excess field")
                 .emit();
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 09610a2f3ec..481cdaa4c6c 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -9,10 +9,7 @@ use rustc_span::def_id::LocalDefId;
 use rustc_span::{Span, Symbol, sym};
 
 use crate::check::check_function_signature;
-use crate::errors::{
-    UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
-    WrongNumberOfGenericArgumentsToIntrinsic,
-};
+use crate::errors::{UnrecognizedIntrinsicFunction, WrongNumberOfGenericArgumentsToIntrinsic};
 
 fn equate_intrinsic_type<'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -172,7 +169,6 @@ pub(crate) fn check_intrinsic_type(
             Ty::new_error_with_message(tcx, span, "expected param")
         }
     };
-    let name_str = intrinsic_name.as_str();
 
     let bound_vars = tcx.mk_bound_variable_kinds(&[
         ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon),
@@ -180,7 +176,7 @@ pub(crate) fn check_intrinsic_type(
         ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv),
     ]);
     let mk_va_list_ty = |mutbl| {
-        let did = tcx.require_lang_item(LangItem::VaList, Some(span));
+        let did = tcx.require_lang_item(LangItem::VaList, span);
         let region = ty::Region::new_bound(
             tcx,
             ty::INNERMOST,
@@ -198,510 +194,471 @@ pub(crate) fn check_intrinsic_type(
         (Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty)
     };
 
-    let (n_tps, n_lts, n_cts, inputs, output, safety) = if name_str.starts_with("atomic_") {
-        let split: Vec<&str> = name_str.split('_').collect();
-        assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format");
+    let safety = intrinsic_operation_unsafety(tcx, intrinsic_id);
+    let n_lts = 0;
+    let (n_tps, n_cts, inputs, output) = match intrinsic_name {
+        sym::abort => (0, 0, vec![], tcx.types.never),
+        sym::unreachable => (0, 0, vec![], tcx.types.never),
+        sym::breakpoint => (0, 0, vec![], tcx.types.unit),
+        sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => {
+            (1, 0, vec![], tcx.types.usize)
+        }
+        sym::size_of_val | sym::min_align_of_val => {
+            (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
+        }
+        sym::rustc_peek => (1, 0, vec![param(0)], param(0)),
+        sym::caller_location => (0, 0, vec![], tcx.caller_location_ty()),
+        sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
+            (1, 0, vec![], tcx.types.unit)
+        }
+        sym::forget => (1, 0, vec![param(0)], tcx.types.unit),
+        sym::transmute | sym::transmute_unchecked => (2, 0, vec![param(0)], param(1)),
+        sym::prefetch_read_data
+        | sym::prefetch_write_data
+        | sym::prefetch_read_instruction
+        | sym::prefetch_write_instruction => {
+            (1, 0, vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.i32], tcx.types.unit)
+        }
+        sym::needs_drop => (1, 0, vec![], tcx.types.bool),
+
+        sym::type_name => (1, 0, vec![], Ty::new_static_str(tcx)),
+        sym::type_id => (1, 0, vec![], tcx.types.u128),
+        sym::offset => (2, 0, vec![param(0), param(1)], param(0)),
+        sym::arith_offset => (
+            1,
+            0,
+            vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.isize],
+            Ty::new_imm_ptr(tcx, param(0)),
+        ),
+        sym::slice_get_unchecked => (3, 0, vec![param(1), tcx.types.usize], param(0)),
+        sym::ptr_mask => (
+            1,
+            0,
+            vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.usize],
+            Ty::new_imm_ptr(tcx, param(0)),
+        ),
+
+        sym::copy | sym::copy_nonoverlapping => (
+            1,
+            0,
+            vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_mut_ptr(tcx, param(0)), tcx.types.usize],
+            tcx.types.unit,
+        ),
+        sym::volatile_copy_memory | sym::volatile_copy_nonoverlapping_memory => (
+            1,
+            0,
+            vec![Ty::new_mut_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0)), tcx.types.usize],
+            tcx.types.unit,
+        ),
+        sym::compare_bytes => {
+            let byte_ptr = Ty::new_imm_ptr(tcx, tcx.types.u8);
+            (0, 0, vec![byte_ptr, byte_ptr, tcx.types.usize], tcx.types.i32)
+        }
+        sym::write_bytes | sym::volatile_set_memory => (
+            1,
+            0,
+            vec![Ty::new_mut_ptr(tcx, param(0)), tcx.types.u8, tcx.types.usize],
+            tcx.types.unit,
+        ),
+
+        sym::sqrtf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::sqrtf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::sqrtf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::sqrtf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::powif16 => (0, 0, vec![tcx.types.f16, tcx.types.i32], tcx.types.f16),
+        sym::powif32 => (0, 0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32),
+        sym::powif64 => (0, 0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64),
+        sym::powif128 => (0, 0, vec![tcx.types.f128, tcx.types.i32], tcx.types.f128),
+
+        sym::sinf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::sinf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::sinf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::sinf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::cosf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::cosf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::cosf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::cosf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::powf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
+        sym::powf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+        sym::powf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+        sym::powf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
+
+        sym::expf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::expf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::expf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::expf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::exp2f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::exp2f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::exp2f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::exp2f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::logf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::logf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::logf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::logf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::log10f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::log10f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::log10f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::log10f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::log2f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::log2f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::log2f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::log2f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::fmaf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16, tcx.types.f16], tcx.types.f16),
+        sym::fmaf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32),
+        sym::fmaf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64),
+        sym::fmaf128 => {
+            (0, 0, vec![tcx.types.f128, tcx.types.f128, tcx.types.f128], tcx.types.f128)
+        }
 
-        // Each atomic op has variants with different suffixes (`_seq_cst`, `_acquire`, etc.). Use
-        // string ops to strip the suffixes, because the variants all get the same treatment here.
-        let (n_tps, n_cts, inputs, output) = match split[1] {
-            "cxchg" | "cxchgweak" => (
-                1,
-                0,
-                vec![Ty::new_mut_ptr(tcx, param(0)), param(0), param(0)],
-                Ty::new_tup(tcx, &[param(0), tcx.types.bool]),
-            ),
-            "load" => (1, 1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
-            "store" => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit),
-
-            "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | "min" | "umax"
-            | "umin" => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)),
-            "fence" | "singlethreadfence" => (0, 0, Vec::new(), tcx.types.unit),
-            op => {
-                tcx.dcx().emit_err(UnrecognizedAtomicOperation { span, op });
-                return;
-            }
-        };
-        (n_tps, 0, n_cts, inputs, output, hir::Safety::Unsafe)
-    } else if intrinsic_name == sym::contract_check_ensures {
-        // contract_check_ensures::<Ret, C>(Ret, C) -> Ret
-        // where C: for<'a> Fn(&'a Ret) -> bool,
-        //
-        // so: two type params, 0 lifetime param, 0 const params, two inputs, no return
-        (2, 0, 0, vec![param(0), param(1)], param(1), hir::Safety::Safe)
-    } else {
-        let safety = intrinsic_operation_unsafety(tcx, intrinsic_id);
-        let (n_tps, n_cts, inputs, output) = match intrinsic_name {
-            sym::abort => (0, 0, vec![], tcx.types.never),
-            sym::unreachable => (0, 0, vec![], tcx.types.never),
-            sym::breakpoint => (0, 0, vec![], tcx.types.unit),
-            sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => {
-                (1, 0, vec![], tcx.types.usize)
-            }
-            sym::size_of_val | sym::min_align_of_val => {
-                (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
-            }
-            sym::rustc_peek => (1, 0, vec![param(0)], param(0)),
-            sym::caller_location => (0, 0, vec![], tcx.caller_location_ty()),
-            sym::assert_inhabited
-            | sym::assert_zero_valid
-            | sym::assert_mem_uninitialized_valid => (1, 0, vec![], tcx.types.unit),
-            sym::forget => (1, 0, vec![param(0)], tcx.types.unit),
-            sym::transmute | sym::transmute_unchecked => (2, 0, vec![param(0)], param(1)),
-            sym::prefetch_read_data
-            | sym::prefetch_write_data
-            | sym::prefetch_read_instruction
-            | sym::prefetch_write_instruction => {
-                (1, 0, vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.i32], tcx.types.unit)
-            }
-            sym::needs_drop => (1, 0, vec![], tcx.types.bool),
-
-            sym::type_name => (1, 0, vec![], Ty::new_static_str(tcx)),
-            sym::type_id => (1, 0, vec![], tcx.types.u128),
-            sym::offset => (2, 0, vec![param(0), param(1)], param(0)),
-            sym::arith_offset => (
-                1,
-                0,
-                vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.isize],
-                Ty::new_imm_ptr(tcx, param(0)),
-            ),
-            sym::slice_get_unchecked => (3, 0, vec![param(1), tcx.types.usize], param(0)),
-            sym::ptr_mask => (
-                1,
-                0,
-                vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.usize],
-                Ty::new_imm_ptr(tcx, param(0)),
-            ),
+        sym::fmuladdf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16, tcx.types.f16], tcx.types.f16),
+        sym::fmuladdf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32),
+        sym::fmuladdf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64),
+        sym::fmuladdf128 => {
+            (0, 0, vec![tcx.types.f128, tcx.types.f128, tcx.types.f128], tcx.types.f128)
+        }
 
-            sym::copy | sym::copy_nonoverlapping => (
-                1,
-                0,
-                vec![
-                    Ty::new_imm_ptr(tcx, param(0)),
-                    Ty::new_mut_ptr(tcx, param(0)),
-                    tcx.types.usize,
-                ],
-                tcx.types.unit,
-            ),
-            sym::volatile_copy_memory | sym::volatile_copy_nonoverlapping_memory => (
+        sym::fabsf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::fabsf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::fabsf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::fabsf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::minnumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
+        sym::minnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+        sym::minnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+        sym::minnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
+
+        sym::minimumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
+        sym::minimumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+        sym::minimumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+        sym::minimumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
+
+        sym::maxnumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
+        sym::maxnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+        sym::maxnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+        sym::maxnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
+
+        sym::maximumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
+        sym::maximumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+        sym::maximumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+        sym::maximumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
+
+        sym::copysignf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
+        sym::copysignf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+        sym::copysignf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+        sym::copysignf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
+
+        sym::floorf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::floorf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::floorf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::floorf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::ceilf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::ceilf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::ceilf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::ceilf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::truncf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::truncf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::round_ties_even_f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::round_ties_even_f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::round_ties_even_f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::round_ties_even_f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
+        sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
+        sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
+        sym::roundf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
+
+        sym::volatile_load | sym::unaligned_volatile_load => {
+            (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
+        }
+        sym::volatile_store | sym::unaligned_volatile_store => {
+            (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
+        }
+
+        sym::ctpop | sym::ctlz | sym::ctlz_nonzero | sym::cttz | sym::cttz_nonzero => {
+            (1, 0, vec![param(0)], tcx.types.u32)
+        }
+
+        sym::bswap | sym::bitreverse => (1, 0, vec![param(0)], param(0)),
+
+        sym::three_way_compare => (1, 0, vec![param(0), param(0)], tcx.ty_ordering_enum(span)),
+
+        sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
+            (1, 0, vec![param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool]))
+        }
+
+        sym::carrying_mul_add => (2, 0, vec![param(0); 4], Ty::new_tup(tcx, &[param(1), param(0)])),
+
+        sym::ptr_guaranteed_cmp => (
+            1,
+            0,
+            vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
+            tcx.types.u8,
+        ),
+
+        sym::const_allocate => {
+            (0, 0, vec![tcx.types.usize, tcx.types.usize], Ty::new_mut_ptr(tcx, tcx.types.u8))
+        }
+        sym::const_deallocate => (
+            0,
+            0,
+            vec![Ty::new_mut_ptr(tcx, tcx.types.u8), tcx.types.usize, tcx.types.usize],
+            tcx.types.unit,
+        ),
+
+        sym::ptr_offset_from => (
+            1,
+            0,
+            vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
+            tcx.types.isize,
+        ),
+        sym::ptr_offset_from_unsigned => (
+            1,
+            0,
+            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::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)),
+        sym::rotate_left | sym::rotate_right => (1, 0, vec![param(0), tcx.types.u32], param(0)),
+        sym::unchecked_add | sym::unchecked_sub | sym::unchecked_mul => {
+            (1, 0, vec![param(0), param(0)], param(0))
+        }
+        sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul => {
+            (1, 0, vec![param(0), param(0)], param(0))
+        }
+        sym::saturating_add | sym::saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
+        sym::fadd_fast | sym::fsub_fast | sym::fmul_fast | sym::fdiv_fast | sym::frem_fast => {
+            (1, 0, vec![param(0), param(0)], param(0))
+        }
+        sym::fadd_algebraic
+        | sym::fsub_algebraic
+        | sym::fmul_algebraic
+        | sym::fdiv_algebraic
+        | sym::frem_algebraic => (1, 0, vec![param(0), param(0)], param(0)),
+        sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)),
+
+        sym::assume => (0, 0, vec![tcx.types.bool], tcx.types.unit),
+        sym::select_unpredictable => (1, 0, vec![tcx.types.bool, param(0), param(0)], param(0)),
+        sym::cold_path => (0, 0, vec![], tcx.types.unit),
+
+        sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
+        sym::write_via_move => {
+            (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
+        }
+
+        sym::typed_swap_nonoverlapping => {
+            (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit)
+        }
+
+        sym::discriminant_value => {
+            let assoc_items = tcx.associated_item_def_ids(
+                tcx.require_lang_item(hir::LangItem::DiscriminantKind, span),
+            );
+            let discriminant_def_id = assoc_items[0];
+
+            let br = ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon };
+            (
                 1,
                 0,
-                vec![
-                    Ty::new_mut_ptr(tcx, param(0)),
-                    Ty::new_imm_ptr(tcx, param(0)),
-                    tcx.types.usize,
-                ],
+                vec![Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0))],
+                Ty::new_projection_from_args(
+                    tcx,
+                    discriminant_def_id,
+                    tcx.mk_args(&[param(0).into()]),
+                ),
+            )
+        }
+
+        sym::catch_unwind => {
+            let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8);
+            let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
+                [mut_u8],
                 tcx.types.unit,
-            ),
-            sym::compare_bytes => {
-                let byte_ptr = Ty::new_imm_ptr(tcx, tcx.types.u8);
-                (0, 0, vec![byte_ptr, byte_ptr, tcx.types.usize], tcx.types.i32)
-            }
-            sym::write_bytes | sym::volatile_set_memory => (
-                1,
-                0,
-                vec![Ty::new_mut_ptr(tcx, param(0)), tcx.types.u8, tcx.types.usize],
+                false,
+                hir::Safety::Safe,
+                ExternAbi::Rust,
+            ));
+            let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
+                [mut_u8, mut_u8],
                 tcx.types.unit,
-            ),
-
-            sym::sqrtf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::sqrtf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::sqrtf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::sqrtf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::powif16 => (0, 0, vec![tcx.types.f16, tcx.types.i32], tcx.types.f16),
-            sym::powif32 => (0, 0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32),
-            sym::powif64 => (0, 0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64),
-            sym::powif128 => (0, 0, vec![tcx.types.f128, tcx.types.i32], tcx.types.f128),
-
-            sym::sinf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::sinf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::sinf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::sinf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::cosf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::cosf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::cosf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::cosf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::powf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
-            sym::powf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::powf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::powf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
-
-            sym::expf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::expf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::expf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::expf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::exp2f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::exp2f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::exp2f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::exp2f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::logf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::logf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::logf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::logf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::log10f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::log10f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::log10f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::log10f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::log2f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::log2f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::log2f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::log2f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::fmaf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16, tcx.types.f16], tcx.types.f16),
-            sym::fmaf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::fmaf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::fmaf128 => {
-                (0, 0, vec![tcx.types.f128, tcx.types.f128, tcx.types.f128], tcx.types.f128)
-            }
-
-            sym::fmuladdf16 => {
-                (0, 0, vec![tcx.types.f16, tcx.types.f16, tcx.types.f16], tcx.types.f16)
-            }
-            sym::fmuladdf32 => {
-                (0, 0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32)
-            }
-            sym::fmuladdf64 => {
-                (0, 0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64)
-            }
-            sym::fmuladdf128 => {
-                (0, 0, vec![tcx.types.f128, tcx.types.f128, tcx.types.f128], tcx.types.f128)
-            }
-
-            sym::fabsf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::fabsf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::fabsf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::fabsf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::minnumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
-            sym::minnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::minnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::minnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
-
-            sym::minimumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
-            sym::minimumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::minimumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::minimumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
-
-            sym::maxnumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
-            sym::maxnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::maxnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::maxnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
-
-            sym::maximumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
-            sym::maximumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::maximumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::maximumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
-
-            sym::copysignf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
-            sym::copysignf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
-            sym::copysignf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
-            sym::copysignf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
-
-            sym::floorf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::floorf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::floorf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::floorf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::ceilf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::ceilf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::ceilf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::ceilf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::truncf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::truncf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::round_ties_even_f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::round_ties_even_f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::round_ties_even_f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::round_ties_even_f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
-            sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32),
-            sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
-            sym::roundf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
-
-            sym::volatile_load | sym::unaligned_volatile_load => {
-                (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
-            }
-            sym::volatile_store | sym::unaligned_volatile_store => {
-                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
-            }
-
-            sym::ctpop | sym::ctlz | sym::ctlz_nonzero | sym::cttz | sym::cttz_nonzero => {
-                (1, 0, vec![param(0)], tcx.types.u32)
-            }
-
-            sym::bswap | sym::bitreverse => (1, 0, vec![param(0)], param(0)),
-
-            sym::three_way_compare => {
-                (1, 0, vec![param(0), param(0)], tcx.ty_ordering_enum(Some(span)))
-            }
-
-            sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
-                (1, 0, vec![param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool]))
-            }
-
-            sym::carrying_mul_add => {
-                (2, 0, vec![param(0); 4], Ty::new_tup(tcx, &[param(1), param(0)]))
-            }
-
-            sym::ptr_guaranteed_cmp => (
-                1,
-                0,
-                vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
-                tcx.types.u8,
-            ),
-
-            sym::const_allocate => {
-                (0, 0, vec![tcx.types.usize, tcx.types.usize], Ty::new_mut_ptr(tcx, tcx.types.u8))
-            }
-            sym::const_deallocate => (
+                false,
+                hir::Safety::Safe,
+                ExternAbi::Rust,
+            ));
+            (
                 0,
                 0,
-                vec![Ty::new_mut_ptr(tcx, tcx.types.u8), tcx.types.usize, tcx.types.usize],
-                tcx.types.unit,
-            ),
+                vec![Ty::new_fn_ptr(tcx, try_fn_ty), mut_u8, Ty::new_fn_ptr(tcx, catch_fn_ty)],
+                tcx.types.i32,
+            )
+        }
 
-            sym::ptr_offset_from => (
-                1,
-                0,
-                vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
-                tcx.types.isize,
-            ),
-            sym::ptr_offset_from_unsigned => (
-                1,
-                0,
-                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::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)),
-            sym::rotate_left | sym::rotate_right => (1, 0, vec![param(0), tcx.types.u32], param(0)),
-            sym::unchecked_add | sym::unchecked_sub | sym::unchecked_mul => {
-                (1, 0, vec![param(0), param(0)], param(0))
-            }
-            sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul => {
-                (1, 0, vec![param(0), param(0)], param(0))
-            }
-            sym::saturating_add | sym::saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
-            sym::fadd_fast | sym::fsub_fast | sym::fmul_fast | sym::fdiv_fast | sym::frem_fast => {
-                (1, 0, vec![param(0), param(0)], param(0))
-            }
-            sym::fadd_algebraic
-            | sym::fsub_algebraic
-            | sym::fmul_algebraic
-            | sym::fdiv_algebraic
-            | sym::frem_algebraic => (1, 0, vec![param(0), param(0)], param(0)),
-            sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)),
-
-            sym::assume => (0, 0, vec![tcx.types.bool], tcx.types.unit),
-            sym::select_unpredictable => (1, 0, vec![tcx.types.bool, param(0), param(0)], param(0)),
-            sym::cold_path => (0, 0, vec![], tcx.types.unit),
-
-            sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
-            sym::write_via_move => {
-                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
-            }
-
-            sym::typed_swap_nonoverlapping => {
-                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit)
-            }
-
-            sym::discriminant_value => {
-                let assoc_items = tcx.associated_item_def_ids(
-                    tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
-                );
-                let discriminant_def_id = assoc_items[0];
-
-                let br =
-                    ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon };
-                (
-                    1,
-                    0,
-                    vec![Ty::new_imm_ref(
-                        tcx,
-                        ty::Region::new_bound(tcx, ty::INNERMOST, br),
-                        param(0),
-                    )],
-                    Ty::new_projection_from_args(
-                        tcx,
-                        discriminant_def_id,
-                        tcx.mk_args(&[param(0).into()]),
-                    ),
-                )
-            }
-
-            sym::catch_unwind => {
-                let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8);
-                let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
-                    [mut_u8],
-                    tcx.types.unit,
-                    false,
-                    hir::Safety::Safe,
-                    ExternAbi::Rust,
-                ));
-                let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
-                    [mut_u8, mut_u8],
-                    tcx.types.unit,
-                    false,
-                    hir::Safety::Safe,
-                    ExternAbi::Rust,
-                ));
-                (
-                    0,
-                    0,
-                    vec![Ty::new_fn_ptr(tcx, try_fn_ty), mut_u8, Ty::new_fn_ptr(tcx, catch_fn_ty)],
-                    tcx.types.i32,
-                )
-            }
-
-            sym::va_start | sym::va_end => {
-                (0, 0, vec![mk_va_list_ty(hir::Mutability::Mut).0], tcx.types.unit)
-            }
-
-            sym::va_copy => {
-                let (va_list_ref_ty, va_list_ty) = mk_va_list_ty(hir::Mutability::Not);
-                let va_list_ptr_ty = Ty::new_mut_ptr(tcx, va_list_ty);
-                (0, 0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.types.unit)
-            }
-
-            sym::va_arg => (1, 0, vec![mk_va_list_ty(hir::Mutability::Mut).0], param(0)),
-
-            sym::nontemporal_store => {
-                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
-            }
-
-            sym::raw_eq => {
-                let br =
-                    ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon };
-                let param_ty_lhs =
-                    Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
-                let br = ty::BoundRegion {
-                    var: ty::BoundVar::from_u32(1),
-                    kind: ty::BoundRegionKind::Anon,
-                };
-                let param_ty_rhs =
-                    Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
-                (1, 0, vec![param_ty_lhs, param_ty_rhs], tcx.types.bool)
-            }
-
-            sym::black_box => (1, 0, vec![param(0)], param(0)),
-
-            sym::is_val_statically_known => (1, 0, vec![param(0)], tcx.types.bool),
-
-            sym::const_eval_select => (4, 0, vec![param(0), param(1), param(2)], param(3)),
-
-            sym::vtable_size | sym::vtable_align => {
-                (0, 0, vec![Ty::new_imm_ptr(tcx, tcx.types.unit)], tcx.types.usize)
-            }
-
-            // This type check is not particularly useful, but the `where` bounds
-            // on the definition in `core` do the heavy lifting for checking it.
-            sym::aggregate_raw_ptr => (3, 0, vec![param(1), param(2)], param(0)),
-            sym::ptr_metadata => (2, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(1)),
-
-            sym::ub_checks => (0, 0, Vec::new(), tcx.types.bool),
-
-            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
-            | sym::simd_le
-            | sym::simd_gt
-            | sym::simd_ge => (2, 0, vec![param(0), param(0)], param(1)),
-            sym::simd_add
-            | sym::simd_sub
-            | sym::simd_mul
-            | sym::simd_rem
-            | sym::simd_div
-            | sym::simd_shl
-            | sym::simd_shr
-            | sym::simd_and
-            | sym::simd_or
-            | sym::simd_xor
-            | sym::simd_fmin
-            | sym::simd_fmax
-            | sym::simd_saturating_add
-            | sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
-            sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)),
-            sym::simd_neg
-            | sym::simd_bswap
-            | sym::simd_bitreverse
-            | sym::simd_ctlz
-            | sym::simd_cttz
-            | sym::simd_ctpop
-            | sym::simd_fsqrt
-            | sym::simd_fsin
-            | sym::simd_fcos
-            | sym::simd_fexp
-            | sym::simd_fexp2
-            | sym::simd_flog2
-            | sym::simd_flog10
-            | sym::simd_flog
-            | sym::simd_fabs
-            | sym::simd_ceil
-            | sym::simd_floor
-            | sym::simd_round
-            | sym::simd_trunc => (1, 0, vec![param(0)], param(0)),
-            sym::simd_fma | sym::simd_relaxed_fma => {
-                (1, 0, vec![param(0), param(0), param(0)], param(0))
-            }
-            sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)),
-            sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)),
-            sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
-            sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
-            sym::simd_insert | sym::simd_insert_dyn => {
-                (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0))
-            }
-            sym::simd_extract | sym::simd_extract_dyn => {
-                (2, 0, vec![param(0), tcx.types.u32], param(1))
-            }
-            sym::simd_cast
-            | sym::simd_as
-            | sym::simd_cast_ptr
-            | sym::simd_expose_provenance
-            | sym::simd_with_exposed_provenance => (2, 0, vec![param(0)], param(1)),
-            sym::simd_bitmask => (2, 0, vec![param(0)], param(1)),
-            sym::simd_select | sym::simd_select_bitmask => {
-                (2, 0, vec![param(0), param(1), param(1)], param(1))
-            }
-            sym::simd_reduce_all | sym::simd_reduce_any => (1, 0, vec![param(0)], tcx.types.bool),
-            sym::simd_reduce_add_ordered | sym::simd_reduce_mul_ordered => {
-                (2, 0, vec![param(0), param(1)], param(1))
-            }
-            sym::simd_reduce_add_unordered
-            | sym::simd_reduce_mul_unordered
-            | sym::simd_reduce_and
-            | sym::simd_reduce_or
-            | sym::simd_reduce_xor
-            | sym::simd_reduce_min
-            | sym::simd_reduce_max => (2, 0, vec![param(0)], param(1)),
-            sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)),
-            sym::simd_shuffle_const_generic => (2, 1, vec![param(0), param(0)], param(1)),
-
-            other => {
-                tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other });
-                return;
-            }
-        };
-        (n_tps, 0, n_cts, inputs, output, safety)
+        sym::va_start | sym::va_end => {
+            (0, 0, vec![mk_va_list_ty(hir::Mutability::Mut).0], tcx.types.unit)
+        }
+
+        sym::va_copy => {
+            let (va_list_ref_ty, va_list_ty) = mk_va_list_ty(hir::Mutability::Not);
+            let va_list_ptr_ty = Ty::new_mut_ptr(tcx, va_list_ty);
+            (0, 0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.types.unit)
+        }
+
+        sym::va_arg => (1, 0, vec![mk_va_list_ty(hir::Mutability::Mut).0], param(0)),
+
+        sym::nontemporal_store => {
+            (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
+        }
+
+        sym::raw_eq => {
+            let br = ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon };
+            let param_ty_lhs =
+                Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
+            let br =
+                ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BoundRegionKind::Anon };
+            let param_ty_rhs =
+                Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
+            (1, 0, vec![param_ty_lhs, param_ty_rhs], tcx.types.bool)
+        }
+
+        sym::black_box => (1, 0, vec![param(0)], param(0)),
+
+        sym::is_val_statically_known => (1, 0, vec![param(0)], tcx.types.bool),
+
+        sym::const_eval_select => (4, 0, vec![param(0), param(1), param(2)], param(3)),
+
+        sym::vtable_size | sym::vtable_align => {
+            (0, 0, vec![Ty::new_imm_ptr(tcx, tcx.types.unit)], tcx.types.usize)
+        }
+
+        // This type check is not particularly useful, but the `where` bounds
+        // on the definition in `core` do the heavy lifting for checking it.
+        sym::aggregate_raw_ptr => (3, 0, vec![param(1), param(2)], param(0)),
+        sym::ptr_metadata => (2, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(1)),
+
+        sym::ub_checks => (0, 0, Vec::new(), tcx.types.bool),
+
+        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::contract_check_ensures => (2, 0, vec![param(0), param(1)], param(1)),
+
+        sym::simd_eq | sym::simd_ne | sym::simd_lt | sym::simd_le | sym::simd_gt | sym::simd_ge => {
+            (2, 0, vec![param(0), param(0)], param(1))
+        }
+        sym::simd_add
+        | sym::simd_sub
+        | sym::simd_mul
+        | sym::simd_rem
+        | sym::simd_div
+        | sym::simd_shl
+        | sym::simd_shr
+        | sym::simd_and
+        | sym::simd_or
+        | sym::simd_xor
+        | sym::simd_fmin
+        | sym::simd_fmax
+        | sym::simd_saturating_add
+        | sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
+        sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)),
+        sym::simd_neg
+        | sym::simd_bswap
+        | sym::simd_bitreverse
+        | sym::simd_ctlz
+        | sym::simd_cttz
+        | sym::simd_ctpop
+        | sym::simd_fsqrt
+        | sym::simd_fsin
+        | sym::simd_fcos
+        | sym::simd_fexp
+        | sym::simd_fexp2
+        | sym::simd_flog2
+        | sym::simd_flog10
+        | sym::simd_flog
+        | sym::simd_fabs
+        | sym::simd_ceil
+        | sym::simd_floor
+        | sym::simd_round
+        | sym::simd_trunc => (1, 0, vec![param(0)], param(0)),
+        sym::simd_fma | sym::simd_relaxed_fma => {
+            (1, 0, vec![param(0), param(0), param(0)], param(0))
+        }
+        sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)),
+        sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)),
+        sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
+        sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
+        sym::simd_insert | sym::simd_insert_dyn => {
+            (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0))
+        }
+        sym::simd_extract | sym::simd_extract_dyn => {
+            (2, 0, vec![param(0), tcx.types.u32], param(1))
+        }
+        sym::simd_cast
+        | sym::simd_as
+        | sym::simd_cast_ptr
+        | sym::simd_expose_provenance
+        | sym::simd_with_exposed_provenance => (2, 0, vec![param(0)], param(1)),
+        sym::simd_bitmask => (2, 0, vec![param(0)], param(1)),
+        sym::simd_select | sym::simd_select_bitmask => {
+            (2, 0, vec![param(0), param(1), param(1)], param(1))
+        }
+        sym::simd_reduce_all | sym::simd_reduce_any => (1, 0, vec![param(0)], tcx.types.bool),
+        sym::simd_reduce_add_ordered | sym::simd_reduce_mul_ordered => {
+            (2, 0, vec![param(0), param(1)], param(1))
+        }
+        sym::simd_reduce_add_unordered
+        | sym::simd_reduce_mul_unordered
+        | sym::simd_reduce_and
+        | sym::simd_reduce_or
+        | sym::simd_reduce_xor
+        | sym::simd_reduce_min
+        | sym::simd_reduce_max => (2, 0, vec![param(0)], param(1)),
+        sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)),
+        sym::simd_shuffle_const_generic => (2, 1, vec![param(0), param(0)], param(1)),
+
+        sym::atomic_cxchg | sym::atomic_cxchgweak => (
+            1,
+            2,
+            vec![Ty::new_mut_ptr(tcx, param(0)), param(0), param(0)],
+            Ty::new_tup(tcx, &[param(0), tcx.types.bool]),
+        ),
+        sym::atomic_load => (1, 1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
+        sym::atomic_store => (1, 1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit),
+
+        sym::atomic_xchg
+        | sym::atomic_xadd
+        | sym::atomic_xsub
+        | sym::atomic_and
+        | sym::atomic_nand
+        | sym::atomic_or
+        | sym::atomic_xor
+        | sym::atomic_max
+        | sym::atomic_min
+        | sym::atomic_umax
+        | sym::atomic_umin => (1, 1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)),
+        sym::atomic_fence | sym::atomic_singlethreadfence => (0, 1, Vec::new(), tcx.types.unit),
+
+        other => {
+            tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other });
+            return;
+        }
     };
     let sig = tcx.mk_fn_sig(inputs, output, false, safety, ExternAbi::Rust);
     let sig = ty::Binder::bind_with_vars(sig, bound_vars);
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 3e872607e31..b8dc01cbc03 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -40,7 +40,6 @@ use tracing::{debug, instrument};
 use {rustc_ast as ast, rustc_hir as hir};
 
 use crate::autoderef::Autoderef;
-use crate::collect::CollectItemTypesVisitor;
 use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params};
 use crate::errors::InvalidReceiverTyHint;
 use crate::{errors, fluent_generated as fluent};
@@ -195,7 +194,9 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
         hir::Node::TraitItem(item) => check_trait_item(tcx, item),
         hir::Node::ImplItem(item) => check_impl_item(tcx, item),
         hir::Node::ForeignItem(item) => check_foreign_item(tcx, item),
-        hir::Node::OpaqueTy(_) => Ok(crate::check::check::check_item_type(tcx, def_id)),
+        hir::Node::ConstBlock(_) | hir::Node::Expr(_) | hir::Node::OpaqueTy(_) => {
+            Ok(crate::check::check::check_item_type(tcx, def_id))
+        }
         _ => unreachable!("{node:?}"),
     };
 
@@ -229,7 +230,8 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
         ?item.owner_id,
         item.name = ? tcx.def_path_str(def_id)
     );
-    CollectItemTypesVisitor { tcx }.visit_item(item);
+    crate::collect::lower_item(tcx, item.item_id());
+    crate::collect::reject_placeholder_type_signatures_in_item(tcx, item);
 
     let res = match item.kind {
         // Right now we check that every default trait implementation
@@ -350,8 +352,6 @@ fn check_foreign_item<'tcx>(
 ) -> Result<(), ErrorGuaranteed> {
     let def_id = item.owner_id.def_id;
 
-    CollectItemTypesVisitor { tcx }.visit_foreign_item(item);
-
     debug!(
         ?item.owner_id,
         item.name = ? tcx.def_path_str(def_id)
@@ -374,7 +374,7 @@ fn check_trait_item<'tcx>(
 ) -> Result<(), ErrorGuaranteed> {
     let def_id = trait_item.owner_id.def_id;
 
-    CollectItemTypesVisitor { tcx }.visit_trait_item(trait_item);
+    crate::collect::lower_trait_item(tcx, trait_item.trait_item_id());
 
     let (method_sig, span) = match trait_item.kind {
         hir::TraitItemKind::Fn(ref sig, _) => (Some(sig), trait_item.span),
@@ -939,7 +939,7 @@ fn check_impl_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_item: &'tcx hir::ImplItem<'tcx>,
 ) -> Result<(), ErrorGuaranteed> {
-    CollectItemTypesVisitor { tcx }.visit_impl_item(impl_item);
+    crate::collect::lower_impl_item(tcx, impl_item.impl_item_id());
 
     let (method_sig, span) = match impl_item.kind {
         hir::ImplItemKind::Fn(ref sig, _) => (Some(sig), impl_item.span),
@@ -969,7 +969,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
                         ),
                         wfcx.param_env,
                         ty,
-                        tcx.require_lang_item(LangItem::UnsizedConstParamTy, Some(hir_ty.span)),
+                        tcx.require_lang_item(LangItem::UnsizedConstParamTy, hir_ty.span),
                     );
                     Ok(())
                 })
@@ -983,7 +983,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
                         ),
                         wfcx.param_env,
                         ty,
-                        tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span)),
+                        tcx.require_lang_item(LangItem::ConstParamTy, hir_ty.span),
                     );
                     Ok(())
                 })
@@ -1232,7 +1232,7 @@ fn check_type_defn<'tcx>(
                     ),
                     wfcx.param_env,
                     ty,
-                    tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)),
+                    tcx.require_lang_item(LangItem::Sized, hir_ty.span),
                 );
             }
 
@@ -1356,7 +1356,7 @@ fn check_static_item(
                 ),
                 wfcx.param_env,
                 item_ty,
-                tcx.require_lang_item(LangItem::Sized, Some(ty_span)),
+                tcx.require_lang_item(LangItem::Sized, ty_span),
             );
         }
 
@@ -1375,7 +1375,7 @@ fn check_static_item(
                 ),
                 wfcx.param_env,
                 item_ty,
-                tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
+                tcx.require_lang_item(LangItem::Sync, ty_span),
             );
         }
         Ok(())
@@ -1401,7 +1401,7 @@ fn check_const_item(
             ),
             wfcx.param_env,
             ty,
-            tcx.require_lang_item(LangItem::Sized, None),
+            tcx.require_lang_item(LangItem::Sized, ty_span),
         );
 
         check_where_clauses(wfcx, item_span, def_id);
@@ -1725,13 +1725,13 @@ fn check_fn_or_method<'tcx>(
                 ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall),
                 wfcx.param_env,
                 *ty,
-                tcx.require_lang_item(hir::LangItem::Tuple, Some(span)),
+                tcx.require_lang_item(hir::LangItem::Tuple, span),
             );
             wfcx.register_bound(
                 ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall),
                 wfcx.param_env,
                 *ty,
-                tcx.require_lang_item(hir::LangItem::Sized, Some(span)),
+                tcx.require_lang_item(hir::LangItem::Sized, span),
             );
         } else {
             tcx.dcx().span_err(
@@ -1776,7 +1776,7 @@ fn check_sized_if_body<'tcx>(
             ObligationCause::new(span, def_id, code),
             wfcx.param_env,
             ty,
-            tcx.require_lang_item(LangItem::Sized, Some(span)),
+            tcx.require_lang_item(LangItem::Sized, span),
         );
     }
 }
@@ -2013,7 +2013,7 @@ fn receiver_is_valid<'tcx>(
         // deref chain implement `LegacyReceiver`.
         if arbitrary_self_types_enabled.is_none() {
             let legacy_receiver_trait_def_id =
-                tcx.require_lang_item(LangItem::LegacyReceiver, Some(span));
+                tcx.require_lang_item(LangItem::LegacyReceiver, span);
             if !legacy_receiver_is_implemented(
                 wfcx,
                 legacy_receiver_trait_def_id,
@@ -2411,6 +2411,7 @@ fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> {
         .and(
             items.par_foreign_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)),
         )
+        .and(items.par_nested_bodies(|item| tcx.ensure_ok().check_well_formed(item)))
         .and(items.par_opaques(|item| tcx.ensure_ok().check_well_formed(item)));
     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 b92d1d7104f..4779f4fb702 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -225,7 +225,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
     // redundant errors for `DispatchFromDyn`. This is best effort, though.
     let mut res = Ok(());
     tcx.for_each_relevant_impl(
-        tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)),
+        tcx.require_lang_item(LangItem::CoerceUnsized, span),
         source,
         |impl_def_id| {
             res = res.and(tcx.ensure_ok().coerce_unsized_info(impl_def_id));
@@ -379,8 +379,8 @@ pub(crate) fn coerce_unsized_info<'tcx>(
     let span = tcx.def_span(impl_did);
     let trait_name = "CoerceUnsized";
 
-    let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span));
-    let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span));
+    let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, span);
+    let unsize_trait = tcx.require_lang_item(LangItem::Unsize, span);
 
     let source = tcx.type_of(impl_did).instantiate_identity();
     let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity();
@@ -591,7 +591,7 @@ fn infringing_fields_error<'tcx>(
     impl_did: LocalDefId,
     impl_span: Span,
 ) -> ErrorGuaranteed {
-    let trait_did = tcx.require_lang_item(lang_item, Some(impl_span));
+    let trait_did = tcx.require_lang_item(lang_item, impl_span);
 
     let trait_name = tcx.def_path_str(trait_did);
 
@@ -748,7 +748,7 @@ fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), Err
                         ObligationCause::misc(impl_span, checker.impl_def_id),
                         param_env,
                         nontrivial_field_ty,
-                        tcx.require_lang_item(LangItem::PointerLike, Some(impl_span)),
+                        tcx.require_lang_item(LangItem::PointerLike, impl_span),
                     );
                     // FIXME(dyn-star): We should regionck this implementation.
                     if ocx.select_all_or_error().is_empty() {
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index a649e7d67af..e1df0d60452 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -28,11 +28,10 @@ use rustc_errors::{
 };
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt, walk_generics};
+use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_generics};
 use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
-use rustc_middle::hir::nested_filter;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::util::{Discr, IntTypeExt};
 use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode, fold_regions};
@@ -148,10 +147,6 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
     }
 }
 
-pub(crate) struct CollectItemTypesVisitor<'tcx> {
-    pub tcx: TyCtxt<'tcx>,
-}
-
 /// If there are any placeholder types (`_`), emit an error explaining that this is not allowed
 /// and suggest adding type parameters in the appropriate place, taking into consideration any and
 /// all already existing generic type parameters to avoid suggesting a name that is already in use.
@@ -243,7 +238,7 @@ pub(crate) fn placeholder_type_error_diag<'cx, 'tcx>(
     err
 }
 
-fn reject_placeholder_type_signatures_in_item<'tcx>(
+pub(super) fn reject_placeholder_type_signatures_in_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     item: &'tcx hir::Item<'tcx>,
 ) {
@@ -274,81 +269,6 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
     );
 }
 
-impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
-    type NestedFilter = nested_filter::OnlyBodies;
-
-    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
-        self.tcx
-    }
-
-    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        lower_item(self.tcx, item.item_id());
-        reject_placeholder_type_signatures_in_item(self.tcx, item);
-        intravisit::walk_item(self, item);
-    }
-
-    fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
-        for param in generics.params {
-            match param.kind {
-                hir::GenericParamKind::Lifetime { .. } => {}
-                hir::GenericParamKind::Type { default: Some(_), .. } => {
-                    self.tcx.ensure_ok().type_of(param.def_id);
-                }
-                hir::GenericParamKind::Type { .. } => {}
-                hir::GenericParamKind::Const { default, .. } => {
-                    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_ok().const_param_default(param.def_id);
-                        if let hir::ConstArgKind::Anon(ac) = default.kind {
-                            self.tcx.ensure_ok().type_of(ac.def_id);
-                        }
-                    }
-                }
-            }
-        }
-        intravisit::walk_generics(self, generics);
-    }
-
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
-        if let hir::ExprKind::Closure(closure) = expr.kind {
-            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.
-        }
-        intravisit::walk_expr(self, expr);
-    }
-
-    /// Don't call `type_of` on opaque types, since that depends on type checking function bodies.
-    /// `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_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_ok().explicit_implied_const_bounds(def_id);
-            self.tcx.ensure_ok().const_conditions(def_id);
-        }
-        intravisit::walk_opaque_ty(self, opaque);
-    }
-
-    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
-        lower_trait_item(self.tcx, trait_item.trait_item_id());
-        intravisit::walk_trait_item(self, trait_item);
-    }
-
-    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
-        lower_impl_item(self.tcx, impl_item.impl_item_id());
-        intravisit::walk_impl_item(self, impl_item);
-    }
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // Utility types and common code for the above passes.
 
@@ -669,7 +589,7 @@ fn get_new_lifetime_name<'tcx>(
 }
 
 #[instrument(level = "debug", skip_all)]
-fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
+pub(super) fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
     let it = tcx.hir_item(item_id);
     debug!(item = ?it.kind.ident(), id = %it.hir_id());
     let def_id = item_id.owner_id.def_id;
@@ -790,7 +710,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
     }
 }
 
-fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
+pub(crate) 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_ok().generics_of(def_id);
@@ -861,7 +781,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
     tcx.ensure_ok().predicates_of(def_id);
 }
 
-fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
+pub(super) fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
     let def_id = impl_item_id.owner_id;
     tcx.ensure_ok().generics_of(def_id);
     tcx.ensure_ok().type_of(def_id);
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 152714b3407..a27d1ed6c53 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -162,15 +162,6 @@ pub(crate) enum AssocItemNotFoundSugg<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_unrecognized_atomic_operation, code = E0092)]
-pub(crate) struct UnrecognizedAtomicOperation<'a> {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    pub op: &'a str,
-}
-
-#[derive(Diagnostic)]
 #[diag(hir_analysis_wrong_number_of_generic_arguments_to_intrinsic, code = E0094)]
 pub(crate) struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
     #[primary_span]
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
index 21f0f9648ea..3a26b8331f8 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
@@ -73,7 +73,7 @@ fn generic_arg_mismatch_err(
                     let param_name = tcx.hir_ty_param_name(param_local_id);
                     let param_type = tcx.type_of(param.def_id).instantiate_identity();
                     if param_type.is_suggestable(tcx, false) {
-                        err.span_suggestion(
+                        err.span_suggestion_verbose(
                             tcx.def_span(src_def_id),
                             "consider changing this type parameter to a const parameter",
                             format!("const {param_name}: {param_type}"),
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 2a37a8bdbd4..4c65d0d0510 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2590,7 +2590,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
             }
             &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
-                let def_id = tcx.require_lang_item(lang_item, Some(span));
+                let def_id = tcx.require_lang_item(lang_item, span);
                 let (args, _) = self.lower_generic_args_of_path(
                     span,
                     def_id,
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index f255817bffc..a92ee89186c 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -192,10 +192,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
         let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(());
     });
 
-    // Make sure we evaluate all static and (non-associated) const items, even if unused.
-    // If any of these fail to evaluate, we do not want this crate to pass compilation.
     tcx.par_hir_body_owners(|item_def_id| {
         let def_kind = tcx.def_kind(item_def_id);
+        // Make sure we evaluate all static and (non-associated) const items, even if unused.
+        // If any of these fail to evaluate, we do not want this crate to pass compilation.
         match def_kind {
             DefKind::Static { .. } => {
                 tcx.ensure_ok().eval_static_initializer(item_def_id);
@@ -215,6 +215,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
         if !matches!(def_kind, DefKind::AnonConst) {
             tcx.ensure_ok().typeck(item_def_id);
         }
+        // Ensure we generate the new `DefId` before finishing `check_crate`.
+        // Afterwards we freeze the list of `DefId`s.
+        if tcx.needs_coroutine_by_move_body_def_id(item_def_id.to_def_id()) {
+            tcx.ensure_done().coroutine_by_move_body_def_id(item_def_id);
+        }
     });
 
     if tcx.features().rustc_attrs() {
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index 5e79d10612d..3bdd1b48666 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -17,6 +17,24 @@ hir_typeck_base_expression_double_dot_enable_default_field_values =
     add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
 hir_typeck_base_expression_double_dot_remove = remove the `..` as all the fields are already present
 
+hir_typeck_break_inside_closure =
+    `{$name}` inside of a closure
+    .label = cannot `{$name}` inside of a closure
+    .closure_label = enclosing closure
+
+hir_typeck_break_inside_coroutine =
+    `{$name}` inside `{$kind}` {$source}
+    .label = cannot `{$name}` inside `{$kind}` {$source}
+    .coroutine_label = enclosing `{$kind}` {$source}
+
+hir_typeck_break_non_loop =
+    `break` with value from a `{$kind}` loop
+    .label = can only break with a value inside `loop` or breakable block
+    .label2 = you can't `break` with a value in a `{$kind}` loop
+    .suggestion = use `break` on its own without a value inside this `{$kind}` loop
+    .break_expr_suggestion = alternatively, you might have meant to use the available loop label
+
+
 hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`{$action_or_ty ->
     [NONE] {""}
     [implement] , perhaps you need to implement it
@@ -64,6 +82,12 @@ hir_typeck_const_select_must_be_fn = this argument must be a function item
     .note = expected a function item, found {$ty}
     .help = consult the documentation on `const_eval_select` for more information
 
+hir_typeck_continue_labeled_block =
+    `continue` pointing to a labeled block
+    .label = labeled blocks cannot be `continue`'d
+    .block_label = labeled block the `continue` points to
+
+
 hir_typeck_convert_to_str = try converting the passed type into a `&str`
 
 hir_typeck_convert_using_method = try using `{$sugg}` to convert `{$found}` to `{$expected}`
@@ -137,6 +161,18 @@ hir_typeck_lossy_provenance_ptr2int =
 
 hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
 
+hir_typeck_naked_asm_outside_naked_fn =
+    the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
+
+hir_typeck_naked_functions_asm_block =
+    naked functions must contain a single `naked_asm!` invocation
+    .label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
+    .label_non_asm = not allowed in naked functions
+
+hir_typeck_naked_functions_must_naked_asm =
+    the `asm!` macro is not allowed in naked functions
+    .label = consider using the `naked_asm!` macro instead
+
 hir_typeck_never_type_fallback_flowing_into_unsafe_call = never type fallback affects this call to an `unsafe` function
     .help = specify the type explicitly
 hir_typeck_never_type_fallback_flowing_into_unsafe_deref = never type fallback affects this raw pointer dereference
@@ -159,6 +195,9 @@ hir_typeck_no_field_on_variant = no field named `{$field}` on enum variant `{$co
 hir_typeck_no_field_on_variant_enum = this enum variant...
 hir_typeck_no_field_on_variant_field = ...does not have this field
 
+hir_typeck_no_patterns =
+    patterns not allowed in naked function parameters
+
 hir_typeck_note_caller_chooses_ty_for_ty_param = the caller chooses a type for `{$ty_param_name}` which can be different from `{$found_ty}`
 
 hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
@@ -167,6 +206,23 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte
 hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}`
 hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}`
 
+hir_typeck_outside_loop =
+    `{$name}` outside of a loop{$is_break ->
+        [true] {" or labeled block"}
+        *[false] {""}
+    }
+    .label = cannot `{$name}` outside of a loop{$is_break ->
+        [true] {" or labeled block"}
+        *[false] {""}
+    }
+
+hir_typeck_outside_loop_suggestion = consider labeling this block to be able to break within it
+
+
+hir_typeck_params_not_allowed =
+    referencing function parameters is not allowed in naked functions
+    .help = follow the calling convention in asm block to use parameters
+
 hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function
     .suggestion = cast the value to `{$cast_ty}`
     .teach_help = certain types, like `{$ty}`, must be cast before passing them to a variadic function to match the implicit cast that a C compiler would perform as part of C's numeric promotion rules
@@ -235,6 +291,13 @@ hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns
 
 hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field
 
+hir_typeck_unlabeled_cf_in_while_condition =
+    `break` or `continue` with no label in the condition of a `while` loop
+    .label = unlabeled `{$cf_type}` in the condition of a `while` loop
+
+hir_typeck_unlabeled_in_labeled_block =
+    unlabeled `{$cf_type}` inside of a labeled block
+    .label = `{$cf_type}` statements that would diverge to or through a labeled block need to bear a label
 hir_typeck_use_is_empty =
     consider using the `is_empty` method on `{$expr_ty}` to determine if it contains anything
 
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index f555d116c52..d173fe7c2c2 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -508,7 +508,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if let Some(ty) = fn_sig.inputs().last().copied() {
                 self.register_bound(
                     ty,
-                    self.tcx.require_lang_item(hir::LangItem::Tuple, Some(sp)),
+                    self.tcx.require_lang_item(hir::LangItem::Tuple, sp),
                     self.cause(sp, ObligationCauseCode::RustCall),
                 );
                 self.require_type_is_sized(ty, sp, ObligationCauseCode::RustCall);
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index e144a6ab599..e17cfc15a43 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -380,20 +380,21 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 err.span_label(self.span, "invalid cast");
                 if self.expr_ty.is_numeric() {
                     if self.expr_ty == fcx.tcx.types.u32 {
-                        match fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) {
-                            Ok(snippet) => err.span_suggestion(
-                                self.span,
-                                "try `char::from_u32` instead",
-                                format!("char::from_u32({snippet})"),
-                                Applicability::MachineApplicable,
-                            ),
-
-                            Err(_) => err.span_help(self.span, "try `char::from_u32` instead"),
-                        };
+                        err.multipart_suggestion(
+                            "consider using `char::from_u32` instead",
+                            vec![
+                                (self.expr_span.shrink_to_lo(), "char::from_u32(".to_string()),
+                                (self.expr_span.shrink_to_hi().to(self.cast_span), ")".to_string()),
+                            ],
+                            Applicability::MachineApplicable,
+                        );
                     } else if self.expr_ty == fcx.tcx.types.i8 {
-                        err.span_help(self.span, "try casting from `u8` instead");
+                        err.span_help(self.span, "consider casting from `u8` instead");
                     } else {
-                        err.span_help(self.span, "try `char::from_u32` instead (via a `u32`)");
+                        err.span_help(
+                            self.span,
+                            "consider using `char::from_u32` instead (via a `u32`)",
+                        );
                     };
                 }
                 err.emit();
@@ -494,11 +495,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     self.cast_ty.kind(),
                     ty::FnDef(..) | ty::FnPtr(..) | ty::Closure(..)
                 ) {
-                    let mut label = true;
                     // Check `impl From<self.expr_ty> for self.cast_ty {}` for accurate suggestion:
-                    if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr_span)
-                        && let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From)
-                    {
+                    if let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From) {
                         let ty = fcx.resolve_vars_if_possible(self.cast_ty);
                         let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
                         if fcx
@@ -506,26 +504,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                             .type_implements_trait(from_trait, [ty, expr_ty], fcx.param_env)
                             .must_apply_modulo_regions()
                         {
-                            label = false;
-                            if let ty::Adt(def, args) = self.cast_ty.kind() {
-                                err.span_suggestion_verbose(
-                                    self.span,
-                                    "consider using the `From` trait instead",
-                                    format!(
-                                        "{}::from({})",
-                                        fcx.tcx.value_path_str_with_args(def.did(), args),
-                                        snippet
-                                    ),
-                                    Applicability::MaybeIncorrect,
-                                );
+                            let to_ty = if let ty::Adt(def, args) = self.cast_ty.kind() {
+                                fcx.tcx.value_path_str_with_args(def.did(), args)
                             } else {
-                                err.span_suggestion(
-                                    self.span,
-                                    "consider using the `From` trait instead",
-                                    format!("{}::from({})", self.cast_ty, snippet),
-                                    Applicability::MaybeIncorrect,
-                                );
+                                self.cast_ty.to_string()
                             };
+                            err.multipart_suggestion(
+                                "consider using the `From` trait instead",
+                                vec![
+                                    (self.expr_span.shrink_to_lo(), format!("{to_ty}::from(")),
+                                    (
+                                        self.expr_span.shrink_to_hi().to(self.cast_span),
+                                        ")".to_string(),
+                                    ),
+                                ],
+                                Applicability::MaybeIncorrect,
+                            );
                         }
                     }
 
@@ -548,11 +542,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                         )
                     };
 
-                    if label {
-                        err.span_label(self.span, msg);
-                    } else {
-                        err.note(msg);
-                    }
+                    err.span_label(self.span, msg);
 
                     if let Some(note) = note {
                         err.note(note);
@@ -654,38 +644,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
         match self.expr_ty.kind() {
             ty::Ref(_, _, mt) => {
                 let mtstr = mt.prefix_str();
-                match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) {
-                    Ok(s) => {
-                        err.span_suggestion(
-                            self.cast_span,
-                            "try casting to a reference instead",
-                            format!("&{mtstr}{s}"),
-                            Applicability::MachineApplicable,
-                        );
-                    }
-                    Err(_) => {
-                        let msg = format!("did you mean `&{mtstr}{tstr}`?");
-                        err.span_help(self.cast_span, msg);
-                    }
-                }
+                err.span_suggestion_verbose(
+                    self.cast_span.shrink_to_lo(),
+                    "consider casting to a reference instead",
+                    format!("&{mtstr}"),
+                    Applicability::MachineApplicable,
+                );
             }
             ty::Adt(def, ..) if def.is_box() => {
-                match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) {
-                    Ok(s) => {
-                        err.span_suggestion(
-                            self.cast_span,
-                            "you can cast to a `Box` instead",
-                            format!("Box<{s}>"),
-                            Applicability::MachineApplicable,
-                        );
-                    }
-                    Err(_) => {
-                        err.span_help(
-                            self.cast_span,
-                            format!("you might have meant `Box<{tstr}>`"),
-                        );
-                    }
-                }
+                err.multipart_suggestion(
+                    "you can cast to a `Box` instead",
+                    vec![
+                        (self.cast_span.shrink_to_lo(), "Box<".to_string()),
+                        (self.cast_span.shrink_to_hi(), ">".to_string()),
+                    ],
+                    Applicability::MachineApplicable,
+                );
             }
             _ => {
                 err.span_help(self.expr_span, "consider using a box or reference as appropriate");
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 99103f14d68..ac42eebf08c 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -57,7 +57,7 @@ pub(super) fn check_fn<'a, 'tcx>(
     // (as it's created inside the body itself, not passed in from outside).
     let maybe_va_list = fn_sig.c_variadic.then(|| {
         let span = body.params.last().unwrap().span;
-        let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span));
+        let va_list_did = tcx.require_lang_item(LangItem::VaList, span);
         let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
 
         tcx.type_of(va_list_did).instantiate(tcx, &[region.into()])
@@ -178,7 +178,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
         tcx.dcx().span_err(span, "should have no const parameters");
     }
 
-    let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, Some(span));
+    let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, span);
 
     // build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
     let panic_info_ty = tcx.type_of(panic_info_did).instantiate(
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index cd3746be1d1..459c0498d50 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -142,13 +142,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                         Ty::new_adt(
                             tcx,
-                            tcx.adt_def(
-                                tcx.require_lang_item(hir::LangItem::Poll, Some(expr_span)),
-                            ),
+                            tcx.adt_def(tcx.require_lang_item(hir::LangItem::Poll, expr_span)),
                             tcx.mk_args(&[Ty::new_adt(
                                 tcx,
                                 tcx.adt_def(
-                                    tcx.require_lang_item(hir::LangItem::Option, Some(expr_span)),
+                                    tcx.require_lang_item(hir::LangItem::Option, expr_span),
                                 ),
                                 tcx.mk_args(&[yield_ty.into()]),
                             )
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index ddc80fab2ce..d9fa56fefeb 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -760,8 +760,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     self.param_env,
                     ty::TraitRef::new(
                         self.tcx,
-                        self.tcx
-                            .require_lang_item(hir::LangItem::PointerLike, Some(self.cause.span)),
+                        self.tcx.require_lang_item(hir::LangItem::PointerLike, self.cause.span),
                         [a],
                     ),
                 ),
@@ -1969,7 +1968,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                 fcx.param_env,
                 ty::TraitRef::new(
                     fcx.tcx,
-                    fcx.tcx.require_lang_item(hir::LangItem::Sized, None),
+                    fcx.tcx.require_lang_item(hir::LangItem::Sized, DUMMY_SP),
                     [sig.output()],
                 ),
             ))
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 06103fe1c91..774815015d5 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -2,11 +2,14 @@
 
 use std::borrow::Cow;
 
+use rustc_ast::Label;
 use rustc_errors::codes::*;
 use rustc_errors::{
-    Applicability, Diag, DiagArgValue, DiagSymbolList, EmissionGuarantee, IntoDiagArg, MultiSpan,
-    Subdiagnostic,
+    Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic,
+    EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic,
 };
+use rustc_hir as hir;
+use rustc_hir::ExprKind;
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::{self, Ty};
 use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
@@ -721,6 +724,131 @@ pub(crate) struct TrivialCast<'tcx> {
     pub cast_ty: Ty<'tcx>,
 }
 
+pub(crate) struct BreakNonLoop<'a> {
+    pub span: Span,
+    pub head: Option<Span>,
+    pub kind: &'a str,
+    pub suggestion: String,
+    pub loop_label: Option<Label>,
+    pub break_label: Option<Label>,
+    pub break_expr_kind: &'a ExprKind<'a>,
+    pub break_expr_span: Span,
+}
+
+impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> {
+    #[track_caller]
+    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
+        let mut diag = Diag::new(dcx, level, fluent::hir_typeck_break_non_loop);
+        diag.span(self.span);
+        diag.code(E0571);
+        diag.arg("kind", self.kind);
+        diag.span_label(self.span, fluent::hir_typeck_label);
+        if let Some(head) = self.head {
+            diag.span_label(head, fluent::hir_typeck_label2);
+        }
+        diag.span_suggestion(
+            self.span,
+            fluent::hir_typeck_suggestion,
+            self.suggestion,
+            Applicability::MaybeIncorrect,
+        );
+        if let (Some(label), None) = (self.loop_label, self.break_label) {
+            match self.break_expr_kind {
+                ExprKind::Path(hir::QPath::Resolved(
+                    None,
+                    hir::Path { segments: [segment], res: hir::def::Res::Err, .. },
+                )) if label.ident.to_string() == format!("'{}", segment.ident) => {
+                    // This error is redundant, we will have already emitted a
+                    // suggestion to use the label when `segment` wasn't found
+                    // (hence the `Res::Err` check).
+                    diag.downgrade_to_delayed_bug();
+                }
+                _ => {
+                    diag.span_suggestion(
+                        self.break_expr_span,
+                        fluent::hir_typeck_break_expr_suggestion,
+                        label.ident,
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+            }
+        }
+        diag
+    }
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_continue_labeled_block, code = E0696)]
+pub(crate) struct ContinueLabeledBlock {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    #[label(hir_typeck_block_label)]
+    pub block_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_break_inside_closure, code = E0267)]
+pub(crate) struct BreakInsideClosure<'a> {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    #[label(hir_typeck_closure_label)]
+    pub closure_span: Span,
+    pub name: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_break_inside_coroutine, code = E0267)]
+pub(crate) struct BreakInsideCoroutine<'a> {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    #[label(hir_typeck_coroutine_label)]
+    pub coroutine_span: Span,
+    pub name: &'a str,
+    pub kind: &'a str,
+    pub source: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_outside_loop, code = E0268)]
+pub(crate) struct OutsideLoop<'a> {
+    #[primary_span]
+    #[label]
+    pub spans: Vec<Span>,
+    pub name: &'a str,
+    pub is_break: bool,
+    #[subdiagnostic]
+    pub suggestion: Option<OutsideLoopSuggestion>,
+}
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(hir_typeck_outside_loop_suggestion, applicability = "maybe-incorrect")]
+pub(crate) struct OutsideLoopSuggestion {
+    #[suggestion_part(code = "'block: ")]
+    pub block_span: Span,
+    #[suggestion_part(code = " 'block")]
+    pub break_spans: Vec<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_unlabeled_in_labeled_block, code = E0695)]
+pub(crate) struct UnlabeledInLabeledBlock<'a> {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub cf_type: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_unlabeled_cf_in_while_condition, code = E0590)]
+pub(crate) struct UnlabeledCfInWhileCondition<'a> {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub cf_type: &'a str,
+}
+
 #[derive(Diagnostic)]
 #[diag(hir_typeck_no_associated_item, code = E0599)]
 pub(crate) struct NoAssociatedItem {
@@ -983,3 +1111,55 @@ pub(crate) struct RegisterTypeUnstable<'a> {
     pub span: Span,
     pub ty: Ty<'a>,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_naked_asm_outside_naked_fn)]
+pub(crate) struct NakedAsmOutsideNakedFn {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_no_patterns)]
+pub(crate) struct NoPatterns {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_params_not_allowed)]
+#[help]
+pub(crate) struct ParamsNotAllowed {
+    #[primary_span]
+    pub span: Span,
+}
+
+pub(crate) struct NakedFunctionsAsmBlock {
+    pub span: Span,
+    pub multiple_asms: Vec<Span>,
+    pub non_asms: Vec<Span>,
+}
+
+impl<G: EmissionGuarantee> Diagnostic<'_, G> for NakedFunctionsAsmBlock {
+    #[track_caller]
+    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
+        let mut diag = Diag::new(dcx, level, fluent::hir_typeck_naked_functions_asm_block);
+        diag.span(self.span);
+        diag.code(E0787);
+        for span in self.multiple_asms.iter() {
+            diag.span_label(*span, fluent::hir_typeck_label_multiple_asm);
+        }
+        for span in self.non_asms.iter() {
+            diag.span_label(*span, fluent::hir_typeck_label_non_asm);
+        }
+        diag
+    }
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_naked_functions_must_naked_asm, code = E0787)]
+pub(crate) struct NakedFunctionsMustNakedAsm {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 082ddac7e5a..dfc7935d02b 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -44,9 +44,9 @@ use crate::errors::{
     AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr,
     BaseExpressionDoubleDotEnableDefaultFieldValues, BaseExpressionDoubleDotRemove,
     CantDereference, FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
-    HelpUseLatestEdition, NoFieldOnType, NoFieldOnVariant, ReturnLikeStatementKind,
-    ReturnStmtOutsideOfFnBody, StructExprNonExhaustive, TypeMismatchFruTypo,
-    YieldExprOutsideOfCoroutine,
+    HelpUseLatestEdition, NakedAsmOutsideNakedFn, NoFieldOnType, NoFieldOnVariant,
+    ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive,
+    TypeMismatchFruTypo, YieldExprOutsideOfCoroutine,
 };
 use crate::{
     BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, GatherLocalsVisitor, Needs,
@@ -524,7 +524,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ExprKind::InlineAsm(asm) => {
                 // We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
                 self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id));
-                self.check_expr_asm(asm)
+                self.check_expr_asm(asm, expr.span)
             }
             ExprKind::OffsetOf(container, fields) => {
                 self.check_expr_offset_of(container, fields, expr)
@@ -1407,7 +1407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let lhs_deref_ty_is_sized = self
                     .infcx
                     .type_implements_trait(
-                        self.tcx.require_lang_item(LangItem::Sized, None),
+                        self.tcx.require_lang_item(LangItem::Sized, span),
                         [lhs_deref_ty],
                         self.param_env,
                     )
@@ -3761,7 +3761,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
+    fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) -> Ty<'tcx> {
+        if let rustc_ast::AsmMacro::NakedAsm = asm.asm_macro {
+            if !self.tcx.has_attr(self.body_id, sym::naked) {
+                self.tcx.dcx().emit_err(NakedAsmOutsideNakedFn { span });
+            }
+        }
+
         let mut diverge = asm.asm_macro.diverges(asm.options);
 
         for (op, _op_sp) in asm.operands {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 362c7d8efac..8a90e768d70 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -409,7 +409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         code: traits::ObligationCauseCode<'tcx>,
     ) {
         if !ty.references_error() {
-            let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
+            let lang_item = self.tcx.require_lang_item(LangItem::Sized, span);
             self.require_type_meets(ty, span, code, lang_item);
         }
     }
@@ -443,7 +443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Nothing else is required here.
             } else {
                 // We can't be sure, let's required full `Sized`.
-                let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
+                let lang_item = self.tcx.require_lang_item(LangItem::Sized, span);
                 self.require_type_meets(ty, span, ObligationCauseCode::Misc, lang_item);
             }
         }
@@ -732,7 +732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         hir_id: HirId,
     ) -> (Res, Ty<'tcx>) {
-        let def_id = self.tcx.require_lang_item(lang_item, Some(span));
+        let def_id = self.tcx.require_lang_item(lang_item, span);
         let def_kind = self.tcx.def_kind(def_id);
 
         let item_ty = if let DefKind::Variant = def_kind {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 59aba6fae5e..95c7f251c88 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -165,7 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 _ => traits::IsConstable::No,
             };
 
-            let lang_item = self.tcx.require_lang_item(LangItem::Copy, None);
+            let lang_item = self.tcx.require_lang_item(LangItem::Copy, element.span);
             let code = traits::ObligationCauseCode::RepeatElementCopy {
                 is_constable,
                 elt_span: element.span,
@@ -1680,8 +1680,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ast::LitKind::CStr(_, _) => Ty::new_imm_ref(
                 tcx,
                 tcx.lifetimes.re_static,
-                tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, Some(lit.span)))
-                    .skip_binder(),
+                tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, lit.span)).skip_binder(),
             ),
             ast::LitKind::Err(guar) => Ty::new_error(tcx, guar),
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
index e068e607902..7f1f3c3c802 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
@@ -4,6 +4,7 @@ use rustc_infer::traits::{self, ObligationCause, PredicateObligations};
 use rustc_middle::traits::solve::GoalSource;
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_span::Span;
+use rustc_trait_selection::solve::Certainty;
 use rustc_trait_selection::solve::inspect::{
     InspectConfig, InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor,
 };
@@ -117,6 +118,20 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> {
     }
 
     fn visit_goal(&mut self, inspect_goal: &InspectGoal<'_, 'tcx>) {
+        // No need to walk into goal subtrees that certainly hold, since they
+        // wouldn't then be stalled on an infer var.
+        // FIXME: We also walk into normalizes-to goals since their certainty
+        // is forced to `Certainty::Yes` since they pass down ambiguous subgoals
+        // to their parent.
+        if inspect_goal.result() == Ok(Certainty::Yes)
+            && !matches!(
+                inspect_goal.goal().predicate.kind().skip_binder(),
+                ty::PredicateKind::NormalizesTo(_)
+            )
+        {
+            return;
+        }
+
         let tcx = self.fcx.tcx;
         let goal = inspect_goal.goal();
         if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty)
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 1c3bc338d85..66af085cfd4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -2679,7 +2679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let mut sugg_sp = sp;
                     if let hir::ExprKind::MethodCall(segment, receiver, args, _) = expr.kind {
                         let clone_trait =
-                            self.tcx.require_lang_item(LangItem::Clone, Some(segment.ident.span));
+                            self.tcx.require_lang_item(LangItem::Clone, segment.ident.span);
                         if args.is_empty()
                             && self
                                 .typeck_results
diff --git a/compiler/rustc_hir_typeck/src/inline_asm.rs b/compiler/rustc_hir_typeck/src/inline_asm.rs
index 6399f0a78ae..b59c1752c25 100644
--- a/compiler/rustc_hir_typeck/src/inline_asm.rs
+++ b/compiler/rustc_hir_typeck/src/inline_asm.rs
@@ -171,7 +171,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             _ if ty.references_error() => return None,
             ty::Adt(adt, args) if self.tcx().is_lang_item(adt.did(), LangItem::MaybeUninit) => {
                 let fields = &adt.non_enum_variant().fields;
-                let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx(), args);
+                let ty = fields[FieldIdx::ONE].ty(self.tcx(), args);
                 // FIXME: Are we just trying to map to the `T` in `MaybeUninit<T>`?
                 // If so, just get it from the args.
                 let ty::Adt(ty, args) = ty.kind() else {
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 5a814822163..a45a7715340 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -1,13 +1,11 @@
 // tidy-alphabetical-start
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
-#![feature(array_windows)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(never_type)]
-#![feature(try_blocks)]
 // tidy-alphabetical-end
 
 mod _match;
@@ -30,7 +28,9 @@ mod fallback;
 mod fn_ctxt;
 mod gather_locals;
 mod intrinsicck;
+mod loops;
 mod method;
+mod naked_functions;
 mod op;
 mod opaque_types;
 mod pat;
@@ -55,8 +55,8 @@ use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::config;
-use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
+use rustc_span::{Span, sym};
 use tracing::{debug, instrument};
 use typeck_root_ctxt::TypeckRootCtxt;
 
@@ -149,7 +149,8 @@ fn typeck_with_inspect<'tcx>(
             tcx.fn_sig(def_id).instantiate_identity()
         };
 
-        check_abi(tcx, span, fn_sig.abi());
+        check_abi(tcx, id, span, fn_sig.abi());
+        loops::check(tcx, def_id, body);
 
         // Compute the function signature from point of view of inside the fn.
         let mut fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
@@ -170,6 +171,10 @@ fn typeck_with_inspect<'tcx>(
                 .map(|(idx, ty)| fcx.normalize(arg_span(idx), ty)),
         );
 
+        if tcx.has_attr(def_id, sym::naked) {
+            naked_functions::typeck_naked_fn(tcx, def_id, body);
+        }
+
         check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params());
     } else {
         let expected_type = if let Some(infer_ty) = infer_type_if_missing(&fcx, node) {
@@ -186,6 +191,8 @@ fn typeck_with_inspect<'tcx>(
             tcx.type_of(def_id).instantiate_identity()
         };
 
+        loops::check(tcx, def_id, body);
+
         let expected_type = fcx.normalize(body.value.span, expected_type);
 
         let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_hir_typeck/src/loops.rs
index b06f16cc7bd..b06e0704b6f 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_hir_typeck/src/loops.rs
@@ -3,11 +3,11 @@ use std::fmt;
 
 use Context::*;
 use rustc_hir as hir;
-use rustc_hir::def_id::{LocalDefId, LocalModDefId};
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Destination, Node};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::query::Providers;
 use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::hygiene::DesugaringKind;
@@ -73,17 +73,17 @@ struct CheckLoopVisitor<'tcx> {
     block_breaks: BTreeMap<Span, BlockInfo>,
 }
 
-fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
+pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<'tcx>) {
     let mut check =
         CheckLoopVisitor { tcx, cx_stack: vec![Normal], block_breaks: Default::default() };
-    tcx.hir_visit_item_likes_in_module(module_def_id, &mut check);
+    let cx = match tcx.def_kind(def_id) {
+        DefKind::AnonConst => AnonConst,
+        _ => Fn,
+    };
+    check.with_context(cx, |v| v.visit_body(body));
     check.report_outside_loop_error();
 }
 
-pub(crate) fn provide(providers: &mut Providers) {
-    *providers = Providers { check_mod_loops, ..*providers };
-}
-
 impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
     type NestedFilter = nested_filter::OnlyBodies;
 
@@ -91,33 +91,14 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
         self.tcx
     }
 
-    fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
-        self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c));
+    fn visit_anon_const(&mut self, _: &'hir hir::AnonConst) {
+        // Typecked on its own.
     }
 
     fn visit_inline_const(&mut self, c: &'hir hir::ConstBlock) {
         self.with_context(ConstBlock, |v| intravisit::walk_inline_const(v, c));
     }
 
-    fn visit_fn(
-        &mut self,
-        fk: hir::intravisit::FnKind<'hir>,
-        fd: &'hir hir::FnDecl<'hir>,
-        b: hir::BodyId,
-        _: Span,
-        id: LocalDefId,
-    ) {
-        self.with_context(Fn, |v| intravisit::walk_fn(v, fk, fd, b, id));
-    }
-
-    fn visit_trait_item(&mut self, trait_item: &'hir hir::TraitItem<'hir>) {
-        self.with_context(Fn, |v| intravisit::walk_trait_item(v, trait_item));
-    }
-
-    fn visit_impl_item(&mut self, impl_item: &'hir hir::ImplItem<'hir>) {
-        self.with_context(Fn, |v| intravisit::walk_impl_item(v, impl_item));
-    }
-
     fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
         match e.kind {
             hir::ExprKind::If(cond, then, else_opt) => {
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 3eae95d5b73..2fac13b7201 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -3494,7 +3494,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             continue;
                         }
                         trait_in_other_version_found = self
-                            .detect_and_explain_multiple_crate_versions(
+                            .detect_and_explain_multiple_crate_versions_of_trait_item(
                                 err,
                                 pick.item.def_id,
                                 rcvr.hir_id,
@@ -3701,12 +3701,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // same crate.
 
             let rcvr_ty = self.node_ty_opt(ty.hir_id);
-            trait_in_other_version_found = self.detect_and_explain_multiple_crate_versions(
-                err,
-                assoc.def_id,
-                ty.hir_id,
-                rcvr_ty,
-            );
+            trait_in_other_version_found = self
+                .detect_and_explain_multiple_crate_versions_of_trait_item(
+                    err,
+                    assoc.def_id,
+                    ty.hir_id,
+                    rcvr_ty,
+                );
         }
         if !trait_in_other_version_found
             && self.suggest_valid_traits(err, item_name, valid_out_of_scope_traits, true)
@@ -4098,7 +4099,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn detect_and_explain_multiple_crate_versions(
+    fn detect_and_explain_multiple_crate_versions_of_trait_item(
         &self,
         err: &mut Diag<'_>,
         item_def_id: DefId,
@@ -4111,6 +4112,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return false;
         }
         let trait_def_id = self.tcx.parent(item_def_id);
+        if !self.tcx.is_trait(trait_def_id) {
+            return false;
+        }
         let krate = self.tcx.crate_name(trait_def_id.krate);
         let name = self.tcx.item_name(trait_def_id);
         let candidates: Vec<_> = traits
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_hir_typeck/src/naked_functions.rs
index 3c9f8b72c36..2518d6478e6 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_hir_typeck/src/naked_functions.rs
@@ -1,56 +1,29 @@
 //! Checks validity of naked functions.
 
 use rustc_hir as hir;
-use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{LocalDefId, LocalModDefId};
+use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{ExprKind, HirIdSet, StmtKind};
-use rustc_middle::hir::nested_filter::OnlyBodies;
-use rustc_middle::query::Providers;
 use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::{Span, sym};
 
 use crate::errors::{
-    NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns,
-    ParamsNotAllowed,
+    NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns, ParamsNotAllowed,
 };
 
-pub(crate) fn provide(providers: &mut Providers) {
-    *providers = Providers { check_mod_naked_functions, ..*providers };
-}
-
-fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
-    let items = tcx.hir_module_items(module_def_id);
-    for def_id in items.definitions() {
-        if !matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
-            continue;
-        }
-
-        let body = match tcx.hir_node_by_def_id(def_id) {
-            hir::Node::Item(hir::Item {
-                kind: hir::ItemKind::Fn { body: body_id, .. }, ..
-            })
-            | hir::Node::TraitItem(hir::TraitItem {
-                kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)),
-                ..
-            })
-            | hir::Node::ImplItem(hir::ImplItem {
-                kind: hir::ImplItemKind::Fn(_, body_id), ..
-            }) => tcx.hir_body(*body_id),
-            _ => continue,
-        };
-
-        if tcx.has_attr(def_id, sym::naked) {
-            check_no_patterns(tcx, body.params);
-            check_no_parameters_use(tcx, body);
-            check_asm(tcx, def_id, body);
-        } else {
-            // `naked_asm!` is not allowed outside of functions marked as `#[naked]`
-            let mut visitor = CheckNakedAsmInNakedFn { tcx };
-            visitor.visit_body(body);
-        }
-    }
+/// Naked fns can only have trivial binding patterns in arguments,
+/// may not actually use those arguments, and the body must consist of just
+/// a single asm statement.
+pub(crate) fn typeck_naked_fn<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: LocalDefId,
+    body: &'tcx hir::Body<'tcx>,
+) {
+    debug_assert!(tcx.has_attr(def_id, sym::naked));
+    check_no_patterns(tcx, body.params);
+    check_no_parameters_use(tcx, body);
+    check_asm(tcx, def_id, body);
 }
 
 /// Checks that parameters don't use patterns. Mirrors the checks for function declarations.
@@ -231,25 +204,3 @@ impl<'tcx> Visitor<'tcx> for CheckInlineAssembly {
         self.check_expr(expr, expr.span);
     }
 }
-
-struct CheckNakedAsmInNakedFn<'tcx> {
-    tcx: TyCtxt<'tcx>,
-}
-
-impl<'tcx> Visitor<'tcx> for CheckNakedAsmInNakedFn<'tcx> {
-    type NestedFilter = OnlyBodies;
-
-    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
-        self.tcx
-    }
-
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
-        if let ExprKind::InlineAsm(inline_asm) = expr.kind {
-            if let rustc_ast::AsmMacro::NakedAsm = inline_asm.asm_macro {
-                self.tcx.dcx().emit_err(NakedAsmOutsideNakedFn { span: expr.span });
-            }
-        }
-
-        hir::intravisit::walk_expr(self, expr);
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 17d48184dd9..432eeae8016 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -796,7 +796,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if *negated {
                     self.register_bound(
                         ty,
-                        self.tcx.require_lang_item(LangItem::Neg, Some(lt.span)),
+                        self.tcx.require_lang_item(LangItem::Neg, lt.span),
                         ObligationCause::dummy_with_span(lt.span),
                     );
                 }
@@ -2553,13 +2553,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let tcx = self.tcx;
         self.register_bound(
             source_ty,
-            tcx.require_lang_item(hir::LangItem::DerefPure, Some(span)),
+            tcx.require_lang_item(hir::LangItem::DerefPure, span),
             self.misc(span),
         );
         // The expected type for the deref pat's inner pattern is `<expected as Deref>::Target`.
         let target_ty = Ty::new_projection(
             tcx,
-            tcx.require_lang_item(hir::LangItem::DerefTarget, Some(span)),
+            tcx.require_lang_item(hir::LangItem::DerefTarget, span),
             [source_ty],
         );
         let target_ty = self.normalize(span, target_ty);
@@ -2580,7 +2580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             for mutably_derefed_ty in derefed_tys {
                 self.register_bound(
                     mutably_derefed_ty,
-                    self.tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)),
+                    self.tcx.require_lang_item(hir::LangItem::DerefMut, span),
                     self.misc(span),
                 );
             }
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 4b2e87f5674..5b5253c7e7e 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -1560,7 +1560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         let is_drop_defined_for_ty = |ty: Ty<'tcx>| {
-            let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span));
+            let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, closure_span);
             self.infcx
                 .type_implements_trait(drop_trait, [ty], self.tcx.param_env(closure_def_id))
                 .must_apply_modulo_regions()
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 96e03e3bea5..e9b58eb959b 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -823,6 +823,13 @@ impl<'tcx> InferCtxt<'tcx> {
         ty::Region::new_var(self.tcx, region_var)
     }
 
+    pub fn next_term_var_of_kind(&self, term: ty::Term<'tcx>, span: Span) -> ty::Term<'tcx> {
+        match term.kind() {
+            ty::TermKind::Ty(_) => self.next_ty_var(span).into(),
+            ty::TermKind::Const(_) => self.next_const_var(span).into(),
+        }
+    }
+
     /// Return the universe that the region `r` was created in. For
     /// most regions (e.g., `'static`, named regions from the user,
     /// etc) this is the root universe U0. For inference variables or
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index ab65da3913d..df5a66243fc 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -53,7 +53,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
         assert!(entry.is_some());
     }
 
-    pub(crate) fn is_empty(&self) -> bool {
+    pub fn is_empty(&self) -> bool {
         let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
         opaque_types.is_empty() && duplicate_entries.is_empty()
     }
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index ab7b7060c09..550707ed4bc 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -20,7 +20,6 @@
 #![doc(rust_logo)]
 #![feature(assert_matches)]
 #![feature(extend_one)]
-#![feature(iterator_try_collect)]
 #![feature(rustdoc_internals)]
 #![recursion_limit = "512"] // For rustdoc
 // tidy-alphabetical-end
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index cf494f8d686..e824e9d4aa9 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -18,7 +18,7 @@ use rustc_parse::parser::attr::AllowLeadingUnsafe;
 use rustc_query_impl::QueryCtxt;
 use rustc_query_system::query::print_query_stack;
 use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
-use rustc_session::filesearch::sysroot_candidates;
+use rustc_session::filesearch::sysroot_with_fallback;
 use rustc_session::parse::ParseSess;
 use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint};
 use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs};
@@ -442,8 +442,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
             let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
 
             let bundle = match rustc_errors::fluent_bundle(
-                config.opts.sysroot.clone(),
-                sysroot_candidates().to_vec(),
+                sysroot_with_fallback(&config.opts.sysroot),
                 config.opts.unstable_opts.translate_lang.clone(),
                 config.opts.unstable_opts.translate_additional_ftl.as_deref(),
                 config.opts.unstable_opts.translate_directionality_markers,
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index f4045eeea4d..99520a3fea3 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -954,9 +954,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
                 tcx.ensure_ok().exportable_items(LOCAL_CRATE);
                 tcx.ensure_ok().stable_order_of_exportable_impls(LOCAL_CRATE);
                 tcx.par_hir_for_each_module(|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);
                 });
             },
@@ -977,13 +975,6 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
     });
 
     rustc_hir_analysis::check_crate(tcx);
-    sess.time("MIR_coroutine_by_move_body", || {
-        tcx.par_hir_body_owners(|def_id| {
-            if tcx.needs_coroutine_by_move_body_def_id(def_id.to_def_id()) {
-                tcx.ensure_done().coroutine_by_move_body_def_id(def_id);
-            }
-        });
-    });
     // Freeze definitions as we don't add new ones at this point.
     // We need to wait until now since we synthesize a by-move body
     // for all coroutine-closures.
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 087b11fdf9d..8bdc24d47d9 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -2,7 +2,7 @@ use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
 use std::path::{Path, PathBuf};
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{Arc, OnceLock};
-use std::{env, iter, thread};
+use std::{env, thread};
 
 use rustc_ast as ast;
 use rustc_codegen_ssa::traits::CodegenBackend;
@@ -12,7 +12,6 @@ use rustc_metadata::{DylibError, load_symbol_from_dylib};
 use rustc_middle::ty::CurrentGcx;
 use rustc_parse::validate_attr;
 use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, host_tuple};
-use rustc_session::filesearch::sysroot_candidates;
 use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
 use rustc_session::output::{CRATE_TYPES, categorize_crate_type};
 use rustc_session::{EarlyDiagCtxt, Session, filesearch};
@@ -346,14 +345,10 @@ pub fn rustc_path<'a>() -> Option<&'a Path> {
 }
 
 fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
-    sysroot_candidates().iter().find_map(|sysroot| {
-        let candidate = sysroot.join(bin_path).join(if cfg!(target_os = "windows") {
-            "rustc.exe"
-        } else {
-            "rustc"
-        });
-        candidate.exists().then_some(candidate)
-    })
+    let candidate = filesearch::get_or_default_sysroot()
+        .join(bin_path)
+        .join(if cfg!(target_os = "windows") { "rustc.exe" } else { "rustc" });
+    candidate.exists().then_some(candidate)
 }
 
 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
@@ -374,10 +369,10 @@ fn get_codegen_sysroot(
     );
 
     let target = host_tuple();
-    let sysroot_candidates = sysroot_candidates();
+    let sysroot_candidates = filesearch::sysroot_with_fallback(&sysroot);
 
-    let sysroot = iter::once(sysroot)
-        .chain(sysroot_candidates.iter().map(<_>::as_ref))
+    let sysroot = sysroot_candidates
+        .iter()
         .map(|sysroot| {
             filesearch::make_target_lib_path(sysroot, target).with_file_name("codegen-backends")
         })
diff --git a/compiler/rustc_lexer/src/cursor.rs b/compiler/rustc_lexer/src/cursor.rs
index 526693d3de1..165262b82c7 100644
--- a/compiler/rustc_lexer/src/cursor.rs
+++ b/compiler/rustc_lexer/src/cursor.rs
@@ -68,7 +68,7 @@ impl<'a> Cursor<'a> {
 
     /// Peeks the third symbol from the input stream without consuming it.
     pub fn third(&self) -> char {
-        // `.next()` optimizes better than `.nth(1)`
+        // `.next()` optimizes better than `.nth(2)`
         let mut iter = self.chars.clone();
         iter.next();
         iter.next();
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index 2374f388250..b2bd5e188ef 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -30,14 +30,13 @@ mod cursor;
 #[cfg(test)]
 mod tests;
 
+use LiteralKind::*;
+use TokenKind::*;
+use cursor::EOF_CHAR;
+pub use cursor::{Cursor, FrontmatterAllowed};
 use unicode_properties::UnicodeEmoji;
 pub use unicode_xid::UNICODE_VERSION as UNICODE_XID_VERSION;
 
-use self::LiteralKind::*;
-use self::TokenKind::*;
-use crate::cursor::EOF_CHAR;
-pub use crate::cursor::{Cursor, FrontmatterAllowed};
-
 /// Parsed token.
 /// It doesn't contain information about data that has been parsed,
 /// only the type of the token and its size.
@@ -372,9 +371,8 @@ pub fn is_ident(string: &str) -> bool {
 impl Cursor<'_> {
     /// Parses a token from the input string.
     pub fn advance_token(&mut self) -> Token {
-        let first_char = match self.bump() {
-            Some(c) => c,
-            None => return Token::new(TokenKind::Eof, 0),
+        let Some(first_char) = self.bump() else {
+            return Token::new(TokenKind::Eof, 0);
         };
 
         let token_kind = match first_char {
@@ -545,11 +543,12 @@ impl Cursor<'_> {
 
         let mut s = self.as_str();
         let mut found = false;
+        let mut size = 0;
         while let Some(closing) = s.find(&"-".repeat(length_opening as usize)) {
             let preceding_chars_start = s[..closing].rfind("\n").map_or(0, |i| i + 1);
             if s[preceding_chars_start..closing].chars().all(is_whitespace) {
                 // candidate found
-                self.bump_bytes(closing);
+                self.bump_bytes(size + closing);
                 // in case like
                 // ---cargo
                 // --- blahblah
@@ -562,6 +561,7 @@ impl Cursor<'_> {
                 break;
             } else {
                 s = &s[closing + length_opening as usize..];
+                size += closing + length_opening as usize;
             }
         }
 
@@ -786,7 +786,7 @@ impl Cursor<'_> {
         } else {
             // No base prefix, parse number in the usual way.
             self.eat_decimal_digits();
-        };
+        }
 
         match self.first() {
             // Don't be greedy if this is actually an
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index e7e60e8701a..fd2e2ba39ac 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -253,11 +253,6 @@ lint_duplicate_macro_attribute =
 
 lint_duplicate_matcher_binding = duplicate matcher binding
 
-lint_elided_named_lifetime = elided lifetime has a name
-    .label_elided = this elided lifetime gets resolved as `{$name}`
-    .label_named = lifetime `{$name}` declared here
-    .suggestion = consider specifying it explicitly
-
 lint_enum_intrinsics_mem_discriminant =
     the return value of `mem::discriminant` is unspecified when called with a non-enum type
     .note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum
@@ -516,6 +511,28 @@ lint_metavariable_still_repeating = variable `{$name}` is still repeating at thi
 
 lint_metavariable_wrong_operator = meta-variable repeats with different Kleene operator
 
+lint_mismatched_lifetime_syntaxes =
+    lifetime flowing from input to output with different syntax can be confusing
+    .label_mismatched_lifetime_syntaxes_inputs =
+        {$n_inputs ->
+            [one] this lifetime flows
+            *[other] these lifetimes flow
+        } to the output
+    .label_mismatched_lifetime_syntaxes_outputs =
+        the {$n_outputs ->
+            [one] lifetime gets
+            *[other] lifetimes get
+        } resolved as `{$lifetime_name}`
+
+lint_mismatched_lifetime_syntaxes_suggestion_explicit =
+    one option is to consistently use `{$lifetime_name}`
+
+lint_mismatched_lifetime_syntaxes_suggestion_implicit =
+    one option is to consistently remove the lifetime
+
+lint_mismatched_lifetime_syntaxes_suggestion_mixed =
+    one option is to remove the lifetime for references and use the anonymous lifetime for paths
+
 lint_missing_fragment_specifier = missing fragment specifier
 
 lint_missing_unsafe_on_extern = extern blocks should be unsafe
diff --git a/compiler/rustc_lint/src/autorefs.rs b/compiler/rustc_lint/src/autorefs.rs
index 5de2cbf9939..845a1f1b81f 100644
--- a/compiler/rustc_lint/src/autorefs.rs
+++ b/compiler/rustc_lint/src/autorefs.rs
@@ -16,7 +16,7 @@ declare_lint! {
     ///
     /// ### Example
     ///
-    /// ```rust
+    /// ```rust,compile_fail
     /// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
     ///     unsafe { &raw mut (*ptr)[..16] }
     ///     //                      ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`,
@@ -51,7 +51,7 @@ declare_lint! {
     /// }
     /// ```
     pub DANGEROUS_IMPLICIT_AUTOREFS,
-    Warn,
+    Deny,
     "implicit reference to a dereference of a raw pointer",
     report_in_external_macro
 }
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 47b80135bae..69e9f8e1b2c 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -39,7 +39,7 @@ pub use rustc_session::lint::builtin::*;
 use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
 use rustc_span::edition::Edition;
 use rustc_span::source_map::Spanned;
-use rustc_span::{BytePos, Ident, InnerSpan, Span, Symbol, kw, sym};
+use rustc_span::{BytePos, DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym};
 use rustc_target::asm::InlineAsmArch;
 use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
 use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy;
@@ -635,7 +635,8 @@ fn type_implements_negative_copy_modulo_regions<'tcx>(
     typing_env: ty::TypingEnv<'tcx>,
 ) -> bool {
     let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
-    let trait_ref = ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, None), [ty]);
+    let trait_ref =
+        ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, DUMMY_SP), [ty]);
     let pred = ty::TraitPredicate { trait_ref, polarity: ty::PredicatePolarity::Negative };
     let obligation = traits::Obligation {
         cause: traits::ObligationCause::dummy(),
diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs
index 71b621e8d20..60c477dd6c7 100644
--- a/compiler/rustc_lint/src/early/diagnostics.rs
+++ b/compiler/rustc_lint/src/early/diagnostics.rs
@@ -10,11 +10,11 @@ use rustc_errors::{
 use rustc_middle::middle::stability;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
-use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution};
-use rustc_span::{BytePos, kw};
+use rustc_session::lint::BuiltinLintDiag;
+use rustc_span::BytePos;
 use tracing::debug;
 
-use crate::lints::{self, ElidedNamedLifetime};
+use crate::lints;
 
 mod check_cfg;
 
@@ -471,16 +471,5 @@ pub fn decorate_builtin_lint(
         BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => {
             lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag)
         }
-        BuiltinLintDiag::ElidedNamedLifetimes { elided: (span, kind), resolution } => {
-            match resolution {
-                ElidedLifetimeResolution::Static => {
-                    ElidedNamedLifetime { span, kind, name: kw::StaticLifetime, declaration: None }
-                }
-                ElidedLifetimeResolution::Param(name, declaration) => {
-                    ElidedNamedLifetime { span, kind, name, declaration: Some(declaration) }
-                }
-            }
-            .decorate_lint(diag)
-        }
     }
 }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 0a52e42e442..72bfeaddbf1 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -55,6 +55,7 @@ mod invalid_from_utf8;
 mod late;
 mod let_underscore;
 mod levels;
+mod lifetime_syntax;
 mod lints;
 mod macro_expr_fragment_specifier_2024_migration;
 mod map_unit_fn;
@@ -96,6 +97,7 @@ use impl_trait_overcaptures::ImplTraitOvercaptures;
 use internal::*;
 use invalid_from_utf8::*;
 use let_underscore::*;
+use lifetime_syntax::*;
 use macro_expr_fragment_specifier_2024_migration::*;
 use map_unit_fn::*;
 use multiple_supertrait_upcastable::*;
@@ -246,6 +248,7 @@ late_lint_methods!(
             StaticMutRefs: StaticMutRefs,
             UnqualifiedLocalImports: UnqualifiedLocalImports,
             CheckTransmutes: CheckTransmutes,
+            LifetimeSyntax: LifetimeSyntax,
         ]
     ]
 );
@@ -353,6 +356,7 @@ fn register_builtins(store: &mut LintStore) {
     store.register_renamed("unused_tuple_struct_fields", "dead_code");
     store.register_renamed("static_mut_ref", "static_mut_refs");
     store.register_renamed("temporary_cstring_as_ptr", "dangling_pointers_from_temporaries");
+    store.register_renamed("elided_named_lifetimes", "mismatched_lifetime_syntaxes");
 
     // These were moved to tool lints, but rustc still sees them when compiling normally, before
     // tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use
@@ -595,7 +599,6 @@ fn register_builtins(store: &mut LintStore) {
         "converted into hard error, see PR #125380 \
          <https://github.com/rust-lang/rust/pull/125380> for more information",
     );
-    store.register_removed("unsupported_calling_conventions", "converted into hard error");
     store.register_removed(
         "cenum_impl_drop_cast",
         "converted into hard error, \
diff --git a/compiler/rustc_lint/src/lifetime_syntax.rs b/compiler/rustc_lint/src/lifetime_syntax.rs
new file mode 100644
index 00000000000..31b038e6a46
--- /dev/null
+++ b/compiler/rustc_lint/src/lifetime_syntax.rs
@@ -0,0 +1,503 @@
+use rustc_data_structures::fx::FxIndexMap;
+use rustc_hir::intravisit::{self, Visitor};
+use rustc_hir::{self as hir, LifetimeSource};
+use rustc_session::{declare_lint, declare_lint_pass};
+use rustc_span::Span;
+use tracing::instrument;
+
+use crate::{LateContext, LateLintPass, LintContext, lints};
+
+declare_lint! {
+    /// The `mismatched_lifetime_syntaxes` lint detects when the same
+    /// lifetime is referred to by different syntaxes between function
+    /// arguments and return values.
+    ///
+    /// The three kinds of syntaxes are:
+    ///
+    /// 1. Named lifetimes. These are references (`&'a str`) or paths
+    ///    (`Person<'a>`) that use a lifetime with a name, such as
+    ///    `'static` or `'a`.
+    ///
+    /// 2. Elided lifetimes. These are references with no explicit
+    ///    lifetime (`&str`), references using the anonymous lifetime
+    ///    (`&'_ str`), and paths using the anonymous lifetime
+    ///    (`Person<'_>`).
+    ///
+    /// 3. Hidden lifetimes. These are paths that do not contain any
+    ///    visual indication that it contains a lifetime (`Person`).
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(mismatched_lifetime_syntaxes)]
+    ///
+    /// pub fn mixing_named_with_elided(v: &'static u8) -> &u8 {
+    ///     v
+    /// }
+    ///
+    /// struct Person<'a> {
+    ///     name: &'a str,
+    /// }
+    ///
+    /// pub fn mixing_hidden_with_elided(v: Person) -> Person<'_> {
+    ///     v
+    /// }
+    ///
+    /// struct Foo;
+    ///
+    /// impl Foo {
+    ///     // Lifetime elision results in the output lifetime becoming
+    ///     // `'static`, which is not what was intended.
+    ///     pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
+    ///         unsafe { &mut *(x as *mut _) }
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Lifetime elision is useful because it frees you from having to
+    /// give each lifetime its own name and show the relation of input
+    /// and output lifetimes for common cases. However, a lifetime
+    /// that uses inconsistent syntax between related arguments and
+    /// return values is more confusing.
+    ///
+    /// In certain `unsafe` code, lifetime elision combined with
+    /// inconsistent lifetime syntax may result in unsound code.
+    pub MISMATCHED_LIFETIME_SYNTAXES,
+    Warn,
+    "detects when a lifetime uses different syntax between arguments and return values"
+}
+
+declare_lint_pass!(LifetimeSyntax => [MISMATCHED_LIFETIME_SYNTAXES]);
+
+impl<'tcx> LateLintPass<'tcx> for LifetimeSyntax {
+    #[instrument(skip_all)]
+    fn check_fn(
+        &mut self,
+        cx: &LateContext<'tcx>,
+        _: hir::intravisit::FnKind<'tcx>,
+        fd: &'tcx hir::FnDecl<'tcx>,
+        _: &'tcx hir::Body<'tcx>,
+        _: rustc_span::Span,
+        _: rustc_span::def_id::LocalDefId,
+    ) {
+        let mut input_map = Default::default();
+        let mut output_map = Default::default();
+
+        for input in fd.inputs {
+            LifetimeInfoCollector::collect(input, &mut input_map);
+        }
+
+        if let hir::FnRetTy::Return(output) = fd.output {
+            LifetimeInfoCollector::collect(output, &mut output_map);
+        }
+
+        report_mismatches(cx, &input_map, &output_map);
+    }
+}
+
+#[instrument(skip_all)]
+fn report_mismatches<'tcx>(
+    cx: &LateContext<'tcx>,
+    inputs: &LifetimeInfoMap<'tcx>,
+    outputs: &LifetimeInfoMap<'tcx>,
+) {
+    for (resolved_lifetime, output_info) in outputs {
+        if let Some(input_info) = inputs.get(resolved_lifetime) {
+            if !lifetimes_use_matched_syntax(input_info, output_info) {
+                emit_mismatch_diagnostic(cx, input_info, output_info);
+            }
+        }
+    }
+}
+
+fn lifetimes_use_matched_syntax(input_info: &[Info<'_>], output_info: &[Info<'_>]) -> bool {
+    // Categorize lifetimes into source/syntax buckets.
+    let mut n_hidden = 0;
+    let mut n_elided = 0;
+    let mut n_named = 0;
+
+    for info in input_info.iter().chain(output_info) {
+        use LifetimeSource::*;
+        use hir::LifetimeSyntax::*;
+
+        let syntax_source = (info.lifetime.syntax, info.lifetime.source);
+
+        match syntax_source {
+            // Ignore any other kind of lifetime.
+            (_, Other) => continue,
+
+            // E.g. `&T`.
+            (Implicit, Reference | OutlivesBound | PreciseCapturing) |
+            // E.g. `&'_ T`.
+            (ExplicitAnonymous, Reference | OutlivesBound | PreciseCapturing) |
+            // E.g. `ContainsLifetime<'_>`.
+            (ExplicitAnonymous, Path { .. }) => n_elided += 1,
+
+            // E.g. `ContainsLifetime`.
+            (Implicit, Path { .. }) => n_hidden += 1,
+
+            // E.g. `&'a T`.
+            (ExplicitBound, Reference | OutlivesBound | PreciseCapturing) |
+            // E.g. `ContainsLifetime<'a>`.
+            (ExplicitBound, Path { .. }) => n_named += 1,
+        };
+    }
+
+    let syntax_counts = (n_hidden, n_elided, n_named);
+    tracing::debug!(?syntax_counts);
+
+    matches!(syntax_counts, (_, 0, 0) | (0, _, 0) | (0, 0, _))
+}
+
+fn emit_mismatch_diagnostic<'tcx>(
+    cx: &LateContext<'tcx>,
+    input_info: &[Info<'_>],
+    output_info: &[Info<'_>],
+) {
+    // There can only ever be zero or one bound lifetime
+    // for a given lifetime resolution.
+    let mut bound_lifetime = None;
+
+    // We offer the following kinds of suggestions (when appropriate
+    // such that the suggestion wouldn't violate the lint):
+    //
+    // 1. Every lifetime becomes named, when there is already a
+    //    user-provided name.
+    //
+    // 2. A "mixed" signature, where references become implicit
+    //    and paths become explicitly anonymous.
+    //
+    // 3. Every lifetime becomes implicit.
+    //
+    // 4. Every lifetime becomes explicitly anonymous.
+    //
+    // Number 2 is arguably the most common pattern and the one we
+    // should push strongest. Number 3 is likely the next most common,
+    // followed by number 1. Coming in at a distant last would be
+    // number 4.
+    //
+    // Beyond these, there are variants of acceptable signatures that
+    // we won't suggest because they are very low-value. For example,
+    // we will never suggest `fn(&T1, &'_ T2) -> &T3` even though that
+    // would pass the lint.
+    //
+    // The following collections are the lifetime instances that we
+    // suggest changing to a given alternate style.
+
+    // 1. Convert all to named.
+    let mut suggest_change_to_explicit_bound = Vec::new();
+
+    // 2. Convert to mixed. We track each kind of change separately.
+    let mut suggest_change_to_mixed_implicit = Vec::new();
+    let mut suggest_change_to_mixed_explicit_anonymous = Vec::new();
+
+    // 3. Convert all to implicit.
+    let mut suggest_change_to_implicit = Vec::new();
+
+    // 4. Convert all to explicit anonymous.
+    let mut suggest_change_to_explicit_anonymous = Vec::new();
+
+    // Some styles prevent using implicit syntax at all.
+    let mut allow_suggesting_implicit = true;
+
+    // It only makes sense to suggest mixed if we have both sources.
+    let mut saw_a_reference = false;
+    let mut saw_a_path = false;
+
+    for info in input_info.iter().chain(output_info) {
+        use LifetimeSource::*;
+        use hir::LifetimeSyntax::*;
+
+        let syntax_source = (info.lifetime.syntax, info.lifetime.source);
+
+        if let (_, Other) = syntax_source {
+            // Ignore any other kind of lifetime.
+            continue;
+        }
+
+        if let (ExplicitBound, _) = syntax_source {
+            bound_lifetime = Some(info);
+        }
+
+        match syntax_source {
+            // E.g. `&T`.
+            (Implicit, Reference) => {
+                suggest_change_to_explicit_anonymous.push(info);
+                suggest_change_to_explicit_bound.push(info);
+            }
+
+            // E.g. `&'_ T`.
+            (ExplicitAnonymous, Reference) => {
+                suggest_change_to_implicit.push(info);
+                suggest_change_to_mixed_implicit.push(info);
+                suggest_change_to_explicit_bound.push(info);
+            }
+
+            // E.g. `ContainsLifetime`.
+            (Implicit, Path { .. }) => {
+                suggest_change_to_mixed_explicit_anonymous.push(info);
+                suggest_change_to_explicit_anonymous.push(info);
+                suggest_change_to_explicit_bound.push(info);
+            }
+
+            // E.g. `ContainsLifetime<'_>`.
+            (ExplicitAnonymous, Path { .. }) => {
+                suggest_change_to_explicit_bound.push(info);
+            }
+
+            // E.g. `&'a T`.
+            (ExplicitBound, Reference) => {
+                suggest_change_to_implicit.push(info);
+                suggest_change_to_mixed_implicit.push(info);
+                suggest_change_to_explicit_anonymous.push(info);
+            }
+
+            // E.g. `ContainsLifetime<'a>`.
+            (ExplicitBound, Path { .. }) => {
+                suggest_change_to_mixed_explicit_anonymous.push(info);
+                suggest_change_to_explicit_anonymous.push(info);
+            }
+
+            (Implicit, OutlivesBound | PreciseCapturing) => {
+                panic!("This syntax / source combination is not possible");
+            }
+
+            // E.g. `+ '_`, `+ use<'_>`.
+            (ExplicitAnonymous, OutlivesBound | PreciseCapturing) => {
+                suggest_change_to_explicit_bound.push(info);
+            }
+
+            // E.g. `+ 'a`, `+ use<'a>`.
+            (ExplicitBound, OutlivesBound | PreciseCapturing) => {
+                suggest_change_to_mixed_explicit_anonymous.push(info);
+                suggest_change_to_explicit_anonymous.push(info);
+            }
+
+            (_, Other) => {
+                panic!("This syntax / source combination has already been skipped");
+            }
+        }
+
+        if matches!(syntax_source, (_, Path { .. } | OutlivesBound | PreciseCapturing)) {
+            allow_suggesting_implicit = false;
+        }
+
+        match syntax_source {
+            (_, Reference) => saw_a_reference = true,
+            (_, Path { .. }) => saw_a_path = true,
+            _ => {}
+        }
+    }
+
+    let make_implicit_suggestions =
+        |infos: &[&Info<'_>]| infos.iter().map(|i| i.removing_span()).collect::<Vec<_>>();
+
+    let inputs = input_info.iter().map(|info| info.reporting_span()).collect();
+    let outputs = output_info.iter().map(|info| info.reporting_span()).collect();
+
+    let explicit_bound_suggestion = bound_lifetime.map(|info| {
+        build_mismatch_suggestion(info.lifetime_name(), &suggest_change_to_explicit_bound)
+    });
+
+    let is_bound_static = bound_lifetime.is_some_and(|info| info.is_static());
+
+    tracing::debug!(?bound_lifetime, ?explicit_bound_suggestion, ?is_bound_static);
+
+    let should_suggest_mixed =
+        // Do we have a mixed case?
+        (saw_a_reference && saw_a_path) &&
+        // Is there anything to change?
+        (!suggest_change_to_mixed_implicit.is_empty() ||
+         !suggest_change_to_mixed_explicit_anonymous.is_empty()) &&
+        // If we have `'static`, we don't want to remove it.
+        !is_bound_static;
+
+    let mixed_suggestion = should_suggest_mixed.then(|| {
+        let implicit_suggestions = make_implicit_suggestions(&suggest_change_to_mixed_implicit);
+
+        let explicit_anonymous_suggestions = suggest_change_to_mixed_explicit_anonymous
+            .iter()
+            .map(|info| info.suggestion("'_"))
+            .collect();
+
+        lints::MismatchedLifetimeSyntaxesSuggestion::Mixed {
+            implicit_suggestions,
+            explicit_anonymous_suggestions,
+            tool_only: false,
+        }
+    });
+
+    tracing::debug!(
+        ?suggest_change_to_mixed_implicit,
+        ?suggest_change_to_mixed_explicit_anonymous,
+        ?mixed_suggestion,
+    );
+
+    let should_suggest_implicit =
+        // Is there anything to change?
+        !suggest_change_to_implicit.is_empty() &&
+        // We never want to hide the lifetime in a path (or similar).
+        allow_suggesting_implicit &&
+        // If we have `'static`, we don't want to remove it.
+        !is_bound_static;
+
+    let implicit_suggestion = should_suggest_implicit.then(|| {
+        let suggestions = make_implicit_suggestions(&suggest_change_to_implicit);
+
+        lints::MismatchedLifetimeSyntaxesSuggestion::Implicit { suggestions, tool_only: false }
+    });
+
+    tracing::debug!(
+        ?should_suggest_implicit,
+        ?suggest_change_to_implicit,
+        allow_suggesting_implicit,
+        ?implicit_suggestion,
+    );
+
+    let should_suggest_explicit_anonymous =
+        // Is there anything to change?
+        !suggest_change_to_explicit_anonymous.is_empty() &&
+        // If we have `'static`, we don't want to remove it.
+        !is_bound_static;
+
+    let explicit_anonymous_suggestion = should_suggest_explicit_anonymous
+        .then(|| build_mismatch_suggestion("'_", &suggest_change_to_explicit_anonymous));
+
+    tracing::debug!(
+        ?should_suggest_explicit_anonymous,
+        ?suggest_change_to_explicit_anonymous,
+        ?explicit_anonymous_suggestion,
+    );
+
+    let lifetime_name = bound_lifetime.map(|info| info.lifetime_name()).unwrap_or("'_").to_owned();
+
+    // We can produce a number of suggestions which may overwhelm
+    // the user. Instead, we order the suggestions based on Rust
+    // idioms. The "best" choice is shown to the user and the
+    // remaining choices are shown to tools only.
+    let mut suggestions = Vec::new();
+    suggestions.extend(explicit_bound_suggestion);
+    suggestions.extend(mixed_suggestion);
+    suggestions.extend(implicit_suggestion);
+    suggestions.extend(explicit_anonymous_suggestion);
+
+    cx.emit_span_lint(
+        MISMATCHED_LIFETIME_SYNTAXES,
+        Vec::clone(&inputs),
+        lints::MismatchedLifetimeSyntaxes { lifetime_name, inputs, outputs, suggestions },
+    );
+}
+
+fn build_mismatch_suggestion(
+    lifetime_name: &str,
+    infos: &[&Info<'_>],
+) -> lints::MismatchedLifetimeSyntaxesSuggestion {
+    let lifetime_name = lifetime_name.to_owned();
+
+    let suggestions = infos.iter().map(|info| info.suggestion(&lifetime_name)).collect();
+
+    lints::MismatchedLifetimeSyntaxesSuggestion::Explicit {
+        lifetime_name,
+        suggestions,
+        tool_only: false,
+    }
+}
+
+#[derive(Debug)]
+struct Info<'tcx> {
+    type_span: Span,
+    referenced_type_span: Option<Span>,
+    lifetime: &'tcx hir::Lifetime,
+}
+
+impl<'tcx> Info<'tcx> {
+    fn lifetime_name(&self) -> &str {
+        self.lifetime.ident.as_str()
+    }
+
+    fn is_static(&self) -> bool {
+        self.lifetime.is_static()
+    }
+
+    /// When reporting a lifetime that is implicit, we expand the span
+    /// to include the type. Otherwise we end up pointing at nothing,
+    /// which is a bit confusing.
+    fn reporting_span(&self) -> Span {
+        if self.lifetime.is_implicit() { self.type_span } else { self.lifetime.ident.span }
+    }
+
+    /// When removing an explicit lifetime from a reference,
+    /// we want to remove the whitespace after the lifetime.
+    ///
+    /// ```rust
+    /// fn x(a: &'_ u8) {}
+    /// ```
+    ///
+    /// Should become:
+    ///
+    /// ```rust
+    /// fn x(a: &u8) {}
+    /// ```
+    // FIXME: Ideally, we'd also remove the lifetime declaration.
+    fn removing_span(&self) -> Span {
+        let mut span = self.suggestion("'dummy").0;
+
+        if let Some(referenced_type_span) = self.referenced_type_span {
+            span = span.until(referenced_type_span);
+        }
+
+        span
+    }
+
+    fn suggestion(&self, lifetime_name: &str) -> (Span, String) {
+        self.lifetime.suggestion(lifetime_name)
+    }
+}
+
+type LifetimeInfoMap<'tcx> = FxIndexMap<&'tcx hir::LifetimeKind, Vec<Info<'tcx>>>;
+
+struct LifetimeInfoCollector<'a, 'tcx> {
+    type_span: Span,
+    referenced_type_span: Option<Span>,
+    map: &'a mut LifetimeInfoMap<'tcx>,
+}
+
+impl<'a, 'tcx> LifetimeInfoCollector<'a, 'tcx> {
+    fn collect(ty: &'tcx hir::Ty<'tcx>, map: &'a mut LifetimeInfoMap<'tcx>) {
+        let mut this = Self { type_span: ty.span, referenced_type_span: None, map };
+
+        intravisit::walk_unambig_ty(&mut this, ty);
+    }
+}
+
+impl<'a, 'tcx> Visitor<'tcx> for LifetimeInfoCollector<'a, 'tcx> {
+    #[instrument(skip(self))]
+    fn visit_lifetime(&mut self, lifetime: &'tcx hir::Lifetime) {
+        let type_span = self.type_span;
+        let referenced_type_span = self.referenced_type_span;
+
+        let info = Info { type_span, referenced_type_span, lifetime };
+
+        self.map.entry(&lifetime.kind).or_default().push(info);
+    }
+
+    #[instrument(skip(self))]
+    fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, hir::AmbigArg>) -> Self::Result {
+        let old_type_span = self.type_span;
+        let old_referenced_type_span = self.referenced_type_span;
+
+        self.type_span = ty.span;
+        if let hir::TyKind::Ref(_, ty) = ty.kind {
+            self.referenced_type_span = Some(ty.ty.span);
+        }
+
+        intravisit::walk_ty(self, ty);
+
+        self.type_span = old_type_span;
+        self.referenced_type_span = old_referenced_type_span;
+    }
+}
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 10d0e2c93a8..9d3c74a9a2b 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -8,17 +8,17 @@ use rustc_errors::{
     Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString, ElidedLifetimeInPathSubdiag,
     EmissionGuarantee, LintDiagnostic, MultiSpan, Subdiagnostic, SuggestionStyle,
 };
+use rustc_hir as hir;
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::VisitorExt;
-use rustc_hir::{self as hir, MissingLifetimeKind};
 use rustc_macros::{LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::inhabitedness::InhabitedPredicate;
 use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt};
 use rustc_session::Session;
 use rustc_session::lint::AmbiguityErrorDiag;
 use rustc_span::edition::Edition;
-use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, kw, sym};
+use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym};
 
 use crate::builtin::{InitError, ShorthandAssocTyCollector, TypeAliasBounds};
 use crate::errors::{OverruledAttributeSub, RequestedLevel};
@@ -2752,58 +2752,6 @@ pub(crate) struct ElidedLifetimesInPaths {
     pub subdiag: ElidedLifetimeInPathSubdiag,
 }
 
-pub(crate) struct ElidedNamedLifetime {
-    pub span: Span,
-    pub kind: MissingLifetimeKind,
-    pub name: Symbol,
-    pub declaration: Option<Span>,
-}
-
-impl<G: EmissionGuarantee> LintDiagnostic<'_, G> for ElidedNamedLifetime {
-    fn decorate_lint(self, diag: &mut rustc_errors::Diag<'_, G>) {
-        let Self { span, kind, name, declaration } = self;
-        diag.primary_message(fluent::lint_elided_named_lifetime);
-        diag.arg("name", name);
-        diag.span_label(span, fluent::lint_label_elided);
-        if let Some(declaration) = declaration {
-            diag.span_label(declaration, fluent::lint_label_named);
-        }
-        // FIXME(GrigorenkoPV): this `if` and `return` should be removed,
-        //  but currently this lint's suggestions can conflict with those of `clippy::needless_lifetimes`:
-        //  https://github.com/rust-lang/rust/pull/129840#issuecomment-2323349119
-        // HACK: `'static` suggestions will never sonflict, emit only those for now.
-        if name != kw::StaticLifetime {
-            return;
-        }
-        match kind {
-            MissingLifetimeKind::Underscore => diag.span_suggestion_verbose(
-                span,
-                fluent::lint_suggestion,
-                format!("{name}"),
-                Applicability::MachineApplicable,
-            ),
-            MissingLifetimeKind::Ampersand => diag.span_suggestion_verbose(
-                span.shrink_to_hi(),
-                fluent::lint_suggestion,
-                format!("{name} "),
-                Applicability::MachineApplicable,
-            ),
-            MissingLifetimeKind::Comma => diag.span_suggestion_verbose(
-                span.shrink_to_hi(),
-                fluent::lint_suggestion,
-                format!("{name}, "),
-                Applicability::MachineApplicable,
-            ),
-            MissingLifetimeKind::Brackets => diag.span_suggestion_verbose(
-                span.shrink_to_hi(),
-                fluent::lint_suggestion,
-                format!("<{name}>"),
-                Applicability::MachineApplicable,
-            ),
-        };
-    }
-}
-
 #[derive(LintDiagnostic)]
 #[diag(lint_invalid_crate_type_value)]
 pub(crate) struct UnknownCrateTypes {
@@ -3241,3 +3189,128 @@ pub(crate) struct ReservedMultihash {
     #[suggestion(code = " ", applicability = "machine-applicable")]
     pub suggestion: Span,
 }
+
+#[derive(Debug)]
+pub(crate) struct MismatchedLifetimeSyntaxes {
+    pub lifetime_name: String,
+    pub inputs: Vec<Span>,
+    pub outputs: Vec<Span>,
+
+    pub suggestions: Vec<MismatchedLifetimeSyntaxesSuggestion>,
+}
+
+impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for MismatchedLifetimeSyntaxes {
+    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
+        diag.primary_message(fluent::lint_mismatched_lifetime_syntaxes);
+
+        diag.arg("lifetime_name", self.lifetime_name);
+
+        diag.arg("n_inputs", self.inputs.len());
+        for input in self.inputs {
+            let a = diag.eagerly_translate(fluent::lint_label_mismatched_lifetime_syntaxes_inputs);
+            diag.span_label(input, a);
+        }
+
+        diag.arg("n_outputs", self.outputs.len());
+        for output in self.outputs {
+            let a = diag.eagerly_translate(fluent::lint_label_mismatched_lifetime_syntaxes_outputs);
+            diag.span_label(output, a);
+        }
+
+        let mut suggestions = self.suggestions.into_iter();
+        if let Some(s) = suggestions.next() {
+            diag.subdiagnostic(s);
+
+            for mut s in suggestions {
+                s.make_tool_only();
+                diag.subdiagnostic(s);
+            }
+        }
+    }
+}
+
+#[derive(Debug)]
+pub(crate) enum MismatchedLifetimeSyntaxesSuggestion {
+    Implicit {
+        suggestions: Vec<Span>,
+        tool_only: bool,
+    },
+
+    Mixed {
+        implicit_suggestions: Vec<Span>,
+        explicit_anonymous_suggestions: Vec<(Span, String)>,
+        tool_only: bool,
+    },
+
+    Explicit {
+        lifetime_name: String,
+        suggestions: Vec<(Span, String)>,
+        tool_only: bool,
+    },
+}
+
+impl MismatchedLifetimeSyntaxesSuggestion {
+    fn make_tool_only(&mut self) {
+        use MismatchedLifetimeSyntaxesSuggestion::*;
+
+        let tool_only = match self {
+            Implicit { tool_only, .. } | Mixed { tool_only, .. } | Explicit { tool_only, .. } => {
+                tool_only
+            }
+        };
+
+        *tool_only = true;
+    }
+}
+
+impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion {
+    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
+        use MismatchedLifetimeSyntaxesSuggestion::*;
+
+        let style = |tool_only| {
+            if tool_only { SuggestionStyle::CompletelyHidden } else { SuggestionStyle::ShowAlways }
+        };
+
+        match self {
+            Implicit { suggestions, tool_only } => {
+                let suggestions = suggestions.into_iter().map(|s| (s, String::new())).collect();
+                diag.multipart_suggestion_with_style(
+                    fluent::lint_mismatched_lifetime_syntaxes_suggestion_implicit,
+                    suggestions,
+                    Applicability::MachineApplicable,
+                    style(tool_only),
+                );
+            }
+
+            Mixed { implicit_suggestions, explicit_anonymous_suggestions, tool_only } => {
+                let implicit_suggestions =
+                    implicit_suggestions.into_iter().map(|s| (s, String::new()));
+
+                let suggestions =
+                    implicit_suggestions.chain(explicit_anonymous_suggestions).collect();
+
+                diag.multipart_suggestion_with_style(
+                    fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed,
+                    suggestions,
+                    Applicability::MachineApplicable,
+                    style(tool_only),
+                );
+            }
+
+            Explicit { lifetime_name, suggestions, tool_only } => {
+                diag.arg("lifetime_name", lifetime_name);
+
+                let msg = diag.eagerly_translate(
+                    fluent::lint_mismatched_lifetime_syntaxes_suggestion_explicit,
+                );
+
+                diag.multipart_suggestion_with_style(
+                    msg,
+                    suggestions,
+                    Applicability::MachineApplicable,
+                    style(tool_only),
+                );
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 1b14157c5f0..777118e69fb 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -40,7 +40,6 @@ declare_lint_pass! {
         DUPLICATE_MACRO_ATTRIBUTES,
         ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
         ELIDED_LIFETIMES_IN_PATHS,
-        ELIDED_NAMED_LIFETIMES,
         EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
         EXPORTED_PRIVATE_DEPENDENCIES,
         FFI_UNWIND_CALLS,
@@ -1833,38 +1832,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `elided_named_lifetimes` lint detects when an elided
-    /// lifetime ends up being a named lifetime, such as `'static`
-    /// or some lifetime parameter `'a`.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,compile_fail
-    /// #![deny(elided_named_lifetimes)]
-    /// struct Foo;
-    /// impl Foo {
-    ///     pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
-    ///         unsafe { &mut *(x as *mut _) }
-    ///     }
-    /// }
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// Lifetime elision is quite useful, because it frees you from having
-    /// to give each lifetime its own name, but sometimes it can produce
-    /// somewhat surprising resolutions. In safe code, it is mostly okay,
-    /// because the borrow checker prevents any unsoundness, so the worst
-    /// case scenario is you get a confusing error message in some other place.
-    /// But with `unsafe` code, such unexpected resolutions may lead to unsound code.
-    pub ELIDED_NAMED_LIFETIMES,
-    Warn,
-    "detects when an elided lifetime gets resolved to be `'static` or some named parameter"
-}
-
-declare_lint! {
     /// The `bare_trait_objects` lint suggests using `dyn Trait` for trait
     /// objects.
     ///
@@ -3655,6 +3622,54 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `unsupported_calling_conventions` lint is output whenever there is a use of the
+    /// `stdcall`, `fastcall`, and `cdecl` calling conventions (or their unwind
+    /// variants) on targets that cannot meaningfully be supported for the requested target.
+    ///
+    /// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc
+    /// code, because this calling convention was never specified for those targets.
+    ///
+    /// Historically MSVC toolchains have fallen back to the regular C calling convention for
+    /// targets other than x86, but Rust doesn't really see a similar need to introduce a similar
+    /// hack across many more targets.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,ignore (needs specific targets)
+    /// extern "stdcall" fn stdcall() {}
+    /// ```
+    ///
+    /// This will produce:
+    ///
+    /// ```text
+    /// warning: use of calling convention not supported on this target
+    ///   --> $DIR/unsupported.rs:39:1
+    ///    |
+    /// LL | extern "stdcall" fn stdcall() {}
+    ///    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    ///    |
+    ///    = note: `#[warn(unsupported_calling_conventions)]` on by default
+    ///    = 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 ...
+    /// ```
+    ///
+    /// ### Explanation
+    ///
+    /// On most of the targets the behaviour of `stdcall` and similar calling conventions is not
+    /// defined at all, but was previously accepted due to a bug in the implementation of the
+    /// compiler.
+    pub UNSUPPORTED_CALLING_CONVENTIONS,
+    Warn,
+    "use of unsupported calling convention",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::FutureReleaseError,
+        report_in_deps: true,
+        reference: "issue #137018 <https://github.com/rust-lang/rust/issues/137018>",
+    };
+}
+
+declare_lint! {
     /// The `unsupported_fn_ptr_calling_conventions` lint is output whenever there is a use of
     /// a target dependent calling convention on a target that does not support this calling
     /// convention on a function pointer.
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index e19bf59e543..1d9b7a7fcb9 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -9,7 +9,7 @@ use rustc_data_structures::stable_hasher::{
 use rustc_error_messages::{DiagMessage, MultiSpan};
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::DefPathHash;
-use rustc_hir::{HashStableContext, HirId, ItemLocalId, MissingLifetimeKind};
+use rustc_hir::{HashStableContext, HirId, ItemLocalId};
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 pub use rustc_span::edition::Edition;
 use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym};
@@ -610,12 +610,6 @@ pub enum DeprecatedSinceKind {
     InVersion(String),
 }
 
-#[derive(Debug)]
-pub enum ElidedLifetimeResolution {
-    Static,
-    Param(Symbol, Span),
-}
-
 // This could be a closure, but then implementing derive trait
 // becomes hacky (and it gets allocated).
 #[derive(Debug)]
@@ -628,10 +622,6 @@ pub enum BuiltinLintDiag {
     },
     MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
     ElidedLifetimesInPaths(usize, Span, bool, Span),
-    ElidedNamedLifetimes {
-        elided: (Span, MissingLifetimeKind),
-        resolution: ElidedLifetimeResolution,
-    },
     UnknownCrateTypes {
         span: Span,
         candidate: Option<Symbol>,
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index 81817018cb1..42d006ef301 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -3,7 +3,6 @@
 #![feature(if_let_guard)]
 #![feature(never_type)]
 #![feature(proc_macro_diagnostic)]
-#![feature(proc_macro_span)]
 #![feature(proc_macro_tracked_env)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index bccffe39243..3bef5ca114b 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -272,6 +272,9 @@ metadata_raw_dylib_no_nul =
 metadata_raw_dylib_only_windows =
     link kind `raw-dylib` is only supported on Windows targets
 
+metadata_raw_dylib_unsupported_abi =
+    ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
+
 metadata_renaming_no_link =
     renaming of the library `{$lib_name}` was specified, however this crate contains no `#[link(...)]` attributes referencing this library
 
@@ -319,12 +322,6 @@ metadata_unknown_link_modifier =
 
 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
-
-metadata_unsupported_abi_i686 =
-    ABI not supported by `#[link(kind = "raw-dylib")]` on i686
-
 metadata_wasm_c_abi =
     older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust; please update to `wasm-bindgen` v0.2.88
 
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 16f59793e63..71da4290174 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -300,15 +300,8 @@ pub struct NoLinkModOverride {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_unsupported_abi_i686)]
-pub struct UnsupportedAbiI686 {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_unsupported_abi)]
-pub struct UnsupportedAbi {
+#[diag(metadata_raw_dylib_unsupported_abi)]
+pub struct RawDylibUnsupportedAbi {
     #[primary_span]
     pub span: Span,
 }
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index cee9cff0775..5cdeb8935f7 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -652,7 +652,13 @@ impl<'tcx> Collector<'tcx> {
     ) -> DllImport {
         let span = self.tcx.def_span(item);
 
-        // this logic is similar to `Target::adjust_abi` (in rustc_target/src/spec/mod.rs) but errors on unsupported inputs
+        // This `extern` block should have been checked for general ABI support before, but let's
+        // double-check that.
+        assert!(self.tcx.sess.target.is_abi_supported(abi));
+
+        // This logic is similar to `AbiMap::canonize_abi` (in rustc_target/src/spec/abi_map.rs) but
+        // we need more detail than those adjustments, and we can't support all ABIs that are
+        // generally supported.
         let calling_convention = if self.tcx.sess.target.arch == "x86" {
             match abi {
                 ExternAbi::C { .. } | ExternAbi::Cdecl { .. } => DllCallingConvention::C,
@@ -679,7 +685,7 @@ impl<'tcx> Collector<'tcx> {
                     DllCallingConvention::Vectorcall(self.i686_arg_list_size(item))
                 }
                 _ => {
-                    self.tcx.dcx().emit_fatal(errors::UnsupportedAbiI686 { span });
+                    self.tcx.dcx().emit_fatal(errors::RawDylibUnsupportedAbi { span });
                 }
             }
         } else {
@@ -688,7 +694,7 @@ impl<'tcx> Collector<'tcx> {
                     DllCallingConvention::C
                 }
                 _ => {
-                    self.tcx.dcx().emit_fatal(errors::UnsupportedAbi { span });
+                    self.tcx.dcx().emit_fatal(errors::RawDylibUnsupportedAbi { span });
                 }
             }
         };
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index bd315577efb..6c6b12fed67 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -95,7 +95,7 @@ pub(crate) struct StrictCoherenceNeedsNegativeCoherence {
 #[diag(middle_requires_lang_item)]
 pub(crate) struct RequiresLangItem {
     #[primary_span]
-    pub span: Option<Span>,
+    pub span: Span,
     pub name: Symbol,
 }
 
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index a28dcb0cb8e..d1f5caaafb2 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -71,6 +71,7 @@ impl ModuleItems {
         self.opaques.iter().copied()
     }
 
+    /// Closures and inline consts
     pub fn nested_bodies(&self) -> impl Iterator<Item = LocalDefId> {
         self.nested_bodies.iter().copied()
     }
@@ -79,6 +80,14 @@ impl ModuleItems {
         self.owners().map(|id| id.def_id)
     }
 
+    /// Closures and inline consts
+    pub fn par_nested_bodies(
+        &self,
+        f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
+    ) -> Result<(), ErrorGuaranteed> {
+        try_par_for_each_in(&self.nested_bodies[..], |&&id| f(id))
+    }
+
     pub fn par_items(
         &self,
         f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index cb3fdd4d3f7..667361b3ca0 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -51,9 +51,9 @@
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(ptr_alignment_type)]
+#![feature(round_char_boundary)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![feature(trusted_len)]
 #![feature(try_blocks)]
 #![feature(try_trait_v2)]
 #![feature(try_trait_v2_yeet)]
diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs
index 0f92c1910f1..93264f02cc2 100644
--- a/compiler/rustc_middle/src/middle/lang_items.rs
+++ b/compiler/rustc_middle/src/middle/lang_items.rs
@@ -17,7 +17,7 @@ use crate::ty::{self, TyCtxt};
 impl<'tcx> TyCtxt<'tcx> {
     /// Returns the `DefId` for a given `LangItem`.
     /// If not found, fatally aborts compilation.
-    pub fn require_lang_item(self, lang_item: LangItem, span: Option<Span>) -> DefId {
+    pub fn require_lang_item(self, lang_item: LangItem, span: Span) -> DefId {
         self.lang_items().get(lang_item).unwrap_or_else(|| {
             self.dcx().emit_fatal(crate::error::RequiresLangItem { span, name: lang_item.name() });
         })
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 7243f87ee63..47ba850d50d 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -1,3 +1,4 @@
+use std::borrow::Cow;
 use std::fmt;
 use std::hash::Hash;
 
@@ -468,6 +469,29 @@ impl<'tcx> CodegenUnit<'tcx> {
         hash.as_u128().to_base_fixed_len(CASE_INSENSITIVE)
     }
 
+    pub fn shorten_name(human_readable_name: &str) -> Cow<'_, str> {
+        // Set a limit a somewhat below the common platform limits for file names.
+        const MAX_CGU_NAME_LENGTH: usize = 200;
+        const TRUNCATED_NAME_PREFIX: &str = "-trunc-";
+        if human_readable_name.len() > MAX_CGU_NAME_LENGTH {
+            let mangled_name = Self::mangle_name(human_readable_name);
+            // Determine a safe byte offset to truncate the name to
+            let truncate_to = human_readable_name.floor_char_boundary(
+                MAX_CGU_NAME_LENGTH - TRUNCATED_NAME_PREFIX.len() - mangled_name.len(),
+            );
+            format!(
+                "{}{}{}",
+                &human_readable_name[..truncate_to],
+                TRUNCATED_NAME_PREFIX,
+                mangled_name
+            )
+            .into()
+        } else {
+            // If the name is short enough, we can just return it as is.
+            human_readable_name.into()
+        }
+    }
+
     pub fn compute_size_estimate(&mut self) {
         // The size of a codegen unit as the sum of the sizes of the items
         // within it.
@@ -604,7 +628,7 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> {
         let cgu_name = self.build_cgu_name_no_mangle(cnum, components, special_suffix);
 
         if self.tcx.sess.opts.unstable_opts.human_readable_cgu_names {
-            cgu_name
+            Symbol::intern(&CodegenUnit::shorten_name(cgu_name.as_str()))
         } else {
             Symbol::intern(&CodegenUnit::mangle_name(cgu_name.as_str()))
         }
diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
index 06e41e64fdc..d98b40f0fcf 100644
--- a/compiler/rustc_middle/src/mir/statement.rs
+++ b/compiler/rustc_middle/src/mir/statement.rs
@@ -835,7 +835,7 @@ impl<'tcx> BinOp {
             &BinOp::Cmp => {
                 // these should be integer-like types of the same size.
                 assert_eq!(lhs_ty, rhs_ty);
-                tcx.ty_ordering_enum(None)
+                tcx.ty_ordering_enum(DUMMY_SP)
             }
         }
     }
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index bb068f3821d..f2f975a6968 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1531,8 +1531,6 @@ pub enum CastKind {
     ///
     /// MIR is well-formed if the input and output types have different sizes,
     /// but running a transmute between differently-sized types is UB.
-    ///
-    /// Allowed only in [`MirPhase::Runtime`]; Earlier it's a [`TerminatorKind::Call`].
     Transmute,
 }
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index d900e16b005..686ac54f89e 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1115,15 +1115,6 @@ rustc_queries! {
         desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) }
     }
 
-    /// Checks the loops in the module.
-    query check_mod_loops(key: LocalModDefId) {
-        desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) }
-    }
-
-    query check_mod_naked_functions(key: LocalModDefId) {
-        desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) }
-    }
-
     query check_mod_privacy(key: LocalModDefId) {
         desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
     }
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs
index a61a6c571a2..3bacdfe5ac8 100644
--- a/compiler/rustc_middle/src/ty/adjustment.rs
+++ b/compiler/rustc_middle/src/ty/adjustment.rs
@@ -128,8 +128,8 @@ impl OverloadedDeref {
     /// for this overloaded deref's mutability.
     pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>) -> DefId {
         let trait_def_id = match self.mutbl {
-            hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None),
-            hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None),
+            hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, self.span),
+            hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, self.span),
         };
         tcx.associated_items(trait_def_id)
             .in_definition_order()
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 57b20a1bba6..5e14516c712 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -179,6 +179,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         f(&mut *self.new_solver_evaluation_cache.lock())
     }
 
+    fn canonical_param_env_cache_get_or_insert<R>(
+        self,
+        param_env: ty::ParamEnv<'tcx>,
+        f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry<Self>,
+        from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry<Self>) -> R,
+    ) -> R {
+        let mut cache = self.new_solver_canonical_param_env_cache.lock();
+        let entry = cache.entry(param_env).or_insert_with(f);
+        from_entry(entry)
+    }
+
     fn evaluation_is_concurrent(&self) -> bool {
         self.sess.threads() > 1
     }
@@ -458,7 +469,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     }
 
     fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
-        self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None)
+        self.require_lang_item(trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
     }
 
     fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
@@ -1444,6 +1455,8 @@ pub struct GlobalCtxt<'tcx> {
 
     /// Caches the results of goal evaluation in the new solver.
     pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,
+    pub new_solver_canonical_param_env_cache:
+        Lock<FxHashMap<ty::ParamEnv<'tcx>, ty::CanonicalParamEnvCacheEntry<TyCtxt<'tcx>>>>,
 
     pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>,
 
@@ -1692,6 +1705,7 @@ impl<'tcx> TyCtxt<'tcx> {
             selection_cache: Default::default(),
             evaluation_cache: Default::default(),
             new_solver_evaluation_cache: Default::default(),
+            new_solver_canonical_param_env_cache: Default::default(),
             canonical_param_env_cache: Default::default(),
             data_layout,
             alloc_map: interpret::AllocMap::new(),
@@ -1710,7 +1724,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Gets a `Ty` representing the [`LangItem::OrderingEnum`]
     #[track_caller]
-    pub fn ty_ordering_enum(self, span: Option<Span>) -> Ty<'tcx> {
+    pub fn ty_ordering_enum(self, span: Span) -> Ty<'tcx> {
         let ordering_enum = self.require_lang_item(hir::LangItem::OrderingEnum, span);
         self.type_of(ordering_enum).no_bound_vars().unwrap()
     }
@@ -2253,7 +2267,7 @@ impl<'tcx> TyCtxt<'tcx> {
         Ty::new_imm_ref(
             self,
             self.lifetimes.re_static,
-            self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
+            self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP))
                 .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])),
         )
     }
@@ -2712,7 +2726,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Given a `ty`, return whether it's an `impl Future<...>`.
     pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
         let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
-        let future_trait = self.require_lang_item(LangItem::Future, None);
+        let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP);
 
         self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
             let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 0d99a1b5149..5ba4e5446e9 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -786,7 +786,7 @@ impl<'tcx> Instance<'tcx> {
     }
 
     pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
-        let def_id = tcx.require_lang_item(LangItem::DropInPlace, None);
+        let def_id = tcx.require_lang_item(LangItem::DropInPlace, DUMMY_SP);
         let args = tcx.mk_args(&[ty.into()]);
         Instance::expect_resolve(
             tcx,
@@ -798,7 +798,7 @@ impl<'tcx> Instance<'tcx> {
     }
 
     pub fn resolve_async_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
-        let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, None);
+        let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, DUMMY_SP);
         let args = tcx.mk_args(&[ty.into()]);
         Instance::expect_resolve(
             tcx,
@@ -824,7 +824,7 @@ impl<'tcx> Instance<'tcx> {
         closure_did: DefId,
         args: ty::GenericArgsRef<'tcx>,
     ) -> Instance<'tcx> {
-        let fn_once = tcx.require_lang_item(LangItem::FnOnce, None);
+        let fn_once = tcx.require_lang_item(LangItem::FnOnce, DUMMY_SP);
         let call_once = tcx
             .associated_items(fn_once)
             .in_definition_order()
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 404674c359e..cbf545c01c5 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -593,7 +593,7 @@ impl<'tcx> Ty<'tcx> {
         ty: Ty<'tcx>,
         mutbl: ty::Mutability,
     ) -> Ty<'tcx> {
-        let pin = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, None));
+        let pin = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, DUMMY_SP));
         Ty::new_adt(tcx, pin, tcx.mk_args(&[Ty::new_ref(tcx, r, ty, mutbl).into()]))
     }
 
@@ -857,19 +857,19 @@ impl<'tcx> Ty<'tcx> {
 
     #[inline]
     pub fn new_box(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let def_id = tcx.require_lang_item(LangItem::OwnedBox, None);
+        let def_id = tcx.require_lang_item(LangItem::OwnedBox, DUMMY_SP);
         Ty::new_generic_adt(tcx, def_id, ty)
     }
 
     #[inline]
     pub fn new_maybe_uninit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let def_id = tcx.require_lang_item(LangItem::MaybeUninit, None);
+        let def_id = tcx.require_lang_item(LangItem::MaybeUninit, DUMMY_SP);
         Ty::new_generic_adt(tcx, def_id, ty)
     }
 
     /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes.
     pub fn new_task_context(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        let context_did = tcx.require_lang_item(LangItem::Context, None);
+        let context_did = tcx.require_lang_item(LangItem::Context, DUMMY_SP);
         let context_adt_ref = tcx.adt_def(context_did);
         let context_args = tcx.mk_args(&[tcx.lifetimes.re_erased.into()]);
         let context_ty = Ty::new_adt(tcx, context_adt_ref, context_args);
@@ -1549,7 +1549,7 @@ impl<'tcx> Ty<'tcx> {
 
             ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => {
                 let assoc_items = tcx.associated_item_def_ids(
-                    tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
+                    tcx.require_lang_item(hir::LangItem::DiscriminantKind, DUMMY_SP),
                 );
                 Ty::new_projection_from_args(tcx, assoc_items[0], tcx.mk_args(&[self.into()]))
             }
@@ -1629,7 +1629,7 @@ impl<'tcx> Ty<'tcx> {
             ty::Str | ty::Slice(_) => Ok(tcx.types.usize),
 
             ty::Dynamic(_, _, ty::Dyn) => {
-                let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None);
+                let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, DUMMY_SP);
                 Ok(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]))
             }
 
@@ -1683,7 +1683,7 @@ impl<'tcx> Ty<'tcx> {
             match pointee_ty.ptr_metadata_ty_or_tail(tcx, |x| x) {
                 Ok(metadata_ty) => metadata_ty,
                 Err(tail_ty) => {
-                    let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
+                    let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, DUMMY_SP);
                     Ty::new_projection(tcx, metadata_def_id, [tail_ty])
                 }
             }
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index cc3887079d8..88583407d25 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -199,7 +199,7 @@ pub struct TypeckResults<'tcx> {
 
     /// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions
     /// by applying extended parameter rules.
-    /// Details may be find in `rustc_hir_analysis::check::rvalue_scopes`.
+    /// Details may be found in `rustc_hir_analysis::check::rvalue_scopes`.
     pub rvalue_scopes: RvalueScopes,
 
     /// Stores the predicates that apply on coroutine witness types.
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 5a97b08db28..b23bc089cd4 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
@@ -145,7 +145,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // malloc some memory of suitable size and align:
                 let exchange_malloc = Operand::function_handle(
                     tcx,
-                    tcx.require_lang_item(LangItem::ExchangeMalloc, Some(expr_span)),
+                    tcx.require_lang_item(LangItem::ExchangeMalloc, expr_span),
                     [],
                     expr_span,
                 );
diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs
index a9a07997410..2074fbce0ae 100644
--- a/compiler/rustc_mir_build/src/builder/expr/into.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/into.rs
@@ -307,7 +307,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 } else if this.infcx.type_is_use_cloned_modulo_regions(this.param_env, ty) {
                     // Convert `expr.use` to a call like `Clone::clone(&expr)`
                     let success = this.cfg.start_new_block();
-                    let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None);
+                    let clone_trait = this.tcx.require_lang_item(LangItem::Clone, span);
                     let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0];
                     let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span);
                     let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty);
diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs
index 210b9cce581..a4609a6053e 100644
--- a/compiler/rustc_mir_build/src/builder/matches/test.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/test.rs
@@ -364,7 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let borrow_kind = super::util::ref_pat_borrow_kind(mutability);
         let source_info = self.source_info(span);
         let re_erased = self.tcx.lifetimes.re_erased;
-        let trait_item = self.tcx.require_lang_item(trait_item, None);
+        let trait_item = self.tcx.require_lang_item(trait_item, span);
         let method = trait_method(self.tcx, trait_item, method, [ty]);
         let ref_src = self.temp(Ty::new_ref(self.tcx, re_erased, ty, mutability), span);
         // `let ref_src = &src_place;`
@@ -437,7 +437,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         val: Operand<'tcx>,
     ) {
         let str_ty = self.tcx.types.str_;
-        let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span));
+        let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, source_info.span);
         let method = trait_method(self.tcx, eq_def_id, sym::eq, [str_ty, str_ty]);
 
         let bool_ty = self.tcx.types.bool;
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 226dc920a49..3baeccf6409 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -38,7 +38,10 @@ impl<'tcx> ThirBuildCx<'tcx> {
     }
 
     pub(crate) fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> Box<[ExprId]> {
-        exprs.iter().map(|expr| self.mirror_expr_inner(expr)).collect()
+        // `mirror_exprs` may also recurse deeply, so it needs protection from stack overflow.
+        // Note that we *could* forward to `mirror_expr` for that, but we can consolidate the
+        // overhead of stack growth by doing it outside the iteration.
+        ensure_sufficient_stack(|| exprs.iter().map(|expr| self.mirror_expr_inner(expr)).collect())
     }
 
     #[instrument(level = "trace", skip(self, hir_expr))]
@@ -220,7 +223,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
                 });
 
                 // kind = Pin { __pointer: pointer }
-                let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, Some(span));
+                let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, span);
                 let args = self.tcx.mk_args(&[new_pin_target.into()]);
                 let kind = ExprKind::Adt(Box::new(AdtExpr {
                     adt_def: self.tcx.adt_def(pin_did),
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index 8c817605847..24d4136c642 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -189,7 +189,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
             // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
             // (as it's created inside the body itself, not passed in from outside).
             let ty = if fn_decl.c_variadic && index == fn_decl.inputs.len() {
-                let va_list_did = self.tcx.require_lang_item(LangItem::VaList, Some(param.span));
+                let va_list_did = self.tcx.require_lang_item(LangItem::VaList, param.span);
 
                 self.tcx
                     .type_of(va_list_did)
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 84a0190a7fa..003ad170861 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -15,7 +15,7 @@ use rustc_middle::ty::{
 };
 use rustc_middle::{mir, span_bug};
 use rustc_span::def_id::DefId;
-use rustc_span::{Span, sym};
+use rustc_span::{DUMMY_SP, Span, sym};
 use rustc_trait_selection::traits::ObligationCause;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use tracing::{debug, instrument, trace};
@@ -480,8 +480,9 @@ fn type_has_partial_eq_impl<'tcx>(
     // (If there isn't, then we can safely issue a hard
     // error, because that's never worked, due to compiler
     // using `PartialEq::eq` in this scenario in the past.)
-    let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None);
-    let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None);
+    let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, DUMMY_SP);
+    let structural_partial_eq_trait_id =
+        tcx.require_lang_item(hir::LangItem::StructuralPeq, DUMMY_SP);
 
     let partial_eq_obligation = Obligation::new(
         tcx,
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index cddb2f84778..d5d0d56f528 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -225,7 +225,7 @@ impl<'tcx> TransformVisitor<'tcx> {
             CoroutineKind::Coroutine(_) => span_bug!(body.span, "`Coroutine`s cannot be fused"),
             // `gen` continues return `None`
             CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
-                let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
+                let option_def_id = self.tcx.require_lang_item(LangItem::Option, body.span);
                 make_aggregate_adt(
                     option_def_id,
                     VariantIdx::ZERO,
@@ -242,7 +242,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                     span: source_info.span,
                     const_: Const::Unevaluated(
                         UnevaluatedConst::new(
-                            self.tcx.require_lang_item(LangItem::AsyncGenFinished, None),
+                            self.tcx.require_lang_item(LangItem::AsyncGenFinished, body.span),
                             self.tcx.mk_args(&[yield_ty.into()]),
                         ),
                         self.old_yield_ty,
@@ -282,7 +282,7 @@ impl<'tcx> TransformVisitor<'tcx> {
         const ONE: VariantIdx = VariantIdx::from_usize(1);
         let rvalue = match self.coroutine_kind {
             CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
-                let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, None);
+                let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, source_info.span);
                 let args = self.tcx.mk_args(&[self.old_ret_ty.into()]);
                 let (variant_idx, operands) = if is_return {
                     (ZERO, IndexVec::from_raw(vec![val])) // Poll::Ready(val)
@@ -292,7 +292,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                 make_aggregate_adt(poll_def_id, variant_idx, args, operands)
             }
             CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
-                let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
+                let option_def_id = self.tcx.require_lang_item(LangItem::Option, source_info.span);
                 let args = self.tcx.mk_args(&[self.old_yield_ty.into()]);
                 let (variant_idx, operands) = if is_return {
                     (ZERO, IndexVec::new()) // None
@@ -310,7 +310,10 @@ impl<'tcx> TransformVisitor<'tcx> {
                         span: source_info.span,
                         const_: Const::Unevaluated(
                             UnevaluatedConst::new(
-                                self.tcx.require_lang_item(LangItem::AsyncGenFinished, None),
+                                self.tcx.require_lang_item(
+                                    LangItem::AsyncGenFinished,
+                                    source_info.span,
+                                ),
                                 self.tcx.mk_args(&[yield_ty.into()]),
                             ),
                             self.old_yield_ty,
@@ -323,7 +326,7 @@ impl<'tcx> TransformVisitor<'tcx> {
             }
             CoroutineKind::Coroutine(_) => {
                 let coroutine_state_def_id =
-                    self.tcx.require_lang_item(LangItem::CoroutineState, None);
+                    self.tcx.require_lang_item(LangItem::CoroutineState, source_info.span);
                 let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]);
                 let variant_idx = if is_return {
                     ONE // CoroutineState::Complete(val)
@@ -496,7 +499,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo
 fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let ref_coroutine_ty = body.local_decls.raw[1].ty;
 
-    let pin_did = tcx.require_lang_item(LangItem::Pin, Some(body.span));
+    let pin_did = tcx.require_lang_item(LangItem::Pin, body.span);
     let pin_adt_ref = tcx.adt_def(pin_did);
     let args = tcx.mk_args(&[ref_coroutine_ty.into()]);
     let pin_ref_coroutine_ty = Ty::new_adt(tcx, pin_adt_ref, args);
@@ -557,7 +560,7 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ty
     // replace the type of the `resume` argument
     replace_resume_ty_local(tcx, body, CTX_ARG, context_mut_ref);
 
-    let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, None);
+    let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, body.span);
 
     for bb in body.basic_blocks.indices() {
         let bb_data = &body[bb];
@@ -618,7 +621,7 @@ fn replace_resume_ty_local<'tcx>(
     #[cfg(debug_assertions)]
     {
         if let ty::Adt(resume_ty_adt, _) = local_ty.kind() {
-            let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None));
+            let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, body.span));
             assert_eq!(*resume_ty_adt, expected_adt);
         } else {
             panic!("expected `ResumeTy`, found `{:?}`", local_ty);
@@ -1095,7 +1098,7 @@ fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) ->
 
 fn return_poll_ready_assign<'tcx>(tcx: TyCtxt<'tcx>, source_info: SourceInfo) -> Statement<'tcx> {
     // Poll::Ready(())
-    let poll_def_id = tcx.require_lang_item(LangItem::Poll, None);
+    let poll_def_id = tcx.require_lang_item(LangItem::Poll, source_info.span);
     let args = tcx.mk_args(&[tcx.types.unit.into()]);
     let val = Operand::Constant(Box::new(ConstOperand {
         span: source_info.span,
@@ -1437,7 +1440,7 @@ fn check_field_tys_sized<'tcx>(
             ),
             param_env,
             field_ty.ty,
-            tcx.require_lang_item(hir::LangItem::Sized, Some(field_ty.source_info.span)),
+            tcx.require_lang_item(hir::LangItem::Sized, field_ty.source_info.span),
         );
     }
 
@@ -1473,14 +1476,14 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
         let new_ret_ty = match coroutine_kind {
             CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
                 // Compute Poll<return_ty>
-                let poll_did = tcx.require_lang_item(LangItem::Poll, None);
+                let poll_did = tcx.require_lang_item(LangItem::Poll, body.span);
                 let poll_adt_ref = tcx.adt_def(poll_did);
                 let poll_args = tcx.mk_args(&[old_ret_ty.into()]);
                 Ty::new_adt(tcx, poll_adt_ref, poll_args)
             }
             CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
                 // Compute Option<yield_ty>
-                let option_did = tcx.require_lang_item(LangItem::Option, None);
+                let option_did = tcx.require_lang_item(LangItem::Option, body.span);
                 let option_adt_ref = tcx.adt_def(option_did);
                 let option_args = tcx.mk_args(&[old_yield_ty.into()]);
                 Ty::new_adt(tcx, option_adt_ref, option_args)
@@ -1491,7 +1494,7 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
             }
             CoroutineKind::Coroutine(_) => {
                 // Compute CoroutineState<yield_ty, return_ty>
-                let state_did = tcx.require_lang_item(LangItem::CoroutineState, None);
+                let state_did = tcx.require_lang_item(LangItem::CoroutineState, body.span);
                 let state_adt_ref = tcx.adt_def(state_did);
                 let state_args = tcx.mk_args(&[old_yield_ty.into(), old_ret_ty.into()]);
                 Ty::new_adt(tcx, state_adt_ref, state_args)
diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs
index 625e53f9959..6021e795d21 100644
--- a/compiler/rustc_mir_transform/src/coroutine/drop.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs
@@ -42,7 +42,7 @@ fn build_poll_call<'tcx>(
     context_ref_place: &Place<'tcx>,
     unwind: UnwindAction,
 ) -> BasicBlock {
-    let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, None);
+    let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, DUMMY_SP);
     let poll_fn = Ty::new_fn_def(tcx, poll_fn, [fut_ty]);
     let poll_fn = Operand::Constant(Box::new(ConstOperand {
         span: DUMMY_SP,
@@ -77,11 +77,8 @@ fn build_pin_fut<'tcx>(
     let fut_ty = fut_place.ty(&body.local_decls, tcx).ty;
     let fut_ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fut_ty);
     let fut_ref_place = Place::from(body.local_decls.push(LocalDecl::new(fut_ref_ty, span)));
-    let pin_fut_new_unchecked_fn = Ty::new_fn_def(
-        tcx,
-        tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)),
-        [fut_ref_ty],
-    );
+    let pin_fut_new_unchecked_fn =
+        Ty::new_fn_def(tcx, tcx.require_lang_item(LangItem::PinNewUnchecked, span), [fut_ref_ty]);
     let fut_pin_ty = pin_fut_new_unchecked_fn.fn_sig(tcx).output().skip_binder();
     let fut_pin_place = Place::from(body.local_decls.push(LocalDecl::new(fut_pin_ty, span)));
     let pin_fut_new_unchecked_fn = Operand::Constant(Box::new(ConstOperand {
@@ -143,13 +140,15 @@ fn build_poll_switch<'tcx>(
     let Discr { val: poll_ready_discr, ty: poll_discr_ty } = poll_enum
         .discriminant_for_variant(
             tcx,
-            poll_enum_adt.variant_index_with_id(tcx.require_lang_item(LangItem::PollReady, None)),
+            poll_enum_adt
+                .variant_index_with_id(tcx.require_lang_item(LangItem::PollReady, DUMMY_SP)),
         )
         .unwrap();
     let poll_pending_discr = poll_enum
         .discriminant_for_variant(
             tcx,
-            poll_enum_adt.variant_index_with_id(tcx.require_lang_item(LangItem::PollPending, None)),
+            poll_enum_adt
+                .variant_index_with_id(tcx.require_lang_item(LangItem::PollPending, DUMMY_SP)),
         )
         .unwrap()
         .val;
@@ -316,16 +315,17 @@ pub(super) fn expand_async_drops<'tcx>(
         //  pending => return rv (yield)
         //  ready => *continue_bb|drop_bb*
 
+        let source_info = body[bb].terminator.as_ref().unwrap().source_info;
+
         // Compute Poll<> (aka Poll with void return)
-        let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None));
+        let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, source_info.span));
         let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()]));
-        let poll_decl = LocalDecl::new(poll_enum, body.span);
+        let poll_decl = LocalDecl::new(poll_enum, source_info.span);
         let poll_unit_place = Place::from(body.local_decls.push(poll_decl));
 
         // First state-loop yield for mainline
         let context_ref_place =
-            Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, body.span)));
-        let source_info = body[bb].terminator.as_ref().unwrap().source_info;
+            Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)));
         let arg = Rvalue::Use(Operand::Move(Place::from(CTX_ARG)));
         body[bb].statements.push(Statement {
             source_info,
@@ -353,8 +353,9 @@ pub(super) fn expand_async_drops<'tcx>(
         let mut dropline_context_ref: Option<Place<'_>> = None;
         let mut dropline_call_bb: Option<BasicBlock> = None;
         if !is_dropline_bb {
-            let context_ref_place2: Place<'_> =
-                Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, body.span)));
+            let context_ref_place2: Place<'_> = Place::from(
+                body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)),
+            );
             let drop_yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield
             let drop_switch_block = build_poll_switch(
                 tcx,
@@ -394,7 +395,7 @@ pub(super) fn expand_async_drops<'tcx>(
                     span: source_info.span,
                     const_: Const::Unevaluated(
                         UnevaluatedConst::new(
-                            tcx.require_lang_item(LangItem::AsyncGenPending, None),
+                            tcx.require_lang_item(LangItem::AsyncGenPending, source_info.span),
                             tcx.mk_args(&[yield_ty.into()]),
                         ),
                         full_yield_ty,
@@ -404,7 +405,7 @@ pub(super) fn expand_async_drops<'tcx>(
             } else {
                 // value needed only for return-yields or gen-coroutines, so just const here
                 Operand::Constant(Box::new(ConstOperand {
-                    span: body.span,
+                    span: source_info.span,
                     user_ty: None,
                     const_: Const::from_bool(tcx, false),
                 }))
@@ -595,7 +596,7 @@ pub(super) fn create_coroutine_drop_shim<'tcx>(
 
     // Update the body's def to become the drop glue.
     let coroutine_instance = body.source.instance;
-    let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None);
+    let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, body.span);
     let drop_instance = InstanceKind::DropGlue(drop_in_place, Some(coroutine_ty));
 
     // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible
@@ -666,7 +667,7 @@ pub(super) fn create_coroutine_drop_shim_async<'tcx>(
     }
 
     // Replace the return variable: Poll<RetT> to Poll<()>
-    let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None));
+    let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, body.span));
     let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()]));
     body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info);
 
@@ -717,7 +718,7 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>(
     let source_info = SourceInfo::outermost(body.span);
 
     // Replace the return variable: Poll<RetT> to Poll<()>
-    let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None));
+    let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, body.span));
     let poll_enum = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()]));
     body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info);
 
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 99b95e7312b..0cf8142a560 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -616,7 +616,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
             place,
             operand,
             &mut |elem, op| match elem {
-                TrackElem::Field(idx) => self.ecx.project_field(op, idx.as_usize()).discard_err(),
+                TrackElem::Field(idx) => self.ecx.project_field(op, idx).discard_err(),
                 TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).discard_err(),
                 TrackElem::Discriminant => {
                     let variant = self.ecx.read_discriminant(op).discard_err()?;
@@ -890,7 +890,8 @@ fn try_write_constant<'tcx>(
 
         ty::Tuple(elem_tys) => {
             for (i, elem) in elem_tys.iter().enumerate() {
-                let Some(field) = map.apply(place, TrackElem::Field(FieldIdx::from_usize(i))) else {
+                let i = FieldIdx::from_usize(i);
+                let Some(field) = map.apply(place, TrackElem::Field(i)) else {
                     throw_machine_stop_str!("missing field in tuple")
                 };
                 let field_dest = ecx.project_field(dest, i)?;
@@ -928,7 +929,7 @@ fn try_write_constant<'tcx>(
                 let Some(field) = map.apply(variant_place, TrackElem::Field(i)) else {
                     throw_machine_stop_str!("missing field in ADT")
                 };
-                let field_dest = ecx.project_field(&variant_dest, i.as_usize())?;
+                let field_dest = ecx.project_field(&variant_dest, i)?;
                 try_write_constant(ecx, &field_dest, field, ty, state, map)?;
             }
             ecx.write_discriminant(variant_idx, dest)?;
diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
index c7feb9e949b..da88e5c698b 100644
--- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
+++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
@@ -128,28 +128,20 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
 
             let mut patch = MirPatch::new(body);
 
-            let (second_discriminant_temp, second_operand) = if opt_data.need_hoist_discriminant {
+            let second_operand = if opt_data.need_hoist_discriminant {
                 // create temp to store second discriminant in, `_s` in example above
                 let second_discriminant_temp =
                     patch.new_temp(opt_data.child_ty, opt_data.child_source.span);
 
-                patch.add_statement(
-                    parent_end,
-                    StatementKind::StorageLive(second_discriminant_temp),
-                );
-
                 // create assignment of discriminant
                 patch.add_assign(
                     parent_end,
                     Place::from(second_discriminant_temp),
                     Rvalue::Discriminant(opt_data.child_place),
                 );
-                (
-                    Some(second_discriminant_temp),
-                    Operand::Move(Place::from(second_discriminant_temp)),
-                )
+                Operand::Move(Place::from(second_discriminant_temp))
             } else {
-                (None, Operand::Copy(opt_data.child_place))
+                Operand::Copy(opt_data.child_place)
             };
 
             // create temp to store inequality comparison between the two discriminants, `_t` in
@@ -157,7 +149,6 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
             let nequal = BinOp::Ne;
             let comp_res_type = nequal.ty(tcx, parent_ty, opt_data.child_ty);
             let comp_temp = patch.new_temp(comp_res_type, opt_data.child_source.span);
-            patch.add_statement(parent_end, StatementKind::StorageLive(comp_temp));
 
             // create inequality comparison
             let comp_rvalue =
@@ -200,23 +191,6 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
                 TerminatorKind::if_(Operand::Move(Place::from(comp_temp)), true_case, false_case),
             );
 
-            if let Some(second_discriminant_temp) = second_discriminant_temp {
-                // generate StorageDead for the second_discriminant_temp not in use anymore
-                patch.add_statement(
-                    parent_end,
-                    StatementKind::StorageDead(second_discriminant_temp),
-                );
-            }
-
-            // Generate a StorageDead for comp_temp in each of the targets, since we moved it into
-            // the switch
-            for bb in [false_case, true_case].iter() {
-                patch.add_statement(
-                    Location { block: *bb, statement_index: 0 },
-                    StatementKind::StorageDead(comp_temp),
-                );
-            }
-
             patch.apply(body);
         }
 
diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs
index c15d7d6f732..3a5e2620b14 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drop.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs
@@ -235,11 +235,8 @@ where
 
         let (fut_ty, drop_fn_def_id, trait_args) = if call_destructor_only {
             // Resolving obj.<AsyncDrop::drop>()
-            let trait_ref = ty::TraitRef::new(
-                tcx,
-                tcx.require_lang_item(LangItem::AsyncDrop, Some(span)),
-                [drop_ty],
-            );
+            let trait_ref =
+                ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::AsyncDrop, span), [drop_ty]);
             let (drop_trait, trait_args) = match tcx.codegen_select_candidate(
                 ty::TypingEnv::fully_monomorphized().as_query_input(trait_ref),
             ) {
@@ -292,7 +289,7 @@ where
             (sig.output(), drop_fn_def_id, trait_args)
         } else {
             // Resolving async_drop_in_place<T> function for drop_ty
-            let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, Some(span));
+            let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, span);
             let trait_args = tcx.mk_args(&[drop_ty.into()]);
             let sig = tcx.fn_sig(drop_fn_def_id).instantiate(tcx, trait_args);
             let sig = tcx.instantiate_bound_regions_with_erased(sig);
@@ -319,7 +316,7 @@ where
         // pin_obj_place preparation
         let pin_obj_new_unchecked_fn = Ty::new_fn_def(
             tcx,
-            tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span)),
+            tcx.require_lang_item(LangItem::PinNewUnchecked, span),
             [GenericArg::from(obj_ref_ty)],
         );
         let pin_obj_ty = pin_obj_new_unchecked_fn.fn_sig(tcx).output().no_bound_vars().unwrap();
@@ -937,7 +934,7 @@ where
     fn destructor_call_block_sync(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> BasicBlock {
         debug!("destructor_call_block_sync({:?}, {:?})", self, succ);
         let tcx = self.tcx();
-        let drop_trait = tcx.require_lang_item(LangItem::Drop, None);
+        let drop_trait = tcx.require_lang_item(LangItem::Drop, DUMMY_SP);
         let drop_fn = tcx.associated_item_def_ids(drop_trait)[0];
         let ty = self.place_ty(self.place);
 
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index a91d46ec406..92c30d239b5 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -438,8 +438,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                         dest.clone()
                     };
                     for (field_index, op) in fields.into_iter().enumerate() {
-                        let field_dest =
-                            self.ecx.project_field(&variant_dest, field_index).discard_err()?;
+                        let field_dest = self
+                            .ecx
+                            .project_field(&variant_dest, FieldIdx::from_usize(field_index))
+                            .discard_err()?;
                         self.ecx.copy_op(op, &field_dest).discard_err()?;
                     }
                     self.ecx
@@ -1583,7 +1585,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             // We needed to check the variant to avoid trying to read the tag
             // field from an enum where no fields have variants, since that tag
             // field isn't in the `Aggregate` from which we're getting values.
-            Some((FieldIdx::from_usize(field_idx), field_layout.ty))
+            Some((field_idx, field_layout.ty))
         } else if let ty::Adt(adt, args) = ty.kind()
             && adt.is_struct()
             && adt.repr().transparent()
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index 31b361ec1a9..48db536c122 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -388,7 +388,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> {
             lhs,
             constant,
             &mut |elem, op| match elem {
-                TrackElem::Field(idx) => self.ecx.project_field(op, idx.as_usize()).discard_err(),
+                TrackElem::Field(idx) => self.ecx.project_field(op, idx).discard_err(),
                 TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).discard_err(),
                 TrackElem::Discriminant => {
                     let variant = self.ecx.read_discriminant(op).discard_err()?;
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index d26e4468715..572ad585c8c 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -7,10 +7,7 @@
 #![feature(file_buffered)]
 #![feature(if_let_guard)]
 #![feature(impl_trait_in_assoc_type)]
-#![feature(map_try_insert)]
-#![feature(never_type)]
 #![feature(try_blocks)]
-#![feature(vec_deque_pop_if)]
 #![feature(yeet_expr)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 9688ac8ed2e..6d45bbc6e16 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -98,7 +98,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
             build_call_shim(tcx, instance, None, CallKind::Direct(def_id))
         }
         ty::InstanceKind::ClosureOnceShim { call_once: _, track_caller: _ } => {
-            let fn_mut = tcx.require_lang_item(LangItem::FnMut, None);
+            let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP);
             let call_mut = tcx
                 .associated_items(fn_mut)
                 .in_definition_order()
diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
index fbc8ee9b06c..fd7b7362cd9 100644
--- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
+++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
@@ -64,7 +64,7 @@ pub(super) fn build_async_drop_shim<'tcx>(
     let needs_async_drop = drop_ty.needs_async_drop(tcx, typing_env);
     let needs_sync_drop = !needs_async_drop && drop_ty.needs_drop(tcx, typing_env);
 
-    let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None));
+    let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP));
     let resume_ty = Ty::new_adt(tcx, resume_adt, ty::List::empty());
 
     let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig(
@@ -220,7 +220,7 @@ fn build_adrop_for_coroutine_shim<'tcx>(
     body.source.instance = instance;
     body.phase = MirPhase::Runtime(RuntimePhase::Initial);
     body.var_debug_info.clear();
-    let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, Some(span)));
+    let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span));
     let args = tcx.mk_args(&[proxy_ref.into()]);
     let pin_proxy_ref = Ty::new_adt(tcx, pin_adt_ref, args);
 
@@ -308,10 +308,10 @@ fn build_adrop_for_adrop_shim<'tcx>(
     let cor_ref = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, impl_ty);
 
     // ret_ty = `Poll<()>`
-    let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None));
+    let poll_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Poll, span));
     let ret_ty = Ty::new_adt(tcx, poll_adt_ref, tcx.mk_args(&[tcx.types.unit.into()]));
     // env_ty = `Pin<&mut proxy_ty>`
-    let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, None));
+    let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span));
     let env_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[proxy_ref.into()]));
     // sig = `fn (Pin<&mut proxy_ty>, &mut Context) -> Poll<()>`
     let sig = tcx.mk_fn_sig(
@@ -376,7 +376,7 @@ fn build_adrop_for_adrop_shim<'tcx>(
     let cor_pin_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[cor_ref.into()]));
     let cor_pin_place = Place::from(locals.push(LocalDecl::new(cor_pin_ty, span)));
 
-    let pin_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, Some(span));
+    let pin_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, span);
     // call Pin<FutTy>::new_unchecked(&mut impl_cor)
     blocks.push(BasicBlockData {
         statements,
@@ -396,7 +396,7 @@ fn build_adrop_for_adrop_shim<'tcx>(
     });
     // When dropping async drop coroutine, we continue its execution:
     // we call impl::poll (impl_layout, ctx)
-    let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, None);
+    let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, span);
     let resume_ctx = Place::from(Local::new(2));
     blocks.push(BasicBlockData {
         statements: vec![],
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index c8aa7588d03..7dcdd7999f2 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -1253,7 +1253,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                             self.tcx,
                             self.tcx.require_lang_item(
                                 LangItem::CoerceUnsized,
-                                Some(self.body.source_info(location).span),
+                                self.body.source_info(location).span,
                             ),
                             [op_ty, *target_type],
                         )) {
@@ -1308,37 +1308,27 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         }
                     }
                     CastKind::Transmute => {
-                        if let MirPhase::Runtime(..) = self.body.phase {
-                            // Unlike `mem::transmute`, a MIR `Transmute` is well-formed
-                            // for any two `Sized` types, just potentially UB to run.
-
-                            if !self
-                                .tcx
-                                .normalize_erasing_regions(self.typing_env, op_ty)
-                                .is_sized(self.tcx, self.typing_env)
-                            {
-                                self.fail(
-                                    location,
-                                    format!("Cannot transmute from non-`Sized` type {op_ty}"),
-                                );
-                            }
-                            if !self
-                                .tcx
-                                .normalize_erasing_regions(self.typing_env, *target_type)
-                                .is_sized(self.tcx, self.typing_env)
-                            {
-                                self.fail(
-                                    location,
-                                    format!("Cannot transmute to non-`Sized` type {target_type:?}"),
-                                );
-                            }
-                        } else {
+                        // Unlike `mem::transmute`, a MIR `Transmute` is well-formed
+                        // for any two `Sized` types, just potentially UB to run.
+
+                        if !self
+                            .tcx
+                            .normalize_erasing_regions(self.typing_env, op_ty)
+                            .is_sized(self.tcx, self.typing_env)
+                        {
                             self.fail(
                                 location,
-                                format!(
-                                    "Transmute is not supported in non-runtime phase {:?}.",
-                                    self.body.phase
-                                ),
+                                format!("Cannot transmute from non-`Sized` type {op_ty}"),
+                            );
+                        }
+                        if !self
+                            .tcx
+                            .normalize_erasing_regions(self.typing_env, *target_type)
+                            .is_sized(self.tcx, self.typing_env)
+                        {
+                            self.fail(
+                                location,
+                                format!("Cannot transmute to non-`Sized` type {target_type:?}"),
                             );
                         }
                     }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 1ee977a5457..173030e0326 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -781,7 +781,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
 
         let tcx = self.tcx;
         let push_mono_lang_item = |this: &mut Self, lang_item: LangItem| {
-            let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, Some(source)));
+            let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, source));
             if tcx.should_codegen_locally(instance) {
                 this.used_items.push(create_fn_mono_item(tcx, instance, source));
             }
@@ -921,7 +921,7 @@ fn visit_instance_use<'tcx>(
             // be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any
             // of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to
             // codegen a call to that function without generating code for the function itself.
-            let def_id = tcx.require_lang_item(LangItem::PanicNounwind, None);
+            let def_id = tcx.require_lang_item(LangItem::PanicNounwind, source);
             let panic_instance = Instance::mono(tcx, def_id);
             if tcx.should_codegen_locally(panic_instance) {
                 output.push(create_fn_mono_item(tcx, panic_instance, source));
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index 5c66017bc61..05683940cba 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -29,7 +29,7 @@ fn custom_coerce_unsize_info<'tcx>(
 ) -> Result<CustomCoerceUnsized, ErrorGuaranteed> {
     let trait_ref = ty::TraitRef::new(
         tcx.tcx,
-        tcx.require_lang_item(LangItem::CoerceUnsized, Some(tcx.span)),
+        tcx.require_lang_item(LangItem::CoerceUnsized, tcx.span),
         [source_ty, target_ty],
     );
 
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index b4169a060d4..49025673bbd 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -461,15 +461,15 @@ fn merge_codegen_units<'tcx>(
 
         for cgu in codegen_units.iter_mut() {
             if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) {
-                if cx.tcx.sess.opts.unstable_opts.human_readable_cgu_names {
-                    cgu.set_name(Symbol::intern(new_cgu_name));
+                let new_cgu_name = if cx.tcx.sess.opts.unstable_opts.human_readable_cgu_names {
+                    Symbol::intern(&CodegenUnit::shorten_name(new_cgu_name))
                 } else {
                     // If we don't require CGU names to be human-readable,
                     // we use a fixed length hash of the composite CGU name
                     // instead.
-                    let new_cgu_name = CodegenUnit::mangle_name(new_cgu_name);
-                    cgu.set_name(Symbol::intern(&new_cgu_name));
-                }
+                    Symbol::intern(&CodegenUnit::mangle_name(new_cgu_name))
+                };
+                cgu.set_name(new_cgu_name);
             }
         }
 
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index a87ae5284b1..cea77533178 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -4,8 +4,9 @@ use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack};
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::solve::{Goal, QueryInput};
 use rustc_type_ir::{
-    self as ty, Canonical, CanonicalTyVarKind, CanonicalVarKind, Flags, InferCtxtLike, Interner,
-    TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
+    self as ty, Canonical, CanonicalParamEnvCacheEntry, CanonicalTyVarKind, CanonicalVarKind,
+    Flags, InferCtxtLike, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    TypeVisitableExt,
 };
 
 use crate::delegate::SolverDelegate;
@@ -100,6 +101,76 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
         Canonical { max_universe, variables, value }
     }
 
+    fn canonicalize_param_env(
+        delegate: &'a D,
+        variables: &'a mut Vec<I::GenericArg>,
+        param_env: I::ParamEnv,
+    ) -> (I::ParamEnv, HashMap<I::GenericArg, usize>, Vec<CanonicalVarKind<I>>) {
+        if !param_env.has_type_flags(NEEDS_CANONICAL) {
+            return (param_env, Default::default(), Vec::new());
+        }
+
+        // Check whether we can use the global cache for this param_env. As we only use
+        // the `param_env` itself as the cache key, considering any additional information
+        // durnig its canonicalization would be incorrect. We always canonicalize region
+        // inference variables in a separate universe, so these are fine. However, we do
+        // track the universe of type and const inference variables so these must not be
+        // globally cached. We don't rely on any additional information when canonicalizing
+        // placeholders.
+        if !param_env.has_non_region_infer() {
+            delegate.cx().canonical_param_env_cache_get_or_insert(
+                param_env,
+                || {
+                    let mut variables = Vec::new();
+                    let mut env_canonicalizer = Canonicalizer {
+                        delegate,
+                        canonicalize_mode: CanonicalizeMode::Input { keep_static: true },
+
+                        variables: &mut variables,
+                        variable_lookup_table: Default::default(),
+                        var_kinds: Vec::new(),
+                        binder_index: ty::INNERMOST,
+
+                        cache: Default::default(),
+                    };
+                    let param_env = param_env.fold_with(&mut env_canonicalizer);
+                    debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST);
+                    CanonicalParamEnvCacheEntry {
+                        param_env,
+                        variable_lookup_table: env_canonicalizer.variable_lookup_table,
+                        var_kinds: env_canonicalizer.var_kinds,
+                        variables,
+                    }
+                },
+                |&CanonicalParamEnvCacheEntry {
+                     param_env,
+                     variables: ref cache_variables,
+                     ref variable_lookup_table,
+                     ref var_kinds,
+                 }| {
+                    debug_assert!(variables.is_empty());
+                    variables.extend(cache_variables.iter().copied());
+                    (param_env, variable_lookup_table.clone(), var_kinds.clone())
+                },
+            )
+        } else {
+            let mut env_canonicalizer = Canonicalizer {
+                delegate,
+                canonicalize_mode: CanonicalizeMode::Input { keep_static: true },
+
+                variables,
+                variable_lookup_table: Default::default(),
+                var_kinds: Vec::new(),
+                binder_index: ty::INNERMOST,
+
+                cache: Default::default(),
+            };
+            let param_env = param_env.fold_with(&mut env_canonicalizer);
+            debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST);
+            (param_env, env_canonicalizer.variable_lookup_table, env_canonicalizer.var_kinds)
+        }
+    }
+
     /// When canonicalizing query inputs, we keep `'static` in the `param_env`
     /// but erase it everywhere else. We generally don't want to depend on region
     /// identity, so while it should not matter whether `'static` is kept in the
@@ -114,37 +185,17 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
         input: QueryInput<I, P>,
     ) -> ty::Canonical<I, QueryInput<I, P>> {
         // First canonicalize the `param_env` while keeping `'static`
-        let mut env_canonicalizer = Canonicalizer {
-            delegate,
-            canonicalize_mode: CanonicalizeMode::Input { keep_static: true },
-
-            variables,
-            variable_lookup_table: Default::default(),
-            var_kinds: Vec::new(),
-            binder_index: ty::INNERMOST,
-
-            cache: Default::default(),
-        };
-
-        let param_env = input.goal.param_env;
-        let param_env = if param_env.has_type_flags(NEEDS_CANONICAL) {
-            param_env.fold_with(&mut env_canonicalizer)
-        } else {
-            param_env
-        };
-
-        debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST);
+        let (param_env, variable_lookup_table, var_kinds) =
+            Canonicalizer::canonicalize_param_env(delegate, variables, input.goal.param_env);
         // Then canonicalize the rest of the input without keeping `'static`
         // while *mostly* reusing the canonicalizer from above.
         let mut rest_canonicalizer = Canonicalizer {
             delegate,
             canonicalize_mode: CanonicalizeMode::Input { keep_static: false },
 
-            variables: env_canonicalizer.variables,
-            // We're able to reuse the `variable_lookup_table` as whether or not
-            // it already contains an entry for `'static` does not matter.
-            variable_lookup_table: env_canonicalizer.variable_lookup_table,
-            var_kinds: env_canonicalizer.var_kinds,
+            variables,
+            variable_lookup_table,
+            var_kinds,
             binder_index: ty::INNERMOST,
 
             // We do not reuse the cache as it may contain entries whose canonicalized
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 38d7ff576a5..345ece20b7e 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -544,8 +544,19 @@ where
                 // to recompute this goal.
                 HasChanged::Yes => None,
                 HasChanged::No => {
-                    // Remove the unconstrained RHS arg, which is expected to have changed.
                     let mut stalled_vars = orig_values;
+
+                    // Remove the canonicalized universal vars, since we only care about stalled existentials.
+                    stalled_vars.retain(|arg| match arg.kind() {
+                        ty::GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Infer(_)),
+                        ty::GenericArgKind::Const(ct) => {
+                            matches!(ct.kind(), ty::ConstKind::Infer(_))
+                        }
+                        // Lifetimes can never stall goals.
+                        ty::GenericArgKind::Lifetime(_) => false,
+                    });
+
+                    // Remove the unconstrained RHS arg, which is expected to have changed.
                     if let Some(normalizes_to) = goal.predicate.as_normalizes_to() {
                         let normalizes_to = normalizes_to.skip_binder();
                         let rhs_arg: I::GenericArg = normalizes_to.term.into();
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 3ab726d9d9d..8ea535599c9 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -9,7 +9,6 @@
 #![feature(debug_closure_helpers)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
-#![feature(string_from_utf8_lossy_owned)]
 #![recursion_limit = "256"]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 6277dde7c97..b49a13ce584 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -2273,9 +2273,9 @@ impl<'a> Parser<'a> {
                     ),
                     // Also catches `fn foo(&a)`.
                     PatKind::Ref(ref inner_pat, mutab)
-                        if matches!(inner_pat.clone().into_inner().kind, PatKind::Ident(..)) =>
+                        if matches!(inner_pat.clone().kind, PatKind::Ident(..)) =>
                     {
-                        match inner_pat.clone().into_inner().kind {
+                        match inner_pat.clone().kind {
                             PatKind::Ident(_, ident, _) => {
                                 let mutab = mutab.prefix_str();
                                 (
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index adfea3641e6..a298c4d4dec 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1119,7 +1119,7 @@ impl<'a> Parser<'a> {
     /// Parse the field access used in offset_of, matched by `$(e:expr)+`.
     /// Currently returns a list of idents. However, it should be possible in
     /// future to also do array indices, which might be arbitrary expressions.
-    fn parse_floating_field_access(&mut self) -> PResult<'a, P<[Ident]>> {
+    fn parse_floating_field_access(&mut self) -> PResult<'a, Vec<Ident>> {
         let mut fields = Vec::new();
         let mut trailing_dot = None;
 
@@ -3468,10 +3468,8 @@ impl<'a> Parser<'a> {
                 // Detect and recover from `($pat if $cond) => $arm`.
                 // FIXME(guard_patterns): convert this to a normal guard instead
                 let span = pat.span;
-                let ast::PatKind::Paren(subpat) = pat.into_inner().kind else { unreachable!() };
-                let ast::PatKind::Guard(_, mut cond) = subpat.into_inner().kind else {
-                    unreachable!()
-                };
+                let ast::PatKind::Paren(subpat) = pat.kind else { unreachable!() };
+                let ast::PatKind::Guard(_, mut cond) = subpat.kind else { unreachable!() };
                 self.psess.gated_spans.ungate_last(sym::guard_patterns, cond.span);
                 CondChecker::new(self, LetChainsPolicy::AlwaysAllowed).visit_expr(&mut cond);
                 let right = self.prev_token.span;
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index c7b0eb11e5a..a325c2a57ab 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -145,7 +145,7 @@ impl<'a> Parser<'a> {
         {
             let mut item = item.expect("an actual item");
             attrs.prepend_to_nt_inner(&mut item.attrs);
-            return Ok(Some(item.into_inner()));
+            return Ok(Some(*item));
         }
 
         self.collect_tokens(None, attrs, force_collect, |this, mut attrs| {
@@ -637,7 +637,7 @@ impl<'a> Parser<'a> {
                     self.dcx().emit_err(errors::MissingForInTraitImpl { span: missing_for_span });
                 }
 
-                let ty_first = ty_first.into_inner();
+                let ty_first = *ty_first;
                 let path = match ty_first.kind {
                     // This notably includes paths passed through `ty` macro fragments (#46438).
                     TyKind::Path(None, path) => path,
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index d6ff80b2eb4..7a226136e23 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -1086,7 +1086,7 @@ impl<'a> Parser<'a> {
         if matches!(pat.kind, PatKind::Ident(BindingMode(ByRef::Yes(_), Mutability::Mut), ..)) {
             self.psess.gated_spans.gate(sym::mut_ref, pat.span);
         }
-        Ok(pat.into_inner().kind)
+        Ok(pat.kind)
     }
 
     /// Turn all by-value immutable bindings in a pattern into mutable bindings.
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 17481731b11..9ddfc179e9b 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -7,6 +7,7 @@ use rustc_ast::{
     Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
     TyKind, UnsafeBinderTy,
 };
+use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{Applicability, Diag, PResult};
 use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym};
 use thin_vec::{ThinVec, thin_vec};
@@ -104,14 +105,17 @@ fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool {
 impl<'a> Parser<'a> {
     /// Parses a type.
     pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
-        self.parse_ty_common(
-            AllowPlus::Yes,
-            AllowCVariadic::No,
-            RecoverQPath::Yes,
-            RecoverReturnSign::Yes,
-            None,
-            RecoverQuestionMark::Yes,
-        )
+        // Make sure deeply nested types don't overflow the stack.
+        ensure_sufficient_stack(|| {
+            self.parse_ty_common(
+                AllowPlus::Yes,
+                AllowCVariadic::No,
+                RecoverQPath::Yes,
+                RecoverReturnSign::Yes,
+                None,
+                RecoverQuestionMark::Yes,
+            )
+        })
     }
 
     pub(super) fn parse_ty_with_generics_recovery(
@@ -404,7 +408,7 @@ impl<'a> Parser<'a> {
         })?;
 
         if ts.len() == 1 && matches!(trailing, Trailing::No) {
-            let ty = ts.into_iter().next().unwrap().into_inner();
+            let ty = ts.into_iter().next().unwrap();
             let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
             match ty.kind {
                 // `(TY_BOUND_NOPAREN) + BOUND + ...`.
@@ -420,7 +424,7 @@ impl<'a> Parser<'a> {
                     self.parse_remaining_bounds(bounds, true)
                 }
                 // `(TYPE)`
-                _ => Ok(TyKind::Paren(P(ty))),
+                _ => Ok(TyKind::Paren(ty)),
             }
         } else {
             Ok(TyKind::Tup(ts))
@@ -1295,7 +1299,7 @@ impl<'a> Parser<'a> {
     ) -> PResult<'a, ()> {
         let fn_path_segment = fn_path.segments.last_mut().unwrap();
         let generic_args = if let Some(p_args) = &fn_path_segment.args {
-            p_args.clone().into_inner()
+            *p_args.clone()
         } else {
             // Normally it wouldn't come here because the upstream should have parsed
             // generic parameters (otherwise it's impossible to call this function).
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 6d815e510ea..a4ef065ea2c 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -56,23 +56,6 @@ passes_autodiff_attr =
 passes_both_ffi_const_and_pure =
     `#[ffi_const]` function cannot be `#[ffi_pure]`
 
-passes_break_inside_closure =
-    `{$name}` inside of a closure
-    .label = cannot `{$name}` inside of a closure
-    .closure_label = enclosing closure
-
-passes_break_inside_coroutine =
-    `{$name}` inside `{$kind}` {$source}
-    .label = cannot `{$name}` inside `{$kind}` {$source}
-    .coroutine_label = enclosing `{$kind}` {$source}
-
-passes_break_non_loop =
-    `break` with value from a `{$kind}` loop
-    .label = can only break with a value inside `loop` or breakable block
-    .label2 = you can't `break` with a value in a `{$kind}` loop
-    .suggestion = use `break` on its own without a value inside this `{$kind}` loop
-    .break_expr_suggestion = alternatively, you might have meant to use the available loop label
-
 passes_cannot_stabilize_deprecated =
     an API can't be stabilized after it is deprecated
     .label = invalid version
@@ -103,10 +86,6 @@ passes_const_stable_not_stable =
     attribute `#[rustc_const_stable]` can only be applied to functions that are declared `#[stable]`
     .label = attribute specified here
 
-passes_continue_labeled_block =
-    `continue` pointing to a labeled block
-    .label = labeled blocks cannot be `continue`'d
-    .block_label = labeled block the `continue` points to
 
 passes_coroutine_on_non_closure =
     attribute should be applied to closures
@@ -509,23 +488,11 @@ passes_must_not_suspend =
 passes_must_use_no_effect =
     `#[must_use]` has no effect when applied to {$article} {$target}
 
-passes_naked_asm_outside_naked_fn =
-    the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
-
-passes_naked_functions_asm_block =
-    naked functions must contain a single `naked_asm!` invocation
-    .label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
-    .label_non_asm = not allowed in naked functions
-
 passes_naked_functions_incompatible_attribute =
     attribute incompatible with `#[unsafe(naked)]`
     .label = the `{$attr}` attribute is incompatible with `#[unsafe(naked)]`
     .naked_attribute = function marked with `#[unsafe(naked)]` here
 
-passes_naked_functions_must_naked_asm =
-    the `asm!` macro is not allowed in naked functions
-    .label = consider using the `naked_asm!` macro instead
-
 passes_no_link =
     attribute should be applied to an `extern crate` item
     .label = not an `extern crate` item
@@ -556,9 +523,6 @@ passes_no_mangle_foreign =
     .note = symbol names in extern blocks are not mangled
     .suggestion = remove this attribute
 
-passes_no_patterns =
-    patterns not allowed in naked function parameters
-
 passes_no_sanitize =
     `#[no_sanitize({$attr_str})]` should be applied to {$accepted_kind}
     .label = not {$accepted_kind}
@@ -589,27 +553,12 @@ passes_optimize_invalid_target =
 passes_outer_crate_level_attr =
     crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
 
-passes_outside_loop =
-    `{$name}` outside of a loop{$is_break ->
-        [true] {" or labeled block"}
-        *[false] {""}
-    }
-    .label = cannot `{$name}` outside of a loop{$is_break ->
-        [true] {" or labeled block"}
-        *[false] {""}
-    }
-
-passes_outside_loop_suggestion = consider labeling this block to be able to break within it
 
 passes_panic_unwind_without_std =
     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
     .help = using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
 
-passes_params_not_allowed =
-    referencing function parameters is not allowed in naked functions
-    .help = follow the calling convention in asm block to use parameters
-
 passes_parent_info =
     {$num ->
       [one] {$descr}
@@ -771,14 +720,6 @@ passes_unknown_lang_item =
     definition of an unknown lang item: `{$name}`
     .label = definition of unknown lang item `{$name}`
 
-passes_unlabeled_cf_in_while_condition =
-    `break` or `continue` with no label in the condition of a `while` loop
-    .label = unlabeled `{$cf_type}` in the condition of a `while` loop
-
-passes_unlabeled_in_labeled_block =
-    unlabeled `{$cf_type}` inside of a labeled block
-    .label = `{$cf_type}` statements that would diverge to or through a labeled block need to bear a label
-
 passes_unnecessary_partial_stable_feature = the feature `{$feature}` has been partially stabilized since {$since} and is succeeded by the feature `{$implies}`
     .suggestion = if you are using features which are still unstable, change to using `{$implies}`
     .suggestion_remove = if you are using features which are now stable, remove this line
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 5b7d45bb152..4e2be8ff0b8 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -132,7 +132,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         target,
                         attrs,
                     ),
-                _ => {
+                Attribute::Parsed(AttributeKind::AllowConstFnUnstable { .. }) => {
+                    self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target)
+                }
+                Attribute::Parsed(AttributeKind::Deprecation { .. }) => {
+                    self.check_deprecated(hir_id, attr, span, target)
+                }
+                Attribute::Parsed(AttributeKind::DocComment { .. }) => { /* `#[doc]` is actually a lot more than just doc comments, so is checked below*/
+                }
+                Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */
+                }
+                Attribute::Parsed(
+                    AttributeKind::BodyStability { .. }
+                    | AttributeKind::ConstStabilityIndirect
+                    | AttributeKind::MacroTransparency(_),
+                ) => { /* do nothing  */ }
+                Attribute::Unparsed(_) => {
                     match attr.path().as_slice() {
                         [sym::diagnostic, sym::do_not_recommend, ..] => {
                             self.check_do_not_recommend(attr.span(), hir_id, target, attr, item)
@@ -169,9 +184,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             self.check_rustc_layout_scalar_valid_range(attr, span, target)
                         }
                         [sym::debugger_visualizer, ..] => self.check_debugger_visualizer(attr, target),
-                        [sym::rustc_allow_const_fn_unstable, ..] => {
-                            self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target)
-                        }
                         [sym::rustc_std_internal_symbol, ..] => {
                             self.check_rustc_std_internal_symbol(attr, span, target)
                         }
@@ -229,7 +241,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         [sym::link_name, ..] => self.check_link_name(hir_id, attr, span, target),
                         [sym::link_section, ..] => self.check_link_section(hir_id, attr, span, target),
                         [sym::no_mangle, ..] => self.check_no_mangle(hir_id, attr, span, target),
-                        [sym::deprecated, ..] => self.check_deprecated(hir_id, attr, span, target),
                         [sym::macro_use, ..] | [sym::macro_escape, ..] => {
                             self.check_macro_use(hir_id, attr, target)
                         }
@@ -283,7 +294,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             | sym::pointee // FIXME(derive_coerce_pointee)
                             | sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
                             | sym::used // handled elsewhere to restrict to static items
-                            | sym::repr // handled elsewhere to restrict to type decls items
                             | sym::instruction_set // broken on stable!!!
                             | sym::windows_subsystem // broken on stable!!!
                             | sym::patchable_function_entry // FIXME(patchable_function_entry)
@@ -1266,13 +1276,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         true
     }
 
-    /// Checks that `doc(test(...))` attribute contains only valid attributes. Returns `true` if
-    /// valid.
-    fn check_test_attr(&self, meta: &MetaItemInner, hir_id: HirId) {
+    /// Checks that `doc(test(...))` attribute contains only valid attributes and are at the right place.
+    fn check_test_attr(&self, attr: &Attribute, meta: &MetaItemInner, hir_id: HirId) {
         if let Some(metas) = meta.meta_item_list() {
             for i_meta in metas {
                 match (i_meta.name(), i_meta.meta_item()) {
-                    (Some(sym::attr | sym::no_crate_inject), _) => {}
+                    (Some(sym::attr), _) => {
+                        // Allowed everywhere like `#[doc]`
+                    }
+                    (Some(sym::no_crate_inject), _) => {
+                        self.check_attr_crate_level(attr, meta, hir_id);
+                    }
                     (_, Some(m)) => {
                         self.tcx.emit_node_span_lint(
                             INVALID_DOC_ATTRIBUTES,
@@ -1359,9 +1373,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         }
 
                         Some(sym::test) => {
-                            if self.check_attr_crate_level(attr, meta, hir_id) {
-                                self.check_test_attr(meta, hir_id);
-                            }
+                            self.check_test_attr(attr, meta, hir_id);
                         }
 
                         Some(
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 6b82252f32c..e597c819a3a 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::DEAD_CODE;
 use rustc_session::lint::{self, LintExpectationId};
-use rustc_span::{Symbol, sym};
+use rustc_span::{Symbol, kw, sym};
 
 use crate::errors::{
     ChangeFields, IgnoredDerivedImpls, MultipleDeadCodes, ParentInfo, UselessAssignment,
@@ -793,6 +793,17 @@ fn check_item<'tcx>(
             // global_asm! is always live.
             worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No));
         }
+        DefKind::Const => {
+            let item = tcx.hir_item(id);
+            if let hir::ItemKind::Const(ident, ..) = item.kind
+                && ident.name == kw::Underscore
+            {
+                // `const _` is always live, as that syntax only exists for the side effects
+                // of type checking and evaluating the constant expression, and marking them
+                // as dead code would defeat that purpose.
+                worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No));
+            }
+        }
         _ => {}
     }
 }
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 00682a9c7a7..74ce92624bd 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1,13 +1,12 @@
 use std::io::Error;
 use std::path::{Path, PathBuf};
 
-use rustc_ast::Label;
 use rustc_errors::codes::*;
 use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level,
     MultiSpan, Subdiagnostic,
 };
-use rustc_hir::{self as hir, ExprKind, Target};
+use rustc_hir::Target;
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::{MainDefinition, Ty};
 use rustc_span::{DUMMY_SP, Span, Symbol};
@@ -1071,176 +1070,6 @@ pub(crate) struct FeaturePreviouslyDeclared<'a> {
     pub prev_declared: &'a str,
 }
 
-pub(crate) struct BreakNonLoop<'a> {
-    pub span: Span,
-    pub head: Option<Span>,
-    pub kind: &'a str,
-    pub suggestion: String,
-    pub loop_label: Option<Label>,
-    pub break_label: Option<Label>,
-    pub break_expr_kind: &'a ExprKind<'a>,
-    pub break_expr_span: Span,
-}
-
-impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> {
-    #[track_caller]
-    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
-        let mut diag = Diag::new(dcx, level, fluent::passes_break_non_loop);
-        diag.span(self.span);
-        diag.code(E0571);
-        diag.arg("kind", self.kind);
-        diag.span_label(self.span, fluent::passes_label);
-        if let Some(head) = self.head {
-            diag.span_label(head, fluent::passes_label2);
-        }
-        diag.span_suggestion(
-            self.span,
-            fluent::passes_suggestion,
-            self.suggestion,
-            Applicability::MaybeIncorrect,
-        );
-        if let (Some(label), None) = (self.loop_label, self.break_label) {
-            match self.break_expr_kind {
-                ExprKind::Path(hir::QPath::Resolved(
-                    None,
-                    hir::Path { segments: [segment], res: hir::def::Res::Err, .. },
-                )) if label.ident.to_string() == format!("'{}", segment.ident) => {
-                    // This error is redundant, we will have already emitted a
-                    // suggestion to use the label when `segment` wasn't found
-                    // (hence the `Res::Err` check).
-                    diag.downgrade_to_delayed_bug();
-                }
-                _ => {
-                    diag.span_suggestion(
-                        self.break_expr_span,
-                        fluent::passes_break_expr_suggestion,
-                        label.ident,
-                        Applicability::MaybeIncorrect,
-                    );
-                }
-            }
-        }
-        diag
-    }
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_continue_labeled_block, code = E0696)]
-pub(crate) struct ContinueLabeledBlock {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    #[label(passes_block_label)]
-    pub block_span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_break_inside_closure, code = E0267)]
-pub(crate) struct BreakInsideClosure<'a> {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    #[label(passes_closure_label)]
-    pub closure_span: Span,
-    pub name: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_break_inside_coroutine, code = E0267)]
-pub(crate) struct BreakInsideCoroutine<'a> {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    #[label(passes_coroutine_label)]
-    pub coroutine_span: Span,
-    pub name: &'a str,
-    pub kind: &'a str,
-    pub source: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_outside_loop, code = E0268)]
-pub(crate) struct OutsideLoop<'a> {
-    #[primary_span]
-    #[label]
-    pub spans: Vec<Span>,
-    pub name: &'a str,
-    pub is_break: bool,
-    #[subdiagnostic]
-    pub suggestion: Option<OutsideLoopSuggestion>,
-}
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(passes_outside_loop_suggestion, applicability = "maybe-incorrect")]
-pub(crate) struct OutsideLoopSuggestion {
-    #[suggestion_part(code = "'block: ")]
-    pub block_span: Span,
-    #[suggestion_part(code = " 'block")]
-    pub break_spans: Vec<Span>,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_unlabeled_in_labeled_block, code = E0695)]
-pub(crate) struct UnlabeledInLabeledBlock<'a> {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    pub cf_type: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_unlabeled_cf_in_while_condition, code = E0590)]
-pub(crate) struct UnlabeledCfInWhileCondition<'a> {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    pub cf_type: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_no_patterns)]
-pub(crate) struct NoPatterns {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_params_not_allowed)]
-#[help]
-pub(crate) struct ParamsNotAllowed {
-    #[primary_span]
-    pub span: Span,
-}
-
-pub(crate) struct NakedFunctionsAsmBlock {
-    pub span: Span,
-    pub multiple_asms: Vec<Span>,
-    pub non_asms: Vec<Span>,
-}
-
-impl<G: EmissionGuarantee> Diagnostic<'_, G> for NakedFunctionsAsmBlock {
-    #[track_caller]
-    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
-        let mut diag = Diag::new(dcx, level, fluent::passes_naked_functions_asm_block);
-        diag.span(self.span);
-        diag.code(E0787);
-        for span in self.multiple_asms.iter() {
-            diag.span_label(*span, fluent::passes_label_multiple_asm);
-        }
-        for span in self.non_asms.iter() {
-            diag.span_label(*span, fluent::passes_label_non_asm);
-        }
-        diag
-    }
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_naked_functions_must_naked_asm, code = E0787)]
-pub(crate) struct NakedFunctionsMustNakedAsm {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-}
-
 #[derive(Diagnostic)]
 #[diag(passes_naked_functions_incompatible_attribute, code = E0736)]
 pub(crate) struct NakedFunctionIncompatibleAttribute {
@@ -1253,13 +1082,6 @@ pub(crate) struct NakedFunctionIncompatibleAttribute {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_asm_outside_naked_fn)]
-pub(crate) struct NakedAsmOutsideNakedFn {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_attr_only_in_functions)]
 pub(crate) struct AttrOnlyInFunctions {
     #[primary_span]
diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index 275714c2d0e..3afed9784de 100644
--- a/compiler/rustc_passes/src/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
@@ -307,18 +307,14 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> {
         self.parent_item = parent_item;
     }
 
-    fn visit_enum_def(&mut self, enum_definition: &'ast ast::EnumDef) {
-        for variant in &enum_definition.variants {
-            self.check_for_lang(
-                Target::Variant,
-                self.resolver.node_id_to_def_id[&variant.id],
-                &variant.attrs,
-                variant.span,
-                None,
-            );
-        }
-
-        visit::walk_enum_def(self, enum_definition);
+    fn visit_variant(&mut self, variant: &'ast ast::Variant) {
+        self.check_for_lang(
+            Target::Variant,
+            self.resolver.node_id_to_def_id[&variant.id],
+            &variant.attrs,
+            variant.span,
+            None,
+        );
     }
 
     fn visit_assoc_item(&mut self, i: &'ast ast::AssocItem, ctxt: visit::AssocCtxt) {
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index f9445485f60..af7ecf0830c 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -8,13 +8,11 @@
 #![allow(internal_features)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
-#![feature(box_patterns)]
 #![feature(map_try_insert)]
 #![feature(rustdoc_internals)]
-#![feature(try_blocks)]
 // tidy-alphabetical-end
 
-use rustc_middle::query::Providers;
+use rustc_middle::util::Providers;
 
 pub mod abi_test;
 mod check_attr;
@@ -31,8 +29,6 @@ mod lang_items;
 pub mod layout_test;
 mod lib_features;
 mod liveness;
-pub mod loops;
-mod naked_functions;
 mod reachable;
 pub mod stability;
 mod upvars;
@@ -48,8 +44,6 @@ pub fn provide(providers: &mut Providers) {
     entry::provide(providers);
     lang_items::provide(providers);
     lib_features::provide(providers);
-    loops::provide(providers);
-    naked_functions::provide(providers);
     liveness::provide(providers);
     reachable::provide(providers);
     stability::provide(providers);
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index d36cb6f0e5b..7fa643d91aa 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -2,7 +2,6 @@
 #![allow(internal_features)]
 #![feature(assert_matches)]
 #![feature(core_intrinsics)]
-#![feature(dropck_eyepatch)]
 #![feature(min_specialization)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index 9b824572b66..2e870c47f8e 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -100,6 +100,21 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
         }
     }
 
+    fn check_use_tree(&mut self, use_tree: &'a ast::UseTree, id: ast::NodeId) {
+        if self.r.effective_visibilities.is_exported(self.r.local_def_id(id)) {
+            self.check_import_as_underscore(use_tree, id);
+            return;
+        }
+
+        if let ast::UseTreeKind::Nested { ref items, .. } = use_tree.kind {
+            if items.is_empty() {
+                self.unused_import(self.base_id).add(id);
+            }
+        } else {
+            self.check_import(id);
+        }
+    }
+
     fn unused_import(&mut self, id: ast::NodeId) -> &mut UnusedImport {
         let use_tree_id = self.base_id;
         let use_tree = self.base_use_tree.unwrap().clone();
@@ -225,13 +240,21 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
 
 impl<'a, 'ra, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
     fn visit_item(&mut self, item: &'a ast::Item) {
-        match item.kind {
+        self.item_span = item.span_with_attributes();
+        match &item.kind {
             // Ignore is_public import statements because there's no way to be sure
             // whether they're used or not. Also ignore imports with a dummy span
             // because this means that they were generated in some fashion by the
             // compiler and we don't need to consider them.
             ast::ItemKind::Use(..) if item.span.is_dummy() => return,
-            ast::ItemKind::ExternCrate(orig_name, ident) => {
+            // Use the base UseTree's NodeId as the item id
+            // This allows the grouping of all the lints in the same item
+            ast::ItemKind::Use(use_tree) => {
+                self.base_id = item.id;
+                self.base_use_tree = Some(use_tree);
+                self.check_use_tree(use_tree, item.id);
+            }
+            &ast::ItemKind::ExternCrate(orig_name, ident) => {
                 self.extern_crate_items.push(ExternCrateToLint {
                     id: item.id,
                     span: item.span,
@@ -245,32 +268,12 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
             _ => {}
         }
 
-        self.item_span = item.span_with_attributes();
         visit::walk_item(self, item);
     }
 
-    fn visit_use_tree(&mut self, use_tree: &'a ast::UseTree, id: ast::NodeId, nested: bool) {
-        // Use the base UseTree's NodeId as the item id
-        // This allows the grouping of all the lints in the same item
-        if !nested {
-            self.base_id = id;
-            self.base_use_tree = Some(use_tree);
-        }
-
-        if self.r.effective_visibilities.is_exported(self.r.local_def_id(id)) {
-            self.check_import_as_underscore(use_tree, id);
-            return;
-        }
-
-        if let ast::UseTreeKind::Nested { ref items, .. } = use_tree.kind {
-            if items.is_empty() {
-                self.unused_import(self.base_id).add(id);
-            }
-        } else {
-            self.check_import(id);
-        }
-
-        visit::walk_use_tree(self, use_tree, id);
+    fn visit_nested_use_tree(&mut self, use_tree: &'a ast::UseTree, id: ast::NodeId) {
+        self.check_use_tree(use_tree, id);
+        visit::walk_use_tree(self, use_tree);
     }
 }
 
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 25485be5622..dc16fe212b1 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -147,7 +147,10 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
                 DefKind::Macro(macro_kind)
             }
             ItemKind::GlobalAsm(..) => DefKind::GlobalAsm,
-            ItemKind::Use(..) => return visit::walk_item(self, i),
+            ItemKind::Use(use_tree) => {
+                self.create_def(i.id, None, DefKind::Use, use_tree.span);
+                return visit::walk_item(self, i);
+            }
             ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {
                 return self.visit_macro_invoc(i.id);
             }
@@ -232,9 +235,9 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
         }
     }
 
-    fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
+    fn visit_nested_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId) {
         self.create_def(id, None, DefKind::Use, use_tree.span);
-        visit::walk_use_tree(self, use_tree, id);
+        visit::walk_use_tree(self, use_tree);
     }
 
     fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 2a4be5fc3b1..3dc285fdab6 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1729,7 +1729,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         if ident.name == kw::StaticLifetime {
             self.record_lifetime_res(
                 lifetime.id,
-                LifetimeRes::Static { suppress_elision_warning: false },
+                LifetimeRes::Static,
                 LifetimeElisionCandidate::Named,
             );
             return;
@@ -1877,8 +1877,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                     if lifetimes_in_scope.is_empty() {
                         self.record_lifetime_res(
                             lifetime.id,
-                            // We are inside a const item, so do not warn.
-                            LifetimeRes::Static { suppress_elision_warning: true },
+                            LifetimeRes::Static,
                             elision_candidate,
                         );
                         return;
@@ -2225,47 +2224,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             panic!("lifetime {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)")
         }
 
-        match candidate {
-            LifetimeElisionCandidate::Missing(missing @ MissingLifetime { .. }) => {
-                debug_assert_eq!(id, missing.id);
-                match res {
-                    LifetimeRes::Static { suppress_elision_warning } => {
-                        if !suppress_elision_warning {
-                            self.r.lint_buffer.buffer_lint(
-                                lint::builtin::ELIDED_NAMED_LIFETIMES,
-                                missing.id_for_lint,
-                                missing.span,
-                                BuiltinLintDiag::ElidedNamedLifetimes {
-                                    elided: (missing.span, missing.kind),
-                                    resolution: lint::ElidedLifetimeResolution::Static,
-                                },
-                            );
-                        }
-                    }
-                    LifetimeRes::Param { param, binder: _ } => {
-                        let tcx = self.r.tcx();
-                        self.r.lint_buffer.buffer_lint(
-                            lint::builtin::ELIDED_NAMED_LIFETIMES,
-                            missing.id_for_lint,
-                            missing.span,
-                            BuiltinLintDiag::ElidedNamedLifetimes {
-                                elided: (missing.span, missing.kind),
-                                resolution: lint::ElidedLifetimeResolution::Param(
-                                    tcx.item_name(param.into()),
-                                    tcx.source_span(param),
-                                ),
-                            },
-                        );
-                    }
-                    LifetimeRes::Fresh { .. }
-                    | LifetimeRes::Infer
-                    | LifetimeRes::Error
-                    | LifetimeRes::ElidedAnchor { .. } => {}
-                }
-            }
-            LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => {}
-        }
-
         match res {
             LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static { .. } => {
                 if let Some(ref mut candidates) = self.lifetime_elision_candidates {
@@ -2788,14 +2746,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 ..
             }) => {
                 self.with_static_rib(def_kind, |this| {
-                    this.with_lifetime_rib(
-                        LifetimeRibKind::Elided(LifetimeRes::Static {
-                            suppress_elision_warning: true,
-                        }),
-                        |this| {
-                            this.visit_ty(ty);
-                        },
-                    );
+                    this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
+                        this.visit_ty(ty);
+                    });
                     if let Some(expr) = expr {
                         // We already forbid generic params because of the above item rib,
                         // so it doesn't matter whether this is a trivial constant.
@@ -2832,9 +2785,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         this.visit_generics(generics);
 
                         this.with_lifetime_rib(
-                            LifetimeRibKind::Elided(LifetimeRes::Static {
-                                suppress_elision_warning: true,
-                            }),
+                            LifetimeRibKind::Elided(LifetimeRes::Static),
                             |this| this.visit_ty(ty),
                         );
 
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 97a45fcf233..2f6aed35f25 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -3440,7 +3440,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                     maybe_static = true;
                     in_scope_lifetimes = vec![(
                         Ident::with_dummy_span(kw::StaticLifetime),
-                        (DUMMY_NODE_ID, LifetimeRes::Static { suppress_elision_warning: false }),
+                        (DUMMY_NODE_ID, LifetimeRes::Static),
                     )];
                 }
             } else if elided_len == 0 {
@@ -3452,7 +3452,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                     maybe_static = true;
                     in_scope_lifetimes = vec![(
                         Ident::with_dummy_span(kw::StaticLifetime),
-                        (DUMMY_NODE_ID, LifetimeRes::Static { suppress_elision_warning: false }),
+                        (DUMMY_NODE_ID, LifetimeRes::Static),
                     )];
                 }
             } else if num_params == 1 {
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
index d2917478e4e..c69991f3fb2 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
@@ -14,7 +14,7 @@ use rustc_middle::ty::{
     TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy,
 };
 use rustc_span::def_id::DefId;
-use rustc_span::sym;
+use rustc_span::{DUMMY_SP, sym};
 use rustc_trait_selection::traits;
 use tracing::{debug, instrument};
 
@@ -414,7 +414,7 @@ pub(crate) fn transform_instance<'tcx>(
                 }
                 ty::Coroutine(..) => match tcx.coroutine_kind(instance.def_id()).unwrap() {
                     hir::CoroutineKind::Coroutine(..) => (
-                        tcx.require_lang_item(LangItem::Coroutine, None),
+                        tcx.require_lang_item(LangItem::Coroutine, DUMMY_SP),
                         Some(instance.args.as_coroutine().resume_ty()),
                     ),
                     hir::CoroutineKind::Desugared(desugaring, _) => {
@@ -423,11 +423,11 @@ pub(crate) fn transform_instance<'tcx>(
                             hir::CoroutineDesugaring::AsyncGen => LangItem::AsyncIterator,
                             hir::CoroutineDesugaring::Gen => LangItem::Iterator,
                         };
-                        (tcx.require_lang_item(lang_item, None), None)
+                        (tcx.require_lang_item(lang_item, DUMMY_SP), None)
                     }
                 },
                 ty::CoroutineClosure(..) => (
-                    tcx.require_lang_item(LangItem::FnOnce, None),
+                    tcx.require_lang_item(LangItem::FnOnce, DUMMY_SP),
                     Some(
                         tcx.instantiate_bound_regions_with_erased(
                             instance.args.as_coroutine_closure().coroutine_closure_sig(),
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index 0e711890e07..def2cc97f06 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -3,7 +3,7 @@
 use std::path::{Path, PathBuf};
 use std::{env, fs};
 
-use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
+use rustc_fs_util::try_canonicalize;
 use rustc_target::spec::Target;
 use smallvec::{SmallVec, smallvec};
 
@@ -87,7 +87,7 @@ fn current_dll_path() -> Result<PathBuf, String> {
                 };
                 let bytes = CStr::from_ptr(fname_ptr).to_bytes();
                 let os = OsStr::from_bytes(bytes);
-                Ok(PathBuf::from(os))
+                try_canonicalize(Path::new(os)).map_err(|e| e.to_string())
             }
 
             #[cfg(target_os = "aix")]
@@ -122,7 +122,7 @@ fn current_dll_path() -> Result<PathBuf, String> {
                     if (data_base..data_end).contains(&addr) {
                         let bytes = CStr::from_ptr(&(*current).ldinfo_filename[0]).to_bytes();
                         let os = OsStr::from_bytes(bytes);
-                        return Ok(PathBuf::from(os));
+                        return try_canonicalize(Path::new(os)).map_err(|e| e.to_string());
                     }
                     if (*current).ldinfo_next == 0 {
                         break;
@@ -169,7 +169,12 @@ fn current_dll_path() -> Result<PathBuf, String> {
 
     filename.truncate(n);
 
-    Ok(OsString::from_wide(&filename).into())
+    let path = try_canonicalize(OsString::from_wide(&filename)).map_err(|e| e.to_string())?;
+
+    // See comments on this target function, but the gist is that
+    // gcc chokes on verbatim paths which fs::canonicalize generates
+    // so we try to avoid those kinds of paths.
+    Ok(rustc_fs_util::fix_windows_verbatim_for_gcc(&path))
 }
 
 #[cfg(target_os = "wasi")]
@@ -177,37 +182,13 @@ fn current_dll_path() -> Result<PathBuf, String> {
     Err("current_dll_path is not supported on WASI".to_string())
 }
 
-pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
-    let target = crate::config::host_tuple();
-    let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = smallvec![get_or_default_sysroot()];
-    let path = current_dll_path().and_then(|s| try_canonicalize(s).map_err(|e| e.to_string()));
-    if let Ok(dll) = path {
-        // use `parent` twice to chop off the file name and then also the
-        // directory containing the dll which should be either `lib` or `bin`.
-        if let Some(path) = dll.parent().and_then(|p| p.parent()) {
-            // The original `path` pointed at the `rustc_driver` crate's dll.
-            // Now that dll should only be in one of two locations. The first is
-            // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
-            // other is the target's libdir, for example
-            // `$sysroot/lib/rustlib/$target/lib/*.dll`.
-            //
-            // We don't know which, so let's assume that if our `path` above
-            // ends in `$target` we *could* be in the target libdir, and always
-            // assume that we may be in the main libdir.
-            sysroot_candidates.push(path.to_owned());
-
-            if path.ends_with(target) {
-                sysroot_candidates.extend(
-                    path.parent() // chop off `$target`
-                        .and_then(|p| p.parent()) // chop off `rustlib`
-                        .and_then(|p| p.parent()) // chop off `lib`
-                        .map(|s| s.to_owned()),
-                );
-            }
-        }
+pub fn sysroot_with_fallback(sysroot: &Path) -> SmallVec<[PathBuf; 2]> {
+    let mut candidates = smallvec![sysroot.to_owned()];
+    let default_sysroot = get_or_default_sysroot();
+    if default_sysroot != sysroot {
+        candidates.push(default_sysroot);
     }
-
-    sysroot_candidates
+    candidates
 }
 
 /// Returns the provided sysroot or calls [`get_or_default_sysroot`] if it's none.
@@ -219,17 +200,8 @@ pub fn materialize_sysroot(maybe_sysroot: Option<PathBuf>) -> PathBuf {
 /// This function checks if sysroot is found using env::args().next(), and if it
 /// is not found, finds sysroot from current rustc_driver dll.
 pub fn get_or_default_sysroot() -> PathBuf {
-    // Follow symlinks. If the resolved path is relative, make it absolute.
-    fn canonicalize(path: PathBuf) -> PathBuf {
-        let path = try_canonicalize(&path).unwrap_or(path);
-        // See comments on this target function, but the gist is that
-        // gcc chokes on verbatim paths which fs::canonicalize generates
-        // so we try to avoid those kinds of paths.
-        fix_windows_verbatim_for_gcc(&path)
-    }
-
     fn default_from_rustc_driver_dll() -> Result<PathBuf, String> {
-        let dll = current_dll_path().map(|s| canonicalize(s))?;
+        let dll = current_dll_path()?;
 
         // `dll` will be in one of the following two:
         // - compiler's libdir: $sysroot/lib/*.dll
@@ -242,7 +214,7 @@ pub fn get_or_default_sysroot() -> PathBuf {
             dll.display()
         ))?;
 
-        // if `dir` points target's dir, move up to the sysroot
+        // if `dir` points to target's dir, move up to the sysroot
         let mut sysroot_dir = if dir.ends_with(crate::config::host_tuple()) {
             dir.parent() // chop off `$target`
                 .and_then(|p| p.parent()) // chop off `rustlib`
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 010ae42c280..6b85e0abc86 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -458,13 +458,9 @@ impl Session {
     /// directories are also returned, for example if `--sysroot` is used but tools are missing
     /// (#125246): we also add the bin directories to the sysroot where rustc is located.
     pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
-        let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_tuple());
-        let fallback_sysroot_paths = filesearch::sysroot_candidates()
+        let search_paths = filesearch::sysroot_with_fallback(&self.sysroot)
             .into_iter()
-            // Ignore sysroot candidate if it was the same as the sysroot path we just used.
-            .filter(|sysroot| *sysroot != self.sysroot)
             .map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_tuple()));
-        let search_paths = std::iter::once(bin_path).chain(fallback_sysroot_paths);
 
         if self_contained {
             // The self-contained tools are expected to be e.g. in `bin/self-contained` in the
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index e950493f135..ed74dea5f1e 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -23,7 +23,6 @@
 #![doc(rust_logo)]
 #![feature(array_windows)]
 #![feature(core_io_borrowed_buf)]
-#![feature(hash_set_entry)]
 #![feature(if_let_guard)]
 #![feature(map_try_insert)]
 #![feature(negative_impls)]
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 4e842a8f93a..d66f98871b9 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -515,8 +515,24 @@ symbols! {
         async_iterator_poll_next,
         async_trait_bounds,
         atomic,
+        atomic_and,
+        atomic_cxchg,
+        atomic_cxchgweak,
+        atomic_fence,
         atomic_load,
+        atomic_max,
+        atomic_min,
         atomic_mod,
+        atomic_nand,
+        atomic_or,
+        atomic_singlethreadfence,
+        atomic_store,
+        atomic_umax,
+        atomic_umin,
+        atomic_xadd,
+        atomic_xchg,
+        atomic_xor,
+        atomic_xsub,
         atomics,
         att_syntax,
         attr,
diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml
index 189b19b0286..0121c752dbd 100644
--- a/compiler/rustc_target/Cargo.toml
+++ b/compiler/rustc_target/Cargo.toml
@@ -20,5 +20,5 @@ tracing = "0.1"
 # tidy-alphabetical-start
 default-features = false
 features = ["elf", "macho"]
-version = "0.36.2"
+version = "0.37.0"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 9f791603c72..e06f881e4b1 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -226,6 +226,7 @@ pub enum InlineAsmArch {
     RiscV64,
     Nvptx64,
     Hexagon,
+    LoongArch32,
     LoongArch64,
     Mips,
     Mips64,
@@ -260,6 +261,7 @@ impl FromStr for InlineAsmArch {
             "powerpc" => Ok(Self::PowerPC),
             "powerpc64" => Ok(Self::PowerPC64),
             "hexagon" => Ok(Self::Hexagon),
+            "loongarch32" => Ok(Self::LoongArch32),
             "loongarch64" => Ok(Self::LoongArch64),
             "mips" | "mips32r6" => Ok(Self::Mips),
             "mips64" | "mips64r6" => Ok(Self::Mips64),
@@ -365,7 +367,9 @@ impl InlineAsmReg {
                 Self::PowerPC(PowerPCInlineAsmReg::parse(name)?)
             }
             InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?),
-            InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmReg::parse(name)?),
+            InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
+                Self::LoongArch(LoongArchInlineAsmReg::parse(name)?)
+            }
             InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
                 Self::Mips(MipsInlineAsmReg::parse(name)?)
             }
@@ -652,7 +656,9 @@ impl InlineAsmRegClass {
                 Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?)
             }
             InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?),
-            InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?),
+            InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
+                Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?)
+            }
             InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
                 Self::Mips(MipsInlineAsmRegClass::parse(name)?)
             }
@@ -860,7 +866,7 @@ pub fn allocatable_registers(
             hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
             map
         }
-        InlineAsmArch::LoongArch64 => {
+        InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
             let mut map = loongarch::regclass_map();
             loongarch::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
             map
@@ -992,7 +998,7 @@ impl InlineAsmClobberAbi {
                 "C" | "system" => Ok(InlineAsmClobberAbi::Avr),
                 _ => Err(&["C", "system"]),
             },
-            InlineAsmArch::LoongArch64 => match name {
+            InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => match name {
                 "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
                 _ => Err(&["C", "system"]),
             },
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index dcb79cce759..f9ecf02f857 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -648,7 +648,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "amdgpu" => amdgpu::compute_abi_info(cx, self),
             "arm" => arm::compute_abi_info(cx, self),
             "avr" => avr::compute_abi_info(self),
-            "loongarch64" => loongarch::compute_abi_info(cx, self),
+            "loongarch32" | "loongarch64" => loongarch::compute_abi_info(cx, self),
             "m68k" => m68k::compute_abi_info(self),
             "csky" => csky::compute_abi_info(self),
             "mips" | "mips32r6" => mips::compute_abi_info(cx, self),
@@ -691,7 +691,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
         match &*spec.arch {
             "x86" => x86::compute_rust_abi_info(cx, self),
             "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self),
-            "loongarch64" => loongarch::compute_rust_abi_info(cx, self),
+            "loongarch32" | "loongarch64" => loongarch::compute_rust_abi_info(cx, self),
             "aarch64" => aarch64::compute_rust_abi_info(cx, self),
             _ => {}
         };
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index 566bee75c7f..91657fef803 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -11,10 +11,8 @@
 #![allow(internal_features)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
-#![feature(assert_matches)]
 #![feature(debug_closure_helpers)]
 #![feature(iter_intersperse)]
-#![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs
index d9101f79f04..c4978a8e52a 100644
--- a/compiler/rustc_target/src/spec/abi_map.rs
+++ b/compiler/rustc_target/src/spec/abi_map.rs
@@ -29,6 +29,7 @@ impl AbiMapping {
         }
     }
 
+    #[track_caller]
     pub fn unwrap(self) -> CanonAbi {
         self.into_option().unwrap()
     }
@@ -115,9 +116,6 @@ impl AbiMap {
             (ExternAbi::Vectorcall { .. }, Arch::X86 | Arch::X86_64) => {
                 CanonAbi::X86(X86Call::Vectorcall)
             }
-            (ExternAbi::Vectorcall { .. }, _) if os == OsKind::Windows => {
-                return AbiMapping::Deprecated(CanonAbi::C);
-            }
             (ExternAbi::Vectorcall { .. }, _) => return AbiMapping::Invalid,
 
             (ExternAbi::SysV64 { .. }, Arch::X86_64) => CanonAbi::X86(X86Call::SysV64),
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index 46fcd7d5c51..aa6d1ec7009 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -124,7 +124,13 @@ pub(crate) fn base(
         // to v4, so we do the same.
         // https://github.com/llvm/llvm-project/blob/378778a0d10c2f8d5df8ceff81f95b6002984a4b/clang/lib/Driver/ToolChains/Darwin.cpp#L1203
         default_dwarf_version: 4,
-        frame_pointer: FramePointer::Always,
+        frame_pointer: match arch {
+            // clang ignores `-fomit-frame-pointer` for Armv7, it only accepts `-momit-leaf-frame-pointer`
+            Armv7k | Armv7s => FramePointer::Always,
+            // clang supports omitting frame pointers for the rest, but... don't?
+            Arm64 | Arm64e | Arm64_32 => FramePointer::NonLeaf,
+            I386 | I686 | X86_64 | X86_64h => FramePointer::Always,
+        },
         has_rpath: true,
         dll_suffix: ".dylib".into(),
         archive_format: "darwin".into(),
diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs
index 54b06d9f9b4..039056a5a25 100644
--- a/compiler/rustc_target/src/spec/json.rs
+++ b/compiler/rustc_target/src/spec/json.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 use std::collections::BTreeMap;
 use std::str::FromStr;
 
-use rustc_abi::ExternAbi;
+use rustc_abi::{Align, AlignFromBytesError, ExternAbi};
 use serde_json::Value;
 
 use super::{Target, TargetKind, TargetOptions, TargetWarnings};
@@ -57,6 +57,14 @@ impl Target {
             base.metadata.std = metadata.remove("std").and_then(|host| host.as_bool());
         }
 
+        let alignment_error = |field_name: &str, error: AlignFromBytesError| -> String {
+            let msg = match error {
+                AlignFromBytesError::NotPowerOfTwo(_) => "not a power of 2 number of bytes",
+                AlignFromBytesError::TooLarge(_) => "too large",
+            };
+            format!("`{}` bits is not a valid value for {field_name}: {msg}", error.align() * 8)
+        };
+
         let mut incorrect_type = vec![];
 
         macro_rules! key {
@@ -111,6 +119,15 @@ impl Target {
                     base.$key_name = Some(s.into());
                 }
             } );
+            ($key_name:ident, Option<Align>) => ( {
+                let name = (stringify!($key_name)).replace("_", "-");
+                if let Some(b) = obj.remove(&name).and_then(|b| b.as_u64()) {
+                    match Align::from_bits(b) {
+                        Ok(align) => base.$key_name = Some(align),
+                        Err(e) => return Err(alignment_error(&name, e)),
+                    }
+                }
+            } );
             ($key_name:ident, BinaryFormat) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.remove(&name).and_then(|f| f.as_str().and_then(|s| {
@@ -617,7 +634,7 @@ impl Target {
         key!(crt_static_default, bool);
         key!(crt_static_respected, bool);
         key!(stack_probes, StackProbeType)?;
-        key!(min_global_align, Option<u64>);
+        key!(min_global_align, Option<Align>);
         key!(default_codegen_units, Option<u64>);
         key!(default_codegen_backend, Option<StaticCow<str>>);
         key!(trap_unreachable, bool);
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 6529c2d72c8..6ceb5e80f21 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -62,7 +62,7 @@ mod abi_map;
 mod base;
 mod json;
 
-pub use abi_map::AbiMap;
+pub use abi_map::{AbiMap, AbiMapping};
 pub use base::apple;
 pub use base::avr::ef_avr_arch;
 
@@ -1697,6 +1697,12 @@ impl ToJson for BinaryFormat {
     }
 }
 
+impl ToJson for Align {
+    fn to_json(&self) -> Json {
+        self.bits().to_json()
+    }
+}
+
 macro_rules! supported_targets {
     ( $(($tuple:literal, $module:ident),)+ ) => {
         mod targets {
@@ -1981,6 +1987,8 @@ supported_targets! {
 
     ("sparc-unknown-none-elf", sparc_unknown_none_elf),
 
+    ("loongarch32-unknown-none", loongarch32_unknown_none),
+    ("loongarch32-unknown-none-softfloat", loongarch32_unknown_none_softfloat),
     ("loongarch64-unknown-none", loongarch64_unknown_none),
     ("loongarch64-unknown-none-softfloat", loongarch64_unknown_none_softfloat),
 
@@ -2513,7 +2521,7 @@ pub struct TargetOptions {
     pub stack_probes: StackProbeType,
 
     /// The minimum alignment for global symbols.
-    pub min_global_align: Option<u64>,
+    pub min_global_align: Option<Align>,
 
     /// Default number of codegen units to use in debug mode
     pub default_codegen_units: Option<u64>,
@@ -3502,6 +3510,7 @@ impl Target {
             "msp430" => (Architecture::Msp430, None),
             "hexagon" => (Architecture::Hexagon, None),
             "bpf" => (Architecture::Bpf, None),
+            "loongarch32" => (Architecture::LoongArch32, None),
             "loongarch64" => (Architecture::LoongArch64, None),
             "csky" => (Architecture::Csky, None),
             "arm64ec" => (Architecture::Aarch64, Some(object::SubArchitecture::Arm64EC)),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs
index 6587abb2ba7..4dd39877715 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, SanitizerSet, Target, TargetMetadata, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("macos", Arch::Arm64, TargetAbi::Normal);
@@ -17,7 +17,6 @@ pub(crate) fn target() -> Target {
         arch,
         options: TargetOptions {
             mcount: "\u{1}mcount".into(),
-            frame_pointer: FramePointer::NonLeaf,
             cpu: "apple-m1".into(),
             max_atomic_width: Some(128),
             // FIXME: The leak sanitizer currently fails the tests, see #88132.
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs
index 183a6c6f2d7..769a7b6c391 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, SanitizerSet, Target, TargetMetadata, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetAbi::Normal);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
-            frame_pointer: FramePointer::NonLeaf,
             supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
             ..opts
         },
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs
index ce9ae03e699..4bb2f73e4f9 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, SanitizerSet, Target, TargetMetadata, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetAbi::MacCatalyst);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a12".into(),
             max_atomic_width: Some(128),
-            frame_pointer: FramePointer::NonLeaf,
             supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD,
             ..opts
         },
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs
index 4405e3fec02..7d04034e759 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, SanitizerSet, Target, TargetMetadata, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetAbi::Simulator);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
-            frame_pointer: FramePointer::NonLeaf,
             supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
             ..opts
         },
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs
index 037685db1b3..ec92a40e255 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, Target, TargetMetadata, TargetOptions};
+use crate::spec::{Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("tvos", Arch::Arm64, TargetAbi::Normal);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
-            frame_pointer: FramePointer::NonLeaf,
             ..opts
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs
index a386220e6fc..74fbe5a89ca 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, Target, TargetMetadata, TargetOptions};
+use crate::spec::{Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("tvos", Arch::Arm64, TargetAbi::Simulator);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
-            frame_pointer: FramePointer::NonLeaf,
             ..opts
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
index 2c1dfdd55ed..dc595fbe7b6 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, SanitizerSet, Target, TargetMetadata, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("visionos", Arch::Arm64, TargetAbi::Normal);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a16".into(),
             max_atomic_width: Some(128),
-            frame_pointer: FramePointer::NonLeaf,
             supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
             ..opts
         },
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
index c0b8b409797..06ff1bfb2f0 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, SanitizerSet, Target, TargetMetadata, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("visionos", Arch::Arm64, TargetAbi::Simulator);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a16".into(),
             max_atomic_width: Some(128),
-            frame_pointer: FramePointer::NonLeaf,
             supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
             ..opts
         },
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs
index 62968f5b555..bad9f6c1485 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, Target, TargetMetadata, TargetOptions};
+use crate::spec::{Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("watchos", Arch::Arm64, TargetAbi::Simulator);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
-            frame_pointer: FramePointer::NonLeaf,
             ..opts
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs
index 79b95dbde52..326f2b16d59 100644
--- a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, SanitizerSet, Target, TargetMetadata, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("macos", Arch::Arm64e, TargetAbi::Normal);
@@ -17,7 +17,6 @@ pub(crate) fn target() -> Target {
         arch,
         options: TargetOptions {
             mcount: "\u{1}mcount".into(),
-            frame_pointer: FramePointer::NonLeaf,
             cpu: "apple-m1".into(),
             max_atomic_width: Some(128),
             // FIXME: The leak sanitizer currently fails the tests, see #88132.
diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs
index 848dbeec199..01c6f0b888d 100644
--- a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, SanitizerSet, Target, TargetMetadata, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("ios", Arch::Arm64e, TargetAbi::Normal);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(),
             max_atomic_width: Some(128),
-            frame_pointer: FramePointer::NonLeaf,
             supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
             ..opts
         },
diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs
index 3dbe169e826..cad3650bda1 100644
--- a/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, Target, TargetMetadata, TargetOptions};
+use crate::spec::{Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("tvos", Arch::Arm64e, TargetAbi::Normal);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(),
             max_atomic_width: Some(128),
-            frame_pointer: FramePointer::NonLeaf,
             ..opts
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
index 161db9a08bb..d1339c57b00 100644
--- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, Target, TargetMetadata, TargetOptions};
+use crate::spec::{Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("macos", Arch::I686, TargetAbi::Normal);
@@ -16,11 +16,6 @@ pub(crate) fn target() -> Target {
             i128:128-f64:32:64-f80:128-n8:16:32-S128"
             .into(),
         arch,
-        options: TargetOptions {
-            mcount: "\u{1}mcount".into(),
-            max_atomic_width: Some(64),
-            frame_pointer: FramePointer::Always,
-            ..opts
-        },
+        options: TargetOptions { mcount: "\u{1}mcount".into(), max_atomic_width: Some(64), ..opts },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs
new file mode 100644
index 00000000000..fb4963b88b0
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs
@@ -0,0 +1,29 @@
+use crate::spec::{
+    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions,
+};
+
+pub(crate) fn target() -> Target {
+    Target {
+        llvm_target: "loongarch32-unknown-none".into(),
+        metadata: TargetMetadata {
+            description: Some("Freestanding/bare-metal LoongArch32".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
+        arch: "loongarch32".into(),
+        options: TargetOptions {
+            cpu: "generic".into(),
+            features: "+f,+d".into(),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
+            llvm_abiname: "ilp32d".into(),
+            max_atomic_width: Some(32),
+            relocation_model: RelocModel::Static,
+            panic_strategy: PanicStrategy::Abort,
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs
new file mode 100644
index 00000000000..0e65f83a71c
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs
@@ -0,0 +1,30 @@
+use crate::spec::{
+    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions,
+};
+
+pub(crate) fn target() -> Target {
+    Target {
+        llvm_target: "loongarch32-unknown-none".into(),
+        metadata: TargetMetadata {
+            description: Some("Freestanding/bare-metal LoongArch32 softfloat".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
+        arch: "loongarch32".into(),
+        options: TargetOptions {
+            cpu: "generic".into(),
+            features: "-f,-d".into(),
+            abi: "softfloat".into(),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
+            llvm_abiname: "ilp32s".into(),
+            max_atomic_width: Some(32),
+            relocation_model: RelocModel::Static,
+            panic_strategy: PanicStrategy::Abort,
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
index e0d16a7bfa5..cdcf7d62a3e 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
@@ -1,4 +1,4 @@
-use rustc_abi::Endian;
+use rustc_abi::{Align, Endian};
 
 use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, base};
 
@@ -8,7 +8,7 @@ pub(crate) fn target() -> Target {
     // z10 is the oldest CPU supported by LLVM
     base.cpu = "z10".into();
     base.max_atomic_width = Some(128);
-    base.min_global_align = Some(16);
+    base.min_global_align = Some(Align::from_bits(16).unwrap());
     base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
index 47050c1f769..e9522ac760e 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
@@ -1,4 +1,4 @@
-use rustc_abi::Endian;
+use rustc_abi::{Align, Endian};
 
 use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, base};
 
@@ -8,7 +8,7 @@ pub(crate) fn target() -> Target {
     // z10 is the oldest CPU supported by LLVM
     base.cpu = "z10".into();
     base.max_atomic_width = Some(128);
-    base.min_global_align = Some(16);
+    base.min_global_align = Some(Align::from_bits(16).unwrap());
     base.static_position_independent_executables = true;
     base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers =
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
index 64c17054780..eba595ba7dd 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
@@ -1,5 +1,5 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, SanitizerSet, Target, TargetMetadata, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (opts, llvm_target, arch) = base("macos", Arch::X86_64, TargetAbi::Normal);
@@ -18,7 +18,6 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             mcount: "\u{1}mcount".into(),
             max_atomic_width: Some(128), // penryn+ supports cmpxchg16b
-            frame_pointer: FramePointer::Always,
             supported_sanitizers: SanitizerSet::ADDRESS
                 | SanitizerSet::CFI
                 | SanitizerSet::LEAK
diff --git a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
index 11010b7d92f..e64556c4132 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
@@ -1,10 +1,9 @@
 use crate::spec::base::apple::{Arch, TargetAbi, base};
-use crate::spec::{FramePointer, SanitizerSet, Target, TargetMetadata, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (mut opts, llvm_target, arch) = base("macos", Arch::X86_64h, TargetAbi::Normal);
     opts.max_atomic_width = Some(128);
-    opts.frame_pointer = FramePointer::Always;
     opts.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
 
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 682c4c5068f..5d1182fce48 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -443,7 +443,7 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("fma", Stable, &["avx"]),
     ("fxsr", Stable, &[]),
     ("gfni", Stable, &["sse2"]),
-    ("kl", Unstable(sym::keylocker_x86), &["sse2"]),
+    ("kl", Stable, &["sse2"]),
     ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
     ("lzcnt", Stable, &[]),
     ("movbe", Stable, &[]),
@@ -455,9 +455,9 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("rdseed", Stable, &[]),
     ("rtm", Unstable(sym::rtm_target_feature), &[]),
     ("sha", Stable, &["sse2"]),
-    ("sha512", Unstable(sym::sha512_sm_x86), &["avx2"]),
-    ("sm3", Unstable(sym::sha512_sm_x86), &["avx"]),
-    ("sm4", Unstable(sym::sha512_sm_x86), &["avx2"]),
+    ("sha512", Stable, &["avx2"]),
+    ("sm3", Stable, &["avx"]),
+    ("sm4", Stable, &["avx2"]),
     // 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), &[]),
@@ -471,7 +471,7 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("tbm", Unstable(sym::tbm_target_feature), &[]),
     ("vaes", Stable, &["avx2", "aes"]),
     ("vpclmulqdq", Stable, &["avx", "pclmulqdq"]),
-    ("widekl", Unstable(sym::keylocker_x86), &["kl"]),
+    ("widekl", Stable, &["kl"]),
     ("x87", Unstable(sym::x87_target_feature), &[]),
     ("xop", Unstable(sym::xop_target_feature), &[/*"fma4", */ "avx", "sse4a"]),
     ("xsave", Stable, &[]),
@@ -846,7 +846,7 @@ impl Target {
             "wasm32" | "wasm64" => WASM_FEATURES,
             "bpf" => BPF_FEATURES,
             "csky" => CSKY_FEATURES,
-            "loongarch64" => LOONGARCH_FEATURES,
+            "loongarch32" | "loongarch64" => LOONGARCH_FEATURES,
             "s390x" => IBMZ_FEATURES,
             "sparc" | "sparc64" => SPARC_FEATURES,
             "m68k" => M68K_FEATURES,
@@ -860,7 +860,7 @@ impl Target {
             "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
-            "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
+            "loongarch32" | "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
@@ -1034,7 +1034,7 @@ impl Target {
                     _ => unreachable!(),
                 }
             }
-            "loongarch64" => {
+            "loongarch32" | "loongarch64" => {
                 // LoongArch handles ABI in a very sane way, being fully explicit via `llvm_abiname`
                 // about what the intended ABI is.
                 match &*self.llvm_abiname {
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 8e2137da655..2c16672d786 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -73,7 +73,7 @@ use rustc_middle::ty::{
     TypeVisitableExt,
 };
 use rustc_span::def_id::LOCAL_CRATE;
-use rustc_span::{BytePos, DesugaringKind, Pos, Span, sym};
+use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, sym};
 use tracing::{debug, instrument};
 
 use crate::error_reporting::TypeErrCtxt;
@@ -194,7 +194,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             _ => return None,
         };
 
-        let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
+        let future_trait = self.tcx.require_lang_item(LangItem::Future, DUMMY_SP);
         let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
 
         self.tcx
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs
index d8b405e904c..8a67e4ccd45 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs
@@ -6,7 +6,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{LangItem, lang_items};
 use rustc_middle::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv};
-use rustc_span::{DesugaringKind, Ident, Span, sym};
+use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, sym};
 use tracing::debug;
 
 use crate::traits::specialization_graph;
@@ -31,9 +31,9 @@ impl CallDesugaringKind {
     pub fn trait_def_id(self, tcx: TyCtxt<'_>) -> DefId {
         match self {
             Self::ForLoopIntoIter => tcx.get_diagnostic_item(sym::IntoIterator).unwrap(),
-            Self::ForLoopNext => tcx.require_lang_item(LangItem::Iterator, None),
+            Self::ForLoopNext => tcx.require_lang_item(LangItem::Iterator, DUMMY_SP),
             Self::QuestionBranch | Self::TryBlockFromOutput => {
-                tcx.require_lang_item(LangItem::Try, None)
+                tcx.require_lang_item(LangItem::Try, DUMMY_SP)
             }
             Self::QuestionFromResidual => tcx.get_diagnostic_item(sym::FromResidual).unwrap(),
             Self::Await => tcx.get_diagnostic_item(sym::IntoFuture).unwrap(),
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 9c301373cf9..68bd9440538 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -955,7 +955,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 return false;
             };
 
-            let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None);
+            let clone_trait = self.tcx.require_lang_item(LangItem::Clone, obligation.cause.span);
             let has_clone = |ty| {
                 self.type_implements_trait(clone_trait, [ty], obligation.param_env)
                     .must_apply_modulo_regions()
@@ -1411,7 +1411,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
         }
 
-        err.span_suggestion(
+        err.span_suggestion_verbose(
             obligation.cause.span.shrink_to_lo(),
             format!(
                 "consider borrowing the value, since `&{self_ty}` can be coerced into `{target_ty}`"
@@ -1574,7 +1574,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     .span_extend_while_whitespace(expr_span)
                     .shrink_to_hi()
                     .to(await_expr.span.shrink_to_hi());
-                err.span_suggestion(
+                err.span_suggestion_verbose(
                     removal_span,
                     "remove the `.await`",
                     "",
@@ -2126,7 +2126,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 ));
 
                 if !assoc_item.is_impl_trait_in_trait() {
-                    err.span_suggestion(
+                    err.span_suggestion_verbose(
                         span,
                         "use the fully qualified path to an implementation",
                         format!(
@@ -2924,12 +2924,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 );
                 let sm = tcx.sess.source_map();
                 if matches!(is_constable, IsConstable::Fn | IsConstable::Ctor)
-                    && let Ok(snip) = sm.span_to_snippet(elt_span)
+                    && let Ok(_) = sm.span_to_snippet(elt_span)
                 {
-                    err.span_suggestion(
-                        elt_span,
+                    err.multipart_suggestion(
                         "create an inline `const` block",
-                        format!("const {{ {snip} }}"),
+                        vec![
+                            (elt_span.shrink_to_lo(), "const { ".to_string()),
+                            (elt_span.shrink_to_hi(), " }".to_string()),
+                        ],
                         Applicability::MachineApplicable,
                     );
                 } else {
@@ -3127,13 +3129,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     }
                 }
                 err.help("change the field's type to have a statically known size");
-                err.span_suggestion(
+                err.span_suggestion_verbose(
                     span.shrink_to_lo(),
                     "borrowed types always have a statically known size",
                     "&",
                     Applicability::MachineApplicable,
                 );
-                err.multipart_suggestion(
+                err.multipart_suggestion_verbose(
                     "the `Box` type always has a statically known size and allocates its contents \
                      in the heap",
                     vec![
@@ -3625,7 +3627,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         trait_pred: ty::PolyTraitPredicate<'tcx>,
         span: Span,
     ) {
-        let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
+        let future_trait = self.tcx.require_lang_item(LangItem::Future, span);
 
         let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
         let impls_future = self.type_implements_trait(
@@ -4141,7 +4143,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         let pred = ty::Binder::dummy(ty::TraitPredicate {
                             trait_ref: ty::TraitRef::new(
                                 tcx,
-                                tcx.require_lang_item(LangItem::Clone, Some(span)),
+                                tcx.require_lang_item(LangItem::Clone, span),
                                 [*ty],
                             ),
                             polarity: ty::PredicatePolarity::Positive,
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 0bea308ed5c..06f81ac554e 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -593,7 +593,7 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
                                         matches!(
                                             arg,
                                             hir::GenericArg::Lifetime(lifetime)
-                                                if lifetime.is_syntactically_hidden()
+                                                if lifetime.is_implicit()
                                         )
                                     }) {
                                         self.suggestions.push((
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index 0dab3adadb0..0118321befb 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -38,7 +38,7 @@ impl<'tcx> InferCtxt<'tcx> {
             return self.tcx.type_is_copy_modulo_regions(self.typing_env(param_env), ty);
         }
 
-        let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, None);
+        let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, DUMMY_SP);
 
         // This can get called from typeck (by euv), and `moves_by_default`
         // rightly refuses to work with inference variables, but
@@ -49,7 +49,7 @@ impl<'tcx> InferCtxt<'tcx> {
 
     fn type_is_clone_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
         let ty = self.resolve_vars_if_possible(ty);
-        let clone_def_id = self.tcx.require_lang_item(LangItem::Clone, None);
+        let clone_def_id = self.tcx.require_lang_item(LangItem::Clone, DUMMY_SP);
         traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, clone_def_id)
     }
 
@@ -59,12 +59,12 @@ impl<'tcx> InferCtxt<'tcx> {
         ty: Ty<'tcx>,
     ) -> bool {
         let ty = self.resolve_vars_if_possible(ty);
-        let use_cloned_def_id = self.tcx.require_lang_item(LangItem::UseCloned, None);
+        let use_cloned_def_id = self.tcx.require_lang_item(LangItem::UseCloned, DUMMY_SP);
         traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, use_cloned_def_id)
     }
 
     fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
-        let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
+        let lang_item = self.tcx.require_lang_item(LangItem::Sized, DUMMY_SP);
         traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item)
     }
 
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 67328defe36..e2b22f7bab7 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -19,14 +19,12 @@
 #![feature(assert_matches)]
 #![feature(associated_type_defaults)]
 #![feature(box_patterns)]
-#![feature(cfg_version)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(iterator_try_reduce)]
 #![feature(never_type)]
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
-#![feature(type_alias_impl_trait)]
 #![feature(unwrap_infallible)]
 #![feature(yeet_expr)]
 #![recursion_limit = "512"] // For rustdoc
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index e92e37b8738..69a0c0809b5 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -64,6 +64,16 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         span: Span,
     ) -> Option<Certainty> {
         if let Some(trait_pred) = goal.predicate.as_trait_clause() {
+            if self.shallow_resolve(trait_pred.self_ty().skip_binder()).is_ty_var()
+                // We don't do this fast path when opaques are defined since we may
+                // eventually use opaques to incompletely guide inference via ty var
+                // self types.
+                // FIXME: Properly consider opaques here.
+                && self.inner.borrow_mut().opaque_types().is_empty()
+            {
+                return Some(Certainty::AMBIGUOUS);
+            }
+
             if trait_pred.polarity() == ty::PredicatePolarity::Positive {
                 match self.0.tcx.as_lang_item(trait_pred.def_id()) {
                     Some(LangItem::Sized)
@@ -115,6 +125,17 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
 
                 Some(Certainty::Yes)
             }
+            ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, .. })
+            | ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
+                if self.shallow_resolve(a).is_ty_var() && self.shallow_resolve(b).is_ty_var() {
+                    // FIXME: We also need to register a subtype relation between these vars
+                    // when those are added, and if they aren't in the same sub root then
+                    // we should mark this goal as `has_changed`.
+                    Some(Certainty::AMBIGUOUS)
+                } else {
+                    None
+                }
+            }
             _ => None,
         }
     }
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
index 1c9d69da322..36a8ae675c0 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
@@ -120,13 +120,15 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>(
                 false,
             ),
             Ok(GoalEvaluation { certainty: Certainty::Yes, .. }) => {
-                bug!(
+                span_bug!(
+                    root_obligation.cause.span,
                     "did not expect successful goal when collecting ambiguity errors for `{:?}`",
                     infcx.resolve_vars_if_possible(root_obligation.predicate),
                 )
             }
             Err(_) => {
-                bug!(
+                span_bug!(
+                    root_obligation.cause.span,
                     "did not expect selection error when collecting ambiguity errors for `{:?}`",
                     infcx.resolve_vars_if_possible(root_obligation.predicate),
                 )
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 1193a9059ca..d5d318ee490 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -133,45 +133,25 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
     /// Instantiate the nested goals for the candidate without rolling back their
     /// inference constraints. This function modifies the state of the `infcx`.
     ///
-    /// See [`Self::instantiate_nested_goals_and_opt_impl_args`] if you need the impl args too.
-    pub fn instantiate_nested_goals(&self, span: Span) -> Vec<InspectGoal<'a, 'tcx>> {
-        self.instantiate_nested_goals_and_opt_impl_args(span).0
-    }
-
-    /// Instantiate the nested goals for the candidate without rolling back their
-    /// inference constraints, and optionally the args of an impl if this candidate
-    /// came from a `CandidateSource::Impl`. This function modifies the state of the
-    /// `infcx`.
+    /// See [`Self::instantiate_impl_args`] if you need the impl args too.
     #[instrument(
         level = "debug",
         skip_all,
         fields(goal = ?self.goal.goal, steps = ?self.steps)
     )]
-    pub fn instantiate_nested_goals_and_opt_impl_args(
-        &self,
-        span: Span,
-    ) -> (Vec<InspectGoal<'a, 'tcx>>, Option<ty::GenericArgsRef<'tcx>>) {
+    pub fn instantiate_nested_goals(&self, span: Span) -> Vec<InspectGoal<'a, 'tcx>> {
         let infcx = self.goal.infcx;
         let param_env = self.goal.goal.param_env;
         let mut orig_values = self.goal.orig_values.to_vec();
 
         let mut instantiated_goals = vec![];
-        let mut opt_impl_args = None;
         for step in &self.steps {
             match **step {
                 inspect::ProbeStep::AddGoal(source, goal) => instantiated_goals.push((
                     source,
                     instantiate_canonical_state(infcx, span, param_env, &mut orig_values, goal),
                 )),
-                inspect::ProbeStep::RecordImplArgs { impl_args } => {
-                    opt_impl_args = Some(instantiate_canonical_state(
-                        infcx,
-                        span,
-                        param_env,
-                        &mut orig_values,
-                        impl_args,
-                    ));
-                }
+                inspect::ProbeStep::RecordImplArgs { .. } => {}
                 inspect::ProbeStep::MakeCanonicalResponse { .. }
                 | inspect::ProbeStep::NestedProbe(_) => unreachable!(),
             }
@@ -187,14 +167,59 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
             let _ = term_hack.constrain(infcx, span, param_env);
         }
 
-        let opt_impl_args = opt_impl_args.map(|impl_args| eager_resolve_vars(infcx, impl_args));
-
-        let goals = instantiated_goals
+        instantiated_goals
             .into_iter()
             .map(|(source, goal)| self.instantiate_proof_tree_for_nested_goal(source, goal, span))
-            .collect();
+            .collect()
+    }
+
+    /// Instantiate the args of an impl if this candidate came from a
+    /// `CandidateSource::Impl`. This function modifies the state of the
+    /// `infcx`.
+    #[instrument(
+        level = "debug",
+        skip_all,
+        fields(goal = ?self.goal.goal, steps = ?self.steps)
+    )]
+    pub fn instantiate_impl_args(&self, span: Span) -> ty::GenericArgsRef<'tcx> {
+        let infcx = self.goal.infcx;
+        let param_env = self.goal.goal.param_env;
+        let mut orig_values = self.goal.orig_values.to_vec();
+
+        for step in &self.steps {
+            match **step {
+                inspect::ProbeStep::RecordImplArgs { impl_args } => {
+                    let impl_args = instantiate_canonical_state(
+                        infcx,
+                        span,
+                        param_env,
+                        &mut orig_values,
+                        impl_args,
+                    );
+
+                    let () = instantiate_canonical_state(
+                        infcx,
+                        span,
+                        param_env,
+                        &mut orig_values,
+                        self.final_state,
+                    );
+
+                    // No reason we couldn't support this, but we don't need to for select.
+                    assert!(
+                        self.goal.normalizes_to_term_hack.is_none(),
+                        "cannot use `instantiate_impl_args` with a `NormalizesTo` goal"
+                    );
+
+                    return eager_resolve_vars(infcx, impl_args);
+                }
+                inspect::ProbeStep::AddGoal(..) => {}
+                inspect::ProbeStep::MakeCanonicalResponse { .. }
+                | inspect::ProbeStep::NestedProbe(_) => unreachable!(),
+            }
+        }
 
-        (goals, opt_impl_args)
+        bug!("expected impl args probe step for `instantiate_impl_args`");
     }
 
     pub fn instantiate_proof_tree_for_nested_goal(
@@ -206,10 +231,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
         let infcx = self.goal.infcx;
         match goal.predicate.kind().no_bound_vars() {
             Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
-                let unconstrained_term = match term.kind() {
-                    ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(),
-                    ty::TermKind::Const(_) => infcx.next_const_var(span).into(),
-                };
+                let unconstrained_term = infcx.next_term_var_of_kind(term, span);
                 let goal =
                     goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term });
                 // We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the
diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs
index d903f94b489..8f44c26b70d 100644
--- a/compiler/rustc_trait_selection/src/solve/normalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalize.rs
@@ -1,4 +1,3 @@
-use std::assert_matches::assert_matches;
 use std::fmt::Debug;
 
 use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -16,7 +15,6 @@ use tracing::instrument;
 use super::{FulfillmentCtxt, NextSolverError};
 use crate::error_reporting::InferCtxtErrorExt;
 use crate::error_reporting::traits::OverflowCause;
-use crate::traits::query::evaluate_obligation::InferCtxtExt;
 use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError};
 
 /// Deeply normalize all aliases in `value`. This does not handle inference and expects
@@ -97,19 +95,18 @@ impl<'tcx, E> NormalizationFolder<'_, 'tcx, E>
 where
     E: FromSolverError<'tcx, NextSolverError<'tcx>>,
 {
-    fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> {
-        assert_matches!(alias_ty.kind(), ty::Alias(..));
-
+    fn normalize_alias_term(
+        &mut self,
+        alias_term: ty::Term<'tcx>,
+    ) -> Result<ty::Term<'tcx>, Vec<E>> {
         let infcx = self.at.infcx;
         let tcx = infcx.tcx;
         let recursion_limit = tcx.recursion_limit();
         if !recursion_limit.value_within_limit(self.depth) {
-            let ty::Alias(_, data) = *alias_ty.kind() else {
-                unreachable!();
-            };
+            let term = alias_term.to_alias_term().unwrap();
 
             self.at.infcx.err_ctxt().report_overflow_error(
-                OverflowCause::DeeplyNormalize(data.into()),
+                OverflowCause::DeeplyNormalize(term),
                 self.at.cause.span,
                 true,
                 |_| {},
@@ -118,14 +115,14 @@ where
 
         self.depth += 1;
 
-        let new_infer_ty = infcx.next_ty_var(self.at.cause.span);
+        let infer_term = infcx.next_term_var_of_kind(alias_term, self.at.cause.span);
         let obligation = Obligation::new(
             tcx,
             self.at.cause.clone(),
             self.at.param_env,
             ty::PredicateKind::AliasRelate(
-                alias_ty.into(),
-                new_infer_ty.into(),
+                alias_term.into(),
+                infer_term.into(),
                 ty::AliasRelationDirection::Equate,
             ),
         );
@@ -135,50 +132,13 @@ where
 
         // Alias is guaranteed to be fully structurally resolved,
         // so we can super fold here.
-        let ty = infcx.resolve_vars_if_possible(new_infer_ty);
-        let result = ty.try_super_fold_with(self)?;
-        self.depth -= 1;
-        Ok(result)
-    }
-
-    fn normalize_unevaluated_const(
-        &mut self,
-        uv: ty::UnevaluatedConst<'tcx>,
-    ) -> Result<ty::Const<'tcx>, Vec<E>> {
-        let infcx = self.at.infcx;
-        let tcx = infcx.tcx;
-        let recursion_limit = tcx.recursion_limit();
-        if !recursion_limit.value_within_limit(self.depth) {
-            self.at.infcx.err_ctxt().report_overflow_error(
-                OverflowCause::DeeplyNormalize(uv.into()),
-                self.at.cause.span,
-                true,
-                |_| {},
-            );
-        }
-
-        self.depth += 1;
-
-        let new_infer_ct = infcx.next_const_var(self.at.cause.span);
-        let obligation = Obligation::new(
-            tcx,
-            self.at.cause.clone(),
-            self.at.param_env,
-            ty::NormalizesTo { alias: uv.into(), term: new_infer_ct.into() },
-        );
-
-        let result = if infcx.predicate_may_hold(&obligation) {
-            self.fulfill_cx.register_predicate_obligation(infcx, obligation);
-            let errors = self.fulfill_cx.select_where_possible(infcx);
-            if !errors.is_empty() {
-                return Err(errors);
-            }
-            let ct = infcx.resolve_vars_if_possible(new_infer_ct);
-            ct.try_fold_with(self)?
-        } else {
-            ty::Const::new_unevaluated(tcx, uv).try_super_fold_with(self)?
+        let term = infcx.resolve_vars_if_possible(infer_term);
+        // super-folding the `term` will directly fold the `Ty` or `Const` so
+        // we have to match on the term and super-fold them manually.
+        let result = match term.kind() {
+            ty::TermKind::Ty(ty) => ty.try_super_fold_with(self)?.into(),
+            ty::TermKind::Const(ct) => ct.try_super_fold_with(self)?.into(),
         };
-
         self.depth -= 1;
         Ok(result)
     }
@@ -238,7 +198,8 @@ where
         if ty.has_escaping_bound_vars() {
             let (ty, mapped_regions, mapped_types, mapped_consts) =
                 BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ty);
-            let result = ensure_sufficient_stack(|| self.normalize_alias_ty(ty))?;
+            let result =
+                ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type();
             Ok(PlaceholderReplacer::replace_placeholders(
                 infcx,
                 mapped_regions,
@@ -248,7 +209,7 @@ where
                 result,
             ))
         } else {
-            ensure_sufficient_stack(|| self.normalize_alias_ty(ty))
+            Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type())
         }
     }
 
@@ -260,15 +221,13 @@ where
             return Ok(ct);
         }
 
-        let uv = match ct.kind() {
-            ty::ConstKind::Unevaluated(ct) => ct,
-            _ => return ct.try_super_fold_with(self),
-        };
+        let ty::ConstKind::Unevaluated(..) = ct.kind() else { return ct.try_super_fold_with(self) };
 
-        if uv.has_escaping_bound_vars() {
-            let (uv, mapped_regions, mapped_types, mapped_consts) =
-                BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, uv);
-            let result = ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv))?;
+        if ct.has_escaping_bound_vars() {
+            let (ct, mapped_regions, mapped_types, mapped_consts) =
+                BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ct);
+            let result =
+                ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const();
             Ok(PlaceholderReplacer::replace_placeholders(
                 infcx,
                 mapped_regions,
@@ -278,7 +237,7 @@ where
                 result,
             ))
         } else {
-            ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv))
+            Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const())
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs
index 21812c8017d..fb1adc2fd2a 100644
--- a/compiler/rustc_trait_selection/src/solve/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/select.rs
@@ -10,6 +10,7 @@ use rustc_infer::traits::{
 use rustc_macros::extension;
 use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
+use thin_vec::thin_vec;
 
 use crate::solve::inspect::{self, ProofTreeInferCtxtExt};
 
@@ -146,18 +147,21 @@ fn to_selection<'tcx>(
         return None;
     }
 
-    let (nested, impl_args) = cand.instantiate_nested_goals_and_opt_impl_args(span);
-    let nested = nested
-        .into_iter()
-        .map(|nested| {
-            Obligation::new(
-                nested.infcx().tcx,
-                ObligationCause::dummy_with_span(span),
-                nested.goal().param_env,
-                nested.goal().predicate,
-            )
-        })
-        .collect();
+    let nested = match cand.result().expect("expected positive result") {
+        Certainty::Yes => thin_vec![],
+        Certainty::Maybe(_) => cand
+            .instantiate_nested_goals(span)
+            .into_iter()
+            .map(|nested| {
+                Obligation::new(
+                    nested.infcx().tcx,
+                    ObligationCause::dummy_with_span(span),
+                    nested.goal().param_env,
+                    nested.goal().predicate,
+                )
+            })
+            .collect(),
+    };
 
     Some(match cand.kind() {
         ProbeKind::TraitCandidate { source, result: _ } => match source {
@@ -166,7 +170,7 @@ fn to_selection<'tcx>(
                 // For impl candidates, we do the rematch manually to compute the args.
                 ImplSource::UserDefined(ImplSourceUserDefinedData {
                     impl_def_id,
-                    args: impl_args.expect("expected recorded impl args for impl candidate"),
+                    args: cand.instantiate_impl_args(span),
                     nested,
                 })
             }
diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs
index cc5861b5a1f..e77d9e32cb9 100644
--- a/compiler/rustc_trait_selection/src/traits/effects.rs
+++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -248,7 +248,7 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>(
     obligation: &HostEffectObligation<'tcx>,
 ) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
     let tcx = selcx.tcx();
-    let destruct_def_id = tcx.require_lang_item(LangItem::Destruct, None);
+    let destruct_def_id = tcx.require_lang_item(LangItem::Destruct, obligation.cause.span);
     let self_ty = obligation.predicate.self_ty();
 
     let const_conditions = match *self_ty.kind() {
@@ -267,7 +267,7 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>(
                 Some(hir::Constness::NotConst) => return Err(EvaluationFailure::NoSolution),
                 // `Drop` impl exists, and it's const. Require `Ty: ~const Drop` to hold.
                 Some(hir::Constness::Const) => {
-                    let drop_def_id = tcx.require_lang_item(LangItem::Drop, None);
+                    let drop_def_id = tcx.require_lang_item(LangItem::Drop, obligation.cause.span);
                     let drop_trait_ref = ty::TraitRef::new(tcx, drop_def_id, [self_ty]);
                     const_conditions.push(drop_trait_ref);
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index a4b6f330b9d..393f458bea2 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -157,7 +157,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
             parent_cause.clone(),
             param_env,
             inner_ty,
-            tcx.require_lang_item(lang_item, Some(parent_cause.span)),
+            tcx.require_lang_item(lang_item, parent_cause.span),
         );
 
         let errors = ocx.select_all_or_error();
@@ -193,7 +193,7 @@ pub fn all_fields_implement_trait<'tcx>(
     parent_cause: ObligationCause<'tcx>,
     lang_item: LangItem,
 ) -> Result<(), Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>> {
-    let trait_def_id = tcx.require_lang_item(lang_item, Some(parent_cause.span));
+    let trait_def_id = tcx.require_lang_item(lang_item, parent_cause.span);
 
     let mut infringing = Vec::new();
     for variant in adt.variants() {
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index ed0f34b5aa9..6dd80551980 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1117,7 +1117,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                                                 selcx.tcx(),
                                                 selcx.tcx().require_lang_item(
                                                     LangItem::Sized,
-                                                    Some(obligation.cause.span),
+                                                    obligation.cause.span,
                                                 ),
                                                 [self_ty],
                                             ),
@@ -1317,7 +1317,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>(
 
     let tcx = selcx.tcx();
 
-    let coroutine_def_id = tcx.require_lang_item(LangItem::Coroutine, None);
+    let coroutine_def_id = tcx.require_lang_item(LangItem::Coroutine, obligation.cause.span);
 
     let (trait_ref, yield_ty, return_ty) = super::util::coroutine_trait_ref_and_outputs(
         tcx,
@@ -1375,7 +1375,7 @@ fn confirm_future_candidate<'cx, 'tcx>(
     debug!(?obligation, ?coroutine_sig, ?obligations, "confirm_future_candidate");
 
     let tcx = selcx.tcx();
-    let fut_def_id = tcx.require_lang_item(LangItem::Future, None);
+    let fut_def_id = tcx.require_lang_item(LangItem::Future, obligation.cause.span);
 
     let (trait_ref, return_ty) = super::util::future_trait_ref_and_outputs(
         tcx,
@@ -1421,7 +1421,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>(
     debug!(?obligation, ?gen_sig, ?obligations, "confirm_iterator_candidate");
 
     let tcx = selcx.tcx();
-    let iter_def_id = tcx.require_lang_item(LangItem::Iterator, None);
+    let iter_def_id = tcx.require_lang_item(LangItem::Iterator, obligation.cause.span);
 
     let (trait_ref, yield_ty) = super::util::iterator_trait_ref_and_outputs(
         tcx,
@@ -1467,7 +1467,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>(
     debug!(?obligation, ?gen_sig, ?obligations, "confirm_async_iterator_candidate");
 
     let tcx = selcx.tcx();
-    let iter_def_id = tcx.require_lang_item(LangItem::AsyncIterator, None);
+    let iter_def_id = tcx.require_lang_item(LangItem::AsyncIterator, obligation.cause.span);
 
     let (trait_ref, yield_ty) = super::util::async_iterator_trait_ref_and_outputs(
         tcx,
@@ -1511,12 +1511,13 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
     let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
     let args = tcx.mk_args(&[self_ty.into()]);
     let (term, obligations) = if tcx.is_lang_item(trait_def_id, LangItem::DiscriminantKind) {
-        let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
+        let discriminant_def_id =
+            tcx.require_lang_item(LangItem::Discriminant, obligation.cause.span);
         assert_eq!(discriminant_def_id, item_def_id);
 
         (self_ty.discriminant_ty(tcx).into(), PredicateObligations::new())
     } else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) {
-        let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
+        let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, obligation.cause.span);
         assert_eq!(metadata_def_id, item_def_id);
 
         let mut obligations = PredicateObligations::new();
@@ -1538,7 +1539,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
                 // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
                 let sized_predicate = ty::TraitRef::new(
                     tcx,
-                    tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span)),
+                    tcx.require_lang_item(LangItem::Sized, obligation.cause.span),
                     [self_ty],
                 );
                 obligations.push(obligation.with(tcx, sized_predicate));
@@ -1620,7 +1621,7 @@ fn confirm_closure_candidate<'cx, 'tcx>(
                     )
                 } else {
                     let upvars_projection_def_id =
-                        tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None);
+                        tcx.require_lang_item(LangItem::AsyncFnKindUpvars, obligation.cause.span);
                     let tupled_upvars_ty = Ty::new_projection(
                         tcx,
                         upvars_projection_def_id,
@@ -1681,8 +1682,9 @@ fn confirm_callable_candidate<'cx, 'tcx>(
 
     debug!(?obligation, ?fn_sig, "confirm_callable_candidate");
 
-    let fn_once_def_id = tcx.require_lang_item(LangItem::FnOnce, None);
-    let fn_once_output_def_id = tcx.require_lang_item(LangItem::FnOnceOutput, None);
+    let fn_once_def_id = tcx.require_lang_item(LangItem::FnOnce, obligation.cause.span);
+    let fn_once_output_def_id =
+        tcx.require_lang_item(LangItem::FnOnceOutput, obligation.cause.span);
 
     let predicate = super::util::closure_trait_ref_and_return_type(
         tcx,
@@ -1740,8 +1742,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
                             args.coroutine_captures_by_ref_ty(),
                         )
                     } else {
-                        let upvars_projection_def_id =
-                            tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None);
+                        let upvars_projection_def_id = tcx
+                            .require_lang_item(LangItem::AsyncFnKindUpvars, obligation.cause.span);
                         // When we don't know the closure kind (and therefore also the closure's upvars,
                         // which are computed at the same time), we must delay the computation of the
                         // generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait
@@ -1798,7 +1800,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
             let term = match item_name {
                 sym::CallOnceFuture | sym::CallRefFuture => sig.output(),
                 sym::Output => {
-                    let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None);
+                    let future_output_def_id =
+                        tcx.require_lang_item(LangItem::FutureOutput, obligation.cause.span);
                     Ty::new_projection(tcx, future_output_def_id, [sig.output()])
                 }
                 name => bug!("no such associated type: {name}"),
@@ -1831,7 +1834,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
             let term = match item_name {
                 sym::CallOnceFuture | sym::CallRefFuture => sig.output(),
                 sym::Output => {
-                    let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None);
+                    let future_output_def_id =
+                        tcx.require_lang_item(LangItem::FutureOutput, obligation.cause.span);
                     Ty::new_projection(tcx, future_output_def_id, [sig.output()])
                 }
                 name => bug!("no such associated type: {name}"),
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index c9169127e0b..7acf0f990d1 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -318,7 +318,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             let make_freeze_obl = |ty| {
                 let trait_ref = ty::TraitRef::new(
                     tcx,
-                    tcx.require_lang_item(LangItem::Freeze, None),
+                    tcx.require_lang_item(LangItem::Freeze, obligation.cause.span),
                     [ty::GenericArg::from(ty)],
                 );
                 Obligation::with_depth(
@@ -657,7 +657,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         );
         let tr = ty::TraitRef::new(
             self.tcx(),
-            self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)),
+            self.tcx().require_lang_item(LangItem::Sized, cause.span),
             [output_ty],
         );
         nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr));
@@ -877,14 +877,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 });
 
                 // We must additionally check that the return type impls `Future + Sized`.
-                let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
+                let future_trait_def_id =
+                    tcx.require_lang_item(LangItem::Future, obligation.cause.span);
                 nested.push(obligation.with(
                     tcx,
                     sig.output().map_bound(|output_ty| {
                         ty::TraitRef::new(tcx, future_trait_def_id, [output_ty])
                     }),
                 ));
-                let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
+                let sized_trait_def_id =
+                    tcx.require_lang_item(LangItem::Sized, obligation.cause.span);
                 nested.push(obligation.with(
                     tcx,
                     sig.output().map_bound(|output_ty| {
@@ -906,13 +908,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 });
 
                 // We must additionally check that the return type impls `Future + Sized`.
-                let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
+                let future_trait_def_id =
+                    tcx.require_lang_item(LangItem::Future, obligation.cause.span);
                 let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
                 nested.push(obligation.with(
                     tcx,
                     ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]),
                 ));
-                let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
+                let sized_trait_def_id =
+                    tcx.require_lang_item(LangItem::Sized, obligation.cause.span);
                 nested.push(obligation.with(
                     tcx,
                     sig.output().map_bound(|output_ty| {
@@ -946,10 +950,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 obligation.param_env,
                 ty::TraitRef::new(
                     self.tcx(),
-                    self.tcx().require_lang_item(
-                        LangItem::AsyncFnKindHelper,
-                        Some(obligation.cause.span),
-                    ),
+                    self.tcx()
+                        .require_lang_item(LangItem::AsyncFnKindHelper, obligation.cause.span),
                     [kind_ty, Ty::from_closure_kind(self.tcx(), goal_kind)],
                 ),
             ));
@@ -1165,7 +1167,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // We can only make objects from sized types.
                 let tr = ty::TraitRef::new(
                     tcx,
-                    tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span)),
+                    tcx.require_lang_item(LangItem::Sized, obligation.cause.span),
                     [source],
                 );
                 nested.push(predicate_to_obligation(tr.upcast(tcx)));
@@ -1359,7 +1361,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     self_ty.map_bound(|ty| {
                         ty::TraitRef::new(
                             tcx,
-                            tcx.require_lang_item(LangItem::Copy, Some(obligation.cause.span)),
+                            tcx.require_lang_item(LangItem::Copy, obligation.cause.span),
                             [ty],
                         )
                     }),
@@ -1411,7 +1413,7 @@ fn pointer_like_goal_for_rpitit<'tcx>(
     ty::Binder::bind_with_vars(
         ty::TraitRef::new(
             tcx,
-            tcx.require_lang_item(LangItem::PointerLike, Some(cause.span)),
+            tcx.require_lang_item(LangItem::PointerLike, cause.span),
             [Ty::new_projection_from_args(tcx, rpitit_item, args)],
         ),
         tcx.mk_bound_variable_kinds(&bound_vars),
diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
index 3f741345404..2e20ede2f50 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
@@ -39,10 +39,7 @@ impl<'tcx> At<'_, 'tcx> {
                 return Ok(term);
             }
 
-            let new_infer = match term.kind() {
-                ty::TermKind::Ty(_) => self.infcx.next_ty_var(self.cause.span).into(),
-                ty::TermKind::Const(_) => self.infcx.next_const_var(self.cause.span).into(),
-            };
+            let new_infer = self.infcx.next_term_var_of_kind(term, self.cause.span);
 
             // We simply emit an `alias-eq` goal here, since that will take care of
             // normalizing the LHS of the projection until it is a rigid projection
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 3018dad8e09..416865e861e 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -541,7 +541,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
             let cause = self.cause(cause);
             let trait_ref = ty::TraitRef::new(
                 self.tcx(),
-                self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)),
+                self.tcx().require_lang_item(LangItem::Sized, cause.span),
                 [subty],
             );
             self.out.push(traits::Obligation::with_depth(
@@ -895,7 +895,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                                 self.tcx(),
                                 self.tcx().require_lang_item(
                                     LangItem::BikeshedGuaranteedNoDrop,
-                                    Some(self.span),
+                                    self.span,
                                 ),
                                 [ty],
                             )
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 83d7416b03e..bb5187e4f5c 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -11,6 +11,7 @@ use rustc_middle::ty::layout::{
 };
 use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt};
 use rustc_session::config::OptLevel;
+use rustc_span::DUMMY_SP;
 use rustc_span::def_id::DefId;
 use rustc_target::callconv::{
     AbiMap, ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, FnAbi, PassMode,
@@ -124,7 +125,7 @@ fn fn_sig_for_fn_abi<'tcx>(
 
             let env_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty);
 
-            let pin_did = tcx.require_lang_item(LangItem::Pin, None);
+            let pin_did = tcx.require_lang_item(LangItem::Pin, DUMMY_SP);
             let pin_adt_ref = tcx.adt_def(pin_did);
             let pin_args = tcx.mk_args(&[env_ty.into()]);
             let env_ty = match coroutine_kind {
@@ -149,7 +150,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                     // The signature should be `Future::poll(_, &mut Context<'_>) -> Poll<Output>`
                     assert_eq!(sig.yield_ty, tcx.types.unit);
 
-                    let poll_did = tcx.require_lang_item(LangItem::Poll, None);
+                    let poll_did = tcx.require_lang_item(LangItem::Poll, DUMMY_SP);
                     let poll_adt_ref = tcx.adt_def(poll_did);
                     let poll_args = tcx.mk_args(&[sig.return_ty.into()]);
                     let ret_ty = Ty::new_adt(tcx, poll_adt_ref, poll_args);
@@ -160,7 +161,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                     {
                         if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() {
                             let expected_adt =
-                                tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None));
+                                tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP));
                             assert_eq!(*resume_ty_adt, expected_adt);
                         } else {
                             panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty);
@@ -172,7 +173,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                 }
                 hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) => {
                     // The signature should be `Iterator::next(_) -> Option<Yield>`
-                    let option_did = tcx.require_lang_item(LangItem::Option, None);
+                    let option_did = tcx.require_lang_item(LangItem::Option, DUMMY_SP);
                     let option_adt_ref = tcx.adt_def(option_did);
                     let option_args = tcx.mk_args(&[sig.yield_ty.into()]);
                     let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args);
@@ -196,7 +197,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                     {
                         if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() {
                             let expected_adt =
-                                tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None));
+                                tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP));
                             assert_eq!(*resume_ty_adt, expected_adt);
                         } else {
                             panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty);
@@ -208,7 +209,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                 }
                 hir::CoroutineKind::Coroutine(_) => {
                     // The signature should be `Coroutine::resume(_, Resume) -> CoroutineState<Yield, Return>`
-                    let state_did = tcx.require_lang_item(LangItem::CoroutineState, None);
+                    let state_did = tcx.require_lang_item(LangItem::CoroutineState, DUMMY_SP);
                     let state_adt_ref = tcx.adt_def(state_did);
                     let state_args = tcx.mk_args(&[sig.yield_ty.into(), sig.return_ty.into()]);
                     let ret_ty = Ty::new_adt(tcx, state_adt_ref, state_args);
diff --git a/compiler/rustc_ty_utils/src/common_traits.rs b/compiler/rustc_ty_utils/src/common_traits.rs
index bb2c4172b08..7219f40710e 100644
--- a/compiler/rustc_ty_utils/src/common_traits.rs
+++ b/compiler/rustc_ty_utils/src/common_traits.rs
@@ -4,6 +4,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::DUMMY_SP;
 use rustc_trait_selection::traits;
 
 fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool {
@@ -42,7 +43,7 @@ fn is_item_raw<'tcx>(
     item: LangItem,
 ) -> bool {
     let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(query.typing_env);
-    let trait_def_id = tcx.require_lang_item(item, None);
+    let trait_def_id = tcx.require_lang_item(item, DUMMY_SP);
     traits::type_known_to_meet_bound_modulo_regions(&infcx, param_env, query.value, trait_def_id)
 }
 
diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs
index 0b4efab1d9c..e900264a76c 100644
--- a/compiler/rustc_ty_utils/src/structural_match.rs
+++ b/compiler/rustc_ty_utils/src/structural_match.rs
@@ -16,8 +16,7 @@ fn has_structural_eq_impl<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool {
 
     let ocx = ObligationCtxt::new(infcx);
     // require `#[derive(PartialEq)]`
-    let structural_peq_def_id =
-        infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span));
+    let structural_peq_def_id = infcx.tcx.require_lang_item(LangItem::StructuralPeq, cause.span);
     ocx.register_bound(cause.clone(), ty::ParamEnv::empty(), adt_ty, structural_peq_def_id);
 
     // We deliberately skip *reporting* fulfillment errors (via
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 330aaa25d13..4dc27622d23 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -104,7 +104,7 @@ fn adt_sized_constraint<'tcx>(
 
     // perf hack: if there is a `constraint_ty: Sized` bound, then we know
     // that the type is sized and do not need to check it on the impl.
-    let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
+    let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, DUMMY_SP);
     let predicates = tcx.predicates_of(def.did()).predicates;
     if predicates.iter().any(|(p, _)| {
         p.as_trait_clause().is_some_and(|trait_pred| {
@@ -319,7 +319,7 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId)
 
     let infcx = tcx.infer_ctxt().ignoring_regions().build(ty::TypingMode::non_body_analysis());
 
-    let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx);
+    let ocx = traits::ObligationCtxt::new(&infcx);
     let cause = traits::ObligationCause::dummy();
     let param_env = tcx.param_env(impl_def_id);
 
diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs
index 2b1b0617cef..c66a83662d7 100644
--- a/compiler/rustc_type_ir/src/canonical.rs
+++ b/compiler/rustc_type_ir/src/canonical.rs
@@ -7,6 +7,7 @@ use derive_where::derive_where;
 use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
 use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
 
+use crate::data_structures::HashMap;
 use crate::inherent::*;
 use crate::{self as ty, Interner, TypingMode, UniverseIndex};
 
@@ -333,3 +334,11 @@ impl<I: Interner> Index<ty::BoundVar> for CanonicalVarValues<I> {
         &self.var_values.as_slice()[value.as_usize()]
     }
 }
+
+#[derive_where(Clone, Debug; I: Interner)]
+pub struct CanonicalParamEnvCacheEntry<I: Interner> {
+    pub param_env: I::ParamEnv,
+    pub variables: Vec<I::GenericArg>,
+    pub variable_lookup_table: HashMap<I::GenericArg, usize>,
+    pub var_kinds: Vec<CanonicalVarKind<I>>,
+}
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 05ca6f10323..9cbbb74f63e 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -12,7 +12,7 @@ use crate::lang_items::TraitSolverLangItem;
 use crate::relate::Relate;
 use crate::solve::{CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult};
 use crate::visit::{Flags, TypeVisitable};
-use crate::{self as ty, search_graph};
+use crate::{self as ty, CanonicalParamEnvCacheEntry, search_graph};
 
 #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_interner")]
 pub trait Interner:
@@ -149,6 +149,13 @@ pub trait Interner:
 
     fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R;
 
+    fn canonical_param_env_cache_get_or_insert<R>(
+        self,
+        param_env: Self::ParamEnv,
+        f: impl FnOnce() -> CanonicalParamEnvCacheEntry<Self>,
+        from_entry: impl FnOnce(&CanonicalParamEnvCacheEntry<Self>) -> R,
+    ) -> R;
+
     fn evaluation_is_concurrent(&self) -> bool;
 
     fn expand_abstract_consts<T: TypeFoldable<Self>>(self, t: T) -> T;
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 0c75977ee79..966ae72dc2a 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -62,11 +62,9 @@ dependencies = [
 [[package]]
 name = "compiler_builtins"
 version = "0.1.160"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6376049cfa92c0aa8b9ac95fae22184b981c658208d4ed8a1dc553cd83612895"
 dependencies = [
  "cc",
- "rustc-std-workspace-core",
+ "core",
 ]
 
 [[package]]
@@ -304,6 +302,7 @@ dependencies = [
 name = "rustc-std-workspace-core"
 version = "1.99.0"
 dependencies = [
+ "compiler_builtins",
  "core",
 ]
 
diff --git a/library/Cargo.toml b/library/Cargo.toml
index 026ba147008..35480b9319d 100644
--- a/library/Cargo.toml
+++ b/library/Cargo.toml
@@ -50,3 +50,4 @@ rustc-demangle.opt-level = "s"
 rustc-std-workspace-core = { path = 'rustc-std-workspace-core' }
 rustc-std-workspace-alloc = { path = 'rustc-std-workspace-alloc' }
 rustc-std-workspace-std = { path = 'rustc-std-workspace-std' }
+compiler_builtins = { path = "compiler-builtins/compiler-builtins" }
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 31b6014af7c..017c790ecac 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -16,7 +16,7 @@ bench = false
 
 [dependencies]
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.160", features = ['rustc-dep-of-std'] }
+compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features = ["rustc-dep-of-std"] }
 
 [features]
 compiler-builtins-mem = ['compiler_builtins/mem']
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 30540f48aa1..f416732a8d6 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -131,7 +131,6 @@
 #![feature(local_waker)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_uninit_array_transpose)]
-#![feature(nonnull_provenance)]
 #![feature(panic_internals)]
 #![feature(pattern)]
 #![feature(pin_coerce_unsized_trait)]
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index b49b3f41a76..b4da56578c8 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -493,8 +493,6 @@ impl<T> [T] {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```
     /// assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
     /// ```
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index f1b1734b8b2..22cdd8ecde0 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -246,8 +246,6 @@ impl str {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```
     /// let s = "this is old";
     ///
@@ -303,8 +301,6 @@ impl str {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```
     /// let s = "foo foo 123 foo";
     /// assert_eq!("new new 123 foo", s.replacen("foo", "new", 2));
diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs
index 56e60ed4c84..3241b4b0045 100644
--- a/library/alloctests/lib.rs
+++ b/library/alloctests/lib.rs
@@ -28,7 +28,6 @@
 #![feature(iter_next_chunk)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_uninit_array_transpose)]
-#![feature(nonnull_provenance)]
 #![feature(ptr_alignment_type)]
 #![feature(ptr_internals)]
 #![feature(sized_type_properties)]
diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml
index d13dd6b0f64..95b0962b082 100644
--- a/library/compiler-builtins/.github/workflows/main.yaml
+++ b/library/compiler-builtins/.github/workflows/main.yaml
@@ -5,7 +5,7 @@ on:
 
 concurrency:
   # Make sure that new pushes cancel running jobs
-  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
   cancel-in-progress: true
 
 env:
@@ -13,7 +13,7 @@ env:
   RUSTDOCFLAGS: -Dwarnings
   RUSTFLAGS: -Dwarnings
   RUST_BACKTRACE: full
-  BENCHMARK_RUSTC: nightly-2025-01-16 # Pin the toolchain for reproducable results
+  BENCHMARK_RUSTC: nightly-2025-05-28 # Pin the toolchain for reproducable results
 
 jobs:
   # Determine which tests should be run based on changed files.
@@ -108,8 +108,6 @@ jobs:
     - name: Print runner information
       run: uname -a
     - uses: actions/checkout@v4
-      with:
-        submodules: true
     - name: Install Rust (rustup)
       shell: bash
       run: |
@@ -119,7 +117,6 @@ jobs:
         rustup update "$channel" --no-self-update
         rustup default "$channel"
         rustup target add "${{ matrix.target }}"
-        rustup component add llvm-tools-preview
     - uses: taiki-e/install-action@nextest
     - uses: Swatinem/rust-cache@v2
       with:
@@ -147,6 +144,10 @@ jobs:
       shell: bash
     - run: echo "RUST_COMPILER_RT_ROOT=$(realpath ./compiler-rt)" >> "$GITHUB_ENV"
       shell: bash
+      
+    - name: Download musl source
+      run: ./ci/update-musl.sh
+      shell: bash
 
     - name: Verify API list
       if: matrix.os == 'ubuntu-24.04'
@@ -183,8 +184,6 @@ jobs:
     timeout-minutes: 10
     steps:
     - uses: actions/checkout@v4
-      with:
-        submodules: true
     # Unlike rustfmt, stable clippy does not work on code with nightly features.
     - name: Install nightly `clippy`
       run: |
@@ -192,16 +191,22 @@ jobs:
         rustup default nightly
         rustup component add clippy
     - uses: Swatinem/rust-cache@v2
+    - name: Download musl source
+      run: ./ci/update-musl.sh
     - run: cargo clippy --workspace --all-targets
 
   benchmarks:
     name: Benchmarks
-    runs-on: ubuntu-24.04
     timeout-minutes: 20
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+        - target: x86_64-unknown-linux-gnu
+          os: ubuntu-24.04
+    runs-on: ${{ matrix.os }}
     steps:
     - uses: actions/checkout@master
-      with:
-        submodules: true
     - uses: taiki-e/install-action@cargo-binstall
 
     - name: Set up dependencies
@@ -216,12 +221,16 @@ jobs:
         cargo binstall -y iai-callgrind-runner --version "$iai_version"
         sudo apt-get install valgrind
     - uses: Swatinem/rust-cache@v2
+      with:
+        key: ${{ matrix.target }}
+    - name: Download musl source
+      run: ./ci/update-musl.sh
 
     - name: Run icount benchmarks
       env:
         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         PR_NUMBER: ${{ github.event.pull_request.number }}
-      run: ./ci/bench-icount.sh
+      run: ./ci/bench-icount.sh ${{ matrix.target }}
 
     - name: Upload the benchmark baseline
       uses: actions/upload-artifact@v4
@@ -249,8 +258,6 @@ jobs:
     timeout-minutes: 10
     steps:
     - uses: actions/checkout@v4
-      with:
-        submodules: true
     - name: Install Rust (rustup)
       run: rustup update nightly --no-self-update && rustup default nightly
       shell: bash
@@ -285,8 +292,6 @@ jobs:
     timeout-minutes: 10
     steps:
     - uses: actions/checkout@v4
-      with:
-        submodules: true
     - name: Install stable `rustfmt`
       run: rustup set profile minimal && rustup default stable && rustup component add rustfmt
     - run: cargo fmt -- --check
@@ -310,13 +315,13 @@ jobs:
       TO_TEST: ${{ matrix.to_test }}
     steps:
       - uses: actions/checkout@v4
-        with:
-          submodules: true
       - name: Install Rust
         run: |
           rustup update nightly --no-self-update
           rustup default nightly
       - uses: Swatinem/rust-cache@v2
+      - name: download musl source
+        run: ./ci/update-musl.sh
       - name: Run extensive tests
         run: ./ci/run-extensive.sh
       - name: Print test logs if available
diff --git a/library/compiler-builtins/.gitignore b/library/compiler-builtins/.gitignore
index 5287a6c72be..f12b871c2f7 100644
--- a/library/compiler-builtins/.gitignore
+++ b/library/compiler-builtins/.gitignore
@@ -14,3 +14,6 @@ iai-home
 *.bk
 *.rs.bk
 .#*
+
+# Manually managed
+crates/musl-math-sys/musl
diff --git a/library/compiler-builtins/.gitmodules b/library/compiler-builtins/.gitmodules
deleted file mode 100644
index 792ed9ab21f..00000000000
--- a/library/compiler-builtins/.gitmodules
+++ /dev/null
@@ -1,4 +0,0 @@
-[submodule "crates/musl-math-sys/musl"]
-	path = crates/musl-math-sys/musl
-	url = https://git.musl-libc.org/git/musl
-	shallow = true
diff --git a/library/compiler-builtins/Cargo.toml b/library/compiler-builtins/Cargo.toml
index b39ec8a25da..fb638f2fb37 100644
--- a/library/compiler-builtins/Cargo.toml
+++ b/library/compiler-builtins/Cargo.toml
@@ -3,9 +3,11 @@ resolver = "2"
 members = [
     "builtins-test",
     "compiler-builtins",
+    "crates/josh-sync",
     "crates/libm-macros",
     "crates/musl-math-sys",
     "crates/panic-handler",
+    "crates/symbol-check",
     "crates/util",
     "libm",
     "libm-test",
diff --git a/library/compiler-builtins/README.md b/library/compiler-builtins/README.md
index 3130ff7b77d..177bce624e0 100644
--- a/library/compiler-builtins/README.md
+++ b/library/compiler-builtins/README.md
@@ -5,7 +5,7 @@ This repository contains two main crates:
 * `compiler-builtins`: symbols that the compiler expects to be available at
   link time
 * `libm`: a Rust implementation of C math libraries, used to provide
-  implementations in `ocre`.
+  implementations in `core`.
 
 More details are at [compiler-builtins/README.md](compiler-builtins/README.md)
 and [libm/README.md](libm/README.md).
diff --git a/library/compiler-builtins/builtins-test-intrinsics/Cargo.toml b/library/compiler-builtins/builtins-test-intrinsics/Cargo.toml
index 6e10628a41b..064b7cad2f6 100644
--- a/library/compiler-builtins/builtins-test-intrinsics/Cargo.toml
+++ b/library/compiler-builtins/builtins-test-intrinsics/Cargo.toml
@@ -1,12 +1,12 @@
 [package]
 name = "builtins-test-intrinsics"
 version = "0.1.0"
-edition = "2021"
+edition = "2024"
 publish = false
 license = "MIT OR Apache-2.0"
 
 [dependencies]
-compiler_builtins = { path = "../compiler-builtins", features = ["compiler-builtins"]}
+compiler_builtins = { path = "../compiler-builtins", features = ["compiler-builtins"] }
 panic-handler = { path = "../crates/panic-handler" }
 
 [features]
diff --git a/library/compiler-builtins/builtins-test-intrinsics/src/main.rs b/library/compiler-builtins/builtins-test-intrinsics/src/main.rs
index 1fa7b00916f..66744a0817f 100644
--- a/library/compiler-builtins/builtins-test-intrinsics/src/main.rs
+++ b/library/compiler-builtins/builtins-test-intrinsics/src/main.rs
@@ -13,11 +13,14 @@
 #![no_std]
 #![no_main]
 
+// Ensure this `compiler_builtins` gets used, rather than the version injected from the sysroot.
+extern crate compiler_builtins;
 extern crate panic_handler;
 
+// SAFETY: no definitions, only used for linking
 #[cfg(all(not(thumb), not(windows), not(target_arch = "wasm32")))]
 #[link(name = "c")]
-extern "C" {}
+unsafe extern "C" {}
 
 // Every function in this module maps will be lowered to an intrinsic by LLVM, if the platform
 // doesn't have native support for the operation used in the function. ARM has a naming convention
@@ -651,22 +654,23 @@ fn something_with_a_dtor(f: &dyn Fn()) {
 
 #[unsafe(no_mangle)]
 #[cfg(not(thumb))]
-fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
+extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
     run();
     0
 }
 
 #[unsafe(no_mangle)]
 #[cfg(thumb)]
-pub fn _start() -> ! {
+extern "C" fn _start() -> ! {
     run();
     loop {}
 }
 
+// SAFETY: no definitions, only used for linking
 #[cfg(windows)]
 #[link(name = "kernel32")]
 #[link(name = "msvcrt")]
-extern "C" {}
+unsafe extern "C" {}
 
 // ARM targets need these symbols
 #[unsafe(no_mangle)]
diff --git a/library/compiler-builtins/builtins-test/Cargo.toml b/library/compiler-builtins/builtins-test/Cargo.toml
index 10978c0bb7e..c7742aa2427 100644
--- a/library/compiler-builtins/builtins-test/Cargo.toml
+++ b/library/compiler-builtins/builtins-test/Cargo.toml
@@ -10,11 +10,11 @@ license = "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)"
 # For fuzzing tests we want a deterministic seedable RNG. We also eliminate potential
 # problems with system RNGs on the variety of platforms this crate is tested on.
 # `xoshiro128**` is used for its quality, size, and speed at generating `u32` shift amounts.
-rand_xoshiro = "0.6"
+rand_xoshiro = "0.7"
 # To compare float builtins against
-rustc_apfloat = "0.2.1"
+rustc_apfloat = "0.2.2"
 # Really a dev dependency, but dev dependencies can't be optional
-iai-callgrind = { version = "0.14.0", optional = true }
+iai-callgrind = { version = "0.14.1", optional = true }
 
 [dependencies.compiler_builtins]
 path = "../compiler-builtins"
@@ -22,7 +22,7 @@ default-features = false
 features = ["unstable-public-internals"]
 
 [dev-dependencies]
-criterion = { version = "0.5.1", default-features = false, features = ["cargo_bench_support"] }
+criterion = { version = "0.6.0", default-features = false, features = ["cargo_bench_support"] }
 paste = "1.0.15"
 
 [target.'cfg(all(target_arch = "arm", not(any(target_env = "gnu", target_env = "musl")), target_os = "linux"))'.dev-dependencies]
diff --git a/library/compiler-builtins/builtins-test/benches/float_cmp.rs b/library/compiler-builtins/builtins-test/benches/float_cmp.rs
index 42d6652397d..87a89efb5a4 100644
--- a/library/compiler-builtins/builtins-test/benches/float_cmp.rs
+++ b/library/compiler-builtins/builtins-test/benches/float_cmp.rs
@@ -1,12 +1,23 @@
 #![cfg_attr(f128_enabled, feature(f128))]
 
 use builtins_test::float_bench;
-use compiler_builtins::float::cmp;
+use compiler_builtins::float::cmp::{self, CmpResult};
 use criterion::{Criterion, criterion_main};
 
 /// `gt` symbols are allowed to return differing results, they just get compared
 /// to 0.
-fn gt_res_eq(a: i32, b: i32) -> bool {
+fn gt_res_eq(mut a: CmpResult, mut b: CmpResult) -> bool {
+    // FIXME: Our CmpResult used to be `i32`, but GCC/LLVM expect `isize`. on 64-bit platforms,
+    // this means the top half of the word may be garbage if built with an old version of
+    // `compiler-builtins`, so add a hack around this.
+    //
+    // This can be removed once a version of `compiler-builtins` with the return type fix makes
+    // it upstream.
+    if size_of::<CmpResult>() == 8 {
+        a = a as i32 as CmpResult;
+        b = b as i32 as CmpResult;
+    }
+
     let a_lt_0 = a <= 0;
     let b_lt_0 = b <= 0;
     (a_lt_0 && b_lt_0) || (!a_lt_0 && !b_lt_0)
@@ -14,14 +25,14 @@ fn gt_res_eq(a: i32, b: i32) -> bool {
 
 float_bench! {
     name: cmp_f32_gt,
-    sig: (a: f32, b: f32) -> i32,
+    sig: (a: f32, b: f32) -> CmpResult,
     crate_fn: cmp::__gtsf2,
     sys_fn: __gtsf2,
     sys_available: all(),
     output_eq: gt_res_eq,
     asm: [
         #[cfg(target_arch = "x86_64")] {
-            let ret: i32;
+            let ret: CmpResult;
             asm!(
                 "xor     {ret:e}, {ret:e}",
                 "ucomiss {a}, {b}",
@@ -36,7 +47,7 @@ float_bench! {
         };
 
         #[cfg(target_arch = "aarch64")] {
-            let ret: i32;
+            let ret: CmpResult;
             asm!(
                 "fcmp    {a:s}, {b:s}",
                 "cset    {ret:w}, gt",
@@ -53,13 +64,13 @@ float_bench! {
 
 float_bench! {
     name: cmp_f32_unord,
-    sig: (a: f32, b: f32) -> i32,
+    sig: (a: f32, b: f32) -> CmpResult,
     crate_fn: cmp::__unordsf2,
     sys_fn: __unordsf2,
     sys_available: all(),
     asm: [
         #[cfg(target_arch = "x86_64")] {
-            let ret: i32;
+            let ret: CmpResult;
             asm!(
                 "xor     {ret:e}, {ret:e}",
                 "ucomiss {a}, {b}",
@@ -74,7 +85,7 @@ float_bench! {
         };
 
         #[cfg(target_arch = "aarch64")] {
-            let ret: i32;
+            let ret: CmpResult;
             asm!(
                 "fcmp    {a:s}, {b:s}",
                 "cset    {ret:w}, vs",
@@ -91,14 +102,14 @@ float_bench! {
 
 float_bench! {
     name: cmp_f64_gt,
-    sig: (a: f64, b: f64) -> i32,
+    sig: (a: f64, b: f64) -> CmpResult,
     crate_fn: cmp::__gtdf2,
     sys_fn: __gtdf2,
     sys_available: all(),
     output_eq: gt_res_eq,
     asm: [
         #[cfg(target_arch = "x86_64")] {
-            let ret: i32;
+            let ret: CmpResult;
             asm!(
                 "xor     {ret:e}, {ret:e}",
                 "ucomisd {a}, {b}",
@@ -113,7 +124,7 @@ float_bench! {
         };
 
         #[cfg(target_arch = "aarch64")] {
-            let ret: i32;
+            let ret: CmpResult;
             asm!(
                 "fcmp    {a:d}, {b:d}",
                 "cset {ret:w}, gt",
@@ -130,13 +141,13 @@ float_bench! {
 
 float_bench! {
     name: cmp_f64_unord,
-    sig: (a: f64, b: f64) -> i32,
+    sig: (a: f64, b: f64) -> CmpResult,
     crate_fn: cmp::__unorddf2,
     sys_fn: __unorddf2,
     sys_available: all(),
     asm: [
         #[cfg(target_arch = "x86_64")] {
-            let ret: i32;
+            let ret: CmpResult;
             asm!(
                 "xor     {ret:e}, {ret:e}",
                 "ucomisd {a}, {b}",
@@ -151,7 +162,7 @@ float_bench! {
         };
 
         #[cfg(target_arch = "aarch64")] {
-            let ret: i32;
+            let ret: CmpResult;
             asm!(
                 "fcmp    {a:d}, {b:d}",
                 "cset    {ret:w}, vs",
@@ -168,7 +179,7 @@ float_bench! {
 
 float_bench! {
     name: cmp_f128_gt,
-    sig: (a: f128, b: f128) -> i32,
+    sig: (a: f128, b: f128) -> CmpResult,
     crate_fn: cmp::__gttf2,
     crate_fn_ppc: cmp::__gtkf2,
     sys_fn: __gttf2,
@@ -180,7 +191,7 @@ float_bench! {
 
 float_bench! {
     name: cmp_f128_unord,
-    sig: (a: f128, b: f128) -> i32,
+    sig: (a: f128, b: f128) -> CmpResult,
     crate_fn: cmp::__unordtf2,
     crate_fn_ppc: cmp::__unordkf2,
     sys_fn: __unordtf2,
diff --git a/library/compiler-builtins/builtins-test/src/bench.rs b/library/compiler-builtins/builtins-test/src/bench.rs
index 2348f6bc973..0987185670e 100644
--- a/library/compiler-builtins/builtins-test/src/bench.rs
+++ b/library/compiler-builtins/builtins-test/src/bench.rs
@@ -358,8 +358,8 @@ impl_testio!(float f16);
 impl_testio!(float f32, f64);
 #[cfg(f128_enabled)]
 impl_testio!(float f128);
-impl_testio!(int i16, i32, i64, i128);
-impl_testio!(int u16, u32, u64, u128);
+impl_testio!(int i8, i16, i32, i64, i128, isize);
+impl_testio!(int u8, u16, u32, u64, u128, usize);
 impl_testio!((float, int)(f32, i32));
 impl_testio!((float, int)(f64, i32));
 #[cfg(f128_enabled)]
diff --git a/library/compiler-builtins/builtins-test/src/lib.rs b/library/compiler-builtins/builtins-test/src/lib.rs
index c596ac21380..f1673133be2 100644
--- a/library/compiler-builtins/builtins-test/src/lib.rs
+++ b/library/compiler-builtins/builtins-test/src/lib.rs
@@ -40,6 +40,75 @@ pub const N: u32 = if cfg!(target_arch = "x86_64") && !cfg!(debug_assertions) {
     10_000
 };
 
+/// Additional constants that determine how the integer gets fuzzed.
+trait FuzzInt: MinInt {
+    /// LUT used for maximizing the space covered and minimizing the computational cost of fuzzing
+    /// in `builtins-test`. For example, Self = u128 produces [0,1,2,7,8,15,16,31,32,63,64,95,96,
+    /// 111,112,119,120,125,126,127].
+    const FUZZ_LENGTHS: [u8; 20] = make_fuzz_lengths(Self::BITS);
+
+    /// The number of entries of `FUZZ_LENGTHS` actually used. The maximum is 20 for u128.
+    const FUZZ_NUM: usize = {
+        let log2 = Self::BITS.ilog2() as usize;
+        if log2 == 3 {
+            // case for u8
+            6
+        } else {
+            // 3 entries on each extreme, 2 in the middle, and 4 for each scale of intermediate
+            // boundaries.
+            8 + (4 * (log2 - 4))
+        }
+    };
+}
+
+impl<I> FuzzInt for I where I: MinInt {}
+
+const fn make_fuzz_lengths(bits: u32) -> [u8; 20] {
+    let mut v = [0u8; 20];
+    v[0] = 0;
+    v[1] = 1;
+    v[2] = 2; // important for parity and the iX::MIN case when reversed
+    let mut i = 3;
+
+    // No need for any more until the byte boundary, because there should be no algorithms
+    // that are sensitive to anything not next to byte boundaries after 2. We also scale
+    // in powers of two, which is important to prevent u128 corner tests from getting too
+    // big.
+    let mut l = 8;
+    loop {
+        if l >= ((bits / 2) as u8) {
+            break;
+        }
+        // get both sides of the byte boundary
+        v[i] = l - 1;
+        i += 1;
+        v[i] = l;
+        i += 1;
+        l *= 2;
+    }
+
+    if bits != 8 {
+        // add the lower side of the middle boundary
+        v[i] = ((bits / 2) - 1) as u8;
+        i += 1;
+    }
+
+    // We do not want to jump directly from the Self::BITS/2 boundary to the Self::BITS
+    // boundary because of algorithms that split the high part up. We reverse the scaling
+    // as we go to Self::BITS.
+    let mid = i;
+    let mut j = 1;
+    loop {
+        v[i] = (bits as u8) - (v[mid - j]) - 1;
+        if j == mid {
+            break;
+        }
+        i += 1;
+        j += 1;
+    }
+    v
+}
+
 /// Random fuzzing step. When run several times, it results in excellent fuzzing entropy such as:
 /// 11110101010101011110111110011111
 /// 10110101010100001011101011001010
@@ -92,10 +161,9 @@ fn fuzz_step<I: Int>(rng: &mut Xoshiro128StarStar, x: &mut I) {
 macro_rules! edge_cases {
     ($I:ident, $case:ident, $inner:block) => {
         for i0 in 0..$I::FUZZ_NUM {
-            let mask_lo = (!$I::UnsignedInt::ZERO).wrapping_shr($I::FUZZ_LENGTHS[i0] as u32);
+            let mask_lo = (!$I::Unsigned::ZERO).wrapping_shr($I::FUZZ_LENGTHS[i0] as u32);
             for i1 in i0..I::FUZZ_NUM {
-                let mask_hi =
-                    (!$I::UnsignedInt::ZERO).wrapping_shl($I::FUZZ_LENGTHS[i1 - i0] as u32);
+                let mask_hi = (!$I::Unsigned::ZERO).wrapping_shl($I::FUZZ_LENGTHS[i1 - i0] as u32);
                 let $case = I::from_unsigned(mask_lo & mask_hi);
                 $inner
             }
@@ -107,7 +175,7 @@ macro_rules! edge_cases {
 /// edge cases, followed by a more random fuzzer that runs `n` times.
 pub fn fuzz<I: Int, F: FnMut(I)>(n: u32, mut f: F)
 where
-    <I as MinInt>::UnsignedInt: Int,
+    <I as MinInt>::Unsigned: Int,
 {
     // edge case tester. Calls `f` 210 times for u128.
     // zero gets skipped by the loop
@@ -128,7 +196,7 @@ where
 /// The same as `fuzz`, except `f` has two inputs.
 pub fn fuzz_2<I: Int, F: Fn(I, I)>(n: u32, f: F)
 where
-    <I as MinInt>::UnsignedInt: Int,
+    <I as MinInt>::Unsigned: Int,
 {
     // Check cases where the first and second inputs are zero. Both call `f` 210 times for `u128`.
     edge_cases!(I, case, {
diff --git a/library/compiler-builtins/builtins-test/tests/aeabi_memclr.rs b/library/compiler-builtins/builtins-test/tests/aeabi_memclr.rs
index bfd15a391aa..0761feaffd9 100644
--- a/library/compiler-builtins/builtins-test/tests/aeabi_memclr.rs
+++ b/library/compiler-builtins/builtins-test/tests/aeabi_memclr.rs
@@ -24,7 +24,8 @@ macro_rules! panic {
     };
 }
 
-extern "C" {
+// SAFETY: defined in  compiler-builtins
+unsafe extern "aapcs" {
     fn __aeabi_memclr4(dest: *mut u8, n: usize);
     fn __aeabi_memset4(dest: *mut u8, n: usize, c: u32);
 }
diff --git a/library/compiler-builtins/builtins-test/tests/aeabi_memcpy.rs b/library/compiler-builtins/builtins-test/tests/aeabi_memcpy.rs
index c892c5aba0f..e76e712a246 100644
--- a/library/compiler-builtins/builtins-test/tests/aeabi_memcpy.rs
+++ b/library/compiler-builtins/builtins-test/tests/aeabi_memcpy.rs
@@ -22,7 +22,8 @@ macro_rules! panic {
     };
 }
 
-extern "C" {
+// SAFETY: defined in  compiler-builtins
+unsafe extern "aapcs" {
     fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize);
     fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, n: usize);
 }
diff --git a/library/compiler-builtins/builtins-test/tests/aeabi_memset.rs b/library/compiler-builtins/builtins-test/tests/aeabi_memset.rs
index 34ab3acc78c..8f9f80f969c 100644
--- a/library/compiler-builtins/builtins-test/tests/aeabi_memset.rs
+++ b/library/compiler-builtins/builtins-test/tests/aeabi_memset.rs
@@ -24,7 +24,8 @@ macro_rules! panic {
     };
 }
 
-extern "C" {
+// SAFETY: defined in  compiler-builtins
+unsafe extern "aapcs" {
     fn __aeabi_memset4(dest: *mut u8, n: usize, c: u32);
 }
 
diff --git a/library/compiler-builtins/builtins-test/tests/float_pow.rs b/library/compiler-builtins/builtins-test/tests/float_pow.rs
index 8209543e666..0e8ae88e83e 100644
--- a/library/compiler-builtins/builtins-test/tests/float_pow.rs
+++ b/library/compiler-builtins/builtins-test/tests/float_pow.rs
@@ -58,8 +58,6 @@ pow! {
 }
 
 #[cfg(f128_enabled)]
-// FIXME(f16_f128): MSVC cannot build these until `__divtf3` is available in nightly.
-#[cfg(not(target_env = "msvc"))]
 #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
 pow! {
     f128, 1e-36, __powitf2, not(feature = "no-sys-f128");
diff --git a/library/compiler-builtins/ci/bench-icount.sh b/library/compiler-builtins/ci/bench-icount.sh
index 4d93e257a6c..5724955fe36 100755
--- a/library/compiler-builtins/ci/bench-icount.sh
+++ b/library/compiler-builtins/ci/bench-icount.sh
@@ -2,10 +2,21 @@
 
 set -eux
 
+target="${1:-}"
+
+if [ -z "$target" ]; then
+    host_target=$(rustc -vV | awk '/^host/ { print $2 }')
+    echo "Defaulted to host target $host_target"
+    target="$host_target"
+fi
+
 iai_home="iai-home"
 
+# Use the arch as a tag to disambiguate artifacts
+tag="$(echo "$target" | cut -d'-' -f1)"
+
 # Download the baseline from master
-./ci/ci-util.py locate-baseline --download --extract
+./ci/ci-util.py locate-baseline --download --extract --tag "$tag"
 
 # Run benchmarks once
 function run_icount_benchmarks() {
@@ -35,16 +46,18 @@ function run_icount_benchmarks() {
         shift
     done
 
-    # Run iai-callgrind benchmarks
-    cargo bench "${cargo_args[@]}" -- "${iai_args[@]}"
+    # Run iai-callgrind benchmarks. Do this in a subshell with `&& true` to
+    # capture rather than exit on error.
+    (cargo bench "${cargo_args[@]}" -- "${iai_args[@]}") && true
+    exit_code="$?"
 
-    # NB: iai-callgrind should exit on error but does not, so we inspect the sumary
-    # for errors. See  https://github.com/iai-callgrind/iai-callgrind/issues/337
-    if [ -n "${PR_NUMBER:-}" ]; then
-        # If this is for a pull request, ignore regressions if specified.
-        ./ci/ci-util.py check-regressions --home "$iai_home" --allow-pr-override "$PR_NUMBER"
+    if [ "$exit_code" -eq 0 ]; then
+        echo "Benchmarks completed with no regressions"
+    elif [ -z "${PR_NUMBER:-}" ]; then
+        # Disregard regressions after merge
+        echo "Benchmarks completed with regressions; ignoring (not in a PR)"
     else
-        ./ci/ci-util.py check-regressions --home "$iai_home" || true
+        ./ci/ci-util.py handle-banch-regressions "$PR_NUMBER"
     fi
 }
 
@@ -53,6 +66,6 @@ run_icount_benchmarks --features force-soft-floats -- --save-baseline=softfloat
 run_icount_benchmarks -- --save-baseline=hardfloat
 
 # Name and tar the new baseline
-name="baseline-icount-$(date -u +'%Y%m%d%H%M')-${GITHUB_SHA:0:12}"
+name="baseline-icount-$tag-$(date -u +'%Y%m%d%H%M')-${GITHUB_SHA:0:12}"
 echo "BASELINE_NAME=$name" >>"$GITHUB_ENV"
 tar cJf "$name.tar.xz" "$iai_home"
diff --git a/library/compiler-builtins/ci/ci-util.py b/library/compiler-builtins/ci/ci-util.py
index d785b2e9e1d..3437d304f48 100755
--- a/library/compiler-builtins/ci/ci-util.py
+++ b/library/compiler-builtins/ci/ci-util.py
@@ -11,7 +11,7 @@ import re
 import subprocess as sp
 import sys
 from dataclasses import dataclass
-from glob import glob, iglob
+from glob import glob
 from inspect import cleandoc
 from os import getenv
 from pathlib import Path
@@ -28,21 +28,20 @@ USAGE = cleandoc(
             Calculate a matrix of which functions had source change, print that as
             a JSON object.
 
-        locate-baseline [--download] [--extract]
+        locate-baseline [--download] [--extract] [--tag TAG]
             Locate the most recent benchmark baseline available in CI and, if flags
             specify, download and extract it. Never exits with nonzero status if
             downloading fails.
 
-            Note that `--extract` will overwrite files in `iai-home`.
+            `--tag` can be specified to look for artifacts with a specific tag, such as
+            for a specific architecture.
 
-        check-regressions [--home iai-home] [--allow-pr-override pr_number]
-            Check `iai-home` (or `iai-home` if unspecified) for `summary.json`
-            files and see if there are any regressions. This is used as a workaround
-            for `iai-callgrind` not exiting with error status; see
-            <https://github.com/iai-callgrind/iai-callgrind/issues/337>.
+            Note that `--extract` will overwrite files in `iai-home`.
 
-            If `--allow-pr-override` is specified, the regression check will not exit
-            with failure if any line in the PR starts with `allow-regressions`.
+        handle-bench-regressions PR_NUMBER
+            Exit with success if the pull request contains a line starting with
+            `ci: allow-regressions`, indicating that regressions in benchmarks should
+            be accepted. Otherwise, exit 1.
     """
 )
 
@@ -50,7 +49,7 @@ REPO_ROOT = Path(__file__).parent.parent
 GIT = ["git", "-C", REPO_ROOT]
 DEFAULT_BRANCH = "master"
 WORKFLOW_NAME = "CI"  # Workflow that generates the benchmark artifacts
-ARTIFACT_GLOB = "baseline-icount*"
+ARTIFACT_PREFIX = "baseline-icount*"
 # Place this in a PR body to skip regression checks (must be at the start of a line).
 REGRESSION_DIRECTIVE = "ci: allow-regressions"
 # Place this in a PR body to skip extensive tests
@@ -278,6 +277,7 @@ def locate_baseline(flags: list[str]) -> None:
 
     download = False
     extract = False
+    tag = ""
 
     while len(flags) > 0:
         match flags[0]:
@@ -285,6 +285,9 @@ def locate_baseline(flags: list[str]) -> None:
                 download = True
             case "--extract":
                 extract = True
+            case "--tag":
+                tag = flags[1]
+                flags = flags[1:]
             case _:
                 eprint(USAGE)
                 exit(1)
@@ -333,8 +336,10 @@ def locate_baseline(flags: list[str]) -> None:
         eprint("skipping download step")
         return
 
+    artifact_glob = f"{ARTIFACT_PREFIX}{f"-{tag}" if tag else ""}*"
+
     sp.run(
-        ["gh", "run", "download", str(job_id), f"--pattern={ARTIFACT_GLOB}"],
+        ["gh", "run", "download", str(job_id), f"--pattern={artifact_glob}"],
         check=False,
     )
 
@@ -344,7 +349,7 @@ def locate_baseline(flags: list[str]) -> None:
 
     # Find the baseline with the most recent timestamp. GH downloads the files to e.g.
     # `some-dirname/some-dirname.tar.xz`, so just glob the whole thing together.
-    candidate_baselines = glob(f"{ARTIFACT_GLOB}/{ARTIFACT_GLOB}")
+    candidate_baselines = glob(f"{artifact_glob}/{artifact_glob}")
     if len(candidate_baselines) == 0:
         eprint("no possible baseline directories found")
         return
@@ -356,64 +361,22 @@ def locate_baseline(flags: list[str]) -> None:
     eprint("baseline extracted successfully")
 
 
-def check_iai_regressions(args: list[str]):
-    """Find regressions in iai summary.json files, exit with failure if any are
-    found.
-    """
-
-    iai_home_str = "iai-home"
-    pr_number = None
-
-    while len(args) > 0:
-        match args:
-            case ["--home", home, *rest]:
-                iai_home_str = home
-                args = rest
-            case ["--allow-pr-override", pr_num, *rest]:
-                pr_number = pr_num
-                args = rest
-            case _:
-                eprint(USAGE)
-                exit(1)
-
-    iai_home = Path(iai_home_str)
-
-    found_summaries = False
-    regressions: list[dict] = []
-    for summary_path in iglob("**/summary.json", root_dir=iai_home, recursive=True):
-        found_summaries = True
-        with open(iai_home / summary_path, "r") as f:
-            summary = json.load(f)
-
-        summary_regs = []
-        run = summary["callgrind_summary"]["callgrind_run"]
-        fname = summary["function_name"]
-        id = summary["id"]
-        name_entry = {"name": f"{fname}.{id}"}
+def handle_bench_regressions(args: list[str]):
+    """Exit with error unless the PR message contains an ignore directive."""
 
-        for segment in run["segments"]:
-            summary_regs.extend(segment["regressions"])
-
-        summary_regs.extend(run["total"]["regressions"])
-
-        regressions.extend(name_entry | reg for reg in summary_regs)
-
-    if not found_summaries:
-        eprint(f"did not find any summary.json files within {iai_home}")
-        exit(1)
+    match args:
+        case [pr_number]:
+            pr_number = pr_number
+        case _:
+            eprint(USAGE)
+            exit(1)
 
-    if len(regressions) == 0:
-        eprint("No regressions found")
+    pr = PrInfo.load(pr_number)
+    if pr.contains_directive(REGRESSION_DIRECTIVE):
+        eprint("PR allows regressions")
         return
 
-    eprint("Found regressions:", json.dumps(regressions, indent=4))
-
-    if pr_number is not None:
-        pr = PrInfo.load(pr_number)
-        if pr.contains_directive(REGRESSION_DIRECTIVE):
-            eprint("PR allows regressions, returning")
-            return
-
+    eprint("Regressions were found; benchmark failed")
     exit(1)
 
 
@@ -424,8 +387,8 @@ def main():
             ctx.emit_workflow_output()
         case ["locate-baseline", *flags]:
             locate_baseline(flags)
-        case ["check-regressions", *args]:
-            check_iai_regressions(args)
+        case ["handle-bench-regressions", *args]:
+            handle_bench_regressions(args)
         case ["--help" | "-h"]:
             print(USAGE)
             exit()
diff --git a/library/compiler-builtins/ci/run.sh b/library/compiler-builtins/ci/run.sh
index 68d13c130bc..27b9686eac6 100755
--- a/library/compiler-builtins/ci/run.sh
+++ b/library/compiler-builtins/ci/run.sh
@@ -47,130 +47,49 @@ else
     fi
 fi
 
+# Ensure there are no duplicate symbols or references to `core` when
+# `compiler-builtins` is built with various features. Symcheck invokes Cargo to
+# build with the arguments we provide it, then validates the built artifacts.
+symcheck=(cargo run -p symbol-check --release)
+[[ "$target" = "wasm"* ]] && symcheck+=(--features wasm)
+symcheck+=(-- build-and-check)
+
+"${symcheck[@]}" -p compiler_builtins --target "$target"
+"${symcheck[@]}" -p compiler_builtins --target "$target" --release
+"${symcheck[@]}" -p compiler_builtins --target "$target" --features c
+"${symcheck[@]}" -p compiler_builtins --target "$target" --features c --release
+"${symcheck[@]}" -p compiler_builtins --target "$target" --features no-asm
+"${symcheck[@]}" -p compiler_builtins --target "$target" --features no-asm --release
+"${symcheck[@]}" -p compiler_builtins --target "$target" --features no-f16-f128
+"${symcheck[@]}" -p compiler_builtins --target "$target" --features no-f16-f128 --release
+
+run_intrinsics_test() {
+    args=(
+        --target "$target" --verbose \
+        --manifest-path builtins-test-intrinsics/Cargo.toml
+    )
+    args+=( "$@" )
 
-declare -a rlib_paths
-
-# Set the `rlib_paths` global array to a list of all compiler-builtins rlibs
-update_rlib_paths() {
-    if [ -d /builtins-target ]; then
-        rlib_paths=( /builtins-target/"${target}"/debug/deps/libcompiler_builtins-*.rlib )
-    else
-        rlib_paths=( target/"${target}"/debug/deps/libcompiler_builtins-*.rlib )
-    fi
-}
-
-# Remove any existing artifacts from previous tests that don't set #![compiler_builtins]
-update_rlib_paths
-rm -f "${rlib_paths[@]}"
-
-cargo build -p compiler_builtins --target "$target"
-cargo build -p compiler_builtins --target "$target" --release
-cargo build -p compiler_builtins --target "$target" --features c
-cargo build -p compiler_builtins --target "$target" --features c --release
-cargo build -p compiler_builtins --target "$target" --features no-asm
-cargo build -p compiler_builtins --target "$target" --features no-asm --release
-cargo build -p compiler_builtins --target "$target" --features no-f16-f128
-cargo build -p compiler_builtins --target "$target" --features no-f16-f128 --release
-
-PREFIX=${target//unknown-/}-
-case "$target" in
-    armv7-*)
-        PREFIX=arm-linux-gnueabihf-
-        ;;
-    thumb*)
-        PREFIX=arm-none-eabi-
-        ;;
-    *86*-*)
-        PREFIX=
-        ;;
-esac
-
-NM=$(find "$(rustc --print sysroot)" \( -name llvm-nm -o -name llvm-nm.exe \) )
-if [ "$NM" = "" ]; then
-  NM="${PREFIX}nm"
-fi
+    # symcheck also checks the results of builtins-test-intrinsics
+    "${symcheck[@]}" "${args[@]}"
 
-# i686-pc-windows-gnu tools have a dependency on some DLLs, so run it with
-# rustup run to ensure that those are in PATH.
-TOOLCHAIN="$(rustup show active-toolchain | sed 's/ (default)//')"
-if [[ "$TOOLCHAIN" == *i686-pc-windows-gnu ]]; then
-  NM="rustup run $TOOLCHAIN $NM"
-fi
-
-# Look out for duplicated symbols when we include the compiler-rt (C) implementation
-update_rlib_paths
-for rlib in "${rlib_paths[@]}"; do
-    set +x
-    echo "================================================================"
-    echo "checking $rlib for duplicate symbols"
-    echo "================================================================"
-    set -x
-    
-    duplicates_found=0
-
-    # NOTE On i586, It's normal that the get_pc_thunk symbol appears several
-    # times so ignore it
-    $NM -g --defined-only "$rlib" 2>&1 |
-      sort |
-      uniq -d |
-      grep -v __x86.get_pc_thunk --quiet |
-      grep 'T __' && duplicates_found=1
-
-    if [ "$duplicates_found" != 0 ]; then
-        echo "error: found duplicate symbols"
-        exit 1
-    else
-        echo "success; no duplicate symbols found"
+    # FIXME: we get access violations on Windows, our entrypoint may need to
+    # be tweaked.
+    if [ "${BUILD_ONLY:-}" != "1" ] && ! [[ "$target" = *"windows"* ]]; then
+        cargo run "${args[@]}"
     fi
-done
-
-rm -f "${rlib_paths[@]}"
-
-build_intrinsics_test() {
-    cargo build \
-        --target "$target" --verbose \
-        --manifest-path builtins-test-intrinsics/Cargo.toml "$@"
 }
 
 # Verify that we haven't dropped any intrinsics/symbols
-build_intrinsics_test
-build_intrinsics_test --release
-build_intrinsics_test --features c
-build_intrinsics_test --features c --release
+run_intrinsics_test
+run_intrinsics_test --release
+run_intrinsics_test --features c
+run_intrinsics_test --features c --release
 
 # Verify that there are no undefined symbols to `panic` within our
 # implementations
-CARGO_PROFILE_DEV_LTO=true build_intrinsics_test
-CARGO_PROFILE_RELEASE_LTO=true build_intrinsics_test --release
-
-# Ensure no references to any symbols from core
-update_rlib_paths
-for rlib in "${rlib_paths[@]}"; do
-    set +x
-    echo "================================================================"
-    echo "checking $rlib for references to core"
-    echo "================================================================"
-    set -x
-
-    tmpdir="${CARGO_TARGET_DIR:-target}/tmp"
-    test -d "$tmpdir" || mkdir "$tmpdir"
-    defined="$tmpdir/defined_symbols.txt"
-    undefined="$tmpdir/defined_symbols.txt"
-
-    $NM --quiet -U "$rlib" | grep 'T _ZN4core' | awk '{print $3}' | sort | uniq > "$defined"
-    $NM --quiet -u "$rlib" | grep 'U _ZN4core' | awk '{print $2}' | sort | uniq > "$undefined"
-    grep_has_results=0
-    grep -v -F -x -f "$defined" "$undefined" && grep_has_results=1
-
-    if [ "$target" = "powerpc64-unknown-linux-gnu" ]; then
-        echo "FIXME: powerpc64 fails these tests"
-    elif [ "$grep_has_results" != 0 ]; then
-        echo "error: found unexpected references to core"
-        exit 1
-    else
-        echo "success; no references to core found"
-    fi
-done
+CARGO_PROFILE_DEV_LTO=true run_intrinsics_test
+CARGO_PROFILE_RELEASE_LTO=true run_intrinsics_test --release
 
 # Test libm
 
diff --git a/library/compiler-builtins/ci/update-musl.sh b/library/compiler-builtins/ci/update-musl.sh
new file mode 100755
index 00000000000..b71cf577830
--- /dev/null
+++ b/library/compiler-builtins/ci/update-musl.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# Download musl to a repository for `musl-math-sys`
+
+set -eux
+
+url=git://git.musl-libc.org/musl
+ref=c47ad25ea3b484e10326f933e927c0bc8cded3da
+dst=crates/musl-math-sys/musl
+
+if ! [ -d "$dst" ]; then
+    git clone "$url" "$dst" --single-branch --depth=1000
+fi
+
+git -C "$dst" fetch "$url" --depth=1
+git -C "$dst" checkout "$ref"
diff --git a/library/compiler-builtins/compiler-builtins/CHANGELOG.md b/library/compiler-builtins/compiler-builtins/CHANGELOG.md
index a7c01c463ca..880e56c443e 100644
--- a/library/compiler-builtins/compiler-builtins/CHANGELOG.md
+++ b/library/compiler-builtins/compiler-builtins/CHANGELOG.md
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
+## [0.1.160](https://github.com/rust-lang/compiler-builtins/compare/compiler_builtins-v0.1.159...compiler_builtins-v0.1.160) - 2025-05-29
+
+### Other
+
+- Change `compiler-builtins` to edition 2024
+- Remove unneeded C symbols
+- Reuse `libm`'s `Caat` and `CastFrom` in `compiler-builtins`
+- Reuse `MinInt` and `Int` from `libm` in `compiler-builtins`
+- Update `CmpResult` to use a pointer-sized return type
+- Enable `__powitf2` on MSVC
+- Fix `i256::MAX`
+- Add a note saying why we use `frintx` rather than `frintn`
+- Typo in README.md
+- Clean up unused files
+
 ## [0.1.159](https://github.com/rust-lang/compiler-builtins/compare/compiler_builtins-v0.1.158...compiler_builtins-v0.1.159) - 2025-05-12
 
 ### Other
diff --git a/library/compiler-builtins/compiler-builtins/Cargo.toml b/library/compiler-builtins/compiler-builtins/Cargo.toml
index d65a22152ef..df8e964825b 100644
--- a/library/compiler-builtins/compiler-builtins/Cargo.toml
+++ b/library/compiler-builtins/compiler-builtins/Cargo.toml
@@ -1,13 +1,13 @@
 [package]
 authors = ["Jorge Aparicio <japaricious@gmail.com>"]
 name = "compiler_builtins"
-version = "0.1.159"
+version = "0.1.160"
 license = "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)"
 readme = "README.md"
 repository = "https://github.com/rust-lang/compiler-builtins"
 homepage = "https://github.com/rust-lang/compiler-builtins"
 documentation = "https://docs.rs/compiler_builtins"
-edition = "2021"
+edition = "2024"
 description = "Compiler intrinsics used by the Rust compiler."
 links = "compiler-rt"
 
@@ -17,15 +17,10 @@ doctest = false
 test = false
 
 [dependencies]
-# For more information on this dependency see
-# https://github.com/rust-lang/rust/tree/master/library/rustc-std-workspace-core
-core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
+core = { path = "../../core", optional = true }
 
 [build-dependencies]
-cc = { optional = true, version = "1.0" }
-
-[dev-dependencies]
-panic-handler = { path = "../crates/panic-handler" }
+cc = { optional = true, version = "1.2" }
 
 [features]
 default = ["compiler-builtins"]
diff --git a/library/compiler-builtins/compiler-builtins/build.rs b/library/compiler-builtins/compiler-builtins/build.rs
index 90d98ec7ce9..7c8da02fd28 100644
--- a/library/compiler-builtins/compiler-builtins/build.rs
+++ b/library/compiler-builtins/compiler-builtins/build.rs
@@ -22,6 +22,9 @@ fn main() {
 
     println!("cargo:compiler-rt={}", cwd.join("compiler-rt").display());
 
+    println!("cargo::rustc-check-cfg=cfg(kernel_user_helpers)");
+    println!("cargo::rustc-check-cfg=cfg(feature, values(\"mem-unaligned\"))");
+
     // Emscripten's runtime includes all the builtins
     if target.os == "emscripten" {
         return;
@@ -47,7 +50,6 @@ fn main() {
     }
 
     // These targets have hardware unaligned access support.
-    println!("cargo::rustc-check-cfg=cfg(feature, values(\"mem-unaligned\"))");
     if target.arch.contains("x86_64")
         || target.arch.contains("x86")
         || target.arch.contains("aarch64")
@@ -78,7 +80,6 @@ fn main() {
     // Only emit the ARM Linux atomic emulation on pre-ARMv6 architectures. This
     // includes the old androideabi. It is deprecated but it is available as a
     // rustc target (arm-linux-androideabi).
-    println!("cargo::rustc-check-cfg=cfg(kernel_user_helpers)");
     if llvm_target[0] == "armv4t"
         || llvm_target[0] == "armv5te"
         || target.triple == "arm-linux-androideabi"
@@ -555,7 +556,6 @@ mod c {
 
         if (target.arch == "aarch64" || target.arch == "arm64ec") && consider_float_intrinsics {
             sources.extend(&[
-                ("__comparetf2", "comparetf2.c"),
                 ("__fe_getround", "fp_mode.c"),
                 ("__fe_raise_inexact", "fp_mode.c"),
             ]);
@@ -570,11 +570,11 @@ mod c {
         }
 
         if target.arch == "mips64" {
-            sources.extend(&[("__netf2", "comparetf2.c"), ("__fe_getround", "fp_mode.c")]);
+            sources.extend(&[("__fe_getround", "fp_mode.c")]);
         }
 
         if target.arch == "loongarch64" {
-            sources.extend(&[("__netf2", "comparetf2.c"), ("__fe_getround", "fp_mode.c")]);
+            sources.extend(&[("__fe_getround", "fp_mode.c")]);
         }
 
         // Remove the assembly implementations that won't compile for the target
diff --git a/library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs b/library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs
index e238d0237eb..226121237e8 100644
--- a/library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs
+++ b/library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs
@@ -4,7 +4,7 @@
 //! To avoid breaking backwards compat, C toolchains introduced a concept of "outlined atomics",
 //! where atomic operations call into the compiler runtime to dispatch between two depending on
 //! which is supported on the current CPU.
-//! See https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/making-the-most-of-the-arm-architecture-in-gcc-10#:~:text=out%20of%20line%20atomics for more discussion.
+//! See <https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/making-the-most-of-the-arm-architecture-in-gcc-10#:~:text=out%20of%20line%20atomics> for more discussion.
 //!
 //! Currently we only support LL/SC, because LSE requires `getauxval` from libc in order to do runtime detection.
 //! Use the `compiler-rt` intrinsics if you want LSE support.
diff --git a/library/compiler-builtins/compiler-builtins/src/arm.rs b/library/compiler-builtins/compiler-builtins/src/arm.rs
index a9107e3cdfd..a7d84e49b34 100644
--- a/library/compiler-builtins/compiler-builtins/src/arm.rs
+++ b/library/compiler-builtins/compiler-builtins/src/arm.rs
@@ -1,13 +1,16 @@
 #![cfg(not(feature = "no-asm"))]
 
 // Interfaces used by naked trampolines.
-extern "C" {
+// SAFETY: these are defined in compiler-builtins
+unsafe extern "C" {
     fn __udivmodsi4(a: u32, b: u32, rem: *mut u32) -> u32;
     fn __udivmoddi4(a: u64, b: u64, rem: *mut u64) -> u64;
     fn __divmoddi4(a: i64, b: i64, rem: *mut i64) -> i64;
 }
 
-extern "aapcs" {
+// SAFETY: these are defined in compiler-builtins
+// FIXME(extern_custom), this isn't always the correct ABI
+unsafe extern "aapcs" {
     // AAPCS is not always the correct ABI for these intrinsics, but we only use this to
     // forward another `__aeabi_` call so it doesn't matter.
     fn __aeabi_idiv(a: i32, b: i32) -> i32;
diff --git a/library/compiler-builtins/compiler-builtins/src/arm_linux.rs b/library/compiler-builtins/compiler-builtins/src/arm_linux.rs
index 6ce67ba719c..ab9f8680739 100644
--- a/library/compiler-builtins/compiler-builtins/src/arm_linux.rs
+++ b/library/compiler-builtins/compiler-builtins/src/arm_linux.rs
@@ -4,12 +4,17 @@ use core::{arch, mem};
 // Kernel-provided user-mode helper functions:
 // https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt
 unsafe fn __kuser_cmpxchg(oldval: u32, newval: u32, ptr: *mut u32) -> bool {
-    let f: extern "C" fn(u32, u32, *mut u32) -> u32 = mem::transmute(0xffff0fc0usize as *const ());
+    // FIXME(volatile): the third parameter is a volatile pointer
+    // SAFETY: kernel docs specify a known address with the given signature
+    let f = unsafe {
+        mem::transmute::<_, extern "C" fn(u32, u32, *mut u32) -> u32>(0xffff0fc0usize as *const ())
+    };
     f(oldval, newval, ptr) == 0
 }
 
 unsafe fn __kuser_memory_barrier() {
-    let f: extern "C" fn() = mem::transmute(0xffff0fa0usize as *const ());
+    // SAFETY: kernel docs specify a known address with the given signature
+    let f = unsafe { mem::transmute::<_, extern "C" fn()>(0xffff0fa0usize as *const ()) };
     f();
 }
 
@@ -67,8 +72,10 @@ fn insert_aligned(aligned: u32, val: u32, shift: u32, mask: u32) -> u32 {
 /// - if `size_of::<T>() == 2`, `ptr` or `ptr` offset by 2 bytes must be valid for a relaxed atomic
 ///   read of 2 bytes.
 /// - if `size_of::<T>() == 4`, `ptr` must be valid for a relaxed atomic read of 4 bytes.
+// FIXME: assert some of the preconditions in debug mode
 unsafe fn atomic_load_aligned<T>(ptr: *mut u32) -> u32 {
-    if mem::size_of::<T>() == 4 {
+    const { assert!(size_of::<T>() <= 4) };
+    if size_of::<T>() == 4 {
         // SAFETY: As `T` has a size of 4, the caller garantees this is sound.
         unsafe { AtomicU32::from_ptr(ptr).load(Ordering::Relaxed) }
     } else {
@@ -100,11 +107,13 @@ unsafe fn atomic_rmw<T, F: Fn(u32) -> u32, G: Fn(u32, u32) -> u32>(ptr: *mut T,
     let (shift, mask) = get_shift_mask(ptr);
 
     loop {
-        let curval_aligned = atomic_load_aligned::<T>(aligned_ptr);
+        // FIXME(safety): preconditions review needed
+        let curval_aligned = unsafe { atomic_load_aligned::<T>(aligned_ptr) };
         let curval = extract_aligned(curval_aligned, shift, mask);
         let newval = f(curval);
         let newval_aligned = insert_aligned(curval_aligned, newval, shift, mask);
-        if __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) {
+        // FIXME(safety): preconditions review needed
+        if unsafe { __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) } {
             return g(curval, newval);
         }
     }
@@ -116,13 +125,15 @@ unsafe fn atomic_cmpxchg<T>(ptr: *mut T, oldval: u32, newval: u32) -> u32 {
     let (shift, mask) = get_shift_mask(ptr);
 
     loop {
-        let curval_aligned = atomic_load_aligned::<T>(aligned_ptr);
+        // FIXME(safety): preconditions review needed
+        let curval_aligned = unsafe { atomic_load_aligned::<T>(aligned_ptr) };
         let curval = extract_aligned(curval_aligned, shift, mask);
         if curval != oldval {
             return curval;
         }
         let newval_aligned = insert_aligned(curval_aligned, newval, shift, mask);
-        if __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) {
+        // FIXME(safety): preconditions review needed
+        if unsafe { __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) } {
             return oldval;
         }
     }
@@ -132,7 +143,14 @@ macro_rules! atomic_rmw {
     ($name:ident, $ty:ty, $op:expr, $fetch:expr) => {
         intrinsics! {
             pub unsafe extern "C" fn $name(ptr: *mut $ty, val: $ty) -> $ty {
-                atomic_rmw(ptr, |x| $op(x as $ty, val) as u32, |old, new| $fetch(old, new)) as $ty
+                // FIXME(safety): preconditions review needed
+                unsafe {
+                    atomic_rmw(
+                        ptr,
+                        |x| $op(x as $ty, val) as u32,
+                        |old, new| $fetch(old, new)
+                    ) as $ty
+                }
             }
         }
     };
@@ -149,7 +167,8 @@ macro_rules! atomic_cmpxchg {
     ($name:ident, $ty:ty) => {
         intrinsics! {
             pub unsafe extern "C" fn $name(ptr: *mut $ty, oldval: $ty, newval: $ty) -> $ty {
-                atomic_cmpxchg(ptr, oldval as u32, newval as u32) as $ty
+                // FIXME(safety): preconditions review needed
+                unsafe { atomic_cmpxchg(ptr, oldval as u32, newval as u32) as $ty }
             }
         }
     };
@@ -285,6 +304,7 @@ atomic_cmpxchg!(__sync_val_compare_and_swap_4, u32);
 
 intrinsics! {
     pub unsafe extern "C" fn __sync_synchronize() {
-        __kuser_memory_barrier();
+       // SAFETY: preconditions are the same as the calling function.
+       unsafe {  __kuser_memory_barrier() };
     }
 }
diff --git a/library/compiler-builtins/compiler-builtins/src/float/add.rs b/library/compiler-builtins/compiler-builtins/src/float/add.rs
index 0426c9cc44f..0cc362f705b 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/add.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/add.rs
@@ -1,5 +1,5 @@
 use crate::float::Float;
-use crate::int::{CastInto, Int, MinInt};
+use crate::int::{CastFrom, CastInto, Int, MinInt};
 
 /// Returns `a + b`
 fn add<F: Float>(a: F, b: F) -> F
@@ -12,7 +12,7 @@ where
     let one = F::Int::ONE;
     let zero = F::Int::ZERO;
 
-    let bits = F::BITS.cast();
+    let bits: F::Int = F::BITS.cast();
     let significand_bits = F::SIG_BITS;
     let max_exponent = F::EXP_SAT;
 
@@ -115,9 +115,10 @@ where
     let align = a_exponent.wrapping_sub(b_exponent).cast();
     if align != MinInt::ZERO {
         if align < bits {
-            let sticky =
-                F::Int::from_bool(b_significand << bits.wrapping_sub(align).cast() != MinInt::ZERO);
-            b_significand = (b_significand >> align.cast()) | sticky;
+            let sticky = F::Int::from_bool(
+                b_significand << u32::cast_from(bits.wrapping_sub(align)) != MinInt::ZERO,
+            );
+            b_significand = (b_significand >> u32::cast_from(align)) | sticky;
         } else {
             b_significand = one; // sticky; b is known to be non-zero.
         }
@@ -132,8 +133,8 @@ where
         // If partial cancellation occured, we need to left-shift the result
         // and adjust the exponent:
         if a_significand < implicit_bit << 3 {
-            let shift =
-                a_significand.leading_zeros() as i32 - (implicit_bit << 3).leading_zeros() as i32;
+            let shift = a_significand.leading_zeros() as i32
+                - (implicit_bit << 3u32).leading_zeros() as i32;
             a_significand <<= shift;
             a_exponent -= shift;
         }
@@ -159,14 +160,15 @@ where
         // Result is denormal before rounding; the exponent is zero and we
         // need to shift the significand.
         let shift = (1 - a_exponent).cast();
-        let sticky =
-            F::Int::from_bool((a_significand << bits.wrapping_sub(shift).cast()) != MinInt::ZERO);
-        a_significand = (a_significand >> shift.cast()) | sticky;
+        let sticky = F::Int::from_bool(
+            (a_significand << u32::cast_from(bits.wrapping_sub(shift))) != MinInt::ZERO,
+        );
+        a_significand = (a_significand >> u32::cast_from(shift)) | sticky;
         a_exponent = 0;
     }
 
     // Low three bits are round, guard, and sticky.
-    let a_significand_i32: i32 = a_significand.cast();
+    let a_significand_i32: i32 = a_significand.cast_lossy();
     let round_guard_sticky: i32 = a_significand_i32 & 0x7;
 
     // Shift the significand into place, and mask off the implicit bit.
diff --git a/library/compiler-builtins/compiler-builtins/src/float/cmp.rs b/library/compiler-builtins/compiler-builtins/src/float/cmp.rs
index 296952821cb..f1e54dc1c83 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/cmp.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/cmp.rs
@@ -2,14 +2,23 @@
 
 use crate::float::Float;
 use crate::int::MinInt;
-
-// https://github.com/llvm/llvm-project/blob/1e6ba3cd2fe96be00b6ed6ba28b3d9f9271d784d/compiler-rt/lib/builtins/fp_compare_impl.inc#L22
-#[cfg(target_arch = "avr")]
-pub type CmpResult = i8;
-
-// https://github.com/llvm/llvm-project/blob/1e6ba3cd2fe96be00b6ed6ba28b3d9f9271d784d/compiler-rt/lib/builtins/fp_compare_impl.inc#L25
-#[cfg(not(target_arch = "avr"))]
-pub type CmpResult = i32;
+use crate::support::cfg_if;
+
+// Taken from LLVM config:
+// https://github.com/llvm/llvm-project/blob/0cf3c437c18ed27d9663d87804a9a15ff6874af2/compiler-rt/lib/builtins/fp_compare_impl.inc#L11-L27
+cfg_if! {
+    if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] {
+        // Aarch64 uses `int` rather than a pointer-sized value.
+        pub type CmpResult = i32;
+    } else if #[cfg(target_arch = "avr")] {
+        // AVR uses a single byte.
+        pub type CmpResult = i8;
+    } else {
+        // In compiler-rt, LLP64 ABIs use `long long` and everything else uses `long`. In effect,
+        // this means the return value is always pointer-sized.
+        pub type CmpResult = isize;
+    }
+}
 
 #[derive(Clone, Copy)]
 enum Result {
diff --git a/library/compiler-builtins/compiler-builtins/src/float/conv.rs b/library/compiler-builtins/compiler-builtins/src/float/conv.rs
index f5427a11390..75ea7ce0242 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/conv.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/conv.rs
@@ -72,9 +72,9 @@ mod int_to_float {
         F: Float,
         I: Int,
         F::Int: CastFrom<I>,
-        Conv: Fn(I::UnsignedInt) -> F::Int,
+        Conv: Fn(I::Unsigned) -> F::Int,
     {
-        let sign_bit = F::Int::cast_from(i >> (I::BITS - 1)) << (F::BITS - 1);
+        let sign_bit = F::Int::cast_from_lossy(i >> (I::BITS - 1)) << (F::BITS - 1);
         F::from_bits(conv(i.unsigned_abs()) | sign_bit)
     }
 
@@ -166,7 +166,7 @@ mod int_to_float {
 
         // Within the upper `F::BITS`, everything except for the signifcand
         // gets truncated
-        let d1: u32 = (i_m >> (u128::BITS - f32::BITS - f32::SIG_BITS - 1)).cast();
+        let d1: u32 = (i_m >> (u128::BITS - f32::BITS - f32::SIG_BITS - 1)).cast_lossy();
 
         // The entire rest of `i_m` gets truncated. Zero the upper `F::BITS` then just
         // check if it is nonzero.
@@ -313,10 +313,10 @@ intrinsics! {
 fn float_to_unsigned_int<F, U>(f: F) -> U
 where
     F: Float,
-    U: Int<UnsignedInt = U>,
+    U: Int<Unsigned = U>,
     F::Int: CastInto<U>,
     F::Int: CastFrom<u32>,
-    F::Int: CastInto<U::UnsignedInt>,
+    F::Int: CastInto<U::Unsigned>,
     u32: CastFrom<F::Int>,
 {
     float_to_int_inner::<F, U, _, _>(f.to_bits(), |i: U| i, || U::MAX)
@@ -327,8 +327,8 @@ fn float_to_signed_int<F, I>(f: F) -> I
 where
     F: Float,
     I: Int + Neg<Output = I>,
-    I::UnsignedInt: Int,
-    F::Int: CastInto<I::UnsignedInt>,
+    I::Unsigned: Int,
+    F::Int: CastInto<I::Unsigned>,
     F::Int: CastFrom<u32>,
     u32: CastFrom<F::Int>,
 {
@@ -355,27 +355,27 @@ where
     I: Int,
     FnFoo: FnOnce(I) -> I,
     FnOob: FnOnce() -> I,
-    I::UnsignedInt: Int,
-    F::Int: CastInto<I::UnsignedInt>,
+    I::Unsigned: Int,
+    F::Int: CastInto<I::Unsigned>,
     F::Int: CastFrom<u32>,
     u32: CastFrom<F::Int>,
 {
     let int_max_exp = F::EXP_BIAS + I::MAX.ilog2() + 1;
-    let foobar = F::EXP_BIAS + I::UnsignedInt::BITS - 1;
+    let foobar = F::EXP_BIAS + I::Unsigned::BITS - 1;
 
     if fbits < F::ONE.to_bits() {
         // < 0 gets rounded to 0
         I::ZERO
     } else if fbits < F::Int::cast_from(int_max_exp) << F::SIG_BITS {
         // >= 1, < integer max
-        let m_base = if I::UnsignedInt::BITS >= F::Int::BITS {
-            I::UnsignedInt::cast_from(fbits) << (I::BITS - F::SIG_BITS - 1)
+        let m_base = if I::Unsigned::BITS >= F::Int::BITS {
+            I::Unsigned::cast_from(fbits) << (I::BITS - F::SIG_BITS - 1)
         } else {
-            I::UnsignedInt::cast_from(fbits >> (F::SIG_BITS - I::BITS + 1))
+            I::Unsigned::cast_from_lossy(fbits >> (F::SIG_BITS - I::BITS + 1))
         };
 
         // Set the implicit 1-bit.
-        let m: I::UnsignedInt = (I::UnsignedInt::ONE << (I::BITS - 1)) | m_base;
+        let m: I::Unsigned = (I::Unsigned::ONE << (I::BITS - 1)) | m_base;
 
         // Shift based on the exponent and bias.
         let s: u32 = (foobar) - u32::cast_from(fbits >> F::SIG_BITS);
diff --git a/library/compiler-builtins/compiler-builtins/src/float/div.rs b/library/compiler-builtins/compiler-builtins/src/float/div.rs
index 5df637c7e0f..fc1fc085105 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/div.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/div.rs
@@ -370,7 +370,7 @@ where
         let hi_corr: F::Int = corr_uq1 >> hw;
 
         // x_UQ0 * corr_UQ1 = (x_UQ0_hw * 2^HW) * (hi_corr * 2^HW + lo_corr) - corr_UQ1
-        let mut x_uq0: F::Int = ((F::Int::from(x_uq0_hw) * hi_corr) << 1)
+        let mut x_uq0: F::Int = ((F::Int::from(x_uq0_hw) * hi_corr) << 1u32)
             .wrapping_add((F::Int::from(x_uq0_hw) * lo_corr) >> (hw - 1))
             // 1 to account for the highest bit of corr_UQ1 can be 1
             // 1 to account for possible carry
@@ -482,7 +482,7 @@ where
 
         let ret = quotient.wrapping_shr(u32::cast_from(res_exponent.wrapping_neg()) + 1);
         residual_lo = a_significand
-            .wrapping_shl(significand_bits.wrapping_add(CastInto::<u32>::cast(res_exponent)))
+            .wrapping_shl(significand_bits.wrapping_add(CastInto::<u32>::cast_lossy(res_exponent)))
             .wrapping_sub(ret.wrapping_mul(b_significand) << 1);
         ret
     };
diff --git a/library/compiler-builtins/compiler-builtins/src/float/mul.rs b/library/compiler-builtins/compiler-builtins/src/float/mul.rs
index 7f1f19d9bd7..dbed3095cda 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/mul.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/mul.rs
@@ -143,7 +143,7 @@ where
         // a zero of the appropriate sign.  Mathematically there is no need to
         // handle this case separately, but we make it a special case to
         // simplify the shift logic.
-        let shift = one.wrapping_sub(product_exponent.cast()).cast();
+        let shift: u32 = one.wrapping_sub(product_exponent.cast_lossy()).cast();
         if shift >= bits {
             return F::from_bits(product_sign);
         }
diff --git a/library/compiler-builtins/compiler-builtins/src/float/pow.rs b/library/compiler-builtins/compiler-builtins/src/float/pow.rs
index 45a4ad9049d..6997a9c213c 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/pow.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/pow.rs
@@ -32,8 +32,6 @@ intrinsics! {
 
     #[ppc_alias = __powikf2]
     #[cfg(f128_enabled)]
-    // FIXME(f16_f128): MSVC cannot build these until `__divtf3` is available in nightly.
-    #[cfg(not(target_env = "msvc"))]
     pub extern "C" fn __powitf2(a: f128, b: i32) -> f128 {
         pow(a, b)
     }
diff --git a/library/compiler-builtins/compiler-builtins/src/float/traits.rs b/library/compiler-builtins/compiler-builtins/src/float/traits.rs
index 8ccaa7bcbd7..a30d20900b1 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/traits.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/traits.rs
@@ -20,10 +20,10 @@ pub trait Float:
     + ops::Rem<Output = Self>
 {
     /// A uint of the same width as the float
-    type Int: Int<OtherSign = Self::SignedInt, UnsignedInt = Self::Int>;
+    type Int: Int<OtherSign = Self::SignedInt, Unsigned = Self::Int>;
 
     /// A int of the same width as the float
-    type SignedInt: Int + MinInt<OtherSign = Self::Int, UnsignedInt = Self::Int>;
+    type SignedInt: Int + MinInt<OtherSign = Self::Int, Unsigned = Self::Int>;
 
     /// An int capable of containing the exponent bits plus a sign bit. This is signed.
     type ExpInt: Int;
diff --git a/library/compiler-builtins/compiler-builtins/src/float/trunc.rs b/library/compiler-builtins/compiler-builtins/src/float/trunc.rs
index ca8a0f368b5..93db5d8bbde 100644
--- a/library/compiler-builtins/compiler-builtins/src/float/trunc.rs
+++ b/library/compiler-builtins/compiler-builtins/src/float/trunc.rs
@@ -50,7 +50,7 @@ where
         // The exponent of a is within the range of normal numbers in the
         // destination format.  We can convert by simply right-shifting with
         // rounding and adjusting the exponent.
-        abs_result = (a_abs >> sig_bits_delta).cast();
+        abs_result = (a_abs >> sig_bits_delta).cast_lossy();
         // Cast before shifting to prevent overflow.
         let bias_diff: R::Int = src_exp_bias.wrapping_sub(dst_exp_bias).cast();
         let tmp = bias_diff << R::SIG_BITS;
diff --git a/library/compiler-builtins/compiler-builtins/src/int/addsub.rs b/library/compiler-builtins/compiler-builtins/src/int/addsub.rs
index 1f84e8eb1e1..b2b21fc2c44 100644
--- a/library/compiler-builtins/compiler-builtins/src/int/addsub.rs
+++ b/library/compiler-builtins/compiler-builtins/src/int/addsub.rs
@@ -22,7 +22,7 @@ impl UAddSub for u128 {}
 
 trait AddSub: Int
 where
-    <Self as MinInt>::UnsignedInt: UAddSub,
+    <Self as MinInt>::Unsigned: UAddSub,
 {
     fn add(self, other: Self) -> Self {
         Self::from_unsigned(self.unsigned().uadd(other.unsigned()))
@@ -37,7 +37,7 @@ impl AddSub for i128 {}
 
 trait Addo: AddSub
 where
-    <Self as MinInt>::UnsignedInt: UAddSub,
+    <Self as MinInt>::Unsigned: UAddSub,
 {
     fn addo(self, other: Self) -> (Self, bool) {
         let sum = AddSub::add(self, other);
@@ -50,7 +50,7 @@ impl Addo for u128 {}
 
 trait Subo: AddSub
 where
-    <Self as MinInt>::UnsignedInt: UAddSub,
+    <Self as MinInt>::Unsigned: UAddSub,
 {
     fn subo(self, other: Self) -> (Self, bool) {
         let sum = AddSub::sub(self, other);
diff --git a/library/compiler-builtins/compiler-builtins/src/int/big.rs b/library/compiler-builtins/compiler-builtins/src/int/big.rs
index 1402efb8ed4..8e06009090c 100644
--- a/library/compiler-builtins/compiler-builtins/src/int/big.rs
+++ b/library/compiler-builtins/compiler-builtins/src/int/big.rs
@@ -45,7 +45,7 @@ impl i256 {
 impl MinInt for u256 {
     type OtherSign = i256;
 
-    type UnsignedInt = u256;
+    type Unsigned = u256;
 
     const SIGNED: bool = false;
     const BITS: u32 = 256;
@@ -58,7 +58,7 @@ impl MinInt for u256 {
 impl MinInt for i256 {
     type OtherSign = u256;
 
-    type UnsignedInt = u256;
+    type Unsigned = u256;
 
     const SIGNED: bool = false;
     const BITS: u32 = 256;
diff --git a/library/compiler-builtins/compiler-builtins/src/int/leading_zeros.rs b/library/compiler-builtins/compiler-builtins/src/int/leading_zeros.rs
index 112f4d03613..aa5cb39935a 100644
--- a/library/compiler-builtins/compiler-builtins/src/int/leading_zeros.rs
+++ b/library/compiler-builtins/compiler-builtins/src/int/leading_zeros.rs
@@ -9,11 +9,14 @@ pub use implementation::{leading_zeros_default, leading_zeros_riscv};
 pub(crate) use implementation::{leading_zeros_default, leading_zeros_riscv};
 
 mod implementation {
-    use crate::int::{CastInto, Int};
+    use crate::int::{CastFrom, Int};
 
     /// Returns the number of leading binary zeros in `x`.
     #[allow(dead_code)]
-    pub fn leading_zeros_default<T: Int + CastInto<usize>>(x: T) -> usize {
+    pub fn leading_zeros_default<I: Int>(x: I) -> usize
+    where
+        usize: CastFrom<I>,
+    {
         // The basic idea is to test if the higher bits of `x` are zero and bisect the number
         // of leading zeros. It is possible for all branches of the bisection to use the same
         // code path by conditionally shifting the higher parts down to let the next bisection
@@ -23,44 +26,48 @@ mod implementation {
         // because it simplifies the final bisection step.
         let mut x = x;
         // the number of potential leading zeros
-        let mut z = T::BITS as usize;
+        let mut z = I::BITS as usize;
         // a temporary
-        let mut t: T;
+        let mut t: I;
 
-        const { assert!(T::BITS <= 64) };
-        if T::BITS >= 64 {
+        const { assert!(I::BITS <= 64) };
+        if I::BITS >= 64 {
             t = x >> 32;
-            if t != T::ZERO {
+            if t != I::ZERO {
                 z -= 32;
                 x = t;
             }
         }
-        if T::BITS >= 32 {
+        if I::BITS >= 32 {
             t = x >> 16;
-            if t != T::ZERO {
+            if t != I::ZERO {
                 z -= 16;
                 x = t;
             }
         }
-        const { assert!(T::BITS >= 16) };
+        const { assert!(I::BITS >= 16) };
         t = x >> 8;
-        if t != T::ZERO {
+        if t != I::ZERO {
             z -= 8;
             x = t;
         }
         t = x >> 4;
-        if t != T::ZERO {
+        if t != I::ZERO {
             z -= 4;
             x = t;
         }
         t = x >> 2;
-        if t != T::ZERO {
+        if t != I::ZERO {
             z -= 2;
             x = t;
         }
         // the last two bisections are combined into one conditional
         t = x >> 1;
-        if t != T::ZERO { z - 2 } else { z - x.cast() }
+        if t != I::ZERO {
+            z - 2
+        } else {
+            z - usize::cast_from(x)
+        }
 
         // We could potentially save a few cycles by using the LUT trick from
         // "https://embeddedgurus.com/state-space/2014/09/
@@ -82,10 +89,13 @@ mod implementation {
 
     /// Returns the number of leading binary zeros in `x`.
     #[allow(dead_code)]
-    pub fn leading_zeros_riscv<T: Int + CastInto<usize>>(x: T) -> usize {
+    pub fn leading_zeros_riscv<I: Int>(x: I) -> usize
+    where
+        usize: CastFrom<I>,
+    {
         let mut x = x;
         // the number of potential leading zeros
-        let mut z = T::BITS;
+        let mut z = I::BITS;
         // a temporary
         let mut t: u32;
 
@@ -97,11 +107,11 @@ mod implementation {
         // right). If we try to save an instruction by using `x < imm` for each bisection, we
         // have to shift `x` left and compare with powers of two approaching `usize::MAX + 1`,
         // but the immediate will never fit into 12 bits and never save an instruction.
-        const { assert!(T::BITS <= 64) };
-        if T::BITS >= 64 {
+        const { assert!(I::BITS <= 64) };
+        if I::BITS >= 64 {
             // If the upper 32 bits of `x` are not all 0, `t` is set to `1 << 5`, otherwise
             // `t` is set to 0.
-            t = ((x >= (T::ONE << 32)) as u32) << 5;
+            t = ((x >= (I::ONE << 32)) as u32) << 5;
             // If `t` was set to `1 << 5`, then the upper 32 bits are shifted down for the
             // next step to process.
             x >>= t;
@@ -109,27 +119,27 @@ mod implementation {
             // leading zeros
             z -= t;
         }
-        if T::BITS >= 32 {
-            t = ((x >= (T::ONE << 16)) as u32) << 4;
+        if I::BITS >= 32 {
+            t = ((x >= (I::ONE << 16)) as u32) << 4;
             x >>= t;
             z -= t;
         }
-        const { assert!(T::BITS >= 16) };
-        t = ((x >= (T::ONE << 8)) as u32) << 3;
+        const { assert!(I::BITS >= 16) };
+        t = ((x >= (I::ONE << 8)) as u32) << 3;
         x >>= t;
         z -= t;
-        t = ((x >= (T::ONE << 4)) as u32) << 2;
+        t = ((x >= (I::ONE << 4)) as u32) << 2;
         x >>= t;
         z -= t;
-        t = ((x >= (T::ONE << 2)) as u32) << 1;
+        t = ((x >= (I::ONE << 2)) as u32) << 1;
         x >>= t;
         z -= t;
-        t = (x >= (T::ONE << 1)) as u32;
+        t = (x >= (I::ONE << 1)) as u32;
         x >>= t;
         z -= t;
         // All bits except the LSB are guaranteed to be zero for this final bisection step.
         // If `x != 0` then `x == 1` and subtracts one potential zero from `z`.
-        z as usize - x.cast()
+        z as usize - usize::cast_from(x)
     }
 }
 
diff --git a/library/compiler-builtins/compiler-builtins/src/int/specialized_div_rem/mod.rs b/library/compiler-builtins/compiler-builtins/src/int/specialized_div_rem/mod.rs
index 43f466e75ba..7841e4f33cd 100644
--- a/library/compiler-builtins/compiler-builtins/src/int/specialized_div_rem/mod.rs
+++ b/library/compiler-builtins/compiler-builtins/src/int/specialized_div_rem/mod.rs
@@ -125,10 +125,10 @@ impl_normalization_shift!(
 /// dependencies.
 #[inline]
 fn u64_by_u64_div_rem(duo: u64, div: u64) -> (u64, u64) {
-    if let Some(quo) = duo.checked_div(div) {
-        if let Some(rem) = duo.checked_rem(div) {
-            return (quo, rem);
-        }
+    if let Some(quo) = duo.checked_div(div)
+        && let Some(rem) = duo.checked_rem(div)
+    {
+        return (quo, rem);
     }
     zero_div_fn()
 }
@@ -227,10 +227,10 @@ impl_asymmetric!(
 #[inline]
 #[allow(dead_code)]
 fn u32_by_u32_div_rem(duo: u32, div: u32) -> (u32, u32) {
-    if let Some(quo) = duo.checked_div(div) {
-        if let Some(rem) = duo.checked_rem(div) {
-            return (quo, rem);
-        }
+    if let Some(quo) = duo.checked_div(div)
+        && let Some(rem) = duo.checked_rem(div)
+    {
+        return (quo, rem);
     }
     zero_div_fn()
 }
diff --git a/library/compiler-builtins/compiler-builtins/src/int/trailing_zeros.rs b/library/compiler-builtins/compiler-builtins/src/int/trailing_zeros.rs
index c45d6b1cfe8..1b0ae5b73ad 100644
--- a/library/compiler-builtins/compiler-builtins/src/int/trailing_zeros.rs
+++ b/library/compiler-builtins/compiler-builtins/src/int/trailing_zeros.rs
@@ -4,33 +4,38 @@ pub use implementation::trailing_zeros;
 pub(crate) use implementation::trailing_zeros;
 
 mod implementation {
-    use crate::int::{CastInto, Int};
+    use crate::int::{CastFrom, Int};
 
     /// Returns number of trailing binary zeros in `x`.
     #[allow(dead_code)]
-    pub fn trailing_zeros<T: Int + CastInto<u32> + CastInto<u16> + CastInto<u8>>(x: T) -> usize {
+    pub fn trailing_zeros<I: Int>(x: I) -> usize
+    where
+        u32: CastFrom<I>,
+        u16: CastFrom<I>,
+        u8: CastFrom<I>,
+    {
         let mut x = x;
         let mut r: u32 = 0;
         let mut t: u32;
 
-        const { assert!(T::BITS <= 64) };
-        if T::BITS >= 64 {
-            r += ((CastInto::<u32>::cast(x) == 0) as u32) << 5; // if (x has no 32 small bits) t = 32 else 0
+        const { assert!(I::BITS <= 64) };
+        if I::BITS >= 64 {
+            r += ((u32::cast_from_lossy(x) == 0) as u32) << 5; // if (x has no 32 small bits) t = 32 else 0
             x >>= r; // remove 32 zero bits
         }
 
-        if T::BITS >= 32 {
-            t = ((CastInto::<u16>::cast(x) == 0) as u32) << 4; // if (x has no 16 small bits) t = 16 else 0
+        if I::BITS >= 32 {
+            t = ((u16::cast_from_lossy(x) == 0) as u32) << 4; // if (x has no 16 small bits) t = 16 else 0
             r += t;
             x >>= t; // x = [0 - 0xFFFF] + higher garbage bits
         }
 
-        const { assert!(T::BITS >= 16) };
-        t = ((CastInto::<u8>::cast(x) == 0) as u32) << 3;
+        const { assert!(I::BITS >= 16) };
+        t = ((u8::cast_from_lossy(x) == 0) as u32) << 3;
         x >>= t; // x = [0 - 0xFF] + higher garbage bits
         r += t;
 
-        let mut x: u8 = x.cast();
+        let mut x: u8 = x.cast_lossy();
 
         t = (((x & 0x0F) == 0) as u32) << 2;
         x >>= t; // x = [0 - 0xF] + higher garbage bits
diff --git a/library/compiler-builtins/compiler-builtins/src/int/traits.rs b/library/compiler-builtins/compiler-builtins/src/int/traits.rs
index 152cb2eee2e..25b9718ad53 100644
--- a/library/compiler-builtins/compiler-builtins/src/int/traits.rs
+++ b/library/compiler-builtins/compiler-builtins/src/int/traits.rs
@@ -1,275 +1,4 @@
-use core::ops;
-
-/// Minimal integer implementations needed on all integer types, including wide integers.
-#[allow(dead_code)]
-pub trait MinInt:
-    Copy
-    + core::fmt::Debug
-    + ops::BitOr<Output = Self>
-    + ops::Not<Output = Self>
-    + ops::Shl<u32, Output = Self>
-{
-    /// Type with the same width but other signedness
-    type OtherSign: MinInt;
-    /// Unsigned version of Self
-    type UnsignedInt: MinInt;
-
-    /// If `Self` is a signed integer
-    const SIGNED: bool;
-
-    /// The bitwidth of the int type
-    const BITS: u32;
-
-    const ZERO: Self;
-    const ONE: Self;
-    const MIN: Self;
-    const MAX: Self;
-}
-
-/// Trait for some basic operations on integers
-#[allow(dead_code)]
-pub trait Int:
-    MinInt
-    + PartialEq
-    + PartialOrd
-    + ops::AddAssign
-    + ops::SubAssign
-    + ops::BitAndAssign
-    + ops::BitOrAssign
-    + ops::BitXorAssign
-    + ops::ShlAssign<i32>
-    + ops::ShrAssign<u32>
-    + ops::Add<Output = Self>
-    + ops::Sub<Output = Self>
-    + ops::Mul<Output = Self>
-    + ops::Div<Output = Self>
-    + ops::Shr<u32, Output = Self>
-    + ops::BitXor<Output = Self>
-    + ops::BitAnd<Output = Self>
-{
-    /// LUT used for maximizing the space covered and minimizing the computational cost of fuzzing
-    /// in `builtins-test`. For example, Self = u128 produces [0,1,2,7,8,15,16,31,32,63,64,95,96,
-    /// 111,112,119,120,125,126,127].
-    const FUZZ_LENGTHS: [u8; 20] = make_fuzz_lengths(<Self as MinInt>::BITS);
-
-    /// The number of entries of `FUZZ_LENGTHS` actually used. The maximum is 20 for u128.
-    const FUZZ_NUM: usize = {
-        let log2 = (<Self as MinInt>::BITS - 1).count_ones() as usize;
-        if log2 == 3 {
-            // case for u8
-            6
-        } else {
-            // 3 entries on each extreme, 2 in the middle, and 4 for each scale of intermediate
-            // boundaries.
-            8 + (4 * (log2 - 4))
-        }
-    };
-
-    fn unsigned(self) -> Self::UnsignedInt;
-    fn from_unsigned(unsigned: Self::UnsignedInt) -> Self;
-    fn unsigned_abs(self) -> Self::UnsignedInt;
-
-    fn from_bool(b: bool) -> Self;
-
-    /// Prevents the need for excessive conversions between signed and unsigned
-    fn logical_shr(self, other: u32) -> Self;
-
-    /// Absolute difference between two integers.
-    fn abs_diff(self, other: Self) -> Self::UnsignedInt;
-
-    // copied from primitive integers, but put in a trait
-    fn is_zero(self) -> bool;
-    fn wrapping_neg(self) -> Self;
-    fn wrapping_add(self, other: Self) -> Self;
-    fn wrapping_mul(self, other: Self) -> Self;
-    fn wrapping_sub(self, other: Self) -> Self;
-    fn wrapping_shl(self, other: u32) -> Self;
-    fn wrapping_shr(self, other: u32) -> Self;
-    fn rotate_left(self, other: u32) -> Self;
-    fn overflowing_add(self, other: Self) -> (Self, bool);
-    fn leading_zeros(self) -> u32;
-    fn ilog2(self) -> u32;
-}
-
-pub(crate) const fn make_fuzz_lengths(bits: u32) -> [u8; 20] {
-    let mut v = [0u8; 20];
-    v[0] = 0;
-    v[1] = 1;
-    v[2] = 2; // important for parity and the iX::MIN case when reversed
-    let mut i = 3;
-
-    // No need for any more until the byte boundary, because there should be no algorithms
-    // that are sensitive to anything not next to byte boundaries after 2. We also scale
-    // in powers of two, which is important to prevent u128 corner tests from getting too
-    // big.
-    let mut l = 8;
-    loop {
-        if l >= ((bits / 2) as u8) {
-            break;
-        }
-        // get both sides of the byte boundary
-        v[i] = l - 1;
-        i += 1;
-        v[i] = l;
-        i += 1;
-        l *= 2;
-    }
-
-    if bits != 8 {
-        // add the lower side of the middle boundary
-        v[i] = ((bits / 2) - 1) as u8;
-        i += 1;
-    }
-
-    // We do not want to jump directly from the Self::BITS/2 boundary to the Self::BITS
-    // boundary because of algorithms that split the high part up. We reverse the scaling
-    // as we go to Self::BITS.
-    let mid = i;
-    let mut j = 1;
-    loop {
-        v[i] = (bits as u8) - (v[mid - j]) - 1;
-        if j == mid {
-            break;
-        }
-        i += 1;
-        j += 1;
-    }
-    v
-}
-
-macro_rules! int_impl_common {
-    ($ty:ty) => {
-        fn from_bool(b: bool) -> Self {
-            b as $ty
-        }
-
-        fn logical_shr(self, other: u32) -> Self {
-            Self::from_unsigned(self.unsigned().wrapping_shr(other))
-        }
-
-        fn is_zero(self) -> bool {
-            self == Self::ZERO
-        }
-
-        fn wrapping_neg(self) -> Self {
-            <Self>::wrapping_neg(self)
-        }
-
-        fn wrapping_add(self, other: Self) -> Self {
-            <Self>::wrapping_add(self, other)
-        }
-
-        fn wrapping_mul(self, other: Self) -> Self {
-            <Self>::wrapping_mul(self, other)
-        }
-        fn wrapping_sub(self, other: Self) -> Self {
-            <Self>::wrapping_sub(self, other)
-        }
-
-        fn wrapping_shl(self, other: u32) -> Self {
-            <Self>::wrapping_shl(self, other)
-        }
-
-        fn wrapping_shr(self, other: u32) -> Self {
-            <Self>::wrapping_shr(self, other)
-        }
-
-        fn rotate_left(self, other: u32) -> Self {
-            <Self>::rotate_left(self, other)
-        }
-
-        fn overflowing_add(self, other: Self) -> (Self, bool) {
-            <Self>::overflowing_add(self, other)
-        }
-
-        fn leading_zeros(self) -> u32 {
-            <Self>::leading_zeros(self)
-        }
-
-        fn ilog2(self) -> u32 {
-            <Self>::ilog2(self)
-        }
-    };
-}
-
-macro_rules! int_impl {
-    ($ity:ty, $uty:ty) => {
-        impl MinInt for $uty {
-            type OtherSign = $ity;
-            type UnsignedInt = $uty;
-
-            const BITS: u32 = <Self as MinInt>::ZERO.count_zeros();
-            const SIGNED: bool = Self::MIN != Self::ZERO;
-
-            const ZERO: Self = 0;
-            const ONE: Self = 1;
-            const MIN: Self = <Self>::MIN;
-            const MAX: Self = <Self>::MAX;
-        }
-
-        impl Int for $uty {
-            fn unsigned(self) -> $uty {
-                self
-            }
-
-            // It makes writing macros easier if this is implemented for both signed and unsigned
-            #[allow(clippy::wrong_self_convention)]
-            fn from_unsigned(me: $uty) -> Self {
-                me
-            }
-
-            fn unsigned_abs(self) -> Self {
-                self
-            }
-
-            fn abs_diff(self, other: Self) -> Self {
-                self.abs_diff(other)
-            }
-
-            int_impl_common!($uty);
-        }
-
-        impl MinInt for $ity {
-            type OtherSign = $uty;
-            type UnsignedInt = $uty;
-
-            const BITS: u32 = <Self as MinInt>::ZERO.count_zeros();
-            const SIGNED: bool = Self::MIN != Self::ZERO;
-
-            const ZERO: Self = 0;
-            const ONE: Self = 1;
-            const MIN: Self = <Self>::MIN;
-            const MAX: Self = <Self>::MAX;
-        }
-
-        impl Int for $ity {
-            fn unsigned(self) -> $uty {
-                self as $uty
-            }
-
-            fn from_unsigned(me: $uty) -> Self {
-                me as $ity
-            }
-
-            fn unsigned_abs(self) -> Self::UnsignedInt {
-                self.unsigned_abs()
-            }
-
-            fn abs_diff(self, other: Self) -> $uty {
-                self.abs_diff(other)
-            }
-
-            int_impl_common!($ity);
-        }
-    };
-}
-
-int_impl!(isize, usize);
-int_impl!(i8, u8);
-int_impl!(i16, u16);
-int_impl!(i32, u32);
-int_impl!(i64, u64);
-int_impl!(i128, u128);
+pub use crate::support::{CastFrom, CastInto, Int, MinInt};
 
 /// Trait for integers twice the bit width of another integer. This is implemented for all
 /// primitives except for `u8`, because there is not a smaller primitive.
@@ -368,44 +97,3 @@ impl_h_int!(
     i32 u32 i64,
     i64 u64 i128
 );
-
-/// Trait to express (possibly lossy) casting of integers
-pub trait CastInto<T: Copy>: Copy {
-    fn cast(self) -> T;
-}
-
-pub trait CastFrom<T: Copy>: Copy {
-    fn cast_from(value: T) -> Self;
-}
-
-impl<T: Copy, U: CastInto<T> + Copy> CastFrom<U> for T {
-    fn cast_from(value: U) -> Self {
-        value.cast()
-    }
-}
-
-macro_rules! cast_into {
-    ($ty:ty) => {
-        cast_into!($ty; usize, isize, u8, i8, u16, i16, u32, i32, u64, i64, u128, i128);
-    };
-    ($ty:ty; $($into:ty),*) => {$(
-        impl CastInto<$into> for $ty {
-            fn cast(self) -> $into {
-                self as $into
-            }
-        }
-    )*};
-}
-
-cast_into!(usize);
-cast_into!(isize);
-cast_into!(u8);
-cast_into!(i8);
-cast_into!(u16);
-cast_into!(i16);
-cast_into!(u32);
-cast_into!(i32);
-cast_into!(u64);
-cast_into!(i64);
-cast_into!(u128);
-cast_into!(i128);
diff --git a/library/compiler-builtins/compiler-builtins/src/lib.rs b/library/compiler-builtins/compiler-builtins/src/lib.rs
index 6a6b28067e8..6549d4cef9e 100644
--- a/library/compiler-builtins/compiler-builtins/src/lib.rs
+++ b/library/compiler-builtins/compiler-builtins/src/lib.rs
@@ -8,6 +8,7 @@
 #![feature(linkage)]
 #![feature(naked_functions)]
 #![feature(repr_simd)]
+#![feature(rustc_attrs)]
 #![cfg_attr(f16_enabled, feature(f16))]
 #![cfg_attr(f128_enabled, feature(f128))]
 #![no_builtins]
diff --git a/library/compiler-builtins/compiler-builtins/src/macros.rs b/library/compiler-builtins/compiler-builtins/src/macros.rs
index 22e0dd27f2f..203cd0949ac 100644
--- a/library/compiler-builtins/compiler-builtins/src/macros.rs
+++ b/library/compiler-builtins/compiler-builtins/src/macros.rs
@@ -132,7 +132,7 @@ macro_rules! intrinsics {
     ) => (
         #[cfg($name = "optimized-c")]
         pub $(unsafe $($empty)? )? extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
-            extern $abi {
+            unsafe extern $abi {
                 fn $name($($argname: $ty),*) $(-> $ret)?;
             }
             unsafe {
@@ -435,7 +435,7 @@ macro_rules! intrinsics {
         pub mod $name {
             #[unsafe(naked)]
             $(#[$($attr)*])*
-            #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
+            #[cfg_attr(not(feature = "mangled-names"), unsafe(no_mangle))]
             #[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
             pub unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
                 $($body)*
diff --git a/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs b/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs
index 5cbe83ab1e2..fb29eb11b23 100644
--- a/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs
+++ b/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs
@@ -69,7 +69,7 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, count: usize) {
         "rep movsb",
         "sub $7, %rsi",
         "sub $7, %rdi",
-        "mov {qword_count}, %rcx",
+        "mov {qword_count:r}, %rcx",
         "rep movsq",
         "test {pre_byte_count:e}, {pre_byte_count:e}",
         "add $7, %rsi",
@@ -212,7 +212,7 @@ pub unsafe fn c_string_length(mut s: *const core::ffi::c_char) -> usize {
     let x = {
         let r;
         asm!(
-            "movdqa ({addr}), {dest}",
+            "movdqa ({addr:r}), {dest}",
             addr = in(reg) s,
             dest = out(xmm_reg) r,
             options(att_syntax, nostack),
@@ -232,7 +232,7 @@ pub unsafe fn c_string_length(mut s: *const core::ffi::c_char) -> usize {
         let x = {
             let r;
             asm!(
-                "movdqa ({addr}), {dest}",
+                "movdqa ({addr:r}), {dest}",
                 addr = in(reg) s,
                 dest = out(xmm_reg) r,
                 options(att_syntax, nostack),
diff --git a/library/compiler-builtins/compiler-builtins/src/probestack.rs b/library/compiler-builtins/compiler-builtins/src/probestack.rs
index 5b6abd21a1d..1441fd73b8d 100644
--- a/library/compiler-builtins/compiler-builtins/src/probestack.rs
+++ b/library/compiler-builtins/compiler-builtins/src/probestack.rs
@@ -49,302 +49,198 @@
 // We only define stack probing for these architectures today.
 #![cfg(any(target_arch = "x86_64", target_arch = "x86"))]
 
-extern "C" {
-    pub fn __rust_probestack();
-}
-
-// A wrapper for our implementation of __rust_probestack, which allows us to
-// keep the assembly inline while controlling all CFI directives in the assembly
-// emitted for the function.
-//
-// This is the ELF version.
-#[cfg(not(any(target_vendor = "apple", target_os = "uefi")))]
-macro_rules! define_rust_probestack {
-    ($body: expr) => {
-        concat!(
-            "
-            .pushsection .text.__rust_probestack
-            .globl __rust_probestack
-            .type  __rust_probestack, @function
-            .hidden __rust_probestack
-        __rust_probestack:
-            ",
-            $body,
-            "
-            .size __rust_probestack, . - __rust_probestack
-            .popsection
-            "
-        )
-    };
-}
-
-#[cfg(all(target_os = "uefi", target_arch = "x86_64"))]
-macro_rules! define_rust_probestack {
-    ($body: expr) => {
-        concat!(
-            "
-            .globl __rust_probestack
-        __rust_probestack:
-            ",
-            $body
-        )
-    };
-}
-
-// Same as above, but for Mach-O. Note that the triple underscore
-// is deliberate
-#[cfg(target_vendor = "apple")]
-macro_rules! define_rust_probestack {
-    ($body: expr) => {
-        concat!(
-            "
-            .globl ___rust_probestack
-        ___rust_probestack:
-            ",
-            $body
-        )
-    };
-}
-
-// In UEFI x86 arch, triple underscore is deliberate.
-#[cfg(all(target_os = "uefi", target_arch = "x86"))]
-macro_rules! define_rust_probestack {
-    ($body: expr) => {
-        concat!(
-            "
-            .globl ___rust_probestack
-        ___rust_probestack:
-            ",
-            $body
-        )
-    };
-}
-
 // Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax,
 // ensuring that if any pages are unmapped we'll make a page fault.
 //
+// FIXME(abi_custom): This function is unsafe because it uses a custom ABI,
+// it does not actually match `extern "C"`.
+//
 // The ABI here is that the stack frame size is located in `%rax`. Upon
 // return we're not supposed to modify `%rsp` or `%rax`.
-//
-// Any changes to this function should be replicated to the SGX version below.
-#[cfg(all(
-    target_arch = "x86_64",
-    not(all(target_env = "sgx", target_vendor = "fortanix"))
-))]
-core::arch::global_asm!(
-    define_rust_probestack!(
-        "
-    .cfi_startproc
-    pushq  %rbp
-    .cfi_adjust_cfa_offset 8
-    .cfi_offset %rbp, -16
-    movq   %rsp, %rbp
-    .cfi_def_cfa_register %rbp
-
-    mov    %rax,%r11        // duplicate %rax as we're clobbering %r11
-
-    // Main loop, taken in one page increments. We're decrementing rsp by
-    // a page each time until there's less than a page remaining. We're
-    // guaranteed that this function isn't called unless there's more than a
-    // page needed.
-    //
-    // Note that we're also testing against `8(%rsp)` to account for the 8
-    // bytes pushed on the stack orginally with our return address. Using
-    // `8(%rsp)` simulates us testing the stack pointer in the caller's
-    // context.
-
-    // It's usually called when %rax >= 0x1000, but that's not always true.
-    // Dynamic stack allocation, which is needed to implement unsized
-    // rvalues, triggers stackprobe even if %rax < 0x1000.
-    // Thus we have to check %r11 first to avoid segfault.
-    cmp    $0x1000,%r11
-    jna    3f
-2:
-    sub    $0x1000,%rsp
-    test   %rsp,8(%rsp)
-    sub    $0x1000,%r11
-    cmp    $0x1000,%r11
-    ja     2b
-
-3:
-    // Finish up the last remaining stack space requested, getting the last
-    // bits out of r11
-    sub    %r11,%rsp
-    test   %rsp,8(%rsp)
-
-    // Restore the stack pointer to what it previously was when entering
-    // this function. The caller will readjust the stack pointer after we
-    // return.
-    add    %rax,%rsp
-
-    leave
-    .cfi_def_cfa_register %rsp
-    .cfi_adjust_cfa_offset -8
-    ret
-    .cfi_endproc
-    "
-    ),
-    options(att_syntax)
-);
+#[cfg(target_arch = "x86_64")]
+#[unsafe(naked)]
+#[rustc_std_internal_symbol]
+pub unsafe extern "C" fn __rust_probestack() {
+    #[cfg(not(all(target_env = "sgx", target_vendor = "fortanix")))]
+    macro_rules! ret {
+        () => {
+            "ret"
+        };
+    }
+
+    #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))]
+    macro_rules! ret {
+        // for this target, [manually patch for LVI].
+        //
+        // [manually patch for LVI]: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions
+        () => {
+            "
+            pop %r11
+            lfence
+            jmp *%r11
+            "
+        };
+    }
 
-// This function is the same as above, except that some instructions are
-// [manually patched for LVI].
-//
-// [manually patched for LVI]: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions
-#[cfg(all(
-    target_arch = "x86_64",
-    all(target_env = "sgx", target_vendor = "fortanix")
-))]
-core::arch::global_asm!(
-    define_rust_probestack!(
+    core::arch::naked_asm!(
         "
-    .cfi_startproc
-    pushq  %rbp
-    .cfi_adjust_cfa_offset 8
-    .cfi_offset %rbp, -16
-    movq   %rsp, %rbp
-    .cfi_def_cfa_register %rbp
-
-    mov    %rax,%r11        // duplicate %rax as we're clobbering %r11
-
-    // Main loop, taken in one page increments. We're decrementing rsp by
-    // a page each time until there's less than a page remaining. We're
-    // guaranteed that this function isn't called unless there's more than a
-    // page needed.
-    //
-    // Note that we're also testing against `8(%rsp)` to account for the 8
-    // bytes pushed on the stack orginally with our return address. Using
-    // `8(%rsp)` simulates us testing the stack pointer in the caller's
-    // context.
-
-    // It's usually called when %rax >= 0x1000, but that's not always true.
-    // Dynamic stack allocation, which is needed to implement unsized
-    // rvalues, triggers stackprobe even if %rax < 0x1000.
-    // Thus we have to check %r11 first to avoid segfault.
-    cmp    $0x1000,%r11
-    jna    3f
-2:
-    sub    $0x1000,%rsp
-    test   %rsp,8(%rsp)
-    sub    $0x1000,%r11
-    cmp    $0x1000,%r11
-    ja     2b
-
-3:
-    // Finish up the last remaining stack space requested, getting the last
-    // bits out of r11
-    sub    %r11,%rsp
-    test   %rsp,8(%rsp)
-
-    // Restore the stack pointer to what it previously was when entering
-    // this function. The caller will readjust the stack pointer after we
-    // return.
-    add    %rax,%rsp
-
-    leave
-    .cfi_def_cfa_register %rsp
-    .cfi_adjust_cfa_offset -8
-    pop %r11
-    lfence
-    jmp *%r11
-    .cfi_endproc
-    "
-    ),
-    options(att_syntax)
-);
+            .cfi_startproc
+            pushq  %rbp
+            .cfi_adjust_cfa_offset 8
+            .cfi_offset %rbp, -16
+            movq   %rsp, %rbp
+            .cfi_def_cfa_register %rbp
+
+            mov    %rax,%r11        // duplicate %rax as we're clobbering %r11
+
+            // Main loop, taken in one page increments. We're decrementing rsp by
+            // a page each time until there's less than a page remaining. We're
+            // guaranteed that this function isn't called unless there's more than a
+            // page needed.
+            //
+            // Note that we're also testing against `8(%rsp)` to account for the 8
+            // bytes pushed on the stack orginally with our return address. Using
+            // `8(%rsp)` simulates us testing the stack pointer in the caller's
+            // context.
+
+            // It's usually called when %rax >= 0x1000, but that's not always true.
+            // Dynamic stack allocation, which is needed to implement unsized
+            // rvalues, triggers stackprobe even if %rax < 0x1000.
+            // Thus we have to check %r11 first to avoid segfault.
+            cmp    $0x1000,%r11
+            jna    3f
+        2:
+            sub    $0x1000,%rsp
+            test   %rsp,8(%rsp)
+            sub    $0x1000,%r11
+            cmp    $0x1000,%r11
+            ja     2b
+
+        3:
+            // Finish up the last remaining stack space requested, getting the last
+            // bits out of r11
+            sub    %r11,%rsp
+            test   %rsp,8(%rsp)
+
+            // Restore the stack pointer to what it previously was when entering
+            // this function. The caller will readjust the stack pointer after we
+            // return.
+            add    %rax,%rsp
+
+            leave
+            .cfi_def_cfa_register %rsp
+            .cfi_adjust_cfa_offset -8
+    ",
+        ret!(),
+        "
+            .cfi_endproc
+    ",
+        options(att_syntax)
+    )
+}
 
 #[cfg(all(target_arch = "x86", not(target_os = "uefi")))]
 // This is the same as x86_64 above, only translated for 32-bit sizes. Note
 // that on Unix we're expected to restore everything as it was, this
 // function basically can't tamper with anything.
 //
+// FIXME(abi_custom): This function is unsafe because it uses a custom ABI,
+// it does not actually match `extern "C"`.
+//
 // The ABI here is the same as x86_64, except everything is 32-bits large.
-core::arch::global_asm!(
-    define_rust_probestack!(
+#[unsafe(naked)]
+#[rustc_std_internal_symbol]
+pub unsafe extern "C" fn __rust_probestack() {
+    core::arch::naked_asm!(
         "
-    .cfi_startproc
-    push   %ebp
-    .cfi_adjust_cfa_offset 4
-    .cfi_offset %ebp, -8
-    mov    %esp, %ebp
-    .cfi_def_cfa_register %ebp
-    push   %ecx
-    mov    %eax,%ecx
-
-    cmp    $0x1000,%ecx
-    jna    3f
-2:
-    sub    $0x1000,%esp
-    test   %esp,8(%esp)
-    sub    $0x1000,%ecx
-    cmp    $0x1000,%ecx
-    ja     2b
-
-3:
-    sub    %ecx,%esp
-    test   %esp,8(%esp)
-
-    add    %eax,%esp
-    pop    %ecx
-    leave
-    .cfi_def_cfa_register %esp
-    .cfi_adjust_cfa_offset -4
-    ret
-    .cfi_endproc
-    "
-    ),
-    options(att_syntax)
-);
+            .cfi_startproc
+            push   %ebp
+            .cfi_adjust_cfa_offset 4
+            .cfi_offset %ebp, -8
+            mov    %esp, %ebp
+            .cfi_def_cfa_register %ebp
+            push   %ecx
+            mov    %eax,%ecx
+
+            cmp    $0x1000,%ecx
+            jna    3f
+        2:
+            sub    $0x1000,%esp
+            test   %esp,8(%esp)
+            sub    $0x1000,%ecx
+            cmp    $0x1000,%ecx
+            ja     2b
+
+        3:
+            sub    %ecx,%esp
+            test   %esp,8(%esp)
+
+            add    %eax,%esp
+            pop    %ecx
+            leave
+            .cfi_def_cfa_register %esp
+            .cfi_adjust_cfa_offset -4
+            ret
+            .cfi_endproc
+    ",
+        options(att_syntax)
+    )
+}
 
 #[cfg(all(target_arch = "x86", target_os = "uefi"))]
 // UEFI target is windows like target. LLVM will do _chkstk things like windows.
 // probestack function will also do things like _chkstk in MSVC.
 // So we need to sub %ax %sp in probestack when arch is x86.
 //
+// FIXME(abi_custom): This function is unsafe because it uses a custom ABI,
+// it does not actually match `extern "C"`.
+//
 // REF: Rust commit(74e80468347)
 // rust\src\llvm-project\llvm\lib\Target\X86\X86FrameLowering.cpp: 805
 // Comments in LLVM:
 //   MSVC x32's _chkstk and cygwin/mingw's _alloca adjust %esp themselves.
 //   MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp
 //   themselves.
-core::arch::global_asm!(
-    define_rust_probestack!(
+#[unsafe(naked)]
+#[rustc_std_internal_symbol]
+pub unsafe extern "C" fn __rust_probestack() {
+    core::arch::naked_asm!(
         "
-    .cfi_startproc
-    push   %ebp
-    .cfi_adjust_cfa_offset 4
-    .cfi_offset %ebp, -8
-    mov    %esp, %ebp
-    .cfi_def_cfa_register %ebp
-    push   %ecx
-    push   %edx
-    mov    %eax,%ecx
-
-    cmp    $0x1000,%ecx
-    jna    3f
-2:
-    sub    $0x1000,%esp
-    test   %esp,8(%esp)
-    sub    $0x1000,%ecx
-    cmp    $0x1000,%ecx
-    ja     2b
-
-3:
-    sub    %ecx,%esp
-    test   %esp,8(%esp)
-    mov    4(%ebp),%edx
-    mov    %edx, 12(%esp)
-    add    %eax,%esp
-    pop    %edx
-    pop    %ecx
-    leave
-
-    sub   %eax, %esp
-    .cfi_def_cfa_register %esp
-    .cfi_adjust_cfa_offset -4
-    ret
-    .cfi_endproc
-    "
-    ),
-    options(att_syntax)
-);
+            .cfi_startproc
+            push   %ebp
+            .cfi_adjust_cfa_offset 4
+            .cfi_offset %ebp, -8
+            mov    %esp, %ebp
+            .cfi_def_cfa_register %ebp
+            push   %ecx
+            push   %edx
+            mov    %eax,%ecx
+
+            cmp    $0x1000,%ecx
+            jna    3f
+        2:
+            sub    $0x1000,%esp
+            test   %esp,8(%esp)
+            sub    $0x1000,%ecx
+            cmp    $0x1000,%ecx
+            ja     2b
+
+        3:
+            sub    %ecx,%esp
+            test   %esp,8(%esp)
+            mov    4(%ebp),%edx
+            mov    %edx, 12(%esp)
+            add    %eax,%esp
+            pop    %edx
+            pop    %ecx
+            leave
+
+            sub   %eax, %esp
+            .cfi_def_cfa_register %esp
+            .cfi_adjust_cfa_offset -4
+            ret
+            .cfi_endproc
+    ",
+        options(att_syntax)
+    )
+}
diff --git a/library/compiler-builtins/crates/josh-sync/Cargo.toml b/library/compiler-builtins/crates/josh-sync/Cargo.toml
new file mode 100644
index 00000000000..1f3bb376d6d
--- /dev/null
+++ b/library/compiler-builtins/crates/josh-sync/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "josh-sync"
+edition = "2024"
+publish = false
+
+[dependencies]
+directories = "6.0.0"
diff --git a/library/compiler-builtins/crates/josh-sync/src/main.rs b/library/compiler-builtins/crates/josh-sync/src/main.rs
new file mode 100644
index 00000000000..7f0b1190033
--- /dev/null
+++ b/library/compiler-builtins/crates/josh-sync/src/main.rs
@@ -0,0 +1,45 @@
+use std::io::{Read, Write};
+use std::process::exit;
+use std::{env, io};
+
+use crate::sync::{GitSync, Josh};
+
+mod sync;
+
+const USAGE: &str = r#"Utility for synchroniing compiler-builtins with rust-lang/rust
+
+Usage:
+
+    josh-sync rustc-pull
+
+        Pull from rust-lang/rust to compiler-builtins. Creates a commit
+        updating the version file, followed by a merge commit.
+
+    josh-sync rustc-push GITHUB_USERNAME [BRANCH]
+
+        Create a branch off of rust-lang/rust updating compiler-builtins.
+"#;
+
+fn main() {
+    let sync = GitSync::from_current_dir();
+
+    // Collect args, then recollect as str refs so we can match on them
+    let args: Vec<_> = env::args().collect();
+    let args: Vec<&str> = args.iter().map(String::as_str).collect();
+
+    match args.as_slice()[1..] {
+        ["rustc-pull"] => sync.rustc_pull(None),
+        ["rustc-push", github_user, branch] => sync.rustc_push(github_user, Some(branch)),
+        ["rustc-push", github_user] => sync.rustc_push(github_user, None),
+        ["start-josh"] => {
+            let _josh = Josh::start();
+            println!("press enter to stop");
+            io::stdout().flush().unwrap();
+            let _ = io::stdin().read(&mut [0u8]).unwrap();
+        }
+        _ => {
+            println!("{USAGE}");
+            exit(1);
+        }
+    }
+}
diff --git a/library/compiler-builtins/crates/josh-sync/src/sync.rs b/library/compiler-builtins/crates/josh-sync/src/sync.rs
new file mode 100644
index 00000000000..003cf187d83
--- /dev/null
+++ b/library/compiler-builtins/crates/josh-sync/src/sync.rs
@@ -0,0 +1,371 @@
+use std::net::{SocketAddr, TcpStream};
+use std::process::{Command, Stdio, exit};
+use std::time::Duration;
+use std::{env, fs, process, thread};
+
+const JOSH_PORT: u16 = 42042;
+const DEFAULT_PR_BRANCH: &str = "update-builtins";
+
+pub struct GitSync {
+    upstream_repo: String,
+    upstream_ref: String,
+    upstream_url: String,
+    josh_filter: String,
+    josh_url_base: String,
+}
+
+/// This code was adapted from the miri repository, via the rustc-dev-guide
+/// (<https://github.com/rust-lang/rustc-dev-guide/tree/c51adbd12d/josh-sync>)
+impl GitSync {
+    pub fn from_current_dir() -> Self {
+        let upstream_repo =
+            env::var("UPSTREAM_ORG").unwrap_or_else(|_| "rust-lang".to_owned()) + "/rust";
+
+        Self {
+            upstream_url: format!("https://github.com/{upstream_repo}"),
+            upstream_repo,
+            upstream_ref: env::var("UPSTREAM_REF").unwrap_or_else(|_| "HEAD".to_owned()),
+            josh_filter: ":/library/compiler-builtins".to_owned(),
+            josh_url_base: format!("http://localhost:{JOSH_PORT}"),
+        }
+    }
+
+    /// Pull from rust-lang/rust to compiler-builtins.
+    pub fn rustc_pull(&self, commit: Option<String>) {
+        let Self {
+            upstream_ref,
+            upstream_url,
+            upstream_repo,
+            ..
+        } = self;
+
+        let new_upstream_base = commit.unwrap_or_else(|| {
+            let out = check_output(["git", "ls-remote", upstream_url, upstream_ref]);
+            out.split_whitespace()
+                .next()
+                .unwrap_or_else(|| panic!("could not split output: '{out}'"))
+                .to_owned()
+        });
+
+        ensure_clean();
+
+        // Make sure josh is running.
+        let _josh = Josh::start();
+        let josh_url_filtered = self.josh_url(
+            &self.upstream_repo,
+            Some(&new_upstream_base),
+            Some(&self.josh_filter),
+        );
+
+        let previous_upstream_base = fs::read_to_string("rust-version")
+            .expect("failed to read `rust-version`")
+            .trim()
+            .to_string();
+        assert_ne!(previous_upstream_base, new_upstream_base, "nothing to pull");
+
+        let orig_head = check_output(["git", "rev-parse", "HEAD"]);
+        println!("original upstream base: {previous_upstream_base}");
+        println!("new upstream base: {new_upstream_base}");
+        println!("original HEAD: {orig_head}");
+
+        // Fetch the latest upstream HEAD so we can get a summary. Use the Josh URL for caching.
+        run([
+            "git",
+            "fetch",
+            &self.josh_url(&self.upstream_repo, Some(&new_upstream_base), Some(":/")),
+            &new_upstream_base,
+            "--depth=1",
+        ]);
+        let new_summary = check_output(["git", "log", "-1", "--format=%h %s", &new_upstream_base]);
+
+        // Update rust-version file. As a separate commit, since making it part of
+        // the merge has confused the heck out of josh in the past.
+        // We pass `--no-verify` to avoid running git hooks.
+        // We do this before the merge so that if there are merge conflicts, we have
+        // the right rust-version file while resolving them.
+        fs::write("rust-version", format!("{new_upstream_base}\n"))
+            .expect("failed to write rust-version");
+
+        let prep_message = format!(
+            "Update the upstream Rust version\n\n\
+            To prepare for merging from {upstream_repo}, set the version file to:\n\n    \
+            {new_summary}\n\
+            ",
+        );
+        run([
+            "git",
+            "commit",
+            "rust-version",
+            "--no-verify",
+            "-m",
+            &prep_message,
+        ]);
+
+        // Fetch given rustc commit.
+        run(["git", "fetch", &josh_url_filtered]);
+        let incoming_ref = check_output(["git", "rev-parse", "FETCH_HEAD"]);
+        println!("incoming ref: {incoming_ref}");
+
+        let merge_message = format!(
+            "Merge ref '{upstream_head_short}{filter}' from {upstream_url}\n\n\
+            Pull recent changes from {upstream_repo} via Josh.\n\n\
+            Upstream ref: {new_upstream_base}\n\
+            Filtered ref: {incoming_ref}\n\
+            ",
+            upstream_head_short = &new_upstream_base[..12],
+            filter = self.josh_filter
+        );
+
+        // This should not add any new root commits. So count those before and after merging.
+        let num_roots = || -> u32 {
+            let out = check_output(["git", "rev-list", "HEAD", "--max-parents=0", "--count"]);
+            out.trim()
+                .parse::<u32>()
+                .unwrap_or_else(|e| panic!("failed to parse `{out}`: {e}"))
+        };
+        let num_roots_before = num_roots();
+
+        let pre_merge_sha = check_output(["git", "rev-parse", "HEAD"]);
+        println!("pre-merge HEAD: {pre_merge_sha}");
+
+        // Merge the fetched commit.
+        run([
+            "git",
+            "merge",
+            "FETCH_HEAD",
+            "--no-verify",
+            "--no-ff",
+            "-m",
+            &merge_message,
+        ]);
+
+        let current_sha = check_output(["git", "rev-parse", "HEAD"]);
+        if current_sha == pre_merge_sha {
+            run(["git", "reset", "--hard", &orig_head]);
+            eprintln!(
+                "No merge was performed, no changes to pull were found. \
+                Rolled back the preparation commit."
+            );
+            exit(1);
+        }
+
+        // Check that the number of roots did not increase.
+        assert_eq!(
+            num_roots(),
+            num_roots_before,
+            "Josh created a new root commit. This is probably not the history you want."
+        );
+    }
+
+    /// Construct an update to rust-lang/rust from compiler-builtins.
+    pub fn rustc_push(&self, github_user: &str, branch: Option<&str>) {
+        let Self {
+            josh_filter,
+            upstream_url,
+            ..
+        } = self;
+
+        let branch = branch.unwrap_or(DEFAULT_PR_BRANCH);
+        let josh_url = self.josh_url(&format!("{github_user}/rust"), None, Some(josh_filter));
+        let user_upstream_url = format!("git@github.com:{github_user}/rust.git");
+
+        let Ok(rustc_git) = env::var("RUSTC_GIT") else {
+            panic!("the RUSTC_GIT environment variable must be set to a rust-lang/rust checkout")
+        };
+
+        ensure_clean();
+        let base = fs::read_to_string("rust-version")
+            .expect("failed to read `rust-version`")
+            .trim()
+            .to_string();
+
+        // Make sure josh is running.
+        let _josh = Josh::start();
+
+        // Prepare the branch. Pushing works much better if we use as base exactly
+        // the commit that we pulled from last time, so we use the `rust-version`
+        // file to find out which commit that would be.
+        println!("Preparing {github_user}/rust (base: {base})...");
+
+        if Command::new("git")
+            .args(["-C", &rustc_git, "fetch", &user_upstream_url, branch])
+            .output() // capture output
+            .expect("could not run fetch")
+            .status
+            .success()
+        {
+            panic!(
+                "The branch '{branch}' seems to already exist in '{user_upstream_url}'. \
+                 Please delete it and try again."
+            );
+        }
+
+        run(["git", "-C", &rustc_git, "fetch", upstream_url, &base]);
+
+        run_cfg("git", |c| {
+            c.args([
+                "-C",
+                &rustc_git,
+                "push",
+                &user_upstream_url,
+                &format!("{base}:refs/heads/{branch}"),
+            ])
+            .stdout(Stdio::null())
+            .stderr(Stdio::null()) // silence the "create GitHub PR" message
+        });
+        println!("pushed PR branch");
+
+        // Do the actual push.
+        println!("Pushing changes...");
+        run(["git", "push", &josh_url, &format!("HEAD:{branch}")]);
+        println!();
+
+        // Do a round-trip check to make sure the push worked as expected.
+        run(["git", "fetch", &josh_url, branch]);
+
+        let head = check_output(["git", "rev-parse", "HEAD"]);
+        let fetch_head = check_output(["git", "rev-parse", "FETCH_HEAD"]);
+        assert_eq!(
+            head, fetch_head,
+            "Josh created a non-roundtrip push! Do NOT merge this into rustc!\n\
+             Expected {head}, got {fetch_head}."
+        );
+        println!(
+            "Confirmed that the push round-trips back to compiler-builtins properly. Please \
+            create a rustc PR:"
+        );
+        // Open PR with `subtree update` title to silence the `no-merges` triagebot check
+        println!(
+            "    {upstream_url}/compare/{github_user}:{branch}?quick_pull=1\
+            &title=Update%20the%20%60compiler-builtins%60%20subtree\
+            &body=Update%20the%20Josh%20subtree%20to%20https%3A%2F%2Fgithub.com%2Frust-lang%2F\
+            compiler-builtins%2Fcommit%2F{head_short}.%0A%0Ar%3F%20%40ghost",
+            head_short = &head[..12],
+        );
+    }
+
+    /// Construct a url to the local Josh server with (optionally)
+    fn josh_url(&self, repo: &str, rev: Option<&str>, filter: Option<&str>) -> String {
+        format!(
+            "{base}/{repo}.git{at}{rev}{filter}{filt_git}",
+            base = self.josh_url_base,
+            at = if rev.is_some() { "@" } else { "" },
+            rev = rev.unwrap_or_default(),
+            filter = filter.unwrap_or_default(),
+            filt_git = if filter.is_some() { ".git" } else { "" }
+        )
+    }
+}
+
+/// Fail if there are files that need to be checked in.
+fn ensure_clean() {
+    let read = check_output(["git", "status", "--untracked-files=no", "--porcelain"]);
+    assert!(
+        read.is_empty(),
+        "working directory must be clean before performing rustc pull"
+    );
+}
+
+/* Helpers for running commands with logged invocations */
+
+/// Run a command from an array, passing its output through.
+fn run<'a, Args: AsRef<[&'a str]>>(l: Args) {
+    let l = l.as_ref();
+    run_cfg(l[0], |c| c.args(&l[1..]));
+}
+
+/// Run a command from an array, collecting its output.
+fn check_output<'a, Args: AsRef<[&'a str]>>(l: Args) -> String {
+    let l = l.as_ref();
+    check_output_cfg(l[0], |c| c.args(&l[1..]))
+}
+
+/// [`run`] with configuration.
+fn run_cfg(prog: &str, f: impl FnOnce(&mut Command) -> &mut Command) {
+    // self.read(l.as_ref());
+    check_output_cfg(prog, |c| f(c.stdout(Stdio::inherit())));
+}
+
+/// [`read`] with configuration. All shell helpers print the command and pass stderr.
+fn check_output_cfg(prog: &str, f: impl FnOnce(&mut Command) -> &mut Command) -> String {
+    let mut cmd = Command::new(prog);
+    cmd.stderr(Stdio::inherit());
+    f(&mut cmd);
+    eprintln!("+ {cmd:?}");
+    let out = cmd.output().expect("command failed");
+    assert!(out.status.success());
+    String::from_utf8(out.stdout.trim_ascii().to_vec()).expect("non-UTF8 output")
+}
+
+/// Create a wrapper that stops Josh on drop.
+pub struct Josh(process::Child);
+
+impl Josh {
+    pub fn start() -> Self {
+        // Determine cache directory.
+        let user_dirs =
+            directories::ProjectDirs::from("org", "rust-lang", "rustc-compiler-builtins-josh")
+                .unwrap();
+        let local_dir = user_dirs.cache_dir().to_owned();
+
+        // Start josh, silencing its output.
+        #[expect(clippy::zombie_processes, reason = "clippy can't handle the loop")]
+        let josh = process::Command::new("josh-proxy")
+            .arg("--local")
+            .arg(local_dir)
+            .args([
+                "--remote=https://github.com",
+                &format!("--port={JOSH_PORT}"),
+                "--no-background",
+            ])
+            .stdout(Stdio::null())
+            .stderr(Stdio::null())
+            .spawn()
+            .expect("failed to start josh-proxy, make sure it is installed");
+
+        // Wait until the port is open. We try every 10ms until 1s passed.
+        for _ in 0..100 {
+            // This will generally fail immediately when the port is still closed.
+            let addr = SocketAddr::from(([127, 0, 0, 1], JOSH_PORT));
+            let josh_ready = TcpStream::connect_timeout(&addr, Duration::from_millis(1));
+
+            if josh_ready.is_ok() {
+                println!("josh up and running");
+                return Josh(josh);
+            }
+
+            // Not ready yet.
+            thread::sleep(Duration::from_millis(10));
+        }
+        panic!("Even after waiting for 1s, josh-proxy is still not available.")
+    }
+}
+
+impl Drop for Josh {
+    fn drop(&mut self) {
+        if cfg!(unix) {
+            // Try to gracefully shut it down.
+            Command::new("kill")
+                .args(["-s", "INT", &self.0.id().to_string()])
+                .output()
+                .expect("failed to SIGINT josh-proxy");
+            // Sadly there is no "wait with timeout"... so we just give it some time to finish.
+            thread::sleep(Duration::from_millis(100));
+            // Now hopefully it is gone.
+            if self
+                .0
+                .try_wait()
+                .expect("failed to wait for josh-proxy")
+                .is_some()
+            {
+                return;
+            }
+        }
+        // If that didn't work (or we're not on Unix), kill it hard.
+        eprintln!(
+            "I have to kill josh-proxy the hard way, let's hope this does not \
+            break anything."
+        );
+        self.0.kill().expect("failed to SIGKILL josh-proxy");
+    }
+}
diff --git a/library/compiler-builtins/crates/libm-macros/Cargo.toml b/library/compiler-builtins/crates/libm-macros/Cargo.toml
index 3929854f08e..6bbf47784ff 100644
--- a/library/compiler-builtins/crates/libm-macros/Cargo.toml
+++ b/library/compiler-builtins/crates/libm-macros/Cargo.toml
@@ -10,9 +10,9 @@ proc-macro = true
 
 [dependencies]
 heck = "0.5.0"
-proc-macro2 = "1.0.94"
+proc-macro2 = "1.0.95"
 quote = "1.0.40"
-syn = { version = "2.0.100", features = ["full", "extra-traits", "visit-mut"] }
+syn = { version = "2.0.101", features = ["full", "extra-traits", "visit-mut"] }
 
 [lints.rust]
 # Values used during testing
diff --git a/library/compiler-builtins/crates/musl-math-sys/Cargo.toml b/library/compiler-builtins/crates/musl-math-sys/Cargo.toml
index d3fb147e526..3b88117343b 100644
--- a/library/compiler-builtins/crates/musl-math-sys/Cargo.toml
+++ b/library/compiler-builtins/crates/musl-math-sys/Cargo.toml
@@ -11,4 +11,4 @@ license = "MIT OR Apache-2.0"
 libm = { path = "../../libm" }
 
 [build-dependencies]
-cc = "1.2.16"
+cc = "1.2.25"
diff --git a/library/compiler-builtins/crates/musl-math-sys/build.rs b/library/compiler-builtins/crates/musl-math-sys/build.rs
index b00dbc73e28..59e42f2d2e6 100644
--- a/library/compiler-builtins/crates/musl-math-sys/build.rs
+++ b/library/compiler-builtins/crates/musl-math-sys/build.rs
@@ -120,7 +120,7 @@ fn build_musl_math(cfg: &Config) {
     let arch_dir = musl_dir.join("arch").join(&cfg.musl_arch);
     assert!(
         math.exists(),
-        "musl source not found. Is the submodule up to date?"
+        "musl source not found. You may need to run `./ci/update-musl.sh`."
     );
 
     let source_map = find_math_source(&math, cfg);
diff --git a/library/compiler-builtins/crates/musl-math-sys/musl b/library/compiler-builtins/crates/musl-math-sys/musl
deleted file mode 160000
-Subproject c47ad25ea3b484e10326f933e927c0bc8cded3d
diff --git a/library/compiler-builtins/crates/panic-handler/src/lib.rs b/library/compiler-builtins/crates/panic-handler/src/lib.rs
index 673e005224b..f4d7c839740 100644
--- a/library/compiler-builtins/crates/panic-handler/src/lib.rs
+++ b/library/compiler-builtins/crates/panic-handler/src/lib.rs
@@ -1,11 +1,8 @@
 //! This is needed for tests on targets that require a `#[panic_handler]` function
 
-#![feature(no_core)]
-#![no_core]
-
-extern crate core;
+#![no_std]
 
 #[panic_handler]
-fn panic(_: &core::panic::PanicInfo) -> ! {
+fn panic(_: &core::panic::PanicInfo<'_>) -> ! {
     loop {}
 }
diff --git a/library/compiler-builtins/crates/symbol-check/Cargo.toml b/library/compiler-builtins/crates/symbol-check/Cargo.toml
new file mode 100644
index 00000000000..30969ee406a
--- /dev/null
+++ b/library/compiler-builtins/crates/symbol-check/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "symbol-check"
+version = "0.1.0"
+edition = "2024"
+publish = false
+
+[dependencies]
+# FIXME: used as a git dependency since the latest release does not support wasm
+object = { git = "https://github.com/gimli-rs/object.git", rev = "013fac75da56a684377af4151b8164b78c1790e0" }
+serde_json = "1.0.140"
+
+[features]
+wasm = ["object/wasm"]
diff --git a/library/compiler-builtins/crates/symbol-check/src/main.rs b/library/compiler-builtins/crates/symbol-check/src/main.rs
new file mode 100644
index 00000000000..d83cd318d6a
--- /dev/null
+++ b/library/compiler-builtins/crates/symbol-check/src/main.rs
@@ -0,0 +1,232 @@
+//! Tool used by CI to inspect compiler-builtins archives and help ensure we won't run into any
+//! linking errors.
+
+use std::collections::{BTreeMap, BTreeSet};
+use std::fs;
+use std::io::{BufRead, BufReader};
+use std::path::{Path, PathBuf};
+use std::process::{Command, Stdio};
+
+use object::read::archive::{ArchiveFile, ArchiveMember};
+use object::{Object, ObjectSymbol, Symbol, SymbolKind, SymbolScope, SymbolSection};
+use serde_json::Value;
+
+const CHECK_LIBRARIES: &[&str] = &["compiler_builtins", "builtins_test_intrinsics"];
+const CHECK_EXTENSIONS: &[Option<&str>] = &[Some("rlib"), Some("a"), Some("exe"), None];
+
+const USAGE: &str = "Usage:
+
+    symbol-check build-and-check CARGO_ARGS ...
+
+Cargo will get invoked with `CARGO_ARGS` and all output
+`compiler_builtins*.rlib` files will be checked.
+";
+
+fn main() {
+    // Create a `&str` vec so we can match on it.
+    let args = std::env::args().collect::<Vec<_>>();
+    let args_ref = args.iter().map(String::as_str).collect::<Vec<_>>();
+
+    match &args_ref[1..] {
+        ["build-and-check", rest @ ..] if !rest.is_empty() => {
+            let paths = exec_cargo_with_args(rest);
+            for path in paths {
+                println!("Checking {}", path.display());
+                verify_no_duplicates(&path);
+                verify_core_symbols(&path);
+            }
+        }
+        _ => {
+            println!("{USAGE}");
+            std::process::exit(1);
+        }
+    }
+}
+
+/// Run `cargo build` with the provided additional arguments, collecting the list of created
+/// libraries.
+fn exec_cargo_with_args(args: &[&str]) -> Vec<PathBuf> {
+    let mut cmd = Command::new("cargo");
+    cmd.arg("build")
+        .arg("--message-format=json")
+        .args(args)
+        .stdout(Stdio::piped());
+
+    println!("running: {cmd:?}");
+    let mut child = cmd.spawn().expect("failed to launch Cargo");
+
+    let stdout = child.stdout.take().unwrap();
+    let reader = BufReader::new(stdout);
+    let mut check_files = Vec::new();
+
+    for line in reader.lines() {
+        let line = line.expect("failed to read line");
+        println!("{line}"); // tee to stdout
+
+        // Select only steps that create files
+        let j: Value = serde_json::from_str(&line).expect("failed to deserialize");
+        if j["reason"] != "compiler-artifact" {
+            continue;
+        }
+
+        // Find rlibs in the created file list that match our expected library names and
+        // extensions.
+        for fpath in j["filenames"].as_array().expect("filenames not an array") {
+            let path = fpath.as_str().expect("file name not a string");
+            let path = PathBuf::from(path);
+
+            if CHECK_EXTENSIONS.contains(&path.extension().map(|ex| ex.to_str().unwrap())) {
+                let fname = path.file_name().unwrap().to_str().unwrap();
+
+                if CHECK_LIBRARIES.iter().any(|lib| fname.contains(lib)) {
+                    check_files.push(path);
+                }
+            }
+        }
+    }
+
+    assert!(child.wait().expect("failed to wait on Cargo").success());
+
+    assert!(!check_files.is_empty(), "no compiler_builtins rlibs found");
+    println!("Collected the following rlibs to check: {check_files:#?}");
+
+    check_files
+}
+
+/// Information collected from `object`, for convenience.
+#[expect(unused)] // only for printing
+#[derive(Clone, Debug)]
+struct SymInfo {
+    name: String,
+    kind: SymbolKind,
+    scope: SymbolScope,
+    section: SymbolSection,
+    is_undefined: bool,
+    is_global: bool,
+    is_local: bool,
+    is_weak: bool,
+    is_common: bool,
+    address: u64,
+    object: String,
+}
+
+impl SymInfo {
+    fn new(sym: &Symbol, member: &ArchiveMember) -> Self {
+        Self {
+            name: sym.name().expect("missing name").to_owned(),
+            kind: sym.kind(),
+            scope: sym.scope(),
+            section: sym.section(),
+            is_undefined: sym.is_undefined(),
+            is_global: sym.is_global(),
+            is_local: sym.is_local(),
+            is_weak: sym.is_weak(),
+            is_common: sym.is_common(),
+            address: sym.address(),
+            object: String::from_utf8_lossy(member.name()).into_owned(),
+        }
+    }
+}
+
+/// Ensure that the same global symbol isn't defined in multiple object files within an archive.
+///
+/// Note that this will also locate cases where a symbol is weakly defined in more than one place.
+/// Technically there are no linker errors that will come from this, but it keeps our binary more
+/// straightforward and saves some distribution size.
+fn verify_no_duplicates(path: &Path) {
+    let mut syms = BTreeMap::<String, SymInfo>::new();
+    let mut dups = Vec::new();
+    let mut found_any = false;
+
+    for_each_symbol(path, |symbol, member| {
+        // Only check defined globals
+        if !symbol.is_global() || symbol.is_undefined() {
+            return;
+        }
+
+        let sym = SymInfo::new(&symbol, member);
+
+        // x86-32 includes multiple copies of thunk symbols
+        if sym.name.starts_with("__x86.get_pc_thunk") {
+            return;
+        }
+
+        // Windows has symbols for literal numeric constants, string literals, and MinGW pseudo-
+        // relocations. These are allowed to have repeated definitions.
+        let win_allowed_dup_pfx = ["__real@", "__xmm@", "??_C@_", ".refptr"];
+        if win_allowed_dup_pfx
+            .iter()
+            .any(|pfx| sym.name.starts_with(pfx))
+        {
+            return;
+        }
+
+        match syms.get(&sym.name) {
+            Some(existing) => {
+                dups.push(sym);
+                dups.push(existing.clone());
+            }
+            None => {
+                syms.insert(sym.name.clone(), sym);
+            }
+        }
+
+        found_any = true;
+    });
+
+    assert!(found_any, "no symbols found");
+
+    if !dups.is_empty() {
+        dups.sort_unstable_by(|a, b| a.name.cmp(&b.name));
+        panic!("found duplicate symbols: {dups:#?}");
+    }
+
+    println!("    success: no duplicate symbols found");
+}
+
+/// Ensure that there are no references to symbols from `core` that aren't also (somehow) defined.
+fn verify_core_symbols(path: &Path) {
+    let mut defined = BTreeSet::new();
+    let mut undefined = Vec::new();
+    let mut has_symbols = false;
+
+    for_each_symbol(path, |symbol, member| {
+        has_symbols = true;
+
+        // Find only symbols from `core`
+        if !symbol.name().unwrap().contains("_ZN4core") {
+            return;
+        }
+
+        let sym = SymInfo::new(&symbol, member);
+        if sym.is_undefined {
+            undefined.push(sym);
+        } else {
+            defined.insert(sym.name);
+        }
+    });
+
+    assert!(has_symbols, "no symbols found");
+
+    // Discard any symbols that are defined somewhere in the archive
+    undefined.retain(|sym| !defined.contains(&sym.name));
+
+    if !undefined.is_empty() {
+        undefined.sort_unstable_by(|a, b| a.name.cmp(&b.name));
+        panic!("found undefined symbols from core: {undefined:#?}");
+    }
+
+    println!("    success: no undefined references to core found");
+}
+
+/// For a given archive path, do something with each symbol.
+fn for_each_symbol(path: &Path, mut f: impl FnMut(Symbol, &ArchiveMember)) {
+    let data = fs::read(path).expect("reading file failed");
+    let archive = ArchiveFile::parse(data.as_slice()).expect("archive parse failed");
+    for member in archive.members() {
+        let member = member.expect("failed to access member");
+        let obj_data = member.data(&*data).expect("failed to access object");
+        let obj = object::File::parse(obj_data).expect("failed to parse object");
+        obj.symbols().for_each(|sym| f(sym, &member));
+    }
+}
diff --git a/library/compiler-builtins/libm-test/Cargo.toml b/library/compiler-builtins/libm-test/Cargo.toml
index 7a306e73557..05fcc3234e0 100644
--- a/library/compiler-builtins/libm-test/Cargo.toml
+++ b/library/compiler-builtins/libm-test/Cargo.toml
@@ -6,7 +6,7 @@ publish = false
 license = "MIT OR Apache-2.0"
 
 [features]
-default = ["build-mpfr", "build-musl", "unstable-float"]
+default = ["build-mpfr", "unstable-float"]
 
 # Propagated from libm because this affects which functions we test.
 unstable-float = ["libm/unstable-float", "rug?/nightly-float"]
@@ -28,28 +28,28 @@ icount = ["dep:iai-callgrind"]
 short-benchmarks = []
 
 [dependencies]
-anyhow = "1.0.97"
+anyhow = "1.0.98"
 # This is not directly used but is required so we can enable `gmp-mpfr-sys/force-cross`.
-gmp-mpfr-sys = { version = "1.6.4", optional = true, default-features = false }
-iai-callgrind = { version = "0.14.0", optional = true }
+gmp-mpfr-sys = { version = "1.6.5", optional = true, default-features = false }
+iai-callgrind = { version = "0.14.1", optional = true }
 indicatif = { version = "0.17.11", default-features = false }
 libm = { path = "../libm", features = ["unstable-public-internals"] }
 libm-macros = { path = "../crates/libm-macros" }
 musl-math-sys = { path = "../crates/musl-math-sys", optional = true }
 paste = "1.0.15"
-rand = "0.9.0"
+rand = "0.9.1"
 rand_chacha = "0.9.0"
 rayon = "1.10.0"
 rug = { version = "1.27.0", optional = true, default-features = false, features = ["float", "integer", "std"] }
 
 [target.'cfg(target_family = "wasm")'.dependencies]
-getrandom = { version = "0.3.2", features = ["wasm_js"] }
+getrandom = { version = "0.3.3", features = ["wasm_js"] }
 
 [build-dependencies]
-rand = { version = "0.9.0", optional = true }
+rand = { version = "0.9.1", optional = true }
 
 [dev-dependencies]
-criterion = { version = "0.5.1", default-features = false, features = ["cargo_bench_support"] }
+criterion = { version = "0.6.0", default-features = false, features = ["cargo_bench_support"] }
 libtest-mimic = "0.8.1"
 
 [[bench]]
diff --git a/library/compiler-builtins/libm-test/benches/icount.rs b/library/compiler-builtins/libm-test/benches/icount.rs
index da8c6bfd15a..a0928a29f99 100644
--- a/library/compiler-builtins/libm-test/benches/icount.rs
+++ b/library/compiler-builtins/libm-test/benches/icount.rs
@@ -1,9 +1,11 @@
 //! Benchmarks that use `iai-cachegrind` to be reasonably CI-stable.
+#![feature(f16)]
+#![feature(f128)]
 
 use std::hint::black_box;
 
 use iai_callgrind::{library_benchmark, library_benchmark_group, main};
-use libm::support::{HInt, u256};
+use libm::support::{HInt, Hexf, hf16, hf32, hf64, hf128, u256};
 use libm_test::generate::spaced;
 use libm_test::{CheckBasis, CheckCtx, GeneratorKind, MathOp, OpRustArgs, TupleCall, op};
 
@@ -21,7 +23,7 @@ macro_rules! icount_benches {
                 let mut ctx = CheckCtx::new(
                     Op::IDENTIFIER,
                     CheckBasis::None,
-                    GeneratorKind::QuickSpaced
+                    GeneratorKind::Spaced
                 );
                 ctx.override_iterations(BENCH_ITER_ITEMS);
                 let ret = spaced::get_test_cases::<Op>(&ctx).0.collect::<Vec<_>>();
@@ -109,11 +111,6 @@ fn icount_bench_u128_widen_mul(cases: Vec<(u128, u128)>) {
     }
 }
 
-library_benchmark_group!(
-    name = icount_bench_u128_widen_mul_group;
-    benchmarks = icount_bench_u128_widen_mul
-);
-
 #[library_benchmark]
 #[bench::linspace(setup_u256_add())]
 fn icount_bench_u256_add(cases: Vec<(u256, u256)>) {
@@ -122,11 +119,6 @@ fn icount_bench_u256_add(cases: Vec<(u256, u256)>) {
     }
 }
 
-library_benchmark_group!(
-    name = icount_bench_u256_add_group;
-    benchmarks = icount_bench_u256_add
-);
-
 #[library_benchmark]
 #[bench::linspace(setup_u256_shift())]
 fn icount_bench_u256_shr(cases: Vec<(u256, u32)>) {
@@ -136,16 +128,90 @@ fn icount_bench_u256_shr(cases: Vec<(u256, u32)>) {
 }
 
 library_benchmark_group!(
-    name = icount_bench_u256_shr_group;
-    benchmarks = icount_bench_u256_shr
+    name = icount_bench_u128_group;
+    benchmarks = icount_bench_u128_widen_mul, icount_bench_u256_add, icount_bench_u256_shr
+);
+
+#[library_benchmark]
+#[bench::short("0x12.34p+8")]
+#[bench::max("0x1.ffcp+15")]
+fn icount_bench_hf16(s: &str) -> f16 {
+    black_box(hf16(s))
+}
+
+#[library_benchmark]
+#[bench::short("0x12.34p+8")]
+#[bench::max("0x1.fffffep+127")]
+fn icount_bench_hf32(s: &str) -> f32 {
+    black_box(hf32(s))
+}
+
+#[library_benchmark]
+#[bench::short("0x12.34p+8")]
+#[bench::max("0x1.fffffffffffffp+1023")]
+fn icount_bench_hf64(s: &str) -> f64 {
+    black_box(hf64(s))
+}
+
+#[library_benchmark]
+#[bench::short("0x12.34p+8")]
+#[bench::max("0x1.ffffffffffffffffffffffffffffp+16383")]
+fn icount_bench_hf128(s: &str) -> f128 {
+    black_box(hf128(s))
+}
+
+library_benchmark_group!(
+    name = icount_bench_hf_parse_group;
+    benchmarks =
+    icount_bench_hf16,
+    icount_bench_hf32,
+    icount_bench_hf64,
+    icount_bench_hf128
+);
+
+#[library_benchmark]
+#[bench::short(1.015625)]
+#[bench::max(f16::MAX)]
+fn icount_bench_print_hf16(x: f16) -> String {
+    black_box(Hexf(x).to_string())
+}
+
+#[library_benchmark]
+#[bench::short(1.015625)]
+#[bench::max(f32::MAX)]
+fn icount_bench_print_hf32(x: f32) -> String {
+    black_box(Hexf(x).to_string())
+}
+
+#[library_benchmark]
+#[bench::short(1.015625)]
+#[bench::max(f64::MAX)]
+fn icount_bench_print_hf64(x: f64) -> String {
+    black_box(Hexf(x).to_string())
+}
+
+#[library_benchmark]
+#[bench::short(1.015625)]
+#[bench::max(f128::MAX)]
+fn icount_bench_print_hf128(x: f128) -> String {
+    black_box(Hexf(x).to_string())
+}
+
+library_benchmark_group!(
+    name = icount_bench_hf_print_group;
+    benchmarks =
+    icount_bench_print_hf16,
+    icount_bench_print_hf32,
+    icount_bench_print_hf64,
+    icount_bench_print_hf128
 );
 
 main!(
     library_benchmark_groups =
-    // u256-related benchmarks
-    icount_bench_u128_widen_mul_group,
-    icount_bench_u256_add_group,
-    icount_bench_u256_shr_group,
+    // Benchmarks not related to public libm math
+    icount_bench_u128_group,
+    icount_bench_hf_parse_group,
+    icount_bench_hf_print_group,
     // verify-apilist-start
     // verify-sorted-start
     icount_bench_acos_group,
diff --git a/library/compiler-builtins/libm-test/examples/plot_domains.rs b/library/compiler-builtins/libm-test/examples/plot_domains.rs
index 3563103b8cd..7331d454f21 100644
--- a/library/compiler-builtins/libm-test/examples/plot_domains.rs
+++ b/library/compiler-builtins/libm-test/examples/plot_domains.rs
@@ -55,7 +55,7 @@ where
     Op: MathOp<FTy = f32, RustArgs = (f32,)>,
     Op::RustArgs: SpacedInput<Op>,
 {
-    let mut ctx = CheckCtx::new(Op::IDENTIFIER, CheckBasis::Mpfr, GeneratorKind::QuickSpaced);
+    let mut ctx = CheckCtx::new(Op::IDENTIFIER, CheckBasis::Mpfr, GeneratorKind::Spaced);
     plot_one_generator(
         out_dir,
         &ctx,
diff --git a/library/compiler-builtins/libm-test/src/generate/edge_cases.rs b/library/compiler-builtins/libm-test/src/generate/edge_cases.rs
index 2fb0746388c..4e4a782a169 100644
--- a/library/compiler-builtins/libm-test/src/generate/edge_cases.rs
+++ b/library/compiler-builtins/libm-test/src/generate/edge_cases.rs
@@ -51,6 +51,7 @@ where
 
     // Check some special values that aren't included in the above ranges
     values.push(Op::FTy::NAN);
+    values.push(Op::FTy::NEG_NAN);
     values.extend(Op::FTy::consts().iter());
 
     // Check around the maximum subnormal value
diff --git a/library/compiler-builtins/libm-test/src/precision.rs b/library/compiler-builtins/libm-test/src/precision.rs
index f5fb5f6707b..32825b15d47 100644
--- a/library/compiler-builtins/libm-test/src/precision.rs
+++ b/library/compiler-builtins/libm-test/src/precision.rs
@@ -381,7 +381,7 @@ fn unop_common<F1: Float, F2: Float>(
         }
 
         // abs and copysign require signaling NaNs to be propagated, so verify bit equality.
-        if actual.to_bits() == expected.to_bits() {
+        if actual.biteq(expected) {
             return CheckAction::Custom(Ok(()));
         } else {
             return CheckAction::Custom(Err(anyhow::anyhow!("NaNs have different bitpatterns")));
@@ -444,13 +444,18 @@ fn binop_common<F1: Float, F2: Float>(
     expected: F2,
     ctx: &CheckCtx,
 ) -> CheckAction {
-    // MPFR only has one NaN bitpattern; allow the default `.is_nan()` checks to validate. Skip if
-    // the first input (magnitude source) is NaN and the output is also a NaN, or if the second
-    // input (sign source) is NaN.
-    if ctx.basis == CheckBasis::Mpfr
+    // MPFR only has one NaN bitpattern; skip tests in cases where the first argument would take
+    // the sign of a NaN second argument. The default NaN checks cover other cases.
+    if ctx.base_name == BaseName::Copysign && ctx.basis == CheckBasis::Mpfr && input.1.is_nan() {
+        return SKIP;
+    }
+
+    // FIXME(#939): this should not be skipped, there is a bug in our implementationi.
+    if ctx.base_name == BaseName::FmaximumNum
+        && ctx.basis == CheckBasis::Mpfr
         && ((input.0.is_nan() && actual.is_nan() && expected.is_nan()) || input.1.is_nan())
     {
-        return SKIP;
+        return XFAIL_NOCHECK;
     }
 
     /* FIXME(#439): our fmin and fmax do not compare signed zeros */
diff --git a/library/compiler-builtins/libm-test/src/run_cfg.rs b/library/compiler-builtins/libm-test/src/run_cfg.rs
index 3345a01d2de..90f81195c85 100644
--- a/library/compiler-builtins/libm-test/src/run_cfg.rs
+++ b/library/compiler-builtins/libm-test/src/run_cfg.rs
@@ -22,13 +22,38 @@ static EXTENSIVE_ITER_OVERRIDE: LazyLock<Option<u64>> = LazyLock::new(|| {
 
 /// Specific tests that need to have a reduced amount of iterations to complete in a reasonable
 /// amount of time.
-///
-/// Contains the itentifier+generator combo to match on, plus the factor to reduce by.
-const EXTEMELY_SLOW_TESTS: &[(Identifier, GeneratorKind, u64)] = &[
-    (Identifier::Fmodf128, GeneratorKind::QuickSpaced, 50),
-    (Identifier::Fmodf128, GeneratorKind::Extensive, 50),
+const EXTREMELY_SLOW_TESTS: &[SlowTest] = &[
+    SlowTest {
+        ident: Identifier::Fmodf128,
+        gen_kind: GeneratorKind::Spaced,
+        extensive: false,
+        reduce_factor: 50,
+    },
+    SlowTest {
+        ident: Identifier::Fmodf128,
+        gen_kind: GeneratorKind::Spaced,
+        extensive: true,
+        reduce_factor: 50,
+    },
 ];
 
+/// A pattern to match a `CheckCtx`, plus a factor to reduce by.
+struct SlowTest {
+    ident: Identifier,
+    gen_kind: GeneratorKind,
+    extensive: bool,
+    reduce_factor: u64,
+}
+
+impl SlowTest {
+    /// True if the test in `CheckCtx` should be reduced by `reduce_factor`.
+    fn matches_ctx(&self, ctx: &CheckCtx) -> bool {
+        self.ident == ctx.fn_ident
+            && self.gen_kind == ctx.gen_kind
+            && self.extensive == ctx.extensive
+    }
+}
+
 /// Maximum number of iterations to run for a single routine.
 ///
 /// The default value of one greater than `u32::MAX` allows testing single-argument `f32` routines
@@ -54,6 +79,7 @@ pub struct CheckCtx {
     /// Source of truth for tests.
     pub basis: CheckBasis,
     pub gen_kind: GeneratorKind,
+    pub extensive: bool,
     /// If specified, this value will override the value returned by [`iteration_count`].
     pub override_iterations: Option<u64>,
 }
@@ -69,12 +95,19 @@ impl CheckCtx {
             base_name_str: fn_ident.base_name().as_str(),
             basis,
             gen_kind,
+            extensive: false,
             override_iterations: None,
         };
         ret.ulp = crate::default_ulp(&ret);
         ret
     }
 
+    /// Configure that this is an extensive test.
+    pub fn extensive(mut self, extensive: bool) -> Self {
+        self.extensive = extensive;
+        self
+    }
+
     /// The number of input arguments for this function.
     pub fn input_count(&self) -> usize {
         self.fn_ident.math_op().rust_sig.args.len()
@@ -100,14 +133,17 @@ pub enum CheckBasis {
 /// and quantity.
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum GeneratorKind {
+    /// Extremes, zeros, nonstandard numbers, etc.
     EdgeCases,
-    Extensive,
-    QuickSpaced,
+    /// Spaced by logarithm (floats) or linear (integers).
+    Spaced,
+    /// Test inputs from an RNG.
     Random,
+    /// A provided test case list.
     List,
 }
 
-/// A list of all functions that should get extensive tests.
+/// A list of all functions that should get extensive tests, as configured by environment variable.
 ///
 /// This also supports the special test name `all` to run all tests, as well as `all_f16`,
 /// `all_f32`, `all_f64`, and `all_f128` to run all tests for a specific float type.
@@ -216,17 +252,17 @@ pub fn iteration_count(ctx: &CheckCtx, argnum: usize) -> u64 {
     let random_iter_count = domain_iter_count / 100;
 
     let mut total_iterations = match ctx.gen_kind {
-        GeneratorKind::QuickSpaced => domain_iter_count,
+        GeneratorKind::Spaced if ctx.extensive => extensive_max_iterations(),
+        GeneratorKind::Spaced => domain_iter_count,
         GeneratorKind::Random => random_iter_count,
-        GeneratorKind::Extensive => extensive_max_iterations(),
         GeneratorKind::EdgeCases | GeneratorKind::List => {
             unimplemented!("shoudn't need `iteration_count` for {:?}", ctx.gen_kind)
         }
     };
 
     // Larger float types get more iterations.
-    if t_env.large_float_ty && ctx.gen_kind != GeneratorKind::Extensive {
-        if ctx.gen_kind == GeneratorKind::Extensive {
+    if t_env.large_float_ty {
+        if ctx.extensive {
             // Extensive already has a pretty high test count.
             total_iterations *= 2;
         } else {
@@ -244,13 +280,13 @@ pub fn iteration_count(ctx: &CheckCtx, argnum: usize) -> u64 {
     }
 
     // Some tests are significantly slower than others and need to be further reduced.
-    if let Some((_id, _gen, scale)) = EXTEMELY_SLOW_TESTS
+    if let Some(slow) = EXTREMELY_SLOW_TESTS
         .iter()
-        .find(|(id, generator, _scale)| *id == ctx.fn_ident && *generator == ctx.gen_kind)
+        .find(|slow| slow.matches_ctx(ctx))
     {
         // However, do not override if the extensive iteration count has been manually set.
-        if !(ctx.gen_kind == GeneratorKind::Extensive && EXTENSIVE_ITER_OVERRIDE.is_some()) {
-            total_iterations /= scale;
+        if !(ctx.extensive && EXTENSIVE_ITER_OVERRIDE.is_some()) {
+            total_iterations /= slow.reduce_factor;
         }
     }
 
@@ -279,7 +315,7 @@ pub fn iteration_count(ctx: &CheckCtx, argnum: usize) -> u64 {
     let total = ntests.pow(t_env.input_count.try_into().unwrap());
 
     let seed_msg = match ctx.gen_kind {
-        GeneratorKind::QuickSpaced | GeneratorKind::Extensive => String::new(),
+        GeneratorKind::Spaced => String::new(),
         GeneratorKind::Random => {
             format!(
                 " using `{SEED_ENV}={}`",
@@ -327,8 +363,8 @@ pub fn int_range(ctx: &CheckCtx, argnum: usize) -> RangeInclusive<i32> {
     let extensive_range = (-0xfff)..=0xfffff;
 
     match ctx.gen_kind {
-        GeneratorKind::Extensive => extensive_range,
-        GeneratorKind::QuickSpaced | GeneratorKind::Random => non_extensive_range,
+        _ if ctx.extensive => extensive_range,
+        GeneratorKind::Spaced | GeneratorKind::Random => non_extensive_range,
         GeneratorKind::EdgeCases => extensive_range,
         GeneratorKind::List => unimplemented!("shoudn't need range for {:?}", ctx.gen_kind),
     }
diff --git a/library/compiler-builtins/libm-test/src/test_traits.rs b/library/compiler-builtins/libm-test/src/test_traits.rs
index dbb97016153..278274d917b 100644
--- a/library/compiler-builtins/libm-test/src/test_traits.rs
+++ b/library/compiler-builtins/libm-test/src/test_traits.rs
@@ -312,12 +312,9 @@ where
     let mut inner = || -> TestResult {
         let mut allowed_ulp = ctx.ulp;
 
-        // Forbid overrides if the items came from an explicit list, as long as we are checking
-        // against either MPFR or the result itself.
-        let require_biteq = ctx.gen_kind == GeneratorKind::List && ctx.basis != CheckBasis::Musl;
-
         match SpecialCase::check_float(input, actual, expected, ctx) {
-            _ if require_biteq => (),
+            // Forbid overrides if the items came from an explicit list
+            _ if ctx.gen_kind == GeneratorKind::List => (),
             CheckAction::AssertSuccess => (),
             CheckAction::AssertFailure(msg) => assert_failure_msg = Some(msg),
             CheckAction::Custom(res) => return res,
@@ -327,12 +324,20 @@ where
 
         // Check when both are NaNs
         if actual.is_nan() && expected.is_nan() {
-            if require_biteq && ctx.basis == CheckBasis::None {
-                ensure!(
-                    actual.to_bits() == expected.to_bits(),
-                    "mismatched NaN bitpatterns"
-                );
+            // Don't assert NaN bitwise equality if:
+            //
+            // * Testing against MPFR (there is a single NaN representation)
+            // * Testing against Musl except for explicit tests (Musl does some NaN quieting)
+            //
+            // In these cases, just the check that actual and expected are both NaNs is
+            // sufficient.
+            let skip_nan_biteq = ctx.basis == CheckBasis::Mpfr
+                || (ctx.basis == CheckBasis::Musl && ctx.gen_kind != GeneratorKind::List);
+
+            if !skip_nan_biteq {
+                ensure!(actual.biteq(expected), "mismatched NaN bitpatterns");
             }
+
             // By default, NaNs have nothing special to check.
             return Ok(());
         } else if actual.is_nan() || expected.is_nan() {
diff --git a/library/compiler-builtins/libm-test/tests/compare_built_musl.rs b/library/compiler-builtins/libm-test/tests/compare_built_musl.rs
index 6ccbb6f4c51..86f3b8b711e 100644
--- a/library/compiler-builtins/libm-test/tests/compare_built_musl.rs
+++ b/library/compiler-builtins/libm-test/tests/compare_built_musl.rs
@@ -65,7 +65,7 @@ macro_rules! musl_tests {
             $(#[$attr])*
             fn [< musl_quickspace_ $fn_name >]() {
                 type Op = libm_test::op::$fn_name::Routine;
-                let ctx = CheckCtx::new(Op::IDENTIFIER, BASIS, GeneratorKind::QuickSpaced);
+                let ctx = CheckCtx::new(Op::IDENTIFIER, BASIS, GeneratorKind::Spaced);
                 let cases = spaced::get_test_cases::<Op>(&ctx).0;
                 musl_runner::<Op>(&ctx, cases, musl_math_sys::$fn_name);
             }
diff --git a/library/compiler-builtins/libm-test/tests/multiprecision.rs b/library/compiler-builtins/libm-test/tests/multiprecision.rs
index 80b2c78688e..60175ae6156 100644
--- a/library/compiler-builtins/libm-test/tests/multiprecision.rs
+++ b/library/compiler-builtins/libm-test/tests/multiprecision.rs
@@ -55,7 +55,7 @@ macro_rules! mp_tests {
             $(#[$attr])*
             fn [< mp_quickspace_ $fn_name >]() {
                 type Op = libm_test::op::$fn_name::Routine;
-                let ctx = CheckCtx::new(Op::IDENTIFIER, BASIS, GeneratorKind::QuickSpaced);
+                let ctx = CheckCtx::new(Op::IDENTIFIER, BASIS, GeneratorKind::Spaced);
                 let cases = spaced::get_test_cases::<Op>(&ctx).0;
                 mp_runner::<Op>(&ctx, cases);
             }
diff --git a/library/compiler-builtins/libm-test/tests/z_extensive/run.rs b/library/compiler-builtins/libm-test/tests/z_extensive/run.rs
index 59c806ce73e..f2ba6a4a0e3 100644
--- a/library/compiler-builtins/libm-test/tests/z_extensive/run.rs
+++ b/library/compiler-builtins/libm-test/tests/z_extensive/run.rs
@@ -17,7 +17,6 @@ use rayon::prelude::*;
 use spaced::SpacedInput;
 
 const BASIS: CheckBasis = CheckBasis::Mpfr;
-const GEN_KIND: GeneratorKind = GeneratorKind::Extensive;
 
 /// Run the extensive test suite.
 pub fn run() {
@@ -77,7 +76,7 @@ where
     Op::RustArgs: SpacedInput<Op> + Send,
 {
     let test_name = format!("mp_extensive_{}", Op::NAME);
-    let ctx = CheckCtx::new(Op::IDENTIFIER, BASIS, GEN_KIND);
+    let ctx = CheckCtx::new(Op::IDENTIFIER, BASIS, GeneratorKind::Spaced).extensive(true);
     let skip = skip_extensive_test(&ctx);
 
     let runner = move || {
diff --git a/library/compiler-builtins/libm/README.md b/library/compiler-builtins/libm/README.md
index 349e892dfcf..77608db3d0d 100644
--- a/library/compiler-builtins/libm/README.md
+++ b/library/compiler-builtins/libm/README.md
@@ -34,7 +34,7 @@ Usage is under the MIT license, available at
 ### Contribution
 
 Contributions are licensed under both the MIT license and the Apache License,
-Version 2.0, available at <htps://www.apache.org/licenses/LICENSE-2.0>. Unless
+Version 2.0, available at <https://www.apache.org/licenses/LICENSE-2.0>. Unless
 you explicitly state otherwise, any contribution intentionally submitted for
 inclusion in the work by you, as defined in the Apache-2.0 license, shall be
 dual licensed as mentioned, without any additional terms or conditions.
diff --git a/library/compiler-builtins/libm/src/math/arch/aarch64.rs b/library/compiler-builtins/libm/src/math/arch/aarch64.rs
index 020bb731cdc..8896804b504 100644
--- a/library/compiler-builtins/libm/src/math/arch/aarch64.rs
+++ b/library/compiler-builtins/libm/src/math/arch/aarch64.rs
@@ -30,6 +30,12 @@ pub fn fmaf(mut x: f32, y: f32, z: f32) -> f32 {
     x
 }
 
+// NB: `frintx` is technically the correct instruction for C's `rint`. However, in Rust (and LLVM
+// by default), `rint` is identical to `roundeven` (no fpenv interaction) so we use the
+// side-effect-free `frintn`.
+//
+// In general, C code that calls Rust's libm should assume that fpenv is ignored.
+
 pub fn rint(mut x: f64) -> f64 {
     // SAFETY: `frintn` is available with neon and has no side effects.
     //
diff --git a/library/compiler-builtins/libm/src/math/copysign.rs b/library/compiler-builtins/libm/src/math/copysign.rs
index d2a86e7fd54..d093d610727 100644
--- a/library/compiler-builtins/libm/src/math/copysign.rs
+++ b/library/compiler-builtins/libm/src/math/copysign.rs
@@ -59,9 +59,17 @@ mod tests {
 
         // Not required but we expect it
         assert_biteq!(f(F::NAN, F::NAN), F::NAN);
-        assert_biteq!(f(F::NEG_NAN, F::NAN), F::NAN);
+        assert_biteq!(f(F::NAN, F::ONE), F::NAN);
+        assert_biteq!(f(F::NAN, F::NEG_ONE), F::NEG_NAN);
         assert_biteq!(f(F::NAN, F::NEG_NAN), F::NEG_NAN);
+        assert_biteq!(f(F::NEG_NAN, F::NAN), F::NAN);
+        assert_biteq!(f(F::NEG_NAN, F::ONE), F::NAN);
+        assert_biteq!(f(F::NEG_NAN, F::NEG_ONE), F::NEG_NAN);
         assert_biteq!(f(F::NEG_NAN, F::NEG_NAN), F::NEG_NAN);
+        assert_biteq!(f(F::ONE, F::NAN), F::ONE);
+        assert_biteq!(f(F::ONE, F::NEG_NAN), F::NEG_ONE);
+        assert_biteq!(f(F::NEG_ONE, F::NAN), F::ONE);
+        assert_biteq!(f(F::NEG_ONE, F::NEG_NAN), F::NEG_ONE);
     }
 
     #[test]
diff --git a/library/compiler-builtins/libm/src/math/copysignf.rs b/library/compiler-builtins/libm/src/math/copysignf.rs
deleted file mode 100644
index 8b9bed4c0c4..00000000000
--- a/library/compiler-builtins/libm/src/math/copysignf.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-/// Sign of Y, magnitude of X (f32)
-///
-/// Constructs a number with the magnitude (absolute value) of its
-/// first argument, `x`, and the sign of its second argument, `y`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn copysignf(x: f32, y: f32) -> f32 {
-    super::generic::copysign(x, y)
-}
diff --git a/library/compiler-builtins/libm/src/math/copysignf128.rs b/library/compiler-builtins/libm/src/math/copysignf128.rs
deleted file mode 100644
index 7bd81d42b2e..00000000000
--- a/library/compiler-builtins/libm/src/math/copysignf128.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-/// Sign of Y, magnitude of X (f128)
-///
-/// Constructs a number with the magnitude (absolute value) of its
-/// first argument, `x`, and the sign of its second argument, `y`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn copysignf128(x: f128, y: f128) -> f128 {
-    super::generic::copysign(x, y)
-}
diff --git a/library/compiler-builtins/libm/src/math/copysignf16.rs b/library/compiler-builtins/libm/src/math/copysignf16.rs
deleted file mode 100644
index 82065868601..00000000000
--- a/library/compiler-builtins/libm/src/math/copysignf16.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-/// Sign of Y, magnitude of X (f16)
-///
-/// Constructs a number with the magnitude (absolute value) of its
-/// first argument, `x`, and the sign of its second argument, `y`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn copysignf16(x: f16, y: f16) -> f16 {
-    super::generic::copysign(x, y)
-}
diff --git a/library/compiler-builtins/libm/src/math/fabsf.rs b/library/compiler-builtins/libm/src/math/fabsf.rs
deleted file mode 100644
index e5820a26c52..00000000000
--- a/library/compiler-builtins/libm/src/math/fabsf.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-/// Absolute value (magnitude) (f32)
-///
-/// Calculates the absolute value (magnitude) of the argument `x`,
-/// by direct manipulation of the bit representation of `x`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn fabsf(x: f32) -> f32 {
-    select_implementation! {
-        name: fabsf,
-        use_arch: all(target_arch = "wasm32", intrinsics_enabled),
-        args: x,
-    }
-
-    super::generic::fabs(x)
-}
-
-// PowerPC tests are failing on LLVM 13: https://github.com/rust-lang/rust/issues/88520
-#[cfg(not(target_arch = "powerpc64"))]
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn sanity_check() {
-        assert_eq!(fabsf(-1.0), 1.0);
-        assert_eq!(fabsf(2.8), 2.8);
-    }
-
-    /// The spec: https://en.cppreference.com/w/cpp/numeric/math/fabs
-    #[test]
-    fn spec_tests() {
-        assert!(fabsf(f32::NAN).is_nan());
-        for f in [0.0, -0.0].iter().copied() {
-            assert_eq!(fabsf(f), 0.0);
-        }
-        for f in [f32::INFINITY, f32::NEG_INFINITY].iter().copied() {
-            assert_eq!(fabsf(f), f32::INFINITY);
-        }
-    }
-}
diff --git a/library/compiler-builtins/libm/src/math/fabsf128.rs b/library/compiler-builtins/libm/src/math/fabsf128.rs
deleted file mode 100644
index 46429ca4940..00000000000
--- a/library/compiler-builtins/libm/src/math/fabsf128.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-/// Absolute value (magnitude) (f128)
-///
-/// Calculates the absolute value (magnitude) of the argument `x`,
-/// by direct manipulation of the bit representation of `x`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn fabsf128(x: f128) -> f128 {
-    super::generic::fabs(x)
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn sanity_check() {
-        assert_eq!(fabsf128(-1.0), 1.0);
-        assert_eq!(fabsf128(2.8), 2.8);
-    }
-
-    /// The spec: https://en.cppreference.com/w/cpp/numeric/math/fabs
-    #[test]
-    fn spec_tests() {
-        assert!(fabsf128(f128::NAN).is_nan());
-        for f in [0.0, -0.0].iter().copied() {
-            assert_eq!(fabsf128(f), 0.0);
-        }
-        for f in [f128::INFINITY, f128::NEG_INFINITY].iter().copied() {
-            assert_eq!(fabsf128(f), f128::INFINITY);
-        }
-    }
-}
diff --git a/library/compiler-builtins/libm/src/math/fabsf16.rs b/library/compiler-builtins/libm/src/math/fabsf16.rs
deleted file mode 100644
index eee42ac6a3c..00000000000
--- a/library/compiler-builtins/libm/src/math/fabsf16.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-/// Absolute value (magnitude) (f16)
-///
-/// Calculates the absolute value (magnitude) of the argument `x`,
-/// by direct manipulation of the bit representation of `x`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn fabsf16(x: f16) -> f16 {
-    super::generic::fabs(x)
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn sanity_check() {
-        assert_eq!(fabsf16(-1.0), 1.0);
-        assert_eq!(fabsf16(2.8), 2.8);
-    }
-
-    /// The spec: https://en.cppreference.com/w/cpp/numeric/math/fabs
-    #[test]
-    fn spec_tests() {
-        assert!(fabsf16(f16::NAN).is_nan());
-        for f in [0.0, -0.0].iter().copied() {
-            assert_eq!(fabsf16(f), 0.0);
-        }
-        for f in [f16::INFINITY, f16::NEG_INFINITY].iter().copied() {
-            assert_eq!(fabsf16(f), f16::INFINITY);
-        }
-    }
-}
diff --git a/library/compiler-builtins/libm/src/math/fdimf.rs b/library/compiler-builtins/libm/src/math/fdimf.rs
deleted file mode 100644
index 367ef517c63..00000000000
--- a/library/compiler-builtins/libm/src/math/fdimf.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-/// Positive difference (f32)
-///
-/// Determines the positive difference between arguments, returning:
-/// * x - y if x > y, or
-/// * +0    if x <= y, or
-/// * NAN   if either argument is NAN.
-///
-/// A range error may occur.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn fdimf(x: f32, y: f32) -> f32 {
-    super::generic::fdim(x, y)
-}
diff --git a/library/compiler-builtins/libm/src/math/fdimf128.rs b/library/compiler-builtins/libm/src/math/fdimf128.rs
deleted file mode 100644
index 6f3d1d0ff1d..00000000000
--- a/library/compiler-builtins/libm/src/math/fdimf128.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-/// Positive difference (f128)
-///
-/// Determines the positive difference between arguments, returning:
-/// * x - y if x > y, or
-/// * +0    if x <= y, or
-/// * NAN   if either argument is NAN.
-///
-/// A range error may occur.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn fdimf128(x: f128, y: f128) -> f128 {
-    super::generic::fdim(x, y)
-}
diff --git a/library/compiler-builtins/libm/src/math/fdimf16.rs b/library/compiler-builtins/libm/src/math/fdimf16.rs
deleted file mode 100644
index 37bd6885817..00000000000
--- a/library/compiler-builtins/libm/src/math/fdimf16.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-/// Positive difference (f16)
-///
-/// Determines the positive difference between arguments, returning:
-/// * x - y if x > y, or
-/// * +0    if x <= y, or
-/// * NAN   if either argument is NAN.
-///
-/// A range error may occur.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn fdimf16(x: f16, y: f16) -> f16 {
-    super::generic::fdim(x, y)
-}
diff --git a/library/compiler-builtins/libm/src/math/floorf.rs b/library/compiler-builtins/libm/src/math/floorf.rs
deleted file mode 100644
index 16957b7f355..00000000000
--- a/library/compiler-builtins/libm/src/math/floorf.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-/// Floor (f32)
-///
-/// Finds the nearest integer less than or equal to `x`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn floorf(x: f32) -> f32 {
-    select_implementation! {
-        name: floorf,
-        use_arch: all(target_arch = "wasm32", intrinsics_enabled),
-        args: x,
-    }
-
-    return super::generic::floor(x);
-}
diff --git a/library/compiler-builtins/libm/src/math/floorf128.rs b/library/compiler-builtins/libm/src/math/floorf128.rs
deleted file mode 100644
index 9a9fe415115..00000000000
--- a/library/compiler-builtins/libm/src/math/floorf128.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-/// Floor (f128)
-///
-/// Finds the nearest integer less than or equal to `x`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn floorf128(x: f128) -> f128 {
-    return super::generic::floor(x);
-}
diff --git a/library/compiler-builtins/libm/src/math/floorf16.rs b/library/compiler-builtins/libm/src/math/floorf16.rs
deleted file mode 100644
index f9b868e0410..00000000000
--- a/library/compiler-builtins/libm/src/math/floorf16.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-/// Floor (f16)
-///
-/// Finds the nearest integer less than or equal to `x`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn floorf16(x: f16) -> f16 {
-    return super::generic::floor(x);
-}
diff --git a/library/compiler-builtins/libm/src/math/fmodf.rs b/library/compiler-builtins/libm/src/math/fmodf.rs
deleted file mode 100644
index 4e95696e20d..00000000000
--- a/library/compiler-builtins/libm/src/math/fmodf.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn fmodf(x: f32, y: f32) -> f32 {
-    super::generic::fmod(x, y)
-}
diff --git a/library/compiler-builtins/libm/src/math/fmodf128.rs b/library/compiler-builtins/libm/src/math/fmodf128.rs
deleted file mode 100644
index ff0e0493e26..00000000000
--- a/library/compiler-builtins/libm/src/math/fmodf128.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn fmodf128(x: f128, y: f128) -> f128 {
-    super::generic::fmod(x, y)
-}
diff --git a/library/compiler-builtins/libm/src/math/fmodf16.rs b/library/compiler-builtins/libm/src/math/fmodf16.rs
deleted file mode 100644
index 11972a7de4f..00000000000
--- a/library/compiler-builtins/libm/src/math/fmodf16.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn fmodf16(x: f16, y: f16) -> f16 {
-    super::generic::fmod(x, y)
-}
diff --git a/library/compiler-builtins/libm/src/math/generic/fmaximum.rs b/library/compiler-builtins/libm/src/math/generic/fmaximum.rs
index 4b6295bc0c6..898828b80c7 100644
--- a/library/compiler-builtins/libm/src/math/generic/fmaximum.rs
+++ b/library/compiler-builtins/libm/src/math/generic/fmaximum.rs
@@ -17,7 +17,7 @@ pub fn fmaximum<F: Float>(x: F, y: F) -> F {
         x
     } else if y.is_nan() {
         y
-    } else if x > y || (y.to_bits() == F::NEG_ZERO.to_bits() && x.is_sign_positive()) {
+    } else if x > y || (y.biteq(F::NEG_ZERO) && x.is_sign_positive()) {
         x
     } else {
         y
diff --git a/library/compiler-builtins/libm/src/math/generic/fmaximum_num.rs b/library/compiler-builtins/libm/src/math/generic/fmaximum_num.rs
index 2e97ff6d369..05df6cbd464 100644
--- a/library/compiler-builtins/libm/src/math/generic/fmaximum_num.rs
+++ b/library/compiler-builtins/libm/src/math/generic/fmaximum_num.rs
@@ -15,12 +15,11 @@ use crate::support::Float;
 
 #[inline]
 pub fn fmaximum_num<F: Float>(x: F, y: F) -> F {
-    let res =
-        if x.is_nan() || x < y || (x.to_bits() == F::NEG_ZERO.to_bits() && y.is_sign_positive()) {
-            y
-        } else {
-            x
-        };
+    let res = if x.is_nan() || x < y || (x.biteq(F::NEG_ZERO) && y.is_sign_positive()) {
+        y
+    } else {
+        x
+    };
 
     // Canonicalize
     res * F::ONE
diff --git a/library/compiler-builtins/libm/src/math/generic/fminimum.rs b/library/compiler-builtins/libm/src/math/generic/fminimum.rs
index 9dc0b64be3f..8592ac5460e 100644
--- a/library/compiler-builtins/libm/src/math/generic/fminimum.rs
+++ b/library/compiler-builtins/libm/src/math/generic/fminimum.rs
@@ -17,7 +17,7 @@ pub fn fminimum<F: Float>(x: F, y: F) -> F {
         x
     } else if y.is_nan() {
         y
-    } else if x < y || (x.to_bits() == F::NEG_ZERO.to_bits() && y.is_sign_positive()) {
+    } else if x < y || (x.biteq(F::NEG_ZERO) && y.is_sign_positive()) {
         x
     } else {
         y
diff --git a/library/compiler-builtins/libm/src/math/generic/fminimum_num.rs b/library/compiler-builtins/libm/src/math/generic/fminimum_num.rs
index 40db8b18957..6777bbf8772 100644
--- a/library/compiler-builtins/libm/src/math/generic/fminimum_num.rs
+++ b/library/compiler-builtins/libm/src/math/generic/fminimum_num.rs
@@ -15,12 +15,11 @@ use crate::support::Float;
 
 #[inline]
 pub fn fminimum_num<F: Float>(x: F, y: F) -> F {
-    let res =
-        if y.is_nan() || x < y || (x.to_bits() == F::NEG_ZERO.to_bits() && y.is_sign_positive()) {
-            x
-        } else {
-            y
-        };
+    let res = if y.is_nan() || x < y || (x.biteq(F::NEG_ZERO) && y.is_sign_positive()) {
+        x
+    } else {
+        y
+    };
 
     // Canonicalize
     res * F::ONE
diff --git a/library/compiler-builtins/libm/src/math/ldexpf.rs b/library/compiler-builtins/libm/src/math/ldexpf.rs
deleted file mode 100644
index 95b27fc49d2..00000000000
--- a/library/compiler-builtins/libm/src/math/ldexpf.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn ldexpf(x: f32, n: i32) -> f32 {
-    super::scalbnf(x, n)
-}
diff --git a/library/compiler-builtins/libm/src/math/ldexpf128.rs b/library/compiler-builtins/libm/src/math/ldexpf128.rs
deleted file mode 100644
index b35277d15fb..00000000000
--- a/library/compiler-builtins/libm/src/math/ldexpf128.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn ldexpf128(x: f128, n: i32) -> f128 {
-    super::scalbnf128(x, n)
-}
diff --git a/library/compiler-builtins/libm/src/math/ldexpf16.rs b/library/compiler-builtins/libm/src/math/ldexpf16.rs
deleted file mode 100644
index 8de6cffd699..00000000000
--- a/library/compiler-builtins/libm/src/math/ldexpf16.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn ldexpf16(x: f16, n: i32) -> f16 {
-    super::scalbnf16(x, n)
-}
diff --git a/library/compiler-builtins/libm/src/math/roundf.rs b/library/compiler-builtins/libm/src/math/roundf.rs
deleted file mode 100644
index b5d7c9d693e..00000000000
--- a/library/compiler-builtins/libm/src/math/roundf.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-/// Round `x` to the nearest integer, breaking ties away from zero.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn roundf(x: f32) -> f32 {
-    super::generic::round(x)
-}
diff --git a/library/compiler-builtins/libm/src/math/roundf128.rs b/library/compiler-builtins/libm/src/math/roundf128.rs
deleted file mode 100644
index fc3164929fe..00000000000
--- a/library/compiler-builtins/libm/src/math/roundf128.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-/// Round `x` to the nearest integer, breaking ties away from zero.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn roundf128(x: f128) -> f128 {
-    super::generic::round(x)
-}
diff --git a/library/compiler-builtins/libm/src/math/roundf16.rs b/library/compiler-builtins/libm/src/math/roundf16.rs
deleted file mode 100644
index 8b356eaabee..00000000000
--- a/library/compiler-builtins/libm/src/math/roundf16.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-/// Round `x` to the nearest integer, breaking ties away from zero.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn roundf16(x: f16) -> f16 {
-    super::generic::round(x)
-}
diff --git a/library/compiler-builtins/libm/src/math/scalbnf.rs b/library/compiler-builtins/libm/src/math/scalbnf.rs
deleted file mode 100644
index 57e7ba76f60..00000000000
--- a/library/compiler-builtins/libm/src/math/scalbnf.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn scalbnf(x: f32, n: i32) -> f32 {
-    super::generic::scalbn(x, n)
-}
diff --git a/library/compiler-builtins/libm/src/math/scalbnf128.rs b/library/compiler-builtins/libm/src/math/scalbnf128.rs
deleted file mode 100644
index c1d2b485585..00000000000
--- a/library/compiler-builtins/libm/src/math/scalbnf128.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn scalbnf128(x: f128, n: i32) -> f128 {
-    super::generic::scalbn(x, n)
-}
diff --git a/library/compiler-builtins/libm/src/math/scalbnf16.rs b/library/compiler-builtins/libm/src/math/scalbnf16.rs
deleted file mode 100644
index 2209e1a1795..00000000000
--- a/library/compiler-builtins/libm/src/math/scalbnf16.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn scalbnf16(x: f16, n: i32) -> f16 {
-    super::generic::scalbn(x, n)
-}
diff --git a/library/compiler-builtins/libm/src/math/sqrtf.rs b/library/compiler-builtins/libm/src/math/sqrtf.rs
deleted file mode 100644
index c28a705e378..00000000000
--- a/library/compiler-builtins/libm/src/math/sqrtf.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-/// The square root of `x` (f32).
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn sqrtf(x: f32) -> f32 {
-    select_implementation! {
-        name: sqrtf,
-        use_arch: any(
-            all(target_arch = "aarch64", target_feature = "neon"),
-            all(target_arch = "wasm32", intrinsics_enabled),
-            target_feature = "sse2"
-        ),
-        args: x,
-    }
-
-    super::generic::sqrt(x)
-}
diff --git a/library/compiler-builtins/libm/src/math/sqrtf128.rs b/library/compiler-builtins/libm/src/math/sqrtf128.rs
deleted file mode 100644
index eaef6ae0c1c..00000000000
--- a/library/compiler-builtins/libm/src/math/sqrtf128.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-/// The square root of `x` (f128).
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn sqrtf128(x: f128) -> f128 {
-    return super::generic::sqrt(x);
-}
diff --git a/library/compiler-builtins/libm/src/math/sqrtf16.rs b/library/compiler-builtins/libm/src/math/sqrtf16.rs
deleted file mode 100644
index 7bedb7f8bbb..00000000000
--- a/library/compiler-builtins/libm/src/math/sqrtf16.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-/// The square root of `x` (f16).
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn sqrtf16(x: f16) -> f16 {
-    select_implementation! {
-        name: sqrtf16,
-        use_arch: all(target_arch = "aarch64", target_feature = "fp16"),
-        args: x,
-    }
-
-    return super::generic::sqrt(x);
-}
diff --git a/library/compiler-builtins/libm/src/math/support/float_traits.rs b/library/compiler-builtins/libm/src/math/support/float_traits.rs
index 4c866ef10bd..dd9f46209c1 100644
--- a/library/compiler-builtins/libm/src/math/support/float_traits.rs
+++ b/library/compiler-builtins/libm/src/math/support/float_traits.rs
@@ -6,6 +6,7 @@ use super::int_traits::{CastFrom, Int, MinInt};
 
 /// Trait for some basic operations on floats
 // #[allow(dead_code)]
+#[allow(dead_code)] // Some constants are only used with tests
 pub trait Float:
     Copy
     + fmt::Debug
diff --git a/library/compiler-builtins/libm/src/math/support/hex_float.rs b/library/compiler-builtins/libm/src/math/support/hex_float.rs
index 85569d98aef..c8558b90053 100644
--- a/library/compiler-builtins/libm/src/math/support/hex_float.rs
+++ b/library/compiler-builtins/libm/src/math/support/hex_float.rs
@@ -1,8 +1,6 @@
 //! Utilities for working with hex float formats.
 
-use core::fmt;
-
-use super::{Float, Round, Status, f32_from_bits, f64_from_bits};
+use super::{Round, Status, f32_from_bits, f64_from_bits};
 
 /// Construct a 16-bit float from hex float representation (C-style)
 #[cfg(f16_enabled)]
@@ -352,133 +350,143 @@ const fn u128_ilog2(v: u128) -> u32 {
     u128::BITS - 1 - v.leading_zeros()
 }
 
-/// Format a floating point number as its IEEE hex (`%a`) representation.
-pub struct Hexf<F>(pub F);
+#[cfg(any(test, feature = "unstable-public-internals"))]
+mod hex_fmt {
+    use core::fmt;
 
-// Adapted from https://github.com/ericseppanen/hexfloat2/blob/a5c27932f0ff/src/format.rs
-#[cfg(not(feature = "compiler-builtins"))]
-fn fmt_any_hex<F: Float>(x: &F, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    if x.is_sign_negative() {
-        write!(f, "-")?;
-    }
+    use crate::support::Float;
 
-    if x.is_nan() {
-        return write!(f, "NaN");
-    } else if x.is_infinite() {
-        return write!(f, "inf");
-    } else if *x == F::ZERO {
-        return write!(f, "0x0p+0");
-    }
+    /// Format a floating point number as its IEEE hex (`%a`) representation.
+    pub struct Hexf<F>(pub F);
 
-    let mut exponent = x.exp_unbiased();
-    let sig = x.to_bits() & F::SIG_MASK;
-
-    let bias = F::EXP_BIAS as i32;
-    // The mantissa MSB needs to be shifted up to the nearest nibble.
-    let mshift = (4 - (F::SIG_BITS % 4)) % 4;
-    let sig = sig << mshift;
-    // The width is rounded up to the nearest char (4 bits)
-    let mwidth = (F::SIG_BITS as usize + 3) / 4;
-    let leading = if exponent == -bias {
-        // subnormal number means we shift our output by 1 bit.
-        exponent += 1;
-        "0."
-    } else {
-        "1."
-    };
+    // Adapted from https://github.com/ericseppanen/hexfloat2/blob/a5c27932f0ff/src/format.rs
+    #[cfg(not(feature = "compiler-builtins"))]
+    pub(super) fn fmt_any_hex<F: Float>(x: &F, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if x.is_sign_negative() {
+            write!(f, "-")?;
+        }
 
-    write!(f, "0x{leading}{sig:0mwidth$x}p{exponent:+}")
-}
+        if x.is_nan() {
+            return write!(f, "NaN");
+        } else if x.is_infinite() {
+            return write!(f, "inf");
+        } else if *x == F::ZERO {
+            return write!(f, "0x0p+0");
+        }
 
-#[cfg(feature = "compiler-builtins")]
-fn fmt_any_hex<F: Float>(_x: &F, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    unimplemented!()
-}
+        let mut exponent = x.exp_unbiased();
+        let sig = x.to_bits() & F::SIG_MASK;
+
+        let bias = F::EXP_BIAS as i32;
+        // The mantissa MSB needs to be shifted up to the nearest nibble.
+        let mshift = (4 - (F::SIG_BITS % 4)) % 4;
+        let sig = sig << mshift;
+        // The width is rounded up to the nearest char (4 bits)
+        let mwidth = (F::SIG_BITS as usize + 3) / 4;
+        let leading = if exponent == -bias {
+            // subnormal number means we shift our output by 1 bit.
+            exponent += 1;
+            "0."
+        } else {
+            "1."
+        };
 
-impl<F: Float> fmt::LowerHex for Hexf<F> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        cfg_if! {
-            if #[cfg(feature = "compiler-builtins")] {
-                let _ = f;
-                unimplemented!()
-            } else {
-                fmt_any_hex(&self.0, f)
+        write!(f, "0x{leading}{sig:0mwidth$x}p{exponent:+}")
+    }
+
+    #[cfg(feature = "compiler-builtins")]
+    pub(super) fn fmt_any_hex<F: Float>(_x: &F, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        unimplemented!()
+    }
+
+    impl<F: Float> fmt::LowerHex for Hexf<F> {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            cfg_if! {
+                if #[cfg(feature = "compiler-builtins")] {
+                    let _ = f;
+                    unimplemented!()
+                } else {
+                    fmt_any_hex(&self.0, f)
+                }
             }
         }
     }
-}
 
-impl<F: Float> fmt::LowerHex for Hexf<(F, F)> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        cfg_if! {
-            if #[cfg(feature = "compiler-builtins")] {
-                let _ = f;
-                unimplemented!()
-            } else {
-                write!(f, "({:x}, {:x})", Hexf(self.0.0), Hexf(self.0.1))
+    impl<F: Float> fmt::LowerHex for Hexf<(F, F)> {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            cfg_if! {
+                if #[cfg(feature = "compiler-builtins")] {
+                    let _ = f;
+                    unimplemented!()
+                } else {
+                    write!(f, "({:x}, {:x})", Hexf(self.0.0), Hexf(self.0.1))
+                }
             }
         }
     }
-}
 
-impl<F: Float> fmt::LowerHex for Hexf<(F, i32)> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        cfg_if! {
-            if #[cfg(feature = "compiler-builtins")] {
-                let _ = f;
-                unimplemented!()
-            } else {
-                write!(f, "({:x}, {:x})", Hexf(self.0.0), Hexf(self.0.1))
+    impl<F: Float> fmt::LowerHex for Hexf<(F, i32)> {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            cfg_if! {
+                if #[cfg(feature = "compiler-builtins")] {
+                    let _ = f;
+                    unimplemented!()
+                } else {
+                    write!(f, "({:x}, {:x})", Hexf(self.0.0), Hexf(self.0.1))
+                }
             }
         }
     }
-}
 
-impl fmt::LowerHex for Hexf<i32> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        cfg_if! {
-            if #[cfg(feature = "compiler-builtins")] {
-                let _ = f;
-                unimplemented!()
-            } else {
-                fmt::LowerHex::fmt(&self.0, f)
+    impl fmt::LowerHex for Hexf<i32> {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            cfg_if! {
+                if #[cfg(feature = "compiler-builtins")] {
+                    let _ = f;
+                    unimplemented!()
+                } else {
+                    fmt::LowerHex::fmt(&self.0, f)
+                }
             }
         }
     }
-}
 
-impl<T> fmt::Debug for Hexf<T>
-where
-    Hexf<T>: fmt::LowerHex,
-{
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        cfg_if! {
-            if #[cfg(feature = "compiler-builtins")] {
-                let _ = f;
-                unimplemented!()
-            } else {
-                fmt::LowerHex::fmt(self, f)
+    impl<T> fmt::Debug for Hexf<T>
+    where
+        Hexf<T>: fmt::LowerHex,
+    {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            cfg_if! {
+                if #[cfg(feature = "compiler-builtins")] {
+                    let _ = f;
+                    unimplemented!()
+                } else {
+                    fmt::LowerHex::fmt(self, f)
+                }
             }
         }
     }
-}
 
-impl<T> fmt::Display for Hexf<T>
-where
-    Hexf<T>: fmt::LowerHex,
-{
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        cfg_if! {
-            if #[cfg(feature = "compiler-builtins")] {
-                let _ = f;
-                unimplemented!()
-            } else {
-                fmt::LowerHex::fmt(self, f)
+    impl<T> fmt::Display for Hexf<T>
+    where
+        Hexf<T>: fmt::LowerHex,
+    {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            cfg_if! {
+                if #[cfg(feature = "compiler-builtins")] {
+                    let _ = f;
+                    unimplemented!()
+                } else {
+                    fmt::LowerHex::fmt(self, f)
+                }
             }
         }
     }
 }
 
+#[cfg(any(test, feature = "unstable-public-internals"))]
+pub use hex_fmt::*;
+
 #[cfg(test)]
 mod parse_tests {
     extern crate std;
@@ -1064,6 +1072,7 @@ mod print_tests {
     use std::string::ToString;
 
     use super::*;
+    use crate::support::Float;
 
     #[test]
     #[cfg(f16_enabled)]
diff --git a/library/compiler-builtins/libm/src/math/support/int_traits.rs b/library/compiler-builtins/libm/src/math/support/int_traits.rs
index 3ec1faba170..9b29e2f4561 100644
--- a/library/compiler-builtins/libm/src/math/support/int_traits.rs
+++ b/library/compiler-builtins/libm/src/math/support/int_traits.rs
@@ -1,6 +1,7 @@
 use core::{cmp, fmt, ops};
 
 /// Minimal integer implementations needed on all integer types, including wide integers.
+#[allow(dead_code)] // Some constants are only used with tests
 pub trait MinInt:
     Copy
     + fmt::Debug
@@ -78,6 +79,7 @@ pub trait Int:
     fn unsigned(self) -> Self::Unsigned;
     fn from_unsigned(unsigned: Self::Unsigned) -> Self;
     fn abs(self) -> Self;
+    fn unsigned_abs(self) -> Self::Unsigned;
 
     fn from_bool(b: bool) -> Self;
 
@@ -203,6 +205,10 @@ macro_rules! int_impl {
                 unimplemented!()
             }
 
+            fn unsigned_abs(self) -> Self {
+                unimplemented!()
+            }
+
             // It makes writing macros easier if this is implemented for both signed and unsigned
             #[allow(clippy::wrong_self_convention)]
             fn from_unsigned(me: $uty) -> Self {
@@ -242,6 +248,10 @@ macro_rules! int_impl {
                 self.abs()
             }
 
+            fn unsigned_abs(self) -> Self::Unsigned {
+                self.unsigned_abs()
+            }
+
             fn from_unsigned(me: $uty) -> Self {
                 me as $ity
             }
@@ -365,14 +375,19 @@ impl_h_int!(
 /// Trait to express (possibly lossy) casting of integers
 pub trait CastInto<T: Copy>: Copy {
     /// By default, casts should be exact.
+    #[track_caller]
     fn cast(self) -> T;
 
     /// Call for casts that are expected to truncate.
+    ///
+    /// In practice, this is exactly the same as `cast`; the main difference is to document intent
+    /// in code. `cast` may panic in debug mode.
     fn cast_lossy(self) -> T;
 }
 
 pub trait CastFrom<T: Copy>: Copy {
     /// By default, casts should be exact.
+    #[track_caller]
     fn cast_from(value: T) -> Self;
 
     /// Call for casts that are expected to truncate.
diff --git a/library/compiler-builtins/libm/src/math/support/macros.rs b/library/compiler-builtins/libm/src/math/support/macros.rs
index 0b72db0e46e..2b8fd580a50 100644
--- a/library/compiler-builtins/libm/src/math/support/macros.rs
+++ b/library/compiler-builtins/libm/src/math/support/macros.rs
@@ -137,12 +137,12 @@ macro_rules! hf128 {
 #[cfg(test)]
 macro_rules! assert_biteq {
     ($left:expr, $right:expr, $($tt:tt)*) => {{
-        use $crate::support::Int;
         let l = $left;
         let r = $right;
-        let bits = Int::leading_zeros(l.to_bits() - l.to_bits()); // hack to get the width from the value
+        // hack to get width from a value
+        let bits = $crate::support::Int::leading_zeros(l.to_bits() - l.to_bits());
         assert!(
-            l.biteq(r),
+            $crate::support::Float::biteq(l, r),
             "{}\nl: {l:?} ({lb:#0width$x})\nr: {r:?} ({rb:#0width$x})",
             format_args!($($tt)*),
             lb = l.to_bits(),
diff --git a/library/compiler-builtins/libm/src/math/support/mod.rs b/library/compiler-builtins/libm/src/math/support/mod.rs
index a4f596ab844..2e7edd03c42 100644
--- a/library/compiler-builtins/libm/src/math/support/mod.rs
+++ b/library/compiler-builtins/libm/src/math/support/mod.rs
@@ -11,10 +11,14 @@ mod int_traits;
 
 #[allow(unused_imports)]
 pub use big::{i256, u256};
+#[allow(unused_imports)]
+pub(crate) use cfg_if;
 pub use env::{FpResult, Round, Status};
 #[allow(unused_imports)]
 pub use float_traits::{DFloat, Float, HFloat, IntTy};
 pub(crate) use float_traits::{f32_from_bits, f64_from_bits};
+#[cfg(any(test, feature = "unstable-public-internals"))]
+pub use hex_float::Hexf;
 #[cfg(f16_enabled)]
 #[allow(unused_imports)]
 pub use hex_float::hf16;
@@ -22,7 +26,7 @@ pub use hex_float::hf16;
 #[allow(unused_imports)]
 pub use hex_float::hf128;
 #[allow(unused_imports)]
-pub use hex_float::{Hexf, hf32, hf64};
+pub use hex_float::{hf32, hf64};
 pub use int_traits::{CastFrom, CastInto, DInt, HInt, Int, MinInt};
 
 /// Hint to the compiler that the current path is cold.
diff --git a/library/compiler-builtins/libm/src/math/truncf.rs b/library/compiler-builtins/libm/src/math/truncf.rs
deleted file mode 100644
index 14533a26706..00000000000
--- a/library/compiler-builtins/libm/src/math/truncf.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-/// Rounds the number toward 0 to the closest integral value (f32).
-///
-/// This effectively removes the decimal part of the number, leaving the integral part.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn truncf(x: f32) -> f32 {
-    select_implementation! {
-        name: truncf,
-        use_arch: all(target_arch = "wasm32", intrinsics_enabled),
-        args: x,
-    }
-
-    super::generic::trunc(x)
-}
-
-// PowerPC tests are failing on LLVM 13: https://github.com/rust-lang/rust/issues/88520
-#[cfg(not(target_arch = "powerpc64"))]
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn sanity_check() {
-        assert_eq!(super::truncf(1.1), 1.0);
-    }
-}
diff --git a/library/compiler-builtins/libm/src/math/truncf128.rs b/library/compiler-builtins/libm/src/math/truncf128.rs
deleted file mode 100644
index 9dccc0d0e9d..00000000000
--- a/library/compiler-builtins/libm/src/math/truncf128.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-/// Rounds the number toward 0 to the closest integral value (f128).
-///
-/// This effectively removes the decimal part of the number, leaving the integral part.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn truncf128(x: f128) -> f128 {
-    super::generic::trunc(x)
-}
diff --git a/library/compiler-builtins/libm/src/math/truncf16.rs b/library/compiler-builtins/libm/src/math/truncf16.rs
deleted file mode 100644
index d7c3d225cf9..00000000000
--- a/library/compiler-builtins/libm/src/math/truncf16.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-/// Rounds the number toward 0 to the closest integral value (f16).
-///
-/// This effectively removes the decimal part of the number, leaving the integral part.
-#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
-pub fn truncf16(x: f16) -> f16 {
-    super::generic::trunc(x)
-}
diff --git a/library/compiler-builtins/rust-version b/library/compiler-builtins/rust-version
new file mode 100644
index 00000000000..e05aaa0573c
--- /dev/null
+++ b/library/compiler-builtins/rust-version
@@ -0,0 +1 @@
+df8102fe5f24f28a918660b0cd918d7331c3896e
diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml
index f88661ee001..5d65b55bcda 100644
--- a/library/core/Cargo.toml
+++ b/library/core/Cargo.toml
@@ -29,6 +29,8 @@ debug_typeid = []
 [lints.rust.unexpected_cfgs]
 level = "warn"
 check-cfg = [
+    # #[cfg(bootstrap)] loongarch32
+    'cfg(target_arch, values("loongarch32"))',
     'cfg(no_fp_fmt_parse)',
     # core use #[path] imports to portable-simd `core_simd` crate
     # and to stdarch `core_arch` crate which messes-up with Cargo list
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index ed523920e42..a4b6efe35fc 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1914,6 +1914,8 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// [`.get()`]: `UnsafeCell::get`
 /// [concurrent memory model]: ../sync/atomic/index.html#memory-model-for-atomic-accesses
 ///
+/// # Aliasing rules
+///
 /// The precise Rust aliasing rules are somewhat in flux, but the main points are not contentious:
 ///
 /// - If you create a safe reference with lifetime `'a` (either a `&T` or `&mut T` reference), then
@@ -2167,10 +2169,9 @@ impl<T: ?Sized> UnsafeCell<T> {
 
     /// Gets a mutable pointer to the wrapped value.
     ///
-    /// This can be cast to a pointer of any kind.
-    /// Ensure that the access is unique (no active references, mutable or not)
-    /// when casting to `&mut T`, and ensure that there are no mutations
-    /// or mutable aliases going on when casting to `&T`
+    /// This can be cast to a pointer of any kind. When creating references, you must uphold the
+    /// aliasing rules; see [the type-level docs][UnsafeCell#aliasing-rules] for more discussion and
+    /// caveats.
     ///
     /// # Examples
     ///
@@ -2219,10 +2220,9 @@ impl<T: ?Sized> UnsafeCell<T> {
     /// The difference from [`get`] is that this function accepts a raw pointer,
     /// which is useful to avoid the creation of temporary references.
     ///
-    /// The result can be cast to a pointer of any kind.
-    /// Ensure that the access is unique (no active references, mutable or not)
-    /// when casting to `&mut T`, and ensure that there are no mutations
-    /// or mutable aliases going on when casting to `&T`.
+    /// This can be cast to a pointer of any kind. When creating references, you must uphold the
+    /// aliasing rules; see [the type-level docs][UnsafeCell#aliasing-rules] for more discussion and
+    /// caveats.
     ///
     /// [`get`]: UnsafeCell::get()
     ///
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index ba30518d70b..dd9c379b666 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -678,8 +678,8 @@ impl fmt::Display for i128 {
 /// It also has to handle 1 last item, as 10^40 > 2^128 > 10^39, whereas
 /// 10^20 > 2^64 > 10^19.
 fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    // 2^128 is about 3*10^38, so 39 gives an extra byte of space
-    let mut buf = [MaybeUninit::<u8>::uninit(); 39];
+    const MAX_DEC_N: usize = u128::MAX.ilog(10) as usize + 1;
+    let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
     let mut curr = buf.len();
 
     let (n, rem) = udiv_1e19(n);
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index bde90464acb..4434ceb49bc 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -84,327 +84,37 @@ pub enum AtomicOrdering {
 /// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::Relaxed`] as both the success and failure parameters.
+/// [`atomic`] types via the `compare_exchange` method.
 /// For example, [`AtomicBool::compare_exchange`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_cxchg_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::Acquire`] as both the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange` method by passing
-/// [`Ordering::SeqCst`] as both the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchg_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::Relaxed`] as both the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_relaxed_relaxed<T: Copy>(
-    _dst: *mut T,
-    _old: T,
-    _src: T,
-) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_relaxed_acquire<T: Copy>(
-    _dst: *mut T,
-    _old: T,
-    _src: T,
-) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_acquire_relaxed<T: Copy>(
-    _dst: *mut T,
-    _old: T,
-    _src: T,
-) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::Acquire`] as both the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_acquire_acquire<T: Copy>(
-    _dst: *mut T,
-    _old: T,
-    _src: T,
-) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_release_relaxed<T: Copy>(
-    _dst: *mut T,
-    _old: T,
-    _src: T,
+pub unsafe fn atomic_cxchg<
+    T: Copy,
+    const ORD_SUCC: AtomicOrdering,
+    const ORD_FAIL: AtomicOrdering,
+>(
+    dst: *mut T,
+    old: T,
+    src: T,
 ) -> (T, bool);
+
 /// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
+/// `T` must be an integer or pointer type. The comparison may spuriously fail.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters.
+/// [`atomic`] types via the `compare_exchange_weak` method.
 /// For example, [`AtomicBool::compare_exchange_weak`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_release_acquire<T: Copy>(
+pub unsafe fn atomic_cxchgweak<
+    T: Copy,
+    const ORD_SUCC: AtomicOrdering,
+    const ORD_FAIL: AtomicOrdering,
+>(
     _dst: *mut T,
     _old: T,
     _src: T,
 ) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-/// Stores a value if the current value is the same as the `old` value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `compare_exchange_weak` method by passing
-/// [`Ordering::SeqCst`] as both the success and failure parameters.
-/// For example, [`AtomicBool::compare_exchange_weak`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_cxchgweak_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 
 /// Loads the current value of the pointer.
 /// `T` must be an integer or pointer type.
@@ -419,75 +129,19 @@ pub unsafe fn atomic_load<T: Copy, const ORD: AtomicOrdering>(src: *const T) ->
 /// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `store` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::store`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
-/// Stores the value at the specified memory location.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `store` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::store`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
-/// Stores the value at the specified memory location.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `store` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::store`].
+/// [`atomic`] types via the `store` method. For example, [`AtomicBool::store`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
+pub unsafe fn atomic_store<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, val: T);
 
 /// Stores the value at the specified memory location, returning the old value.
 /// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `swap` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::swap`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xchg_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Stores the value at the specified memory location, returning the old value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `swap` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::swap`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xchg_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Stores the value at the specified memory location, returning the old value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `swap` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::swap`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xchg_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Stores the value at the specified memory location, returning the old value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `swap` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::swap`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Stores the value at the specified memory location, returning the old value.
-/// `T` must be an integer or pointer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `swap` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::swap`].
+/// [`atomic`] types via the `swap` method. For example, [`AtomicBool::swap`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_xchg<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// Adds to the current value, returning the previous value.
 /// `T` must be an integer or pointer type.
@@ -495,55 +149,10 @@ pub unsafe fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 /// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_add` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xadd_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Adds to the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_add` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xadd_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Adds to the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_add` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xadd_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Adds to the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_add` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Adds to the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_add` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_add`].
+/// [`atomic`] types via the `fetch_add` method. For example, [`AtomicIsize::fetch_add`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_xadd<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// Subtract from the current value, returning the previous value.
 /// `T` must be an integer or pointer type.
@@ -551,55 +160,10 @@ pub unsafe fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 /// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_sub` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
+/// [`atomic`] types via the `fetch_sub` method. For example, [`AtomicIsize::fetch_sub`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_xsub_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Subtract from the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_sub` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xsub_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Subtract from the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_sub` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xsub_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Subtract from the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_sub` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Subtract from the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_sub` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_xsub<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// Bitwise and with the current value, returning the previous value.
 /// `T` must be an integer or pointer type.
@@ -607,55 +171,10 @@ pub unsafe fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 /// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_and` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_and`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_and_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise and with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_and` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_and`].
+/// [`atomic`] types via the `fetch_and` method. For example, [`AtomicBool::fetch_and`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_and_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise and with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_and` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_and`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_and_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise and with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_and` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_and`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise and with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_and` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_and`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_and<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// Bitwise nand with the current value, returning the previous value.
 /// `T` must be an integer or pointer type.
@@ -663,55 +182,10 @@ pub unsafe fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 /// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`AtomicBool`] type via the `fetch_nand` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_nand_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise nand with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`AtomicBool`] type via the `fetch_nand` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_nand`].
+/// [`AtomicBool`] type via the `fetch_nand` method. For example, [`AtomicBool::fetch_nand`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_nand_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise nand with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`AtomicBool`] type via the `fetch_nand` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_nand_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise nand with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`AtomicBool`] type via the `fetch_nand` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise nand with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`AtomicBool`] type via the `fetch_nand` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_nand<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// Bitwise or with the current value, returning the previous value.
 /// `T` must be an integer or pointer type.
@@ -719,55 +193,10 @@ pub unsafe fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 /// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_or` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_or`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_or_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise or with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_or` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_or`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_or_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise or with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_or` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_or`].
+/// [`atomic`] types via the `fetch_or` method. For example, [`AtomicBool::fetch_or`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_or_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise or with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_or` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_or`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise or with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_or` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_or`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_or<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// Bitwise xor with the current value, returning the previous value.
 /// `T` must be an integer or pointer type.
@@ -775,325 +204,62 @@ pub unsafe fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 /// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_xor` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xor_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise xor with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_xor` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xor_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise xor with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_xor` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xor_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise xor with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_xor` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_xor`].
+/// [`atomic`] types via the `fetch_xor` method. For example, [`AtomicBool::fetch_xor`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Bitwise xor with the current value, returning the previous value.
-/// `T` must be an integer or pointer type.
-/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
-/// value stored at `*dst` will have the provenance of the old value stored there.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] types via the `fetch_xor` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_xor<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// Maximum with the current value using a signed comparison.
 /// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] signed integer types via the `fetch_max` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_max`].
+/// [`atomic`] signed integer types via the `fetch_max` method. For example, [`AtomicI32::fetch_max`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_max_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Maximum with the current value using a signed comparison.
-/// `T` must be a signed integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] signed integer types via the `fetch_max` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_max`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_max_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Maximum with the current value using a signed comparison.
-/// `T` must be a signed integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] signed integer types via the `fetch_max` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_max`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_max_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Maximum with the current value using a signed comparison.
-/// `T` must be a signed integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] signed integer types via the `fetch_max` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_max`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Maximum with the current value using a signed comparison.
-/// `T` must be a signed integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] signed integer types via the `fetch_max` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_max`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_max<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// Minimum with the current value using a signed comparison.
 /// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] signed integer types via the `fetch_min` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_min`].
+/// [`atomic`] signed integer types via the `fetch_min` method. For example, [`AtomicI32::fetch_min`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_min_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Minimum with the current value using a signed comparison.
-/// `T` must be a signed integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] signed integer types via the `fetch_min` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_min`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_min_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Minimum with the current value using a signed comparison.
-/// `T` must be a signed integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] signed integer types via the `fetch_min` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_min`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_min_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Minimum with the current value using a signed comparison.
-/// `T` must be a signed integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] signed integer types via the `fetch_min` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_min`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Minimum with the current value using a signed comparison.
-/// `T` must be a signed integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] signed integer types via the `fetch_min` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_min`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_min<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// Minimum with the current value using an unsigned comparison.
 /// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] unsigned integer types via the `fetch_min` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_min`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_umin_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Minimum with the current value using an unsigned comparison.
-/// `T` must be an unsigned integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] unsigned integer types via the `fetch_min` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_min`].
+/// [`atomic`] unsigned integer types via the `fetch_min` method. For example, [`AtomicU32::fetch_min`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_umin_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Minimum with the current value using an unsigned comparison.
-/// `T` must be an unsigned integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] unsigned integer types via the `fetch_min` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_min`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_umin_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Minimum with the current value using an unsigned comparison.
-/// `T` must be an unsigned integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] unsigned integer types via the `fetch_min` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_min`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Minimum with the current value using an unsigned comparison.
-/// `T` must be an unsigned integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] unsigned integer types via the `fetch_min` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_min`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_umin<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// Maximum with the current value using an unsigned comparison.
 /// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
-/// [`atomic`] unsigned integer types via the `fetch_max` method by passing
-/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_max`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_umax_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-/// Maximum with the current value using an unsigned comparison.
-/// `T` must be an unsigned integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] unsigned integer types via the `fetch_max` method by passing
-/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_max`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_umax_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-/// Maximum with the current value using an unsigned comparison.
-/// `T` must be an unsigned integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] unsigned integer types via the `fetch_max` method by passing
-/// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_max`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_umax_release<T: Copy>(dst: *mut T, src: T) -> T;
-/// Maximum with the current value using an unsigned comparison.
-/// `T` must be an unsigned integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] unsigned integer types via the `fetch_max` method by passing
-/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_max`].
+/// [`atomic`] unsigned integer types via the `fetch_max` method. For example, [`AtomicU32::fetch_max`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Maximum with the current value using an unsigned comparison.
-/// `T` must be an unsigned integer type.
-///
-/// The stabilized version of this intrinsic is available on the
-/// [`atomic`] unsigned integer types via the `fetch_max` method by passing
-/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_max`].
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_umax_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+pub unsafe fn atomic_umax<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 /// An atomic fence.
 ///
 /// The stabilized version of this intrinsic is available in
-/// [`atomic::fence`] by passing [`Ordering::SeqCst`]
-/// as the `order`.
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_fence_seqcst();
-/// An atomic fence.
-///
-/// The stabilized version of this intrinsic is available in
-/// [`atomic::fence`] by passing [`Ordering::Acquire`]
-/// as the `order`.
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_fence_acquire();
-/// An atomic fence.
-///
-/// The stabilized version of this intrinsic is available in
-/// [`atomic::fence`] by passing [`Ordering::Release`]
-/// as the `order`.
+/// [`atomic::fence`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_fence_release();
-/// An atomic fence.
-///
-/// The stabilized version of this intrinsic is available in
-/// [`atomic::fence`] by passing [`Ordering::AcqRel`]
-/// as the `order`.
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_fence_acqrel();
+pub unsafe fn atomic_fence<const ORD: AtomicOrdering>();
 
-/// A compiler-only memory barrier.
-///
-/// Memory accesses will never be reordered across this barrier by the
-/// compiler, but no instructions will be emitted for it. This is
-/// appropriate for operations on the same thread that may be preempted,
-/// such as when interacting with signal handlers.
-///
-/// The stabilized version of this intrinsic is available in
-/// [`atomic::compiler_fence`] by passing [`Ordering::SeqCst`]
-/// as the `order`.
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_singlethreadfence_seqcst();
-/// A compiler-only memory barrier.
-///
-/// Memory accesses will never be reordered across this barrier by the
-/// compiler, but no instructions will be emitted for it. This is
-/// appropriate for operations on the same thread that may be preempted,
-/// such as when interacting with signal handlers.
-///
-/// The stabilized version of this intrinsic is available in
-/// [`atomic::compiler_fence`] by passing [`Ordering::Acquire`]
-/// as the `order`.
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_singlethreadfence_acquire();
-/// A compiler-only memory barrier.
-///
-/// Memory accesses will never be reordered across this barrier by the
-/// compiler, but no instructions will be emitted for it. This is
-/// appropriate for operations on the same thread that may be preempted,
-/// such as when interacting with signal handlers.
-///
-/// The stabilized version of this intrinsic is available in
-/// [`atomic::compiler_fence`] by passing [`Ordering::Release`]
-/// as the `order`.
-#[rustc_intrinsic]
-#[rustc_nounwind]
-pub unsafe fn atomic_singlethreadfence_release();
-/// A compiler-only memory barrier.
-///
-/// Memory accesses will never be reordered across this barrier by the
-/// compiler, but no instructions will be emitted for it. This is
-/// appropriate for operations on the same thread that may be preempted,
-/// such as when interacting with signal handlers.
+/// An atomic fence for synchronization within a single thread.
 ///
 /// The stabilized version of this intrinsic is available in
-/// [`atomic::compiler_fence`] by passing [`Ordering::AcqRel`]
-/// as the `order`.
+/// [`atomic::compiler_fence`].
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn atomic_singlethreadfence_acqrel();
+pub unsafe fn atomic_singlethreadfence<const ORD: AtomicOrdering>();
 
 /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
 /// if supported; otherwise, it is a no-op.
@@ -3485,15 +2651,6 @@ pub const fn size_of<T>() -> usize;
 #[rustc_intrinsic]
 pub const fn min_align_of<T>() -> usize;
 
-/// The preferred alignment of a type.
-///
-/// This intrinsic does not have a stable counterpart.
-/// It's "tracking issue" is [#91971](https://github.com/rust-lang/rust/issues/91971).
-#[rustc_nounwind]
-#[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_intrinsic]
-pub const unsafe fn pref_align_of<T>() -> usize;
-
 /// Returns the number of variants of the type `T` cast to a `usize`;
 /// if `T` has no variants, returns `0`. Uninhabited variants will be counted.
 ///
diff --git a/library/core/src/iter/sources/generator.rs b/library/core/src/iter/sources/generator.rs
index c94232e09eb..0846974d526 100644
--- a/library/core/src/iter/sources/generator.rs
+++ b/library/core/src/iter/sources/generator.rs
@@ -9,8 +9,6 @@
 ///
 /// ```
 /// #![feature(iter_macro, coroutines)]
-/// # #[cfg(not(bootstrap))]
-/// # {
 ///
 /// let it = std::iter::iter!{|| {
 ///     yield 1;
@@ -19,11 +17,10 @@
 /// } }();
 /// let v: Vec<_> = it.collect();
 /// assert_eq!(v, [1, 2, 3]);
-/// # }
 /// ```
 #[unstable(feature = "iter_macro", issue = "none", reason = "generators are unstable")]
 #[allow_internal_unstable(coroutines, iter_from_coroutine)]
-#[cfg_attr(not(bootstrap), rustc_builtin_macro)]
+#[rustc_builtin_macro]
 pub macro iter($($t:tt)*) {
     /* compiler-builtin */
 }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index f2a5c40bada..88855831788 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -190,14 +190,12 @@
 #![feature(aarch64_unstable_target_feature)]
 #![feature(arm_target_feature)]
 #![feature(hexagon_target_feature)]
-#![feature(keylocker_x86)]
 #![feature(loongarch_target_feature)]
 #![feature(mips_target_feature)]
 #![feature(powerpc_target_feature)]
 #![feature(riscv_target_feature)]
 #![feature(rtm_target_feature)]
 #![feature(s390x_target_feature)]
-#![feature(sha512_sm_x86)]
 #![feature(sse4a_target_feature)]
 #![feature(tbm_target_feature)]
 #![feature(wasm_target_feature)]
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index d5efb03cfbc..b21845a1c16 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1273,6 +1273,19 @@ pub(crate) mod builtin {
     /// first macro invocation leading up to the invocation of the `file!`
     /// macro.
     ///
+    /// The file name is derived from the crate root's source path passed to the Rust compiler
+    /// and the sequence the compiler takes to get from the crate root to the
+    /// module containing `file!`, modified by any flags passed to the Rust compiler (e.g.
+    /// `--remap-path-prefix`).  If the crate's source path is relative, the initial base
+    /// directory will be the working directory of the Rust compiler.  For example, if the source
+    /// path passed to the compiler is `./src/lib.rs` which has a `mod foo;` with a source path of
+    /// `src/foo/mod.rs`, then calling `file!` inside `mod foo;` will return `./src/foo/mod.rs`.
+    ///
+    /// Future compiler options might make further changes to the behavior of `file!`,
+    /// including potentially making it entirely empty. Code (e.g. test libraries)
+    /// relying on `file!` producing an openable file path would be incompatible
+    /// with such options, and might wish to recommend not using those options.
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 58de62a8be8..4c09c930c79 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -1422,6 +1422,7 @@ impl f128 {
 // due to https://github.com/llvm/llvm-project/issues/44744. aarch64 linux matches this.
 // #[unstable(feature = "core_float_math", issue = "137578")]
 #[cfg(not(test))]
+#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))]
 impl f128 {
     /// Returns the largest integer less than or equal to `self`.
     ///
@@ -1431,8 +1432,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1464,8 +1463,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1497,8 +1494,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1535,8 +1530,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1570,8 +1563,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1604,8 +1595,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1646,8 +1635,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1694,8 +1681,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1739,8 +1724,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1779,8 +1762,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1814,8 +1795,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index 45f402d4967..1d98a485c4f 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -1398,6 +1398,7 @@ impl f16 {
 // Functions in this module fall into `core_float_math`
 // #[unstable(feature = "core_float_math", issue = "137578")]
 #[cfg(not(test))]
+#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))]
 impl f16 {
     /// Returns the largest integer less than or equal to `self`.
     ///
@@ -1407,8 +1408,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1440,8 +1439,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1473,8 +1470,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1511,8 +1506,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1546,8 +1539,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1580,8 +1571,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1622,8 +1611,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1670,8 +1657,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1715,8 +1700,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1755,8 +1738,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1790,8 +1771,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1828,8 +1807,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index bf923d4070a..b460c7d0205 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -1879,7 +1879,7 @@ pub mod math {
     ///
     /// let x = 2.0_f32;
     /// let abs_difference = (f32::math::powi(x, 2) - (x * x)).abs();
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-5);
     ///
     /// assert_eq!(f32::math::powi(f32::NAN, 0), 1.0);
     /// ```
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index be933cfa41a..2f10e6db58c 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -1877,7 +1877,7 @@ pub mod math {
     ///
     /// let x = 2.0_f64;
     /// let abs_difference = (f64::math::powi(x, 2) - (x * x)).abs();
-    /// assert!(abs_difference <= f64::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     ///
     /// assert_eq!(f64::math::powi(f64::NAN, 0), 1.0);
     /// ```
diff --git a/library/core/src/num/niche_types.rs b/library/core/src/num/niche_types.rs
index 47ff4254e53..b92561c9e35 100644
--- a/library/core/src/num/niche_types.rs
+++ b/library/core/src/num/niche_types.rs
@@ -131,6 +131,8 @@ define_valid_range_type! {
     pub struct NonZeroI32Inner(i32 as u32 in 1..=0xffff_ffff);
     pub struct NonZeroI64Inner(i64 as u64 in 1..=0xffffffff_ffffffff);
     pub struct NonZeroI128Inner(i128 as u128 in 1..=0xffffffffffffffff_ffffffffffffffff);
+
+    pub struct NonZeroCharInner(char as u32 in 1..=0x10ffff);
 }
 
 #[cfg(target_pointer_width = "16")]
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index a279f002772..0fa066c8f7e 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -79,6 +79,7 @@ impl_zeroable_primitive!(
     NonZeroI64Inner(i64),
     NonZeroI128Inner(i128),
     NonZeroIsizeInner(isize),
+    NonZeroCharInner(char),
 );
 
 /// A value that is known not to equal zero.
@@ -551,8 +552,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// # use std::num::NonZero;
             /// #
@@ -583,8 +582,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// # use std::num::NonZero;
             /// #
@@ -612,8 +609,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Example
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// #![feature(isolate_most_least_significant_one)]
             ///
@@ -644,8 +639,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Example
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// #![feature(isolate_most_least_significant_one)]
             ///
@@ -676,8 +669,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// # use std::num::NonZero;
             /// #
@@ -713,8 +704,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// #![feature(nonzero_bitwise)]
             /// # use std::num::NonZero;
@@ -746,8 +735,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// #![feature(nonzero_bitwise)]
             /// # use std::num::NonZero;
@@ -775,8 +762,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// #![feature(nonzero_bitwise)]
             /// # use std::num::NonZero;
@@ -805,8 +790,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// #![feature(nonzero_bitwise)]
             /// # use std::num::NonZero;
@@ -837,8 +820,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// #![feature(nonzero_bitwise)]
             /// # use std::num::NonZero;
@@ -872,8 +853,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// #![feature(nonzero_bitwise)]
             /// # use std::num::NonZero;
@@ -907,8 +886,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// #![feature(nonzero_bitwise)]
             /// # use std::num::NonZero;
@@ -942,8 +919,6 @@ macro_rules! nonzero_integer {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// #![feature(nonzero_bitwise)]
             /// # use std::num::NonZero;
@@ -1635,8 +1610,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// # use std::num::NonZero;
         /// #
@@ -1666,7 +1639,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
         ///
         /// # Examples
         ///
-        /// Basic usage:
         /// ```
         /// # use std::num::NonZero;
         /// #
@@ -1699,8 +1671,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// # use std::num::NonZero;
         ///
@@ -2138,8 +2108,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// # use std::num::NonZero;
         ///
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 675556b07a8..c04754848b4 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -137,7 +137,7 @@
 //! | [`ptr::NonNull<U>`]                                                 | when `U: Sized`                                                            |
 //! | `#[repr(transparent)]` struct around one of the types in this list. | when it holds for the inner type                                           |
 //!
-//! [^extern_fn]: this remains true for any argument/return types and any other ABI: `extern "abi" fn` (_e.g._, `extern "system" fn`)
+//! [^extern_fn]: this remains true for `unsafe` variants, any argument/return types, and any other ABI: `[unsafe] extern "abi" fn` (_e.g._, `extern "system" fn`)
 //!
 //! Under some conditions the above types `T` are also null pointer optimized when wrapped in a [`Result`][result_repr].
 //!
diff --git a/library/core/src/pin/unsafe_pinned.rs b/library/core/src/pin/unsafe_pinned.rs
index f65e83662fe..17f7bcd306b 100644
--- a/library/core/src/pin/unsafe_pinned.rs
+++ b/library/core/src/pin/unsafe_pinned.rs
@@ -1,10 +1,13 @@
+use crate::cell::UnsafeCell;
 use crate::marker::{PointerLike, Unpin};
 use crate::ops::{CoerceUnsized, DispatchFromDyn};
 use crate::pin::Pin;
 use crate::{fmt, ptr};
 
-/// This type provides a way to opt-out of typical aliasing rules;
+/// This type provides a way to entirely opt-out of typical aliasing rules;
 /// specifically, `&mut UnsafePinned<T>` is not guaranteed to be a unique pointer.
+/// This also subsumes the effects of `UnsafeCell`, i.e., `&UnsafePinned<T>` may point to data
+/// that is being mutated.
 ///
 /// However, even if you define your type like `pub struct Wrapper(UnsafePinned<...>)`, it is still
 /// very risky to have an `&mut Wrapper` that aliases anything else. Many functions that work
@@ -17,38 +20,24 @@ use crate::{fmt, ptr};
 /// the public API of a library. It is an internal implementation detail of libraries that need to
 /// support aliasing mutable references.
 ///
-/// Further note that this does *not* lift the requirement that shared references must be read-only!
-/// Use `UnsafeCell` for that.
-///
 /// This type blocks niches the same way `UnsafeCell` does.
 #[lang = "unsafe_pinned"]
 #[repr(transparent)]
 #[unstable(feature = "unsafe_pinned", issue = "125735")]
 pub struct UnsafePinned<T: ?Sized> {
-    value: T,
+    value: UnsafeCell<T>,
 }
 
+// Override the manual `!Sync` in `UnsafeCell`.
+#[unstable(feature = "unsafe_pinned", issue = "125735")]
+unsafe impl<T: ?Sized + Sync> Sync for UnsafePinned<T> {}
+
 /// When this type is used, that almost certainly means safe APIs need to use pinning to avoid the
 /// aliases from becoming invalidated. Therefore let's mark this as `!Unpin`. You can always opt
 /// back in to `Unpin` with an `impl` block, provided your API is still sound while unpinned.
 #[unstable(feature = "unsafe_pinned", issue = "125735")]
 impl<T: ?Sized> !Unpin for UnsafePinned<T> {}
 
-/// The type is `Copy` when `T` is to avoid people assuming that `Copy` implies there is no
-/// `UnsafePinned` anywhere. (This is an issue with `UnsafeCell`: people use `Copy` bounds to mean
-/// `Freeze`.) Given that there is no `unsafe impl Copy for ...`, this is also the option that
-/// leaves the user more choices (as they can always wrap this in a `!Copy` type).
-// FIXME(unsafe_pinned): this may be unsound or a footgun?
-#[unstable(feature = "unsafe_pinned", issue = "125735")]
-impl<T: Copy> Copy for UnsafePinned<T> {}
-
-#[unstable(feature = "unsafe_pinned", issue = "125735")]
-impl<T: Copy> Clone for UnsafePinned<T> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
 // `Send` and `Sync` are inherited from `T`. This is similar to `SyncUnsafeCell`, since
 // we eventually concluded that `UnsafeCell` implicitly making things `!Sync` is sometimes
 // unergonomic. A type that needs to be `!Send`/`!Sync` should really have an explicit
@@ -63,7 +52,7 @@ impl<T> UnsafePinned<T> {
     #[must_use]
     #[unstable(feature = "unsafe_pinned", issue = "125735")]
     pub const fn new(value: T) -> Self {
-        UnsafePinned { value }
+        UnsafePinned { value: UnsafeCell::new(value) }
     }
 
     /// Unwraps the value, consuming this `UnsafePinned`.
@@ -72,7 +61,7 @@ impl<T> UnsafePinned<T> {
     #[unstable(feature = "unsafe_pinned", issue = "125735")]
     #[rustc_allow_const_fn_unstable(const_precise_live_drops)]
     pub const fn into_inner(self) -> T {
-        self.value
+        self.value.into_inner()
     }
 }
 
@@ -97,13 +86,12 @@ impl<T: ?Sized> UnsafePinned<T> {
         ptr::from_mut(self) as *mut T
     }
 
-    /// Get read-only access to the contents of a shared `UnsafePinned`.
+    /// Get mutable access to the contents of a shared `UnsafePinned`.
     ///
-    /// Note that `&UnsafePinned<T>` is read-only if `&T` is read-only. This means that if there is
-    /// mutation of the `T`, future reads from the `*const T` returned here are UB! Use
-    /// [`UnsafeCell`] if you also need interior mutability.
+    /// This can be cast to a pointer of any kind. When creating references, you must uphold the
+    /// aliasing rules; see [`UnsafeCell`] for more discussion and caveats.
     ///
-    /// [`UnsafeCell`]: crate::cell::UnsafeCell
+    /// [`UnsafeCell`]: crate::cell::UnsafeCell#aliasing-rules
     ///
     /// ```rust,no_run
     /// #![feature(unsafe_pinned)]
@@ -111,16 +99,16 @@ impl<T: ?Sized> UnsafePinned<T> {
     ///
     /// unsafe {
     ///     let mut x = UnsafePinned::new(0);
-    ///     let ptr = x.get(); // read-only pointer, assumes immutability
+    ///     let ptr = x.get();
     ///     x.get_mut_unchecked().write(1);
-    ///     ptr.read(); // UB!
+    ///     assert_eq!(ptr.read(), 1);
     /// }
     /// ```
     #[inline(always)]
     #[must_use]
     #[unstable(feature = "unsafe_pinned", issue = "125735")]
-    pub const fn get(&self) -> *const T {
-        ptr::from_ref(self) as *const T
+    pub const fn get(&self) -> *mut T {
+        self.value.get()
     }
 
     /// Gets an immutable pointer to the wrapped value.
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index a1dab23ea7b..9366cb36c6e 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -5,24 +5,7 @@ use crate::mem::{self, SizedTypeProperties};
 use crate::slice::{self, SliceIndex};
 
 impl<T: ?Sized> *const T {
-    /// Returns `true` if the pointer is null.
-    ///
-    /// Note that unsized types have many possible null pointers, as only the
-    /// raw data pointer is considered, not their length, vtable, etc.
-    /// Therefore, two pointers that are null may still not compare equal to
-    /// each other.
-    ///
-    /// # Panics during const evaluation
-    ///
-    /// If this method is used during const evaluation, and `self` is a pointer
-    /// that is offset beyond the bounds of the memory it initially pointed to,
-    /// then there might not be enough information to determine whether the
-    /// pointer is null. This is because the absolute address in memory is not
-    /// known at compile time. If the nullness of the pointer cannot be
-    /// determined, this method will panic.
-    ///
-    /// In-bounds pointers are never null, so the method will never panic for
-    /// such pointers.
+    #[doc = include_str!("docs/is_null.md")]
     ///
     /// # Examples
     ///
@@ -1550,50 +1533,7 @@ impl<T> *const [T] {
         unsafe { index.get_unchecked(self) }
     }
 
-    /// Returns `None` if the pointer is null, or else returns a shared slice to
-    /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
-    /// that the value has to be initialized.
-    ///
-    /// [`as_ref`]: #method.as_ref
-    ///
-    /// # Safety
-    ///
-    /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// all of the following is true:
-    ///
-    /// * The pointer must be [valid] for reads for `ptr.len() * size_of::<T>()` many bytes,
-    ///   and it must be properly aligned. This means in particular:
-    ///
-    ///     * The entire memory range of this slice must be contained within a single [allocation]!
-    ///       Slices can never span across multiple allocations.
-    ///
-    ///     * The pointer must be aligned even for zero-length slices. One
-    ///       reason for this is that enum layout optimizations may rely on references
-    ///       (including slices of any length) being aligned and non-null to distinguish
-    ///       them from other data. You can obtain a pointer that is usable as `data`
-    ///       for zero-length slices using [`NonNull::dangling()`].
-    ///
-    /// * The total size `ptr.len() * size_of::<T>()` of the slice must be no larger than `isize::MAX`.
-    ///   See the safety documentation of [`pointer::offset`].
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    ///
-    /// See also [`slice::from_raw_parts`][].
-    ///
-    /// [valid]: crate::ptr#safety
-    /// [allocation]: crate::ptr#allocation
-    ///
-    /// # Panics during const evaluation
-    ///
-    /// This method will panic during const evaluation if the pointer cannot be
-    /// determined to be null or not. See [`is_null`] for more information.
-    ///
-    /// [`is_null`]: #method.is_null
+    #[doc = include_str!("docs/as_uninit_slice.md")]
     #[inline]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
diff --git a/library/core/src/ptr/docs/as_uninit_slice.md b/library/core/src/ptr/docs/as_uninit_slice.md
new file mode 100644
index 00000000000..c80c0405883
--- /dev/null
+++ b/library/core/src/ptr/docs/as_uninit_slice.md
@@ -0,0 +1,44 @@
+Returns `None` if the pointer is null, or else returns a shared slice to
+the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
+that the value has to be initialized.
+
+[`as_ref`]: #method.as_ref
+
+# Safety
+
+When calling this method, you have to ensure that *either* the pointer is null *or*
+all of the following is true:
+
+* The pointer must be [valid] for reads for `ptr.len() * size_of::<T>()` many bytes,
+and it must be properly aligned. This means in particular:
+
+* The entire memory range of this slice must be contained within a single [allocation]!
+Slices can never span across multiple allocations.
+
+* The pointer must be aligned even for zero-length slices. One
+reason for this is that enum layout optimizations may rely on references
+(including slices of any length) being aligned and non-null to distinguish
+them from other data. You can obtain a pointer that is usable as `data`
+for zero-length slices using [`NonNull::dangling()`].
+
+* The total size `ptr.len() * size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+See the safety documentation of [`pointer::offset`].
+
+* You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+In particular, while this reference exists, the memory the pointer points to must
+not get mutated (except inside `UnsafeCell`).
+
+This applies even if the result of this method is unused!
+
+See also [`slice::from_raw_parts`][].
+
+[valid]: crate::ptr#safety
+[allocation]: crate::ptr#allocation
+
+# Panics during const evaluation
+
+This method will panic during const evaluation if the pointer cannot be
+determined to be null or not. See [`is_null`] for more information.
+
+[`is_null`]: #method.is_null
diff --git a/library/core/src/ptr/docs/is_null.md b/library/core/src/ptr/docs/is_null.md
new file mode 100644
index 00000000000..7368ab9b576
--- /dev/null
+++ b/library/core/src/ptr/docs/is_null.md
@@ -0,0 +1,18 @@
+Returns `true` if the pointer is null.
+
+Note that unsized types have many possible null pointers, as only the
+raw data pointer is considered, not their length, vtable, etc.
+Therefore, two pointers that are null may still not compare equal to
+each other.
+
+# Panics during const evaluation
+
+If this method is used during const evaluation, and `self` is a pointer
+that is offset beyond the bounds of the memory it initially pointed to,
+then there might not be enough information to determine whether the
+pointer is null. This is because the absolute address in memory is not
+known at compile time. If the nullness of the pointer cannot be
+determined, this method will panic.
+
+In-bounds pointers are never null, so the method will never panic for
+such pointers.
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 968f033bf59..efe1031b79c 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -5,24 +5,7 @@ use crate::mem::{self, SizedTypeProperties};
 use crate::slice::{self, SliceIndex};
 
 impl<T: ?Sized> *mut T {
-    /// Returns `true` if the pointer is null.
-    ///
-    /// Note that unsized types have many possible null pointers, as only the
-    /// raw data pointer is considered, not their length, vtable, etc.
-    /// Therefore, two pointers that are null may still not compare equal to
-    /// each other.
-    ///
-    /// # Panics during const evaluation
-    ///
-    /// If this method is used during const evaluation, and `self` is a pointer
-    /// that is offset beyond the bounds of the memory it initially pointed to,
-    /// then there might not be enough information to determine whether the
-    /// pointer is null. This is because the absolute address in memory is not
-    /// known at compile time. If the nullness of the pointer cannot be
-    /// determined, this method will panic.
-    ///
-    /// In-bounds pointers are never null, so the method will never panic for
-    /// such pointers.
+    #[doc = include_str!("docs/is_null.md")]
     ///
     /// # Examples
     ///
@@ -1906,53 +1889,10 @@ impl<T> *mut [T] {
         unsafe { index.get_unchecked_mut(self) }
     }
 
-    /// Returns `None` if the pointer is null, or else returns a shared slice to
-    /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
-    /// that the value has to be initialized.
-    ///
-    /// For the mutable counterpart see [`as_uninit_slice_mut`].
-    ///
-    /// [`as_ref`]: pointer#method.as_ref-1
-    /// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut
-    ///
-    /// # Safety
-    ///
-    /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// all of the following is true:
-    ///
-    /// * The pointer must be [valid] for reads for `ptr.len() * size_of::<T>()` many bytes,
-    ///   and it must be properly aligned. This means in particular:
-    ///
-    ///     * The entire memory range of this slice must be contained within a single [allocation]!
-    ///       Slices can never span across multiple allocations.
-    ///
-    ///     * The pointer must be aligned even for zero-length slices. One
-    ///       reason for this is that enum layout optimizations may rely on references
-    ///       (including slices of any length) being aligned and non-null to distinguish
-    ///       them from other data. You can obtain a pointer that is usable as `data`
-    ///       for zero-length slices using [`NonNull::dangling()`].
-    ///
-    /// * The total size `ptr.len() * size_of::<T>()` of the slice must be no larger than `isize::MAX`.
-    ///   See the safety documentation of [`pointer::offset`].
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    ///
-    /// See also [`slice::from_raw_parts`][].
-    ///
-    /// [valid]: crate::ptr#safety
-    /// [allocation]: crate::ptr#allocation
+    #[doc = include_str!("docs/as_uninit_slice.md")]
     ///
-    /// # Panics during const evaluation
-    ///
-    /// This method will panic during const evaluation if the pointer cannot be
-    /// determined to be null or not. See [`is_null`] for more information.
-    ///
-    /// [`is_null`]: #method.is_null-1
+    /// # See Also
+    /// For the mutable counterpart see [`as_uninit_slice_mut`](pointer::as_uninit_slice_mut).
     #[inline]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 91b8d1bf9a7..1fae5b83902 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -89,7 +89,8 @@ impl<T: Sized> NonNull<T> {
     /// For more details, see the equivalent method on a raw pointer, [`ptr::without_provenance_mut`].
     ///
     /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
-    #[unstable(feature = "nonnull_provenance", issue = "135243")]
+    #[stable(feature = "nonnull_provenance", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "nonnull_provenance", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn without_provenance(addr: NonZero<usize>) -> Self {
@@ -132,7 +133,7 @@ impl<T: Sized> NonNull<T> {
     /// For more details, see the equivalent method on a raw pointer, [`ptr::with_exposed_provenance_mut`].
     ///
     /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
-    #[unstable(feature = "nonnull_provenance", issue = "135243")]
+    #[stable(feature = "nonnull_provenance", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub fn with_exposed_provenance(addr: NonZero<usize>) -> Self {
         // SAFETY: we know `addr` is non-zero.
@@ -329,7 +330,7 @@ impl<T: ?Sized> NonNull<T> {
     /// For more details, see the equivalent method on a raw pointer, [`pointer::expose_provenance`].
     ///
     /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
-    #[unstable(feature = "nonnull_provenance", issue = "135243")]
+    #[stable(feature = "nonnull_provenance", since = "CURRENT_RUSTC_VERSION")]
     pub fn expose_provenance(self) -> NonZero<usize> {
         // SAFETY: The pointer is guaranteed by the type to be non-null,
         // meaning that the address will be non-zero.
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index 91befdb8c78..d91f8bba548 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -52,7 +52,7 @@ impl [u8] {
     /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
     /// but without allocating and copying temporaries.
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
-    #[rustc_const_unstable(feature = "const_eq_ignore_ascii_case", issue = "131719")]
+    #[rustc_const_stable(feature = "const_eq_ignore_ascii_case", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 4f7e1440880..c26bbad087a 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -21,6 +21,7 @@ use crate::{fmt, hint, ptr, range, slice};
     issue = "none",
     reason = "exposed from core to be reused in std; use the memchr crate"
 )]
+#[doc(hidden)]
 /// Pure Rust memchr implementation, taken from rust-memchr
 pub mod memchr;
 
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 06161cb6c7c..41834793d22 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -2671,7 +2671,7 @@ impl str {
     /// assert!(!"Ferrös".eq_ignore_ascii_case("FERRÖS"));
     /// ```
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
-    #[rustc_const_unstable(feature = "const_eq_ignore_ascii_case", issue = "131719")]
+    #[rustc_const_stable(feature = "const_eq_ignore_ascii_case", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn eq_ignore_ascii_case(&self, other: &str) -> bool {
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index ea459f6d92d..4f9f2936564 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -178,7 +178,7 @@
 //!
 //! | `target_arch` | Size limit |
 //! |---------------|---------|
-//! | `x86`, `arm`, `mips`, `mips32r6`, `powerpc`, `riscv32`, `sparc`, `hexagon` | 4 bytes |
+//! | `x86`, `arm`, `loongarch32`, `mips`, `mips32r6`, `powerpc`, `riscv32`, `sparc`, `hexagon` | 4 bytes |
 //! | `x86_64`, `aarch64`, `loongarch64`, `mips64`, `mips64r6`, `powerpc64`, `riscv64`, `sparc64`, `s390x` | 8 bytes |
 //!
 //! Atomics loads that are larger than this limit as well as atomic loads with ordering other
@@ -245,6 +245,7 @@
 use self::Ordering::*;
 use crate::cell::UnsafeCell;
 use crate::hint::spin_loop;
+use crate::intrinsics::AtomicOrdering as AO;
 use crate::{fmt, intrinsics};
 
 trait Sealed {}
@@ -349,8 +350,12 @@ pub type Atomic<T> = <T as AtomicPrimitive>::AtomicInner;
 // This list should only contain architectures which have word-sized atomic-or/
 // atomic-and instructions but don't natively support byte-sized atomics.
 #[cfg(target_has_atomic = "8")]
-const EMULATE_ATOMIC_BOOL: bool =
-    cfg!(any(target_arch = "riscv32", target_arch = "riscv64", target_arch = "loongarch64"));
+const EMULATE_ATOMIC_BOOL: bool = cfg!(any(
+    target_arch = "riscv32",
+    target_arch = "riscv64",
+    target_arch = "loongarch32",
+    target_arch = "loongarch64"
+));
 
 /// A boolean type which can be safely shared between threads.
 ///
@@ -3811,9 +3816,9 @@ unsafe fn atomic_store<T: Copy>(dst: *mut T, val: T, order: Ordering) {
     // SAFETY: the caller must uphold the safety contract for `atomic_store`.
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_store_relaxed(dst, val),
-            Release => intrinsics::atomic_store_release(dst, val),
-            SeqCst => intrinsics::atomic_store_seqcst(dst, val),
+            Relaxed => intrinsics::atomic_store::<T, { AO::Relaxed }>(dst, val),
+            Release => intrinsics::atomic_store::<T, { AO::Release }>(dst, val),
+            SeqCst => intrinsics::atomic_store::<T, { AO::SeqCst }>(dst, val),
             Acquire => panic!("there is no such thing as an acquire store"),
             AcqRel => panic!("there is no such thing as an acquire-release store"),
         }
@@ -3823,13 +3828,12 @@ unsafe fn atomic_store<T: Copy>(dst: *mut T, val: T, order: Ordering) {
 #[inline]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 unsafe fn atomic_load<T: Copy>(dst: *const T, order: Ordering) -> T {
-    use intrinsics::AtomicOrdering;
     // SAFETY: the caller must uphold the safety contract for `atomic_load`.
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_load::<T, { AtomicOrdering::Relaxed }>(dst),
-            Acquire => intrinsics::atomic_load::<T, { AtomicOrdering::Acquire }>(dst),
-            SeqCst => intrinsics::atomic_load::<T, { AtomicOrdering::SeqCst }>(dst),
+            Relaxed => intrinsics::atomic_load::<T, { AO::Relaxed }>(dst),
+            Acquire => intrinsics::atomic_load::<T, { AO::Acquire }>(dst),
+            SeqCst => intrinsics::atomic_load::<T, { AO::SeqCst }>(dst),
             Release => panic!("there is no such thing as a release load"),
             AcqRel => panic!("there is no such thing as an acquire-release load"),
         }
@@ -3843,11 +3847,11 @@ unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_swap`.
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
-            Acquire => intrinsics::atomic_xchg_acquire(dst, val),
-            Release => intrinsics::atomic_xchg_release(dst, val),
-            AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
-            SeqCst => intrinsics::atomic_xchg_seqcst(dst, val),
+            Relaxed => intrinsics::atomic_xchg::<T, { AO::Relaxed }>(dst, val),
+            Acquire => intrinsics::atomic_xchg::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_xchg::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_xchg::<T, { AO::AcqRel }>(dst, val),
+            SeqCst => intrinsics::atomic_xchg::<T, { AO::SeqCst }>(dst, val),
         }
     }
 }
@@ -3860,11 +3864,11 @@ unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_add`.
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
-            Acquire => intrinsics::atomic_xadd_acquire(dst, val),
-            Release => intrinsics::atomic_xadd_release(dst, val),
-            AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
-            SeqCst => intrinsics::atomic_xadd_seqcst(dst, val),
+            Relaxed => intrinsics::atomic_xadd::<T, { AO::Relaxed }>(dst, val),
+            Acquire => intrinsics::atomic_xadd::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_xadd::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_xadd::<T, { AO::AcqRel }>(dst, val),
+            SeqCst => intrinsics::atomic_xadd::<T, { AO::SeqCst }>(dst, val),
         }
     }
 }
@@ -3877,11 +3881,11 @@ unsafe fn atomic_sub<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_sub`.
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),
-            Acquire => intrinsics::atomic_xsub_acquire(dst, val),
-            Release => intrinsics::atomic_xsub_release(dst, val),
-            AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
-            SeqCst => intrinsics::atomic_xsub_seqcst(dst, val),
+            Relaxed => intrinsics::atomic_xsub::<T, { AO::Relaxed }>(dst, val),
+            Acquire => intrinsics::atomic_xsub::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_xsub::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_xsub::<T, { AO::AcqRel }>(dst, val),
+            SeqCst => intrinsics::atomic_xsub::<T, { AO::SeqCst }>(dst, val),
         }
     }
 }
@@ -3902,21 +3906,51 @@ pub unsafe fn atomic_compare_exchange<T: Copy>(
     // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`.
     let (val, ok) = unsafe {
         match (success, failure) {
-            (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),
-            (Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
-            (Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),
-            (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new),
-            (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new),
-            (Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),
-            (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new),
-            (Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),
-            (Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),
-            (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new),
-            (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new),
-            (AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),
-            (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new),
-            (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new),
-            (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new),
+            (Relaxed, Relaxed) => {
+                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
+            }
+            (Relaxed, Acquire) => {
+                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::Acquire }>(dst, old, new)
+            }
+            (Relaxed, SeqCst) => {
+                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::SeqCst }>(dst, old, new)
+            }
+            (Acquire, Relaxed) => {
+                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
+            }
+            (Acquire, Acquire) => {
+                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
+            }
+            (Acquire, SeqCst) => {
+                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::SeqCst }>(dst, old, new)
+            }
+            (Release, Relaxed) => {
+                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::Relaxed }>(dst, old, new)
+            }
+            (Release, Acquire) => {
+                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::Acquire }>(dst, old, new)
+            }
+            (Release, SeqCst) => {
+                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::SeqCst }>(dst, old, new)
+            }
+            (AcqRel, Relaxed) => {
+                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::Relaxed }>(dst, old, new)
+            }
+            (AcqRel, Acquire) => {
+                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::Acquire }>(dst, old, new)
+            }
+            (AcqRel, SeqCst) => {
+                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::SeqCst }>(dst, old, new)
+            }
+            (SeqCst, Relaxed) => {
+                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::Relaxed }>(dst, old, new)
+            }
+            (SeqCst, Acquire) => {
+                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::Acquire }>(dst, old, new)
+            }
+            (SeqCst, SeqCst) => {
+                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::SeqCst }>(dst, old, new)
+            }
             (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
             (_, Release) => panic!("there is no such thing as a release failure ordering"),
         }
@@ -3937,21 +3971,51 @@ unsafe fn atomic_compare_exchange_weak<T: Copy>(
     // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`.
     let (val, ok) = unsafe {
         match (success, failure) {
-            (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new),
-            (Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new),
-            (Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new),
-            (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new),
-            (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new),
-            (Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new),
-            (Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new),
-            (Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new),
-            (Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new),
-            (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new),
-            (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new),
-            (AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new),
-            (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new),
-            (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new),
-            (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new),
+            (Relaxed, Relaxed) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
+            }
+            (Relaxed, Acquire) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Acquire }>(dst, old, new)
+            }
+            (Relaxed, SeqCst) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::SeqCst }>(dst, old, new)
+            }
+            (Acquire, Relaxed) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
+            }
+            (Acquire, Acquire) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
+            }
+            (Acquire, SeqCst) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::SeqCst }>(dst, old, new)
+            }
+            (Release, Relaxed) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::Relaxed }>(dst, old, new)
+            }
+            (Release, Acquire) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::Acquire }>(dst, old, new)
+            }
+            (Release, SeqCst) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::SeqCst }>(dst, old, new)
+            }
+            (AcqRel, Relaxed) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::Relaxed }>(dst, old, new)
+            }
+            (AcqRel, Acquire) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::Acquire }>(dst, old, new)
+            }
+            (AcqRel, SeqCst) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::SeqCst }>(dst, old, new)
+            }
+            (SeqCst, Relaxed) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::Relaxed }>(dst, old, new)
+            }
+            (SeqCst, Acquire) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::Acquire }>(dst, old, new)
+            }
+            (SeqCst, SeqCst) => {
+                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::SeqCst }>(dst, old, new)
+            }
             (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
             (_, Release) => panic!("there is no such thing as a release failure ordering"),
         }
@@ -3966,11 +4030,11 @@ unsafe fn atomic_and<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_and`
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_and_relaxed(dst, val),
-            Acquire => intrinsics::atomic_and_acquire(dst, val),
-            Release => intrinsics::atomic_and_release(dst, val),
-            AcqRel => intrinsics::atomic_and_acqrel(dst, val),
-            SeqCst => intrinsics::atomic_and_seqcst(dst, val),
+            Relaxed => intrinsics::atomic_and::<T, { AO::Relaxed }>(dst, val),
+            Acquire => intrinsics::atomic_and::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_and::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_and::<T, { AO::AcqRel }>(dst, val),
+            SeqCst => intrinsics::atomic_and::<T, { AO::SeqCst }>(dst, val),
         }
     }
 }
@@ -3982,11 +4046,11 @@ unsafe fn atomic_nand<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_nand`
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
-            Acquire => intrinsics::atomic_nand_acquire(dst, val),
-            Release => intrinsics::atomic_nand_release(dst, val),
-            AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
-            SeqCst => intrinsics::atomic_nand_seqcst(dst, val),
+            Relaxed => intrinsics::atomic_nand::<T, { AO::Relaxed }>(dst, val),
+            Acquire => intrinsics::atomic_nand::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_nand::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_nand::<T, { AO::AcqRel }>(dst, val),
+            SeqCst => intrinsics::atomic_nand::<T, { AO::SeqCst }>(dst, val),
         }
     }
 }
@@ -3998,11 +4062,11 @@ unsafe fn atomic_or<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_or`
     unsafe {
         match order {
-            SeqCst => intrinsics::atomic_or_seqcst(dst, val),
-            Acquire => intrinsics::atomic_or_acquire(dst, val),
-            Release => intrinsics::atomic_or_release(dst, val),
-            AcqRel => intrinsics::atomic_or_acqrel(dst, val),
-            Relaxed => intrinsics::atomic_or_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_or::<T, { AO::SeqCst }>(dst, val),
+            Acquire => intrinsics::atomic_or::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_or::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_or::<T, { AO::AcqRel }>(dst, val),
+            Relaxed => intrinsics::atomic_or::<T, { AO::Relaxed }>(dst, val),
         }
     }
 }
@@ -4014,16 +4078,16 @@ unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_xor`
     unsafe {
         match order {
-            SeqCst => intrinsics::atomic_xor_seqcst(dst, val),
-            Acquire => intrinsics::atomic_xor_acquire(dst, val),
-            Release => intrinsics::atomic_xor_release(dst, val),
-            AcqRel => intrinsics::atomic_xor_acqrel(dst, val),
-            Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
+            SeqCst => intrinsics::atomic_xor::<T, { AO::SeqCst }>(dst, val),
+            Acquire => intrinsics::atomic_xor::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_xor::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_xor::<T, { AO::AcqRel }>(dst, val),
+            Relaxed => intrinsics::atomic_xor::<T, { AO::Relaxed }>(dst, val),
         }
     }
 }
 
-/// returns the max value (signed comparison)
+/// Updates `*dst` to the max value of `val` and the old value (signed comparison)
 #[inline]
 #[cfg(target_has_atomic)]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -4031,16 +4095,16 @@ unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_max`
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_max_relaxed(dst, val),
-            Acquire => intrinsics::atomic_max_acquire(dst, val),
-            Release => intrinsics::atomic_max_release(dst, val),
-            AcqRel => intrinsics::atomic_max_acqrel(dst, val),
-            SeqCst => intrinsics::atomic_max_seqcst(dst, val),
+            Relaxed => intrinsics::atomic_max::<T, { AO::Relaxed }>(dst, val),
+            Acquire => intrinsics::atomic_max::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_max::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_max::<T, { AO::AcqRel }>(dst, val),
+            SeqCst => intrinsics::atomic_max::<T, { AO::SeqCst }>(dst, val),
         }
     }
 }
 
-/// returns the min value (signed comparison)
+/// Updates `*dst` to the min value of `val` and the old value (signed comparison)
 #[inline]
 #[cfg(target_has_atomic)]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -4048,16 +4112,16 @@ unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_min`
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_min_relaxed(dst, val),
-            Acquire => intrinsics::atomic_min_acquire(dst, val),
-            Release => intrinsics::atomic_min_release(dst, val),
-            AcqRel => intrinsics::atomic_min_acqrel(dst, val),
-            SeqCst => intrinsics::atomic_min_seqcst(dst, val),
+            Relaxed => intrinsics::atomic_min::<T, { AO::Relaxed }>(dst, val),
+            Acquire => intrinsics::atomic_min::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_min::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_min::<T, { AO::AcqRel }>(dst, val),
+            SeqCst => intrinsics::atomic_min::<T, { AO::SeqCst }>(dst, val),
         }
     }
 }
 
-/// returns the max value (unsigned comparison)
+/// Updates `*dst` to the max value of `val` and the old value (unsigned comparison)
 #[inline]
 #[cfg(target_has_atomic)]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -4065,16 +4129,16 @@ unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_umax`
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_umax_relaxed(dst, val),
-            Acquire => intrinsics::atomic_umax_acquire(dst, val),
-            Release => intrinsics::atomic_umax_release(dst, val),
-            AcqRel => intrinsics::atomic_umax_acqrel(dst, val),
-            SeqCst => intrinsics::atomic_umax_seqcst(dst, val),
+            Relaxed => intrinsics::atomic_umax::<T, { AO::Relaxed }>(dst, val),
+            Acquire => intrinsics::atomic_umax::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_umax::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_umax::<T, { AO::AcqRel }>(dst, val),
+            SeqCst => intrinsics::atomic_umax::<T, { AO::SeqCst }>(dst, val),
         }
     }
 }
 
-/// returns the min value (unsigned comparison)
+/// Updates `*dst` to the min value of `val` and the old value (unsigned comparison)
 #[inline]
 #[cfg(target_has_atomic)]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -4082,11 +4146,11 @@ unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_umin`
     unsafe {
         match order {
-            Relaxed => intrinsics::atomic_umin_relaxed(dst, val),
-            Acquire => intrinsics::atomic_umin_acquire(dst, val),
-            Release => intrinsics::atomic_umin_release(dst, val),
-            AcqRel => intrinsics::atomic_umin_acqrel(dst, val),
-            SeqCst => intrinsics::atomic_umin_seqcst(dst, val),
+            Relaxed => intrinsics::atomic_umin::<T, { AO::Relaxed }>(dst, val),
+            Acquire => intrinsics::atomic_umin::<T, { AO::Acquire }>(dst, val),
+            Release => intrinsics::atomic_umin::<T, { AO::Release }>(dst, val),
+            AcqRel => intrinsics::atomic_umin::<T, { AO::AcqRel }>(dst, val),
+            SeqCst => intrinsics::atomic_umin::<T, { AO::SeqCst }>(dst, val),
         }
     }
 }
@@ -4178,10 +4242,10 @@ pub fn fence(order: Ordering) {
     // SAFETY: using an atomic fence is safe.
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_fence_acquire(),
-            Release => intrinsics::atomic_fence_release(),
-            AcqRel => intrinsics::atomic_fence_acqrel(),
-            SeqCst => intrinsics::atomic_fence_seqcst(),
+            Acquire => intrinsics::atomic_fence::<{ AO::Acquire }>(),
+            Release => intrinsics::atomic_fence::<{ AO::Release }>(),
+            AcqRel => intrinsics::atomic_fence::<{ AO::AcqRel }>(),
+            SeqCst => intrinsics::atomic_fence::<{ AO::SeqCst }>(),
             Relaxed => panic!("there is no such thing as a relaxed fence"),
         }
     }
@@ -4256,11 +4320,11 @@ pub fn compiler_fence(order: Ordering) {
     // SAFETY: using an atomic fence is safe.
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_singlethreadfence_acquire(),
-            Release => intrinsics::atomic_singlethreadfence_release(),
-            AcqRel => intrinsics::atomic_singlethreadfence_acqrel(),
-            SeqCst => intrinsics::atomic_singlethreadfence_seqcst(),
-            Relaxed => panic!("there is no such thing as a relaxed compiler fence"),
+            Acquire => intrinsics::atomic_singlethreadfence::<{ AO::Acquire }>(),
+            Release => intrinsics::atomic_singlethreadfence::<{ AO::Release }>(),
+            AcqRel => intrinsics::atomic_singlethreadfence::<{ AO::AcqRel }>(),
+            SeqCst => intrinsics::atomic_singlethreadfence::<{ AO::SeqCst }>(),
+            Relaxed => panic!("there is no such thing as a relaxed fence"),
         }
     }
 }
diff --git a/library/coretests/tests/floats/f32.rs b/library/coretests/tests/floats/f32.rs
index 4e6509ead2b..98e9695d090 100644
--- a/library/coretests/tests/floats/f32.rs
+++ b/library/coretests/tests/floats/f32.rs
@@ -23,6 +23,11 @@ const NAN_MASK1: u32 = 0x002a_aaaa;
 /// Second pattern over the mantissa
 const NAN_MASK2: u32 = 0x0055_5555;
 
+/// Miri adds some extra errors to float functions; make sure the tests still pass.
+/// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides.
+/// They serve as a way to get an idea of the real precision of floating point operations on different platforms.
+const APPROX_DELTA: f32 = if cfg!(miri) { 1e-4 } else { 1e-6 };
+
 #[test]
 fn test_num_f32() {
     super::test_num(10f32, 2f32);
@@ -437,8 +442,8 @@ fn test_powi() {
     let nan: f32 = f32::NAN;
     let inf: f32 = f32::INFINITY;
     let neg_inf: f32 = f32::NEG_INFINITY;
-    assert_biteq!(1.0f32.powi(1), 1.0);
-    assert_approx_eq!((-3.1f32).powi(2), 9.61);
+    assert_approx_eq!(1.0f32.powi(1), 1.0);
+    assert_approx_eq!((-3.1f32).powi(2), 9.61, APPROX_DELTA);
     assert_approx_eq!(5.9f32.powi(-2), 0.028727);
     assert_biteq!(8.3f32.powi(0), 1.0);
     assert!(nan.powi(2).is_nan());
diff --git a/library/coretests/tests/floats/f64.rs b/library/coretests/tests/floats/f64.rs
index 74202a37409..dd5b67c251d 100644
--- a/library/coretests/tests/floats/f64.rs
+++ b/library/coretests/tests/floats/f64.rs
@@ -422,7 +422,7 @@ fn test_powi() {
     let nan: f64 = f64::NAN;
     let inf: f64 = f64::INFINITY;
     let neg_inf: f64 = f64::NEG_INFINITY;
-    assert_biteq!(1.0f64.powi(1), 1.0);
+    assert_approx_eq!(1.0f64.powi(1), 1.0);
     assert_approx_eq!((-3.1f64).powi(2), 9.61);
     assert_approx_eq!(5.9f64.powi(-2), 0.028727);
     assert_biteq!(8.3f64.powi(0), 1.0);
diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs
index 7e27028a2a2..f9b6c85f871 100644
--- a/library/coretests/tests/floats/mod.rs
+++ b/library/coretests/tests/floats/mod.rs
@@ -52,6 +52,119 @@ macro_rules! assert_biteq {
     };
 }
 
+mod const_asserts {
+    // Shadow some assert implementations that would otherwise not compile in a const-context.
+    // Every macro added here also needs to be added in the `float_test!` macro below.
+    macro_rules! assert_eq {
+        ($left:expr, $right:expr $(,)?) => {
+            std::assert!($left == $right)
+        };
+        ($left:expr, $right:expr, $($arg:tt)+) => {
+            std::assert!($left == $right, $($arg)+)
+        };
+    }
+
+    pub(crate) use assert_eq;
+}
+
+/// Generate float tests for all our float types, for compile-time and run-time behavior.
+///
+/// By default all tests run for all float types. Configuration can be applied via `attrs`.
+///
+/// ```ignore (this is only a sketch)
+/// float_test! {
+///     name: fn_name, /* function under test */
+///     attrs: {
+///         // Apply a configuration to the test for a single type
+///         f16: #[cfg(target_has_reliable_f16_math)],
+///         // Types can be excluded with `cfg(false)`
+///         f64: #[cfg(false)],
+///     },
+///     test<Float> {
+///         /* write tests here, using `Float` as the type */
+///     }
+/// }
+macro_rules! float_test {
+    (
+        name: $name:ident,
+        attrs: {
+            $(const: #[ $($const_meta:meta),+ ] ,)?
+            $(f16: #[ $($f16_meta:meta),+ ] ,)?
+            $(const f16: #[ $($f16_const_meta:meta),+ ] ,)?
+            $(f32: #[ $($f32_meta:meta),+ ] ,)?
+            $(const f32: #[ $($f32_const_meta:meta),+ ] ,)?
+            $(f64: #[ $($f64_meta:meta),+ ] ,)?
+            $(const f64: #[ $($f64_const_meta:meta),+ ] ,)?
+            $(f128: #[ $($f128_meta:meta),+ ] ,)?
+            $(const f128: #[ $($f128_const_meta:meta),+ ] ,)?
+        },
+        test<$fty:ident> $test:block
+    ) => {
+        mod $name {
+            #[test]
+            $( $( #[$f16_meta] )+ )?
+            fn test_f16() {
+                type $fty = f16;
+                $test
+            }
+
+            #[test]
+            $( $( #[$f32_meta] )+ )?
+            fn test_f32() {
+                type $fty = f32;
+                $test
+            }
+
+            #[test]
+            $( $( #[$f64_meta] )+ )?
+            fn test_f64() {
+                type $fty = f64;
+                $test
+            }
+
+            #[test]
+            $( $( #[$f128_meta] )+ )?
+            fn test_f128() {
+                type $fty = f128;
+                $test
+            }
+
+            $( $( #[$const_meta] )+ )?
+            mod const_ {
+                use $crate::floats::const_asserts::assert_eq;
+
+                #[test]
+                $( $( #[$f16_const_meta] )+ )?
+                fn test_f16() {
+                    type $fty = f16;
+                    const { $test }
+                }
+
+                #[test]
+                $( $( #[$f32_const_meta] )+ )?
+                fn test_f32() {
+                    type $fty = f32;
+                    const { $test }
+                }
+
+                #[test]
+                $( $( #[$f64_const_meta] )+ )?
+                fn test_f64() {
+                    type $fty = f64;
+                    const { $test }
+                }
+
+                #[test]
+                $( $( #[$f128_const_meta] )+ )?
+                fn test_f128() {
+                    type $fty = f128;
+                    const { $test }
+                }
+            }
+        }
+    };
+}
+
 /// Helper function for testing numeric operations
 pub fn test_num<T>(ten: T, two: T)
 where
@@ -75,3 +188,438 @@ mod f128;
 mod f16;
 mod f32;
 mod f64;
+
+float_test! {
+    name: min,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.0 as Float).min(0.0), 0.0);
+        assert!((0.0 as Float).min(0.0).is_sign_positive());
+        assert_eq!((-0.0 as Float).min(-0.0), -0.0);
+        assert!((-0.0 as Float).min(-0.0).is_sign_negative());
+        assert_eq!((9.0 as Float).min(9.0), 9.0);
+        assert_eq!((-9.0 as Float).min(0.0), -9.0);
+        assert_eq!((0.0 as Float).min(9.0), 0.0);
+        assert!((0.0 as Float).min(9.0).is_sign_positive());
+        assert_eq!((-0.0 as Float).min(9.0), -0.0);
+        assert!((-0.0 as Float).min(9.0).is_sign_negative());
+        assert_eq!((-0.0 as Float).min(-9.0), -9.0);
+        assert_eq!(Float::INFINITY.min(9.0), 9.0);
+        assert_eq!((9.0 as Float).min(Float::INFINITY), 9.0);
+        assert_eq!(Float::INFINITY.min(-9.0), -9.0);
+        assert_eq!((-9.0 as Float).min(Float::INFINITY), -9.0);
+        assert_eq!(Float::NEG_INFINITY.min(9.0), Float::NEG_INFINITY);
+        assert_eq!((9.0 as Float).min(Float::NEG_INFINITY), Float::NEG_INFINITY);
+        assert_eq!(Float::NEG_INFINITY.min(-9.0), Float::NEG_INFINITY);
+        assert_eq!((-9.0 as Float).min(Float::NEG_INFINITY), Float::NEG_INFINITY);
+        assert_eq!(Float::NAN.min(9.0), 9.0);
+        assert_eq!(Float::NAN.min(-9.0), -9.0);
+        assert_eq!((9.0 as Float).min(Float::NAN), 9.0);
+        assert_eq!((-9.0 as Float).min(Float::NAN), -9.0);
+        assert!(Float::NAN.min(Float::NAN).is_nan());
+    }
+}
+
+float_test! {
+    name: max,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.0 as Float).max(0.0), 0.0);
+        assert!((0.0 as Float).max(0.0).is_sign_positive());
+        assert_eq!((-0.0 as Float).max(-0.0), -0.0);
+        assert!((-0.0 as Float).max(-0.0).is_sign_negative());
+        assert_eq!((9.0 as Float).max(9.0), 9.0);
+        assert_eq!((-9.0 as Float).max(0.0), 0.0);
+        assert!((-9.0 as Float).max(0.0).is_sign_positive());
+        assert_eq!((-9.0 as Float).max(-0.0), -0.0);
+        assert!((-9.0 as Float).max(-0.0).is_sign_negative());
+        assert_eq!((0.0 as Float).max(9.0), 9.0);
+        assert_eq!((0.0 as Float).max(-9.0), 0.0);
+        assert!((0.0 as Float).max(-9.0).is_sign_positive());
+        assert_eq!((-0.0 as Float).max(-9.0), -0.0);
+        assert!((-0.0 as Float).max(-9.0).is_sign_negative());
+        assert_eq!(Float::INFINITY.max(9.0), Float::INFINITY);
+        assert_eq!((9.0 as Float).max(Float::INFINITY), Float::INFINITY);
+        assert_eq!(Float::INFINITY.max(-9.0), Float::INFINITY);
+        assert_eq!((-9.0 as Float).max(Float::INFINITY), Float::INFINITY);
+        assert_eq!(Float::NEG_INFINITY.max(9.0), 9.0);
+        assert_eq!((9.0 as Float).max(Float::NEG_INFINITY), 9.0);
+        assert_eq!(Float::NEG_INFINITY.max(-9.0), -9.0);
+        assert_eq!((-9.0 as Float).max(Float::NEG_INFINITY), -9.0);
+        assert_eq!(Float::NAN.max(9.0), 9.0);
+        assert_eq!(Float::NAN.max(-9.0), -9.0);
+        assert_eq!((9.0 as Float).max(Float::NAN), 9.0);
+        assert_eq!((-9.0 as Float).max(Float::NAN), -9.0);
+        assert!(Float::NAN.max(Float::NAN).is_nan());
+    }
+}
+
+float_test! {
+    name: minimum,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.0 as Float).minimum(0.0), 0.0);
+        assert!((0.0 as Float).minimum(0.0).is_sign_positive());
+        assert_eq!((-0.0 as Float).minimum(0.0), -0.0);
+        assert!((-0.0 as Float).minimum(0.0).is_sign_negative());
+        assert_eq!((-0.0 as Float).minimum(-0.0), -0.0);
+        assert!((-0.0 as Float).minimum(-0.0).is_sign_negative());
+        assert_eq!((9.0 as Float).minimum(9.0), 9.0);
+        assert_eq!((-9.0 as Float).minimum(0.0), -9.0);
+        assert_eq!((0.0 as Float).minimum(9.0), 0.0);
+        assert!((0.0 as Float).minimum(9.0).is_sign_positive());
+        assert_eq!((-0.0 as Float).minimum(9.0), -0.0);
+        assert!((-0.0 as Float).minimum(9.0).is_sign_negative());
+        assert_eq!((-0.0 as Float).minimum(-9.0), -9.0);
+        assert_eq!(Float::INFINITY.minimum(9.0), 9.0);
+        assert_eq!((9.0 as Float).minimum(Float::INFINITY), 9.0);
+        assert_eq!(Float::INFINITY.minimum(-9.0), -9.0);
+        assert_eq!((-9.0 as Float).minimum(Float::INFINITY), -9.0);
+        assert_eq!(Float::NEG_INFINITY.minimum(9.0), Float::NEG_INFINITY);
+        assert_eq!((9.0 as Float).minimum(Float::NEG_INFINITY), Float::NEG_INFINITY);
+        assert_eq!(Float::NEG_INFINITY.minimum(-9.0), Float::NEG_INFINITY);
+        assert_eq!((-9.0 as Float).minimum(Float::NEG_INFINITY), Float::NEG_INFINITY);
+        assert!(Float::NAN.minimum(9.0).is_nan());
+        assert!(Float::NAN.minimum(-9.0).is_nan());
+        assert!((9.0 as Float).minimum(Float::NAN).is_nan());
+        assert!((-9.0 as Float).minimum(Float::NAN).is_nan());
+        assert!(Float::NAN.minimum(Float::NAN).is_nan());
+    }
+}
+
+float_test! {
+    name: maximum,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.0 as Float).maximum(0.0), 0.0);
+        assert!((0.0 as Float).maximum(0.0).is_sign_positive());
+        assert_eq!((-0.0 as Float).maximum(0.0), 0.0);
+        assert!((-0.0 as Float).maximum(0.0).is_sign_positive());
+        assert_eq!((-0.0 as Float).maximum(-0.0), -0.0);
+        assert!((-0.0 as Float).maximum(-0.0).is_sign_negative());
+        assert_eq!((9.0 as Float).maximum(9.0), 9.0);
+        assert_eq!((-9.0 as Float).maximum(0.0), 0.0);
+        assert!((-9.0 as Float).maximum(0.0).is_sign_positive());
+        assert_eq!((-9.0 as Float).maximum(-0.0), -0.0);
+        assert!((-9.0 as Float).maximum(-0.0).is_sign_negative());
+        assert_eq!((0.0 as Float).maximum(9.0), 9.0);
+        assert_eq!((0.0 as Float).maximum(-9.0), 0.0);
+        assert!((0.0 as Float).maximum(-9.0).is_sign_positive());
+        assert_eq!((-0.0 as Float).maximum(-9.0), -0.0);
+        assert!((-0.0 as Float).maximum(-9.0).is_sign_negative());
+        assert_eq!(Float::INFINITY.maximum(9.0), Float::INFINITY);
+        assert_eq!((9.0 as Float).maximum(Float::INFINITY), Float::INFINITY);
+        assert_eq!(Float::INFINITY.maximum(-9.0), Float::INFINITY);
+        assert_eq!((-9.0 as Float).maximum(Float::INFINITY), Float::INFINITY);
+        assert_eq!(Float::NEG_INFINITY.maximum(9.0), 9.0);
+        assert_eq!((9.0 as Float).maximum(Float::NEG_INFINITY), 9.0);
+        assert_eq!(Float::NEG_INFINITY.maximum(-9.0), -9.0);
+        assert_eq!((-9.0 as Float).maximum(Float::NEG_INFINITY), -9.0);
+        assert!(Float::NAN.maximum(9.0).is_nan());
+        assert!(Float::NAN.maximum(-9.0).is_nan());
+        assert!((9.0 as Float).maximum(Float::NAN).is_nan());
+        assert!((-9.0 as Float).maximum(Float::NAN).is_nan());
+        assert!(Float::NAN.maximum(Float::NAN).is_nan());
+    }
+}
+
+float_test! {
+    name: midpoint,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.5 as Float).midpoint(0.5), 0.5);
+        assert_eq!((0.5 as Float).midpoint(2.5), 1.5);
+        assert_eq!((3.0 as Float).midpoint(4.0), 3.5);
+        assert_eq!((-3.0 as Float).midpoint(4.0), 0.5);
+        assert_eq!((3.0 as Float).midpoint(-4.0), -0.5);
+        assert_eq!((-3.0 as Float).midpoint(-4.0), -3.5);
+        assert_eq!((0.0 as Float).midpoint(0.0), 0.0);
+        assert_eq!((-0.0 as Float).midpoint(-0.0), -0.0);
+        assert_eq!((-5.0 as Float).midpoint(5.0), 0.0);
+        assert_eq!(Float::MAX.midpoint(Float::MIN), 0.0);
+        assert_eq!(Float::MIN.midpoint(Float::MAX), -0.0);
+        assert_eq!(Float::MAX.midpoint(Float::MIN_POSITIVE), Float::MAX / 2.);
+        assert_eq!((-Float::MAX).midpoint(Float::MIN_POSITIVE), -Float::MAX / 2.);
+        assert_eq!(Float::MAX.midpoint(-Float::MIN_POSITIVE), Float::MAX / 2.);
+        assert_eq!((-Float::MAX).midpoint(-Float::MIN_POSITIVE), -Float::MAX / 2.);
+        assert_eq!((Float::MIN_POSITIVE).midpoint(Float::MAX), Float::MAX / 2.);
+        assert_eq!((Float::MIN_POSITIVE).midpoint(-Float::MAX), -Float::MAX / 2.);
+        assert_eq!((-Float::MIN_POSITIVE).midpoint(Float::MAX), Float::MAX / 2.);
+        assert_eq!((-Float::MIN_POSITIVE).midpoint(-Float::MAX), -Float::MAX / 2.);
+        assert_eq!(Float::MAX.midpoint(Float::MAX), Float::MAX);
+        assert_eq!(
+            (Float::MIN_POSITIVE).midpoint(Float::MIN_POSITIVE),
+            Float::MIN_POSITIVE
+        );
+        assert_eq!(
+            (-Float::MIN_POSITIVE).midpoint(-Float::MIN_POSITIVE),
+            -Float::MIN_POSITIVE
+        );
+        assert_eq!(Float::MAX.midpoint(5.0), Float::MAX / 2.0 + 2.5);
+        assert_eq!(Float::MAX.midpoint(-5.0), Float::MAX / 2.0 - 2.5);
+        assert_eq!(Float::INFINITY.midpoint(Float::INFINITY), Float::INFINITY);
+        assert_eq!(
+            Float::NEG_INFINITY.midpoint(Float::NEG_INFINITY),
+            Float::NEG_INFINITY
+        );
+        assert!(Float::NAN.midpoint(1.0).is_nan());
+        assert!((1.0 as Float).midpoint(Float::NAN).is_nan());
+        assert!(Float::NAN.midpoint(Float::NAN).is_nan());
+    }
+}
+
+// Separate test since the `for` loops cannot be run in `const`.
+float_test! {
+    name: midpoint_large_magnitude,
+    attrs: {
+        const: #[cfg(false)],
+        // FIXME(f16_f128): `powi` does not work in Miri for these types
+        f16: #[cfg(all(not(miri), target_has_reliable_f16_math))],
+        f128: #[cfg(all(not(miri), target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        // test if large differences in magnitude are still correctly computed.
+        // NOTE: that because of how small x and y are, x + y can never overflow
+        // so (x + y) / 2.0 is always correct
+        // in particular, `2.pow(i)` will  never be at the max exponent, so it could
+        // be safely doubled, while j is significantly smaller.
+        for i in Float::MAX_EXP.saturating_sub(64)..Float::MAX_EXP {
+            for j in 0..64u8 {
+                let large = (2.0 as Float).powi(i);
+                // a much smaller number, such that there is no chance of overflow to test
+                // potential double rounding in midpoint's implementation.
+                let small = (2.0 as Float).powi(Float::MAX_EXP - 1)
+                    * Float::EPSILON
+                    * Float::from(j);
+
+                let naive = (large + small) / 2.0;
+                let midpoint = large.midpoint(small);
+
+                assert_eq!(naive, midpoint);
+            }
+        }
+    }
+}
+
+float_test! {
+    name: abs,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((-1.0 as Float).abs(), 1.0);
+        assert_eq!((1.0 as Float).abs(), 1.0);
+        assert_eq!(Float::NEG_INFINITY.abs(), Float::INFINITY);
+        assert_eq!(Float::INFINITY.abs(), Float::INFINITY);
+    }
+}
+
+float_test! {
+    name: copysign,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((1.0 as Float).copysign(-2.0), -1.0);
+        assert_eq!((-1.0 as Float).copysign(2.0), 1.0);
+        assert_eq!(Float::INFINITY.copysign(-0.0), Float::NEG_INFINITY);
+        assert_eq!(Float::NEG_INFINITY.copysign(0.0), Float::INFINITY);
+    }
+}
+
+float_test! {
+    name: rem_euclid,
+    attrs: {
+        const: #[cfg(false)],
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert!(Float::INFINITY.rem_euclid(42.0 as Float).is_nan());
+        assert_eq!((42.0 as Float).rem_euclid(Float::INFINITY), (42.0 as Float));
+        assert!((42.0 as Float).rem_euclid(Float::NAN).is_nan());
+        assert!(Float::INFINITY.rem_euclid(Float::INFINITY).is_nan());
+        assert!(Float::INFINITY.rem_euclid(Float::NAN).is_nan());
+        assert!(Float::NAN.rem_euclid(Float::INFINITY).is_nan());
+    }
+}
+
+float_test! {
+    name: div_euclid,
+    attrs: {
+        const: #[cfg(false)],
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((42.0 as Float).div_euclid(Float::INFINITY), 0.0);
+        assert!((42.0 as Float).div_euclid(Float::NAN).is_nan());
+        assert!(Float::INFINITY.div_euclid(Float::INFINITY).is_nan());
+        assert!(Float::INFINITY.div_euclid(Float::NAN).is_nan());
+        assert!(Float::NAN.div_euclid(Float::INFINITY).is_nan());
+    }
+}
+
+float_test! {
+    name: floor,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.0 as Float).floor(), 0.0);
+        assert!((0.0 as Float).floor().is_sign_positive());
+        assert_eq!((-0.0 as Float).floor(), -0.0);
+        assert!((-0.0 as Float).floor().is_sign_negative());
+        assert_eq!((0.5 as Float).floor(), 0.0);
+        assert_eq!((-0.5 as Float).floor(), -1.0);
+        assert_eq!((1.5 as Float).floor(), 1.0);
+        assert_eq!(Float::MAX.floor(), Float::MAX);
+        assert_eq!(Float::MIN.floor(), Float::MIN);
+        assert_eq!(Float::MIN_POSITIVE.floor(), 0.0);
+        assert_eq!((-Float::MIN_POSITIVE).floor(), -1.0);
+        assert!(Float::NAN.floor().is_nan());
+        assert_eq!(Float::INFINITY.floor(), Float::INFINITY);
+        assert_eq!(Float::NEG_INFINITY.floor(), Float::NEG_INFINITY);
+    }
+}
+
+float_test! {
+    name: ceil,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.0 as Float).ceil(), 0.0);
+        assert!((0.0 as Float).ceil().is_sign_positive());
+        assert_eq!((-0.0 as Float).ceil(), 0.0);
+        assert!((-0.0 as Float).ceil().is_sign_negative());
+        assert_eq!((0.5 as Float).ceil(), 1.0);
+        assert_eq!((-0.5 as Float).ceil(), 0.0);
+        assert_eq!(Float::MAX.ceil(), Float::MAX);
+        assert_eq!(Float::MIN.ceil(), Float::MIN);
+        assert_eq!(Float::MIN_POSITIVE.ceil(), 1.0);
+        assert_eq!((-Float::MIN_POSITIVE).ceil(), 0.0);
+        assert!(Float::NAN.ceil().is_nan());
+        assert_eq!(Float::INFINITY.ceil(), Float::INFINITY);
+        assert_eq!(Float::NEG_INFINITY.ceil(), Float::NEG_INFINITY);
+    }
+}
+
+float_test! {
+    name: round,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.0 as Float).round(), 0.0);
+        assert!((0.0 as Float).round().is_sign_positive());
+        assert_eq!((-0.0 as Float).round(), -0.0);
+        assert!((-0.0 as Float).round().is_sign_negative());
+        assert_eq!((0.5 as Float).round(), 1.0);
+        assert_eq!((-0.5 as Float).round(), -1.0);
+        assert_eq!(Float::MAX.round(), Float::MAX);
+        assert_eq!(Float::MIN.round(), Float::MIN);
+        assert_eq!(Float::MIN_POSITIVE.round(), 0.0);
+        assert_eq!((-Float::MIN_POSITIVE).round(), 0.0);
+        assert!(Float::NAN.round().is_nan());
+        assert_eq!(Float::INFINITY.round(), Float::INFINITY);
+        assert_eq!(Float::NEG_INFINITY.round(), Float::NEG_INFINITY);
+    }
+}
+
+float_test! {
+    name: round_ties_even,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.0 as Float).round_ties_even(), 0.0);
+        assert!((0.0 as Float).round_ties_even().is_sign_positive());
+        assert_eq!((-0.0 as Float).round_ties_even(), -0.0);
+        assert!((-0.0 as Float).round_ties_even().is_sign_negative());
+        assert_eq!((0.5 as Float).round_ties_even(), 0.0);
+        assert!((0.5 as Float).round_ties_even().is_sign_positive());
+        assert_eq!((-0.5 as Float).round_ties_even(), -0.0);
+        assert!((-0.5 as Float).round_ties_even().is_sign_negative());
+        assert_eq!(Float::MAX.round_ties_even(), Float::MAX);
+        assert_eq!(Float::MIN.round_ties_even(), Float::MIN);
+        assert_eq!(Float::MIN_POSITIVE.round_ties_even(), 0.0);
+        assert_eq!((-Float::MIN_POSITIVE).round_ties_even(), 0.0);
+        assert!(Float::NAN.round_ties_even().is_nan());
+        assert_eq!(Float::INFINITY.round_ties_even(), Float::INFINITY);
+        assert_eq!(Float::NEG_INFINITY.round_ties_even(), Float::NEG_INFINITY);
+    }
+}
+
+float_test! {
+    name: trunc,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.0 as Float).trunc(), 0.0);
+        assert!((0.0 as Float).trunc().is_sign_positive());
+        assert_eq!((-0.0 as Float).trunc(), -0.0);
+        assert!((-0.0 as Float).trunc().is_sign_negative());
+        assert_eq!((0.5 as Float).trunc(), 0.0);
+        assert!((0.5 as Float).trunc().is_sign_positive());
+        assert_eq!((-0.5 as Float).trunc(), -0.0);
+        assert!((-0.5 as Float).trunc().is_sign_negative());
+        assert_eq!(Float::MAX.trunc(), Float::MAX);
+        assert_eq!(Float::MIN.trunc(), Float::MIN);
+        assert_eq!(Float::MIN_POSITIVE.trunc(), 0.0);
+        assert_eq!((-Float::MIN_POSITIVE).trunc(), 0.0);
+        assert!(Float::NAN.trunc().is_nan());
+        assert_eq!(Float::INFINITY.trunc(), Float::INFINITY);
+        assert_eq!(Float::NEG_INFINITY.trunc(), Float::NEG_INFINITY);
+    }
+}
+
+float_test! {
+    name: fract,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16_math))],
+        f128: #[cfg(any(miri, target_has_reliable_f128_math))],
+    },
+    test<Float> {
+        assert_eq!((0.0 as Float).fract(), 0.0);
+        assert!((0.0 as Float).fract().is_sign_positive());
+        assert_eq!((-0.0 as Float).fract(), 0.0);
+        assert!((-0.0 as Float).fract().is_sign_positive());
+        assert_eq!((0.5 as Float).fract(), 0.5);
+        assert!((0.5 as Float).fract().is_sign_positive());
+        assert_eq!((-0.5 as Float).fract(), -0.5);
+        assert!((-0.5 as Float).fract().is_sign_negative());
+        assert_eq!(Float::MAX.fract(), 0.0);
+        assert_eq!(Float::MIN.fract(), 0.0);
+        assert_eq!(Float::MIN_POSITIVE.fract(), Float::MIN_POSITIVE);
+        assert!(Float::MIN_POSITIVE.fract().is_sign_positive());
+        assert_eq!((-Float::MIN_POSITIVE).fract(), -Float::MIN_POSITIVE);
+        assert!((-Float::MIN_POSITIVE).fract().is_sign_negative());
+        assert!(Float::NAN.fract().is_nan());
+        assert!(Float::INFINITY.fract().is_nan());
+        assert!(Float::NEG_INFINITY.fract().is_nan());
+    }
+}
diff --git a/library/coretests/tests/num/dec2flt/float.rs b/library/coretests/tests/num/dec2flt/float.rs
index 264de061be9..2407ba50ca3 100644
--- a/library/coretests/tests/num/dec2flt/float.rs
+++ b/library/coretests/tests/num/dec2flt/float.rs
@@ -23,7 +23,8 @@ fn test_f16_integer_decode() {
 fn test_f32_integer_decode() {
     assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
     assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
-    assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1));
+    // Set 2^100 directly instead of using powf, because it doesn't guarentee precision
+    assert_eq!(1.2676506e30_f32.integer_decode(), (8388608, 77, 1));
     assert_eq!(0f32.integer_decode(), (0, -150, 1));
     assert_eq!((-0f32).integer_decode(), (0, -150, -1));
     assert_eq!(f32::INFINITY.integer_decode(), (8388608, 105, 1));
@@ -39,7 +40,8 @@ fn test_f32_integer_decode() {
 fn test_f64_integer_decode() {
     assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
     assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
-    assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1));
+    // Set 2^100 directly instead of using powf, because it doesn't guarentee precision
+    assert_eq!(1.2676506002282294e30_f64.integer_decode(), (4503599627370496, 48, 1));
     assert_eq!(0f64.integer_decode(), (0, -1075, 1));
     assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
     assert_eq!(f64::INFINITY.integer_decode(), (4503599627370496, 972, 1));
diff --git a/library/coretests/tests/num/mod.rs b/library/coretests/tests/num/mod.rs
index c68b569f86b..f340926292c 100644
--- a/library/coretests/tests/num/mod.rs
+++ b/library/coretests/tests/num/mod.rs
@@ -22,20 +22,19 @@ mod u64;
 mod u8;
 
 mod bignum;
-
 mod const_from;
 mod dec2flt;
+mod float_iter_sum_identity;
 mod flt2dec;
+mod ieee754;
 mod int_log;
 mod int_sqrt;
 mod midpoint;
+mod nan;
+mod niche_types;
 mod ops;
 mod wrapping;
 
-mod float_iter_sum_identity;
-mod ieee754;
-mod nan;
-
 /// Adds the attribute to all items in the block.
 macro_rules! cfg_block {
     ($(#[$attr:meta]{$($it:item)*})*) => {$($(
@@ -730,356 +729,3 @@ assume_usize_width! {
         }
     }
 }
-
-// FIXME(141726): there is a lot of duplication between the following tests and
-// the tests in `coretests/tests/floats/f*.rs`
-// See issue https://github.com/rust-lang/rust/issues/141726 for more details.
-macro_rules! test_float {
-    ($modname: ident, $fassert: ident, $fty: ty) => {
-        mod $modname {
-            #[test]
-            fn min() {
-                $fassert!((0.0 as $fty).min(0.0), 0.0);
-                $fassert!((0.0 as $fty).min(0.0).is_sign_positive());
-                $fassert!((-0.0 as $fty).min(-0.0), -0.0);
-                $fassert!((-0.0 as $fty).min(-0.0).is_sign_negative());
-                $fassert!((9.0 as $fty).min(9.0), 9.0);
-                $fassert!((-9.0 as $fty).min(0.0), -9.0);
-                $fassert!((0.0 as $fty).min(9.0), 0.0);
-                $fassert!((0.0 as $fty).min(9.0).is_sign_positive());
-                $fassert!((-0.0 as $fty).min(9.0), -0.0);
-                $fassert!((-0.0 as $fty).min(9.0).is_sign_negative());
-                $fassert!((-0.0 as $fty).min(-9.0), -9.0);
-                $fassert!(<$fty>::INFINITY.min(9.0), 9.0);
-                $fassert!((9.0 as $fty).min(<$fty>::INFINITY), 9.0);
-                $fassert!(<$fty>::INFINITY.min(-9.0), -9.0);
-                $fassert!((-9.0 as $fty).min(<$fty>::INFINITY), -9.0);
-                $fassert!(<$fty>::NEG_INFINITY.min(9.0), <$fty>::NEG_INFINITY);
-                $fassert!((9.0 as $fty).min(<$fty>::NEG_INFINITY), <$fty>::NEG_INFINITY);
-                $fassert!(<$fty>::NEG_INFINITY.min(-9.0), <$fty>::NEG_INFINITY);
-                $fassert!((-9.0 as $fty).min(<$fty>::NEG_INFINITY), <$fty>::NEG_INFINITY);
-                $fassert!(<$fty>::NAN.min(9.0), 9.0);
-                $fassert!(<$fty>::NAN.min(-9.0), -9.0);
-                $fassert!((9.0 as $fty).min(<$fty>::NAN), 9.0);
-                $fassert!((-9.0 as $fty).min(<$fty>::NAN), -9.0);
-                $fassert!(<$fty>::NAN.min(<$fty>::NAN).is_nan());
-            }
-            #[test]
-            fn max() {
-                $fassert!((0.0 as $fty).max(0.0), 0.0);
-                $fassert!((0.0 as $fty).max(0.0).is_sign_positive());
-                $fassert!((-0.0 as $fty).max(-0.0), -0.0);
-                $fassert!((-0.0 as $fty).max(-0.0).is_sign_negative());
-                $fassert!((9.0 as $fty).max(9.0), 9.0);
-                $fassert!((-9.0 as $fty).max(0.0), 0.0);
-                $fassert!((-9.0 as $fty).max(0.0).is_sign_positive());
-                $fassert!((-9.0 as $fty).max(-0.0), -0.0);
-                $fassert!((-9.0 as $fty).max(-0.0).is_sign_negative());
-                $fassert!((0.0 as $fty).max(9.0), 9.0);
-                $fassert!((0.0 as $fty).max(-9.0), 0.0);
-                $fassert!((0.0 as $fty).max(-9.0).is_sign_positive());
-                $fassert!((-0.0 as $fty).max(-9.0), -0.0);
-                $fassert!((-0.0 as $fty).max(-9.0).is_sign_negative());
-                $fassert!(<$fty>::INFINITY.max(9.0), <$fty>::INFINITY);
-                $fassert!((9.0 as $fty).max(<$fty>::INFINITY), <$fty>::INFINITY);
-                $fassert!(<$fty>::INFINITY.max(-9.0), <$fty>::INFINITY);
-                $fassert!((-9.0 as $fty).max(<$fty>::INFINITY), <$fty>::INFINITY);
-                $fassert!(<$fty>::NEG_INFINITY.max(9.0), 9.0);
-                $fassert!((9.0 as $fty).max(<$fty>::NEG_INFINITY), 9.0);
-                $fassert!(<$fty>::NEG_INFINITY.max(-9.0), -9.0);
-                $fassert!((-9.0 as $fty).max(<$fty>::NEG_INFINITY), -9.0);
-                $fassert!(<$fty>::NAN.max(9.0), 9.0);
-                $fassert!(<$fty>::NAN.max(-9.0), -9.0);
-                $fassert!((9.0 as $fty).max(<$fty>::NAN), 9.0);
-                $fassert!((-9.0 as $fty).max(<$fty>::NAN), -9.0);
-                $fassert!(<$fty>::NAN.max(<$fty>::NAN).is_nan());
-            }
-            #[test]
-            fn minimum() {
-                $fassert!((0.0 as $fty).minimum(0.0), 0.0);
-                $fassert!((0.0 as $fty).minimum(0.0).is_sign_positive());
-                $fassert!((-0.0 as $fty).minimum(0.0), -0.0);
-                $fassert!((-0.0 as $fty).minimum(0.0).is_sign_negative());
-                $fassert!((-0.0 as $fty).minimum(-0.0), -0.0);
-                $fassert!((-0.0 as $fty).minimum(-0.0).is_sign_negative());
-                $fassert!((9.0 as $fty).minimum(9.0), 9.0);
-                $fassert!((-9.0 as $fty).minimum(0.0), -9.0);
-                $fassert!((0.0 as $fty).minimum(9.0), 0.0);
-                $fassert!((0.0 as $fty).minimum(9.0).is_sign_positive());
-                $fassert!((-0.0 as $fty).minimum(9.0), -0.0);
-                $fassert!((-0.0 as $fty).minimum(9.0).is_sign_negative());
-                $fassert!((-0.0 as $fty).minimum(-9.0), -9.0);
-                $fassert!(<$fty>::INFINITY.minimum(9.0), 9.0);
-                $fassert!((9.0 as $fty).minimum(<$fty>::INFINITY), 9.0);
-                $fassert!(<$fty>::INFINITY.minimum(-9.0), -9.0);
-                $fassert!((-9.0 as $fty).minimum(<$fty>::INFINITY), -9.0);
-                $fassert!(<$fty>::NEG_INFINITY.minimum(9.0), <$fty>::NEG_INFINITY);
-                $fassert!((9.0 as $fty).minimum(<$fty>::NEG_INFINITY), <$fty>::NEG_INFINITY);
-                $fassert!(<$fty>::NEG_INFINITY.minimum(-9.0), <$fty>::NEG_INFINITY);
-                $fassert!((-9.0 as $fty).minimum(<$fty>::NEG_INFINITY), <$fty>::NEG_INFINITY);
-                $fassert!(<$fty>::NAN.minimum(9.0).is_nan());
-                $fassert!(<$fty>::NAN.minimum(-9.0).is_nan());
-                $fassert!((9.0 as $fty).minimum(<$fty>::NAN).is_nan());
-                $fassert!((-9.0 as $fty).minimum(<$fty>::NAN).is_nan());
-                $fassert!(<$fty>::NAN.minimum(<$fty>::NAN).is_nan());
-            }
-            #[test]
-            fn maximum() {
-                $fassert!((0.0 as $fty).maximum(0.0), 0.0);
-                $fassert!((0.0 as $fty).maximum(0.0).is_sign_positive());
-                $fassert!((-0.0 as $fty).maximum(0.0), 0.0);
-                $fassert!((-0.0 as $fty).maximum(0.0).is_sign_positive());
-                $fassert!((-0.0 as $fty).maximum(-0.0), -0.0);
-                $fassert!((-0.0 as $fty).maximum(-0.0).is_sign_negative());
-                $fassert!((9.0 as $fty).maximum(9.0), 9.0);
-                $fassert!((-9.0 as $fty).maximum(0.0), 0.0);
-                $fassert!((-9.0 as $fty).maximum(0.0).is_sign_positive());
-                $fassert!((-9.0 as $fty).maximum(-0.0), -0.0);
-                $fassert!((-9.0 as $fty).maximum(-0.0).is_sign_negative());
-                $fassert!((0.0 as $fty).maximum(9.0), 9.0);
-                $fassert!((0.0 as $fty).maximum(-9.0), 0.0);
-                $fassert!((0.0 as $fty).maximum(-9.0).is_sign_positive());
-                $fassert!((-0.0 as $fty).maximum(-9.0), -0.0);
-                $fassert!((-0.0 as $fty).maximum(-9.0).is_sign_negative());
-                $fassert!(<$fty>::INFINITY.maximum(9.0), <$fty>::INFINITY);
-                $fassert!((9.0 as $fty).maximum(<$fty>::INFINITY), <$fty>::INFINITY);
-                $fassert!(<$fty>::INFINITY.maximum(-9.0), <$fty>::INFINITY);
-                $fassert!((-9.0 as $fty).maximum(<$fty>::INFINITY), <$fty>::INFINITY);
-                $fassert!(<$fty>::NEG_INFINITY.maximum(9.0), 9.0);
-                $fassert!((9.0 as $fty).maximum(<$fty>::NEG_INFINITY), 9.0);
-                $fassert!(<$fty>::NEG_INFINITY.maximum(-9.0), -9.0);
-                $fassert!((-9.0 as $fty).maximum(<$fty>::NEG_INFINITY), -9.0);
-                $fassert!(<$fty>::NAN.maximum(9.0).is_nan());
-                $fassert!(<$fty>::NAN.maximum(-9.0).is_nan());
-                $fassert!((9.0 as $fty).maximum(<$fty>::NAN).is_nan());
-                $fassert!((-9.0 as $fty).maximum(<$fty>::NAN).is_nan());
-                $fassert!(<$fty>::NAN.maximum(<$fty>::NAN).is_nan());
-            }
-            #[test]
-            fn midpoint() {
-                $fassert!((0.5 as $fty).midpoint(0.5), 0.5);
-                $fassert!((0.5 as $fty).midpoint(2.5), 1.5);
-                $fassert!((3.0 as $fty).midpoint(4.0), 3.5);
-                $fassert!((-3.0 as $fty).midpoint(4.0), 0.5);
-                $fassert!((3.0 as $fty).midpoint(-4.0), -0.5);
-                $fassert!((-3.0 as $fty).midpoint(-4.0), -3.5);
-                $fassert!((0.0 as $fty).midpoint(0.0), 0.0);
-                $fassert!((-0.0 as $fty).midpoint(-0.0), -0.0);
-                $fassert!((-5.0 as $fty).midpoint(5.0), 0.0);
-                $fassert!(<$fty>::MAX.midpoint(<$fty>::MIN), 0.0);
-                $fassert!(<$fty>::MIN.midpoint(<$fty>::MAX), -0.0);
-                $fassert!(<$fty>::MAX.midpoint(<$fty>::MIN_POSITIVE), <$fty>::MAX / 2.);
-                $fassert!((-<$fty>::MAX).midpoint(<$fty>::MIN_POSITIVE), -<$fty>::MAX / 2.);
-                $fassert!(<$fty>::MAX.midpoint(-<$fty>::MIN_POSITIVE), <$fty>::MAX / 2.);
-                $fassert!((-<$fty>::MAX).midpoint(-<$fty>::MIN_POSITIVE), -<$fty>::MAX / 2.);
-                $fassert!((<$fty>::MIN_POSITIVE).midpoint(<$fty>::MAX), <$fty>::MAX / 2.);
-                $fassert!((<$fty>::MIN_POSITIVE).midpoint(-<$fty>::MAX), -<$fty>::MAX / 2.);
-                $fassert!((-<$fty>::MIN_POSITIVE).midpoint(<$fty>::MAX), <$fty>::MAX / 2.);
-                $fassert!((-<$fty>::MIN_POSITIVE).midpoint(-<$fty>::MAX), -<$fty>::MAX / 2.);
-                $fassert!(<$fty>::MAX.midpoint(<$fty>::MAX), <$fty>::MAX);
-                $fassert!(
-                    (<$fty>::MIN_POSITIVE).midpoint(<$fty>::MIN_POSITIVE),
-                    <$fty>::MIN_POSITIVE
-                );
-                $fassert!(
-                    (-<$fty>::MIN_POSITIVE).midpoint(-<$fty>::MIN_POSITIVE),
-                    -<$fty>::MIN_POSITIVE
-                );
-                $fassert!(<$fty>::MAX.midpoint(5.0), <$fty>::MAX / 2.0 + 2.5);
-                $fassert!(<$fty>::MAX.midpoint(-5.0), <$fty>::MAX / 2.0 - 2.5);
-                $fassert!(<$fty>::INFINITY.midpoint(<$fty>::INFINITY), <$fty>::INFINITY);
-                $fassert!(
-                    <$fty>::NEG_INFINITY.midpoint(<$fty>::NEG_INFINITY),
-                    <$fty>::NEG_INFINITY
-                );
-                $fassert!(<$fty>::NAN.midpoint(1.0).is_nan());
-                $fassert!((1.0 as $fty).midpoint(<$fty>::NAN).is_nan());
-                $fassert!(<$fty>::NAN.midpoint(<$fty>::NAN).is_nan());
-
-                // test if large differences in magnitude are still correctly computed.
-                // NOTE: that because of how small x and y are, x + y can never overflow
-                // so (x + y) / 2.0 is always correct
-                // in particular, `2.pow(i)` will  never be at the max exponent, so it could
-                // be safely doubled, while j is significantly smaller.
-                for i in <$fty>::MAX_EXP.saturating_sub(64)..<$fty>::MAX_EXP {
-                    for j in 0..64u8 {
-                        let large = (2.0 as $fty).powi(i);
-                        // a much smaller number, such that there is no chance of overflow to test
-                        // potential double rounding in midpoint's implementation.
-                        let small = (2.0 as $fty).powi(<$fty>::MAX_EXP - 1)
-                            * <$fty>::EPSILON
-                            * <$fty>::from(j);
-
-                        let naive = (large + small) / 2.0;
-                        let midpoint = large.midpoint(small);
-
-                        assert_eq!(naive, midpoint);
-                    }
-                }
-            }
-            #[test]
-            fn abs() {
-                $fassert!((-1.0 as $fty).abs(), 1.0);
-                $fassert!((1.0 as $fty).abs(), 1.0);
-                $fassert!(<$fty>::NEG_INFINITY.abs(), <$fty>::INFINITY);
-                $fassert!(<$fty>::INFINITY.abs(), <$fty>::INFINITY);
-            }
-            #[test]
-            fn copysign() {
-                $fassert!((1.0 as $fty).copysign(-2.0), -1.0);
-                $fassert!((-1.0 as $fty).copysign(2.0), 1.0);
-                $fassert!(<$fty>::INFINITY.copysign(-0.0), <$fty>::NEG_INFINITY);
-                $fassert!(<$fty>::NEG_INFINITY.copysign(0.0), <$fty>::INFINITY);
-            }
-            #[test]
-            fn rem_euclid() {
-                // FIXME: Use $fassert when rem_euclid becomes const
-                assert!(<$fty>::INFINITY.rem_euclid((42.0 as $fty)).is_nan());
-                assert_eq!((42.0 as $fty).rem_euclid(<$fty>::INFINITY), (42.0 as $fty));
-                assert!((42.0 as $fty).rem_euclid(<$fty>::NAN).is_nan());
-                assert!(<$fty>::INFINITY.rem_euclid(<$fty>::INFINITY).is_nan());
-                assert!(<$fty>::INFINITY.rem_euclid(<$fty>::NAN).is_nan());
-                assert!(<$fty>::NAN.rem_euclid(<$fty>::INFINITY).is_nan());
-            }
-            #[test]
-            fn div_euclid() {
-                // FIXME: Use $fassert when div_euclid becomes const
-                assert_eq!((42.0 as $fty).div_euclid(<$fty>::INFINITY), 0.0);
-                assert!((42.0 as $fty).div_euclid(<$fty>::NAN).is_nan());
-                assert!(<$fty>::INFINITY.div_euclid(<$fty>::INFINITY).is_nan());
-                assert!(<$fty>::INFINITY.div_euclid(<$fty>::NAN).is_nan());
-                assert!(<$fty>::NAN.div_euclid(<$fty>::INFINITY).is_nan());
-            }
-            #[test]
-            fn floor() {
-                $fassert!((0.0 as $fty).floor(), 0.0);
-                $fassert!((0.0 as $fty).floor().is_sign_positive());
-                $fassert!((-0.0 as $fty).floor(), -0.0);
-                $fassert!((-0.0 as $fty).floor().is_sign_negative());
-                $fassert!((0.5 as $fty).floor(), 0.0);
-                $fassert!((-0.5 as $fty).floor(), -1.0);
-                $fassert!((1.5 as $fty).floor(), 1.0);
-                $fassert!(<$fty>::MAX.floor(), <$fty>::MAX);
-                $fassert!(<$fty>::MIN.floor(), <$fty>::MIN);
-                $fassert!(<$fty>::MIN_POSITIVE.floor(), 0.0);
-                $fassert!((-<$fty>::MIN_POSITIVE).floor(), -1.0);
-                $fassert!(<$fty>::NAN.floor().is_nan());
-                $fassert!(<$fty>::INFINITY.floor(), <$fty>::INFINITY);
-                $fassert!(<$fty>::NEG_INFINITY.floor(), <$fty>::NEG_INFINITY);
-            }
-            #[test]
-            fn ceil() {
-                $fassert!((0.0 as $fty).ceil(), 0.0);
-                $fassert!((0.0 as $fty).ceil().is_sign_positive());
-                $fassert!((-0.0 as $fty).ceil(), 0.0);
-                $fassert!((-0.0 as $fty).ceil().is_sign_negative());
-                $fassert!((0.5 as $fty).ceil(), 1.0);
-                $fassert!((-0.5 as $fty).ceil(), 0.0);
-                $fassert!(<$fty>::MAX.ceil(), <$fty>::MAX);
-                $fassert!(<$fty>::MIN.ceil(), <$fty>::MIN);
-                $fassert!(<$fty>::MIN_POSITIVE.ceil(), 1.0);
-                $fassert!((-<$fty>::MIN_POSITIVE).ceil(), 0.0);
-                $fassert!(<$fty>::NAN.ceil().is_nan());
-                $fassert!(<$fty>::INFINITY.ceil(), <$fty>::INFINITY);
-                $fassert!(<$fty>::NEG_INFINITY.ceil(), <$fty>::NEG_INFINITY);
-            }
-            #[test]
-            fn round() {
-                $fassert!((0.0 as $fty).round(), 0.0);
-                $fassert!((0.0 as $fty).round().is_sign_positive());
-                $fassert!((-0.0 as $fty).round(), -0.0);
-                $fassert!((-0.0 as $fty).round().is_sign_negative());
-                $fassert!((0.5 as $fty).round(), 1.0);
-                $fassert!((-0.5 as $fty).round(), -1.0);
-                $fassert!(<$fty>::MAX.round(), <$fty>::MAX);
-                $fassert!(<$fty>::MIN.round(), <$fty>::MIN);
-                $fassert!(<$fty>::MIN_POSITIVE.round(), 0.0);
-                $fassert!((-<$fty>::MIN_POSITIVE).round(), 0.0);
-                $fassert!(<$fty>::NAN.round().is_nan());
-                $fassert!(<$fty>::INFINITY.round(), <$fty>::INFINITY);
-                $fassert!(<$fty>::NEG_INFINITY.round(), <$fty>::NEG_INFINITY);
-            }
-            #[test]
-            fn round_ties_even() {
-                $fassert!((0.0 as $fty).round_ties_even(), 0.0);
-                $fassert!((0.0 as $fty).round_ties_even().is_sign_positive());
-                $fassert!((-0.0 as $fty).round_ties_even(), -0.0);
-                $fassert!((-0.0 as $fty).round_ties_even().is_sign_negative());
-                $fassert!((0.5 as $fty).round_ties_even(), 0.0);
-                $fassert!((0.5 as $fty).round_ties_even().is_sign_positive());
-                $fassert!((-0.5 as $fty).round_ties_even(), -0.0);
-                $fassert!((-0.5 as $fty).round_ties_even().is_sign_negative());
-                $fassert!(<$fty>::MAX.round_ties_even(), <$fty>::MAX);
-                $fassert!(<$fty>::MIN.round_ties_even(), <$fty>::MIN);
-                $fassert!(<$fty>::MIN_POSITIVE.round_ties_even(), 0.0);
-                $fassert!((-<$fty>::MIN_POSITIVE).round_ties_even(), 0.0);
-                $fassert!(<$fty>::NAN.round_ties_even().is_nan());
-                $fassert!(<$fty>::INFINITY.round_ties_even(), <$fty>::INFINITY);
-                $fassert!(<$fty>::NEG_INFINITY.round_ties_even(), <$fty>::NEG_INFINITY);
-            }
-            #[test]
-            fn trunc() {
-                $fassert!((0.0 as $fty).trunc(), 0.0);
-                $fassert!((0.0 as $fty).trunc().is_sign_positive());
-                $fassert!((-0.0 as $fty).trunc(), -0.0);
-                $fassert!((-0.0 as $fty).trunc().is_sign_negative());
-                $fassert!((0.5 as $fty).trunc(), 0.0);
-                $fassert!((0.5 as $fty).trunc().is_sign_positive());
-                $fassert!((-0.5 as $fty).trunc(), -0.0);
-                $fassert!((-0.5 as $fty).trunc().is_sign_negative());
-                $fassert!(<$fty>::MAX.trunc(), <$fty>::MAX);
-                $fassert!(<$fty>::MIN.trunc(), <$fty>::MIN);
-                $fassert!(<$fty>::MIN_POSITIVE.trunc(), 0.0);
-                $fassert!((-<$fty>::MIN_POSITIVE).trunc(), 0.0);
-                $fassert!(<$fty>::NAN.trunc().is_nan());
-                $fassert!(<$fty>::INFINITY.trunc(), <$fty>::INFINITY);
-                $fassert!(<$fty>::NEG_INFINITY.trunc(), <$fty>::NEG_INFINITY);
-            }
-            #[test]
-            fn fract() {
-                $fassert!((0.0 as $fty).fract(), 0.0);
-                $fassert!((0.0 as $fty).fract().is_sign_positive());
-                $fassert!((-0.0 as $fty).fract(), 0.0);
-                $fassert!((-0.0 as $fty).fract().is_sign_positive());
-                $fassert!((0.5 as $fty).fract(), 0.5);
-                $fassert!((0.5 as $fty).fract().is_sign_positive());
-                $fassert!((-0.5 as $fty).fract(), -0.5);
-                $fassert!((-0.5 as $fty).fract().is_sign_negative());
-                $fassert!(<$fty>::MAX.fract(), 0.0);
-                $fassert!(<$fty>::MIN.fract(), 0.0);
-                $fassert!(<$fty>::MIN_POSITIVE.fract(), <$fty>::MIN_POSITIVE);
-                $fassert!(<$fty>::MIN_POSITIVE.fract().is_sign_positive());
-                $fassert!((-<$fty>::MIN_POSITIVE).fract(), -<$fty>::MIN_POSITIVE);
-                $fassert!((-<$fty>::MIN_POSITIVE).fract().is_sign_negative());
-                $fassert!(<$fty>::NAN.fract().is_nan());
-                $fassert!(<$fty>::INFINITY.fract().is_nan());
-                $fassert!(<$fty>::NEG_INFINITY.fract().is_nan());
-            }
-        }
-    };
-}
-
-// Custom assert macro that distribute between assert! and assert_eq! in a non-const context
-macro_rules! float_assert {
-    ($b:expr) => {
-        assert!($b);
-    };
-    ($left:expr, $right:expr) => {
-        assert_eq!($left, $right);
-    };
-}
-
-// Custom assert macro that only uses assert! in a const context
-macro_rules! float_const_assert {
-    ($b:expr) => {
-        assert!(const { $b });
-    };
-    ($left:expr, $right:expr) => {
-        assert!(const { $left == $right });
-    };
-}
-
-test_float!(f32, float_assert, f32);
-test_float!(f32_const, float_const_assert, f32);
-test_float!(f64, float_assert, f64);
-test_float!(f64_const, float_const_assert, f64);
diff --git a/library/coretests/tests/num/niche_types.rs b/library/coretests/tests/num/niche_types.rs
new file mode 100644
index 00000000000..171a7f35d53
--- /dev/null
+++ b/library/coretests/tests/num/niche_types.rs
@@ -0,0 +1,12 @@
+use core::num::NonZero;
+
+#[test]
+fn test_new_from_zero_is_none() {
+    assert_eq!(NonZero::<char>::new(0 as char), None);
+}
+
+#[test]
+fn test_new_from_extreme_is_some() {
+    assert!(NonZero::<char>::new(1 as char).is_some());
+    assert!(NonZero::<char>::new(char::MAX).is_some());
+}
diff --git a/library/panic_abort/Cargo.toml b/library/panic_abort/Cargo.toml
index d7d169671f0..e8c66f1a4dd 100644
--- a/library/panic_abort/Cargo.toml
+++ b/library/panic_abort/Cargo.toml
@@ -13,7 +13,7 @@ doc = false
 
 [dependencies]
 core = { path = "../core" }
-compiler_builtins = "0.1.0"
+compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
 
 [target.'cfg(target_os = "android")'.dependencies]
 libc = { version = "0.2", default-features = false }
diff --git a/library/panic_unwind/Cargo.toml b/library/panic_unwind/Cargo.toml
index d176434e06b..47914b9cd3c 100644
--- a/library/panic_unwind/Cargo.toml
+++ b/library/panic_unwind/Cargo.toml
@@ -15,7 +15,7 @@ doc = false
 alloc = { path = "../alloc" }
 core = { path = "../core" }
 unwind = { path = "../unwind" }
-compiler_builtins = "0.1.0"
+compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
 cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 
 [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index 3794b56c089..003ac4f0cd3 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -291,7 +291,7 @@ cfg_if::cfg_if! {
 }
 
 pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
-    use core::intrinsics::atomic_store_seqcst;
+    use core::intrinsics::{AtomicOrdering, atomic_store};
 
     // _CxxThrowException executes entirely on this stack frame, so there's no
     // need to otherwise transfer `data` to the heap. We just pass a stack
@@ -325,23 +325,23 @@ pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     // In any case, we basically need to do something like this until we can
     // express more operations in statics (and we may never be able to).
     unsafe {
-        atomic_store_seqcst(
+        atomic_store::<_, { AtomicOrdering::SeqCst }>(
             (&raw mut THROW_INFO.pmfnUnwind).cast(),
             ptr_t::new(exception_cleanup as *mut u8).raw(),
         );
-        atomic_store_seqcst(
+        atomic_store::<_, { AtomicOrdering::SeqCst }>(
             (&raw mut THROW_INFO.pCatchableTypeArray).cast(),
             ptr_t::new((&raw mut CATCHABLE_TYPE_ARRAY).cast()).raw(),
         );
-        atomic_store_seqcst(
+        atomic_store::<_, { AtomicOrdering::SeqCst }>(
             (&raw mut CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0]).cast(),
             ptr_t::new((&raw mut CATCHABLE_TYPE).cast()).raw(),
         );
-        atomic_store_seqcst(
+        atomic_store::<_, { AtomicOrdering::SeqCst }>(
             (&raw mut CATCHABLE_TYPE.pType).cast(),
             ptr_t::new((&raw mut TYPE_DESCRIPTOR).cast()).raw(),
         );
-        atomic_store_seqcst(
+        atomic_store::<_, { AtomicOrdering::SeqCst }>(
             (&raw mut CATCHABLE_TYPE.copyFunction).cast(),
             ptr_t::new(exception_copy as *mut u8).raw(),
         );
diff --git a/library/rustc-std-workspace-core/Cargo.toml b/library/rustc-std-workspace-core/Cargo.toml
index 9315c08a4d1..bd318fc2f9e 100644
--- a/library/rustc-std-workspace-core/Cargo.toml
+++ b/library/rustc-std-workspace-core/Cargo.toml
@@ -12,3 +12,4 @@ path = "lib.rs"
 
 [dependencies]
 core = { path = "../core" }
+compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features = ["compiler-builtins"] }
diff --git a/library/rustc-std-workspace-core/lib.rs b/library/rustc-std-workspace-core/lib.rs
index 14327852561..21c047dd36e 100644
--- a/library/rustc-std-workspace-core/lib.rs
+++ b/library/rustc-std-workspace-core/lib.rs
@@ -2,3 +2,7 @@
 #![no_core]
 
 pub use core::*;
+
+// Crate must be brought into scope so it appears in the crate graph for anything that
+// depends on `rustc-std-workspace-core`.
+use compiler_builtins as _;
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 196b904d56a..53d78dcc488 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.160" }
+compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.15", default-features = false, features = [
     'rustc-dep-of-std',
@@ -157,6 +157,8 @@ test = true
 [lints.rust.unexpected_cfgs]
 level = "warn"
 check-cfg = [
+    # #[cfg(bootstrap)] loongarch32
+    'cfg(target_arch, values("loongarch32"))',
     # std use #[path] imports to portable-simd `std_float` crate
     # and to the `backtrace` crate which messes-up with Cargo list
     # of declared features, we therefor expect any feature cfg
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index ce2dc795220..6d7d576b32a 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -1046,6 +1046,7 @@ pub mod consts {
     /// * `"sparc"`
     /// * `"sparc64"`
     /// * `"hexagon"`
+    /// * `"loongarch32"`
     /// * `"loongarch64"`
     ///
     /// </details>
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index 024cb71b915..f44e12d48ad 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -178,6 +178,8 @@ pub use core::ffi::{
     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 use core::ffi::{c_ptrdiff_t, c_size_t, c_ssize_t};
 
 #[doc(inline)]
 #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")]
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 21d5b7292e8..3cc225004ea 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -568,7 +568,7 @@ impl OsString {
     /// However, keep in mind that trimming the capacity may result in a reallocation and copy.
     ///
     /// [`into_boxed_os_str`]: Self::into_boxed_os_str
-    #[unstable(feature = "os_string_pathbuf_leak", issue = "125965")]
+    #[stable(feature = "os_string_pathbuf_leak", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub fn leak<'a>(self) -> &'a mut OsStr {
         OsStr::from_inner_mut(self.inner.leak())
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 711efc7d011..6cbf8301e01 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -1311,9 +1311,39 @@ impl Write for &File {
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Seek for &File {
+    /// Seek to an offset, in bytes in a file.
+    ///
+    /// See [`Seek::seek`] docs for more info.
+    ///
+    /// # Platform-specific behavior
+    ///
+    /// This function currently corresponds to the `lseek64` function on Unix
+    /// and the `SetFilePointerEx` function on Windows. Note that this [may
+    /// change in the future][changes].
+    ///
+    /// [changes]: io#platform-specific-behavior
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         self.inner.seek(pos)
     }
+
+    /// Returns the length of this file (in bytes).
+    ///
+    /// See [`Seek::stream_len`] docs for more info.
+    ///
+    /// # Platform-specific behavior
+    ///
+    /// This function currently corresponds to the `statx` function on Linux
+    /// (with fallbacks) and the `GetFileSizeEx` function on Windows. Note that
+    /// this [may change in the future][changes].
+    ///
+    /// [changes]: io#platform-specific-behavior
+    fn stream_len(&mut self) -> io::Result<u64> {
+        if let Some(result) = self.inner.size() {
+            return result;
+        }
+        io::stream_len_default(self)
+    }
+
     fn stream_position(&mut self) -> io::Result<u64> {
         self.inner.tell()
     }
@@ -1363,6 +1393,9 @@ impl Seek for File {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         (&*self).seek(pos)
     }
+    fn stream_len(&mut self) -> io::Result<u64> {
+        (&*self).stream_len()
+    }
     fn stream_position(&mut self) -> io::Result<u64> {
         (&*self).stream_position()
     }
@@ -1412,6 +1445,9 @@ impl Seek for Arc<File> {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         (&**self).seek(pos)
     }
+    fn stream_len(&mut self) -> io::Result<u64> {
+        (&**self).stream_len()
+    }
     fn stream_position(&mut self) -> io::Result<u64> {
         (&**self).stream_position()
     }
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 03f5f838311..a9a24681e7c 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -917,6 +917,19 @@ pub trait Read {
     /// # }
     /// ```
     ///
+    /// # Usage Notes
+    ///
+    /// `read_to_end` attempts to read a source until EOF, but many sources are continuous streams
+    /// that do not send EOF. In these cases, `read_to_end` will block indefinitely. Standard input
+    /// is one such stream which may be finite if piped, but is typically continuous. For example,
+    /// `cat file | my-rust-program` will correctly terminate with an `EOF` upon closure of cat.
+    /// Reading user input or running programs that remain open indefinitely will never terminate
+    /// the stream with `EOF` (e.g. `yes | my-rust-program`).
+    ///
+    /// Using `.lines()` with a [`BufReader`] or using [`read`] can provide a better solution
+    ///
+    ///[`read`]: Read::read
+    ///
     /// [`Vec::try_reserve`]: crate::vec::Vec::try_reserve
     #[stable(feature = "rust1", since = "1.0.0")]
     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
@@ -960,6 +973,19 @@ pub trait Read {
     /// (See also the [`std::fs::read_to_string`] convenience function for
     /// reading from a file.)
     ///
+    /// # Usage Notes
+    ///
+    /// `read_to_string` attempts to read a source until EOF, but many sources are continuous streams
+    /// that do not send EOF. In these cases, `read_to_string` will block indefinitely. Standard input
+    /// is one such stream which may be finite if piped, but is typically continuous. For example,
+    /// `cat file | my-rust-program` will correctly terminate with an `EOF` upon closure of cat.
+    /// Reading user input or running programs that remain open indefinitely will never terminate
+    /// the stream with `EOF` (e.g. `yes | my-rust-program`).
+    ///
+    /// Using `.lines()` with a [`BufReader`] or using [`read`] can provide a better solution
+    ///
+    ///[`read`]: Read::read
+    ///
     /// [`std::fs::read_to_string`]: crate::fs::read_to_string
     #[stable(feature = "rust1", since = "1.0.0")]
     fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
@@ -1262,6 +1288,20 @@ pub trait Read {
 ///     Ok(())
 /// }
 /// ```
+///
+/// # Usage Notes
+///
+/// `read_to_string` attempts to read a source until EOF, but many sources are continuous streams
+/// that do not send EOF. In these cases, `read_to_string` will block indefinitely. Standard input
+/// is one such stream which may be finite if piped, but is typically continuous. For example,
+/// `cat file | my-rust-program` will correctly terminate with an `EOF` upon closure of cat.
+/// Reading user input or running programs that remain open indefinitely will never terminate
+/// the stream with `EOF` (e.g. `yes | my-rust-program`).
+///
+/// Using `.lines()` with a [`BufReader`] or using [`read`] can provide a better solution
+///
+///[`read`]: Read::read
+///
 #[stable(feature = "io_read_to_string", since = "1.65.0")]
 pub fn read_to_string<R: Read>(mut reader: R) -> Result<String> {
     let mut buf = String::new();
@@ -2028,7 +2068,7 @@ pub trait Seek {
 
     /// Returns the length of this stream (in bytes).
     ///
-    /// This method is implemented using up to three seek operations. If this
+    /// The default implementation uses up to three seek operations. If this
     /// method returns successfully, the seek position is unchanged (i.e. the
     /// position before calling this method is the same as afterwards).
     /// However, if this method returns an error, the seek position is
@@ -2062,16 +2102,7 @@ pub trait Seek {
     /// ```
     #[unstable(feature = "seek_stream_len", issue = "59359")]
     fn stream_len(&mut self) -> Result<u64> {
-        let old_pos = self.stream_position()?;
-        let len = self.seek(SeekFrom::End(0))?;
-
-        // Avoid seeking a third time when we were already at the end of the
-        // stream. The branch is usually way cheaper than a seek operation.
-        if old_pos != len {
-            self.seek(SeekFrom::Start(old_pos))?;
-        }
-
-        Ok(len)
+        stream_len_default(self)
     }
 
     /// Returns the current seek position from the start of the stream.
@@ -2132,6 +2163,19 @@ pub trait Seek {
     }
 }
 
+pub(crate) fn stream_len_default<T: Seek + ?Sized>(self_: &mut T) -> Result<u64> {
+    let old_pos = self_.stream_position()?;
+    let len = self_.seek(SeekFrom::End(0))?;
+
+    // Avoid seeking a third time when we were already at the end of the
+    // stream. The branch is usually way cheaper than a seek operation.
+    if old_pos != len {
+        self_.seek(SeekFrom::Start(old_pos))?;
+    }
+
+    Ok(len)
+}
+
 /// Enumeration of possible methods to seek within an I/O object.
 ///
 /// It is used by the [`Seek`] trait.
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index 79b25040ef6..1c55824ab90 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1916,10 +1916,6 @@ mod type_keyword {}
 /// - and to declare that a programmer has checked that these contracts have been upheld (`unsafe
 /// {}` and `unsafe impl`, but also `unsafe fn` -- see below).
 ///
-/// They are not mutually exclusive, as can be seen in `unsafe fn`: the body of an `unsafe fn` is,
-/// by default, treated like an unsafe block. The `unsafe_op_in_unsafe_fn` lint can be enabled to
-/// change that.
-///
 /// # Unsafe abilities
 ///
 /// **No matter what, Safe Rust can't cause Undefined Behavior**. This is
@@ -1961,13 +1957,6 @@ mod type_keyword {}
 /// - `unsafe impl`: the contract necessary to implement the trait has been
 /// checked by the programmer and is guaranteed to be respected.
 ///
-/// By default, `unsafe fn` also acts like an `unsafe {}` block
-/// around the code inside the function. This means it is not just a signal to
-/// the caller, but also promises that the preconditions for the operations
-/// inside the function are upheld. Mixing these two meanings can be confusing, so the
-/// `unsafe_op_in_unsafe_fn` lint can be enabled to warn against that and require explicit unsafe
-/// blocks even inside `unsafe fn`.
-///
 /// See the [Rustonomicon] and the [Reference] for more information.
 ///
 /// # Examples
@@ -2109,6 +2098,7 @@ mod type_keyword {}
 /// impl Indexable for i32 {
 ///     const LEN: usize = 1;
 ///
+///     /// See `Indexable` for the safety contract.
 ///     unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
 ///         debug_assert_eq!(idx, 0);
 ///         *self
@@ -2120,6 +2110,7 @@ mod type_keyword {}
 /// impl Indexable for [i32; 42] {
 ///     const LEN: usize = 42;
 ///
+///     /// See `Indexable` for the safety contract.
 ///     unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
 ///         // SAFETY: As per this trait's documentation, the caller ensures
 ///         // that `idx < 42`.
@@ -2132,6 +2123,7 @@ mod type_keyword {}
 /// impl Indexable for ! {
 ///     const LEN: usize = 0;
 ///
+///     /// See `Indexable` for the safety contract.
 ///     unsafe fn idx_unchecked(&self, idx: usize) -> i32 {
 ///         // SAFETY: As per this trait's documentation, the caller ensures
 ///         // that `idx < 0`, which is impossible, so this is dead code.
@@ -2153,11 +2145,14 @@ mod type_keyword {}
 /// contract of `idx_unchecked`. Implementing `Indexable` is safe because when writing
 /// `idx_unchecked`, we don't have to worry: our *callers* need to discharge a proof obligation
 /// (like `use_indexable` does), but the *implementation* of `get_unchecked` has no proof obligation
-/// to contend with. Of course, the implementation of `Indexable` may choose to call other unsafe
-/// operations, and then it needs an `unsafe` *block* to indicate it discharged the proof
-/// obligations of its callees. (We enabled `unsafe_op_in_unsafe_fn`, so the body of `idx_unchecked`
-/// is not implicitly an unsafe block.) For that purpose it can make use of the contract that all
-/// its callers must uphold -- the fact that `idx < LEN`.
+/// to contend with. Of course, the implementation may choose to call other unsafe operations, and
+/// then it needs an `unsafe` *block* to indicate it discharged the proof obligations of its
+/// callees. For that purpose it can make use of the contract that all its callers must uphold --
+/// the fact that `idx < LEN`.
+///
+/// Note that unlike normal `unsafe fn`, an `unsafe fn` in a trait implementation does not get to
+/// just pick an arbitrary safety contract! It *has* to use the safety contract defined by the trait
+/// (or one with weaker preconditions).
 ///
 /// Formally speaking, an `unsafe fn` in a trait is a function with *preconditions* that go beyond
 /// those encoded by the argument types (such as `idx < LEN`), whereas an `unsafe trait` can declare
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 7c54e731edc..2bb7a63772d 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -351,7 +351,6 @@
 #![feature(lazy_get)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_write_slice)]
-#![feature(nonnull_provenance)]
 #![feature(panic_can_unwind)]
 #![feature(panic_internals)]
 #![feature(pin_coerce_unsized_trait)]
diff --git a/library/std/src/num/f128.rs b/library/std/src/num/f128.rs
index c0190de089f..64e604e35f7 100644
--- a/library/std/src/num/f128.rs
+++ b/library/std/src/num/f128.rs
@@ -5,6 +5,7 @@
 //! Mathematically significant numbers are provided in the `consts` sub-module.
 
 #![unstable(feature = "f128", issue = "116909")]
+#![doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))]
 
 #[unstable(feature = "f128", issue = "116909")]
 pub use core::f128::consts;
@@ -27,8 +28,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -59,8 +58,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -93,8 +90,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -127,8 +122,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -146,8 +139,6 @@ impl f128 {
     /// Non-positive values:
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -180,8 +171,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -197,8 +186,6 @@ impl f128 {
     /// Non-positive values:
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -227,8 +214,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -244,8 +229,6 @@ impl f128 {
     /// Non-positive values:
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -274,8 +257,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -291,8 +272,6 @@ impl f128 {
     /// Non-positive values:
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -323,8 +302,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -362,8 +339,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -395,8 +370,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -426,8 +399,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -460,8 +431,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -495,8 +464,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -533,8 +500,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -570,8 +535,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -611,8 +574,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -656,8 +617,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -694,8 +653,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -733,8 +690,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -751,8 +706,6 @@ impl f128 {
     /// Out-of-range values:
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -783,8 +736,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -821,8 +772,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -859,8 +808,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -894,8 +841,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -929,8 +874,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -966,8 +909,6 @@ impl f128 {
     ///
     /// ```
     /// #![feature(f128)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1003,8 +944,6 @@ impl f128 {
     /// ```
     /// #![feature(f128)]
     /// #![feature(float_gamma)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1041,8 +980,6 @@ impl f128 {
     /// ```
     /// #![feature(f128)]
     /// #![feature(float_gamma)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     ///
@@ -1079,8 +1016,6 @@ impl f128 {
     /// ```
     /// #![feature(f128)]
     /// #![feature(float_erf)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     /// /// The error function relates what percent of a normal distribution lies
@@ -1121,8 +1056,6 @@ impl f128 {
     /// ```
     /// #![feature(f128)]
     /// #![feature(float_erf)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f128_math)] {
     /// let x: f128 = 0.123;
diff --git a/library/std/src/num/f16.rs b/library/std/src/num/f16.rs
index 4a4a8fd839a..7bdefb05858 100644
--- a/library/std/src/num/f16.rs
+++ b/library/std/src/num/f16.rs
@@ -5,6 +5,7 @@
 //! Mathematically significant numbers are provided in the `consts` sub-module.
 
 #![unstable(feature = "f16", issue = "116909")]
+#![doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))]
 
 #[unstable(feature = "f16", issue = "116909")]
 pub use core::f16::consts;
@@ -27,8 +28,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -59,8 +58,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -93,8 +90,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -127,8 +122,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -146,8 +139,6 @@ impl f16 {
     /// Non-positive values:
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -180,8 +171,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -197,8 +186,6 @@ impl f16 {
     /// Non-positive values:
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -227,8 +214,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -244,8 +229,6 @@ impl f16 {
     /// Non-positive values:
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -274,8 +257,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -291,8 +272,6 @@ impl f16 {
     /// Non-positive values:
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -325,8 +304,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -358,8 +335,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -389,8 +364,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -423,8 +396,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -458,8 +429,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -496,8 +465,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -533,8 +500,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -574,8 +539,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -619,8 +582,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -657,8 +618,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -696,8 +655,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -714,8 +671,6 @@ impl f16 {
     /// Out-of-range values:
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -746,8 +701,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -784,8 +737,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -822,8 +773,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -857,8 +806,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -892,8 +839,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -929,8 +874,6 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -966,8 +909,6 @@ impl f16 {
     /// ```
     /// #![feature(f16)]
     /// #![feature(float_gamma)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1004,8 +945,6 @@ impl f16 {
     /// ```
     /// #![feature(f16)]
     /// #![feature(float_gamma)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     ///
@@ -1042,8 +981,6 @@ impl f16 {
     /// ```
     /// #![feature(f16)]
     /// #![feature(float_erf)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     /// /// The error function relates what percent of a normal distribution lies
@@ -1084,8 +1021,6 @@ impl f16 {
     /// ```
     /// #![feature(f16)]
     /// #![feature(float_erf)]
-    /// # #![feature(cfg_target_has_reliable_f16_f128)]
-    /// # #![expect(internal_features)]
     /// # #[cfg(not(miri))]
     /// # #[cfg(target_has_reliable_f16_math)] {
     /// let x: f16 = 0.123;
diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs
index b7f6529ac40..e79ec2ae966 100644
--- a/library/std/src/num/f32.rs
+++ b/library/std/src/num/f32.rs
@@ -304,7 +304,7 @@ impl f32 {
     /// ```
     /// let x = 2.0_f32;
     /// let abs_difference = (x.powi(2) - (x * x)).abs();
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-5);
     ///
     /// assert_eq!(f32::powi(f32::NAN, 0), 1.0);
     /// ```
@@ -328,7 +328,7 @@ impl f32 {
     /// ```
     /// let x = 2.0_f32;
     /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-5);
     ///
     /// assert_eq!(f32::powf(1.0, f32::NAN), 1.0);
     /// assert_eq!(f32::powf(f32::NAN, 0.0), 1.0);
@@ -388,7 +388,7 @@ impl f32 {
     /// // ln(e) - 1 == 0
     /// let abs_difference = (e.ln() - 1.0).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
@@ -413,7 +413,7 @@ impl f32 {
     /// // 2^2 - 4 == 0
     /// let abs_difference = (f.exp2() - 4.0).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-5);
     /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
@@ -442,7 +442,7 @@ impl f32 {
     /// // ln(e) - 1 == 0
     /// let abs_difference = (e.ln() - 1.0).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     /// ```
     ///
     /// Non-positive values:
@@ -479,7 +479,7 @@ impl f32 {
     /// // log5(5) - 1 == 0
     /// let abs_difference = (five.log(5.0) - 1.0).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     /// ```
     ///
     /// Non-positive values:
@@ -512,7 +512,7 @@ impl f32 {
     /// // log2(2) - 1 == 0
     /// let abs_difference = (two.log2() - 1.0).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     /// ```
     ///
     /// Non-positive values:
@@ -545,7 +545,7 @@ impl f32 {
     /// // log10(10) - 1 == 0
     /// let abs_difference = (ten.log10() - 1.0).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     /// ```
     ///
     /// Non-positive values:
@@ -652,7 +652,7 @@ impl f32 {
     /// // sqrt(x^2 + y^2)
     /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
@@ -676,7 +676,7 @@ impl f32 {
     ///
     /// let abs_difference = (x.sin() - 1.0).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
@@ -700,7 +700,7 @@ impl f32 {
     ///
     /// let abs_difference = (x.cos() - 1.0).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
@@ -754,7 +754,7 @@ impl f32 {
     /// // asin(sin(pi/2))
     /// let abs_difference = (f.sin().asin() - std::f32::consts::FRAC_PI_2).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-3);
     /// ```
     #[doc(alias = "arcsin")]
     #[rustc_allow_incoherent_impl]
@@ -784,7 +784,7 @@ impl f32 {
     /// // acos(cos(pi/4))
     /// let abs_difference = (f.cos().acos() - std::f32::consts::FRAC_PI_4).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     /// ```
     #[doc(alias = "arccos")]
     #[rustc_allow_incoherent_impl]
@@ -884,8 +884,8 @@ impl f32 {
     /// let abs_difference_0 = (f.0 - x.sin()).abs();
     /// let abs_difference_1 = (f.1 - x.cos()).abs();
     ///
-    /// assert!(abs_difference_0 <= f32::EPSILON);
-    /// assert!(abs_difference_1 <= f32::EPSILON);
+    /// assert!(abs_difference_0 <= 1e-6);
+    /// assert!(abs_difference_1 <= 1e-6);
     /// ```
     #[doc(alias = "sincos")]
     #[rustc_allow_incoherent_impl]
@@ -1067,7 +1067,7 @@ impl f32 {
     ///
     /// let abs_difference = (f - x).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-7);
     /// ```
     #[doc(alias = "arcsinh")]
     #[rustc_allow_incoherent_impl]
@@ -1095,7 +1095,7 @@ impl f32 {
     ///
     /// let abs_difference = (f - x).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-6);
     /// ```
     #[doc(alias = "arccosh")]
     #[rustc_allow_incoherent_impl]
diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs
index 75e35a8db33..853417825f9 100644
--- a/library/std/src/num/f64.rs
+++ b/library/std/src/num/f64.rs
@@ -304,7 +304,7 @@ impl f64 {
     /// ```
     /// let x = 2.0_f64;
     /// let abs_difference = (x.powi(2) - (x * x)).abs();
-    /// assert!(abs_difference <= f64::EPSILON);
+    /// assert!(abs_difference <= 1e-14);
     ///
     /// assert_eq!(f64::powi(f64::NAN, 0), 1.0);
     /// ```
@@ -328,7 +328,7 @@ impl f64 {
     /// ```
     /// let x = 2.0_f64;
     /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
-    /// assert!(abs_difference <= f64::EPSILON);
+    /// assert!(abs_difference <= 1e-14);
     ///
     /// assert_eq!(f64::powf(1.0, f64::NAN), 1.0);
     /// assert_eq!(f64::powf(f64::NAN, 0.0), 1.0);
@@ -754,7 +754,7 @@ impl f64 {
     /// // asin(sin(pi/2))
     /// let abs_difference = (f.sin().asin() - std::f64::consts::FRAC_PI_2).abs();
     ///
-    /// assert!(abs_difference < 1e-10);
+    /// assert!(abs_difference < 1e-7);
     /// ```
     #[doc(alias = "arcsin")]
     #[rustc_allow_incoherent_impl]
diff --git a/library/std/src/os/android/net.rs b/library/std/src/os/android/net.rs
index 960a304fd0c..3a459ed8aee 100644
--- a/library/std/src/os/android/net.rs
+++ b/library/std/src/os/android/net.rs
@@ -6,5 +6,5 @@
 pub use crate::os::net::linux_ext::addr::SocketAddrExt;
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub use crate::os::net::linux_ext::socket::UnixSocketExt;
-#[unstable(feature = "tcp_quickack", issue = "96256")]
+#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")]
 pub use crate::os::net::linux_ext::tcp::TcpStreamExt;
diff --git a/library/std/src/os/linux/net.rs b/library/std/src/os/linux/net.rs
index 1de120c8fd3..c14aba13bd1 100644
--- a/library/std/src/os/linux/net.rs
+++ b/library/std/src/os/linux/net.rs
@@ -6,5 +6,5 @@
 pub use crate::os::net::linux_ext::addr::SocketAddrExt;
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub use crate::os::net::linux_ext::socket::UnixSocketExt;
-#[unstable(feature = "tcp_quickack", issue = "96256")]
+#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")]
 pub use crate::os::net::linux_ext::tcp::TcpStreamExt;
diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs
index d53674d3c5f..6483f086113 100644
--- a/library/std/src/os/linux/raw.rs
+++ b/library/std/src/os/linux/raw.rs
@@ -231,6 +231,7 @@ mod arch {
 }
 
 #[cfg(any(
+    target_arch = "loongarch32",
     target_arch = "loongarch64",
     target_arch = "mips64",
     target_arch = "mips64r6",
diff --git a/library/std/src/os/net/linux_ext/mod.rs b/library/std/src/os/net/linux_ext/mod.rs
index d0979640c32..bb9dfae2623 100644
--- a/library/std/src/os/net/linux_ext/mod.rs
+++ b/library/std/src/os/net/linux_ext/mod.rs
@@ -8,7 +8,7 @@ pub(crate) mod addr;
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub(crate) mod socket;
 
-#[unstable(feature = "tcp_quickack", issue = "96256")]
+#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")]
 pub(crate) mod tcp;
 
 #[cfg(test)]
diff --git a/library/std/src/os/net/linux_ext/tcp.rs b/library/std/src/os/net/linux_ext/tcp.rs
index 95dffb3bc43..167cfa62531 100644
--- a/library/std/src/os/net/linux_ext/tcp.rs
+++ b/library/std/src/os/net/linux_ext/tcp.rs
@@ -9,7 +9,7 @@ use crate::{io, net};
 /// Os-specific extensions for [`TcpStream`]
 ///
 /// [`TcpStream`]: net::TcpStream
-#[unstable(feature = "tcp_quickack", issue = "96256")]
+#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")]
 pub trait TcpStreamExt: Sealed {
     /// Enable or disable `TCP_QUICKACK`.
     ///
@@ -23,7 +23,6 @@ pub trait TcpStreamExt: Sealed {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(tcp_quickack)]
     /// use std::net::TcpStream;
     /// #[cfg(target_os = "linux")]
     /// use std::os::linux::net::TcpStreamExt;
@@ -34,7 +33,7 @@ pub trait TcpStreamExt: Sealed {
     ///         .expect("Couldn't connect to the server...");
     /// stream.set_quickack(true).expect("set_quickack call failed");
     /// ```
-    #[unstable(feature = "tcp_quickack", issue = "96256")]
+    #[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")]
     fn set_quickack(&self, quickack: bool) -> io::Result<()>;
 
     /// Gets the value of the `TCP_QUICKACK` option on this socket.
@@ -44,7 +43,6 @@ pub trait TcpStreamExt: Sealed {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(tcp_quickack)]
     /// use std::net::TcpStream;
     /// #[cfg(target_os = "linux")]
     /// use std::os::linux::net::TcpStreamExt;
@@ -56,7 +54,7 @@ pub trait TcpStreamExt: Sealed {
     /// stream.set_quickack(true).expect("set_quickack call failed");
     /// assert_eq!(stream.quickack().unwrap_or(false), true);
     /// ```
-    #[unstable(feature = "tcp_quickack", issue = "96256")]
+    #[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")]
     fn quickack(&self) -> io::Result<bool>;
 
     /// A socket listener will be awakened solely when data arrives.
@@ -105,10 +103,10 @@ pub trait TcpStreamExt: Sealed {
     fn deferaccept(&self) -> io::Result<u32>;
 }
 
-#[unstable(feature = "tcp_quickack", issue = "96256")]
+#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")]
 impl Sealed for net::TcpStream {}
 
-#[unstable(feature = "tcp_quickack", issue = "96256")]
+#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")]
 impl TcpStreamExt for net::TcpStream {
     fn set_quickack(&self, quickack: bool) -> io::Result<()> {
         self.as_inner().as_inner().set_quickack(quickack)
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 014b56d28f4..826d9f0f39d 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1252,7 +1252,7 @@ impl PathBuf {
     /// However, keep in mind that trimming the capacity may result in a reallocation and copy.
     ///
     /// [`into_boxed_path`]: Self::into_boxed_path
-    #[unstable(feature = "os_string_pathbuf_leak", issue = "125965")]
+    #[stable(feature = "os_string_pathbuf_leak", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub fn leak<'a>(self) -> &'a mut Path {
         Path::from_inner_mut(self.inner.leak())
diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs
index 8489e17c971..f3af1f7f599 100644
--- a/library/std/src/sys/alloc/mod.rs
+++ b/library/std/src/sys/alloc/mod.rs
@@ -17,6 +17,7 @@ const MIN_ALIGN: usize = if cfg!(any(
     target_arch = "arm",
     target_arch = "m68k",
     target_arch = "csky",
+    target_arch = "loongarch32",
     target_arch = "mips",
     target_arch = "mips32r6",
     target_arch = "powerpc",
diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs
index a9774bef9e3..175d919c289 100644
--- a/library/std/src/sys/fs/hermit.rs
+++ b/library/std/src/sys/fs/hermit.rs
@@ -422,6 +422,10 @@ impl File {
         self.0.seek(pos)
     }
 
+    pub fn size(&self) -> Option<io::Result<u64>> {
+        None
+    }
+
     pub fn tell(&self) -> io::Result<u64> {
         self.0.tell()
     }
diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs
index 3bfb39bac95..808a9582911 100644
--- a/library/std/src/sys/fs/solid.rs
+++ b/library/std/src/sys/fs/solid.rs
@@ -459,6 +459,10 @@ impl File {
         self.tell()
     }
 
+    pub fn size(&self) -> Option<io::Result<u64>> {
+        None
+    }
+
     pub fn tell(&self) -> io::Result<u64> {
         unsafe {
             let mut out_offset = MaybeUninit::uninit();
diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs
index 416c90b98b6..5763d7862f5 100644
--- a/library/std/src/sys/fs/uefi.rs
+++ b/library/std/src/sys/fs/uefi.rs
@@ -280,6 +280,10 @@ impl File {
         self.0
     }
 
+    pub fn size(&self) -> Option<io::Result<u64>> {
+        self.0
+    }
+
     pub fn tell(&self) -> io::Result<u64> {
         self.0
     }
diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs
index a3e520fdeef..dc278274f00 100644
--- a/library/std/src/sys/fs/unix.rs
+++ b/library/std/src/sys/fs/unix.rs
@@ -1464,6 +1464,15 @@ impl File {
         Ok(n as u64)
     }
 
+    pub fn size(&self) -> Option<io::Result<u64>> {
+        match self.file_attr().map(|attr| attr.size()) {
+            // Fall back to default implementation if the returned size is 0,
+            // we might be in a proc mount.
+            Ok(0) => None,
+            result => Some(result),
+        }
+    }
+
     pub fn tell(&self) -> io::Result<u64> {
         self.seek(SeekFrom::Current(0))
     }
diff --git a/library/std/src/sys/fs/unsupported.rs b/library/std/src/sys/fs/unsupported.rs
index 0ff9533c047..efaddb51b37 100644
--- a/library/std/src/sys/fs/unsupported.rs
+++ b/library/std/src/sys/fs/unsupported.rs
@@ -259,6 +259,10 @@ impl File {
         self.0
     }
 
+    pub fn size(&self) -> Option<io::Result<u64>> {
+        self.0
+    }
+
     pub fn tell(&self) -> io::Result<u64> {
         self.0
     }
diff --git a/library/std/src/sys/fs/wasi.rs b/library/std/src/sys/fs/wasi.rs
index ebfc7377a2e..b65d86de12a 100644
--- a/library/std/src/sys/fs/wasi.rs
+++ b/library/std/src/sys/fs/wasi.rs
@@ -516,6 +516,10 @@ impl File {
         self.fd.seek(pos)
     }
 
+    pub fn size(&self) -> Option<io::Result<u64>> {
+        None
+    }
+
     pub fn tell(&self) -> io::Result<u64> {
         self.fd.tell()
     }
diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs
index d01a572ac73..a95709b4891 100644
--- a/library/std/src/sys/fs/windows.rs
+++ b/library/std/src/sys/fs/windows.rs
@@ -616,6 +616,14 @@ impl File {
         Ok(newpos as u64)
     }
 
+    pub fn size(&self) -> Option<io::Result<u64>> {
+        let mut result = 0;
+        Some(
+            cvt(unsafe { c::GetFileSizeEx(self.handle.as_raw_handle(), &mut result) })
+                .map(|_| result as u64),
+        )
+    }
+
     pub fn tell(&self) -> io::Result<u64> {
         self.seek(SeekFrom::Current(0))
     }
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index 48609030aed..850bdfdf5b5 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -282,7 +282,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
         return getcwd().map(|cwd| cwd.join(path))?.canonicalize();
     }
     // Search PATH to infer current_exe.
-    if let Some(p) = getenv(OsStr::from_bytes("PATH".as_bytes())) {
+    if let Some(p) = env::var_os(OsStr::from_bytes("PATH".as_bytes())) {
         for search_path in split_paths(&p) {
             let pb = search_path.join(&path);
             if pb.is_file()
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index d5fbb453c6f..a99c474c763 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2156,6 +2156,7 @@ GetExitCodeProcess
 GetFileAttributesW
 GetFileInformationByHandle
 GetFileInformationByHandleEx
+GetFileSizeEx
 GetFileType
 GETFINALPATHNAMEBYHANDLE_FLAGS
 GetFinalPathNameByHandleW
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index eb2914b8644..95bf8040229 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -44,6 +44,7 @@ windows_targets::link!("kernel32.dll" "system" fn GetExitCodeProcess(hprocess :
 windows_targets::link!("kernel32.dll" "system" fn GetFileAttributesW(lpfilename : PCWSTR) -> u32);
 windows_targets::link!("kernel32.dll" "system" fn GetFileInformationByHandle(hfile : HANDLE, lpfileinformation : *mut BY_HANDLE_FILE_INFORMATION) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn GetFileInformationByHandleEx(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *mut core::ffi::c_void, dwbuffersize : u32) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn GetFileSizeEx(hfile : HANDLE, lpfilesize : *mut i64) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn GetFileType(hfile : HANDLE) -> FILE_TYPE);
 windows_targets::link!("kernel32.dll" "system" fn GetFinalPathNameByHandleW(hfile : HANDLE, lpszfilepath : PWSTR, cchfilepath : u32, dwflags : GETFINALPATHNAMEBYHANDLE_FLAGS) -> u32);
 windows_targets::link!("kernel32.dll" "system" fn GetFullPathNameW(lpfilename : PCWSTR, nbufferlength : u32, lpbuffer : PWSTR, lpfilepart : *mut PWSTR) -> u32);
diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index b012e47f9aa..75e793f18b8 100644
--- a/library/std/src/sys/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
@@ -86,7 +86,7 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1
 #[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))]
 const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11
 
-#[cfg(target_arch = "loongarch64")]
+#[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))]
 const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
 
 // The following code is based on GCC's C and C++ personality routines.  For reference, see:
diff --git a/library/std/tests/floats/f32.rs b/library/std/tests/floats/f32.rs
index e54f227bb77..38c906c1d87 100644
--- a/library/std/tests/floats/f32.rs
+++ b/library/std/tests/floats/f32.rs
@@ -1,5 +1,10 @@
 use std::f32::consts;
 
+/// Miri adds some extra errors to float functions; make sure the tests still pass.
+/// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides.
+/// They serve as a way to get an idea of the real precision of floating point operations on different platforms.
+const APPROX_DELTA: f32 = if cfg!(miri) { 1e-3 } else { 1e-6 };
+
 #[allow(unused_macros)]
 macro_rules! assert_f32_biteq {
     ($left : expr, $right : expr) => {
@@ -17,9 +22,9 @@ fn test_powf() {
     let inf: f32 = f32::INFINITY;
     let neg_inf: f32 = f32::NEG_INFINITY;
     assert_eq!(1.0f32.powf(1.0), 1.0);
-    assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
+    assert_approx_eq!(3.4f32.powf(4.5), 246.408218, APPROX_DELTA);
     assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
-    assert_approx_eq!((-3.1f32).powf(2.0), 9.61);
+    assert_approx_eq!((-3.1f32).powf(2.0), 9.61, APPROX_DELTA);
     assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
     assert_eq!(8.3f32.powf(0.0), 1.0);
     assert!(nan.powf(2.0).is_nan());
@@ -30,8 +35,8 @@ fn test_powf() {
 #[test]
 fn test_exp() {
     assert_eq!(1.0, 0.0f32.exp());
-    assert_approx_eq!(2.718282, 1.0f32.exp());
-    assert_approx_eq!(148.413162, 5.0f32.exp());
+    assert_approx_eq!(2.718282, 1.0f32.exp(), APPROX_DELTA);
+    assert_approx_eq!(148.413162, 5.0f32.exp(), APPROX_DELTA);
 
     let inf: f32 = f32::INFINITY;
     let neg_inf: f32 = f32::NEG_INFINITY;
@@ -43,7 +48,7 @@ fn test_exp() {
 
 #[test]
 fn test_exp2() {
-    assert_eq!(32.0, 5.0f32.exp2());
+    assert_approx_eq!(32.0, 5.0f32.exp2(), APPROX_DELTA);
     assert_eq!(1.0, 0.0f32.exp2());
 
     let inf: f32 = f32::INFINITY;
@@ -66,7 +71,7 @@ fn test_ln() {
     assert!((-2.3f32).ln().is_nan());
     assert_eq!((-0.0f32).ln(), neg_inf);
     assert_eq!(0.0f32.ln(), neg_inf);
-    assert_approx_eq!(4.0f32.ln(), 1.386294);
+    assert_approx_eq!(4.0f32.ln(), 1.386294, APPROX_DELTA);
 }
 
 #[test]
@@ -74,9 +79,9 @@ fn test_log() {
     let nan: f32 = f32::NAN;
     let inf: f32 = f32::INFINITY;
     let neg_inf: f32 = f32::NEG_INFINITY;
-    assert_eq!(10.0f32.log(10.0), 1.0);
+    assert_approx_eq!(10.0f32.log(10.0), 1.0);
     assert_approx_eq!(2.3f32.log(3.5), 0.664858);
-    assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0);
+    assert_approx_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0, APPROX_DELTA);
     assert!(1.0f32.log(1.0).is_nan());
     assert!(1.0f32.log(-13.9).is_nan());
     assert!(nan.log(2.3).is_nan());
@@ -92,9 +97,9 @@ fn test_log2() {
     let nan: f32 = f32::NAN;
     let inf: f32 = f32::INFINITY;
     let neg_inf: f32 = f32::NEG_INFINITY;
-    assert_approx_eq!(10.0f32.log2(), 3.321928);
+    assert_approx_eq!(10.0f32.log2(), 3.321928, APPROX_DELTA);
     assert_approx_eq!(2.3f32.log2(), 1.201634);
-    assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
+    assert_approx_eq!(1.0f32.exp().log2(), 1.442695, APPROX_DELTA);
     assert!(nan.log2().is_nan());
     assert_eq!(inf.log2(), inf);
     assert!(neg_inf.log2().is_nan());
@@ -108,7 +113,7 @@ fn test_log10() {
     let nan: f32 = f32::NAN;
     let inf: f32 = f32::INFINITY;
     let neg_inf: f32 = f32::NEG_INFINITY;
-    assert_eq!(10.0f32.log10(), 1.0);
+    assert_approx_eq!(10.0f32.log10(), 1.0);
     assert_approx_eq!(2.3f32.log10(), 0.361728);
     assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
     assert_eq!(1.0f32.log10(), 0.0);
@@ -158,7 +163,7 @@ fn test_acosh() {
     assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
 
     // test for low accuracy from issue 104548
-    assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh());
+    assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh(), APPROX_DELTA);
 }
 
 #[test]
@@ -237,7 +242,7 @@ fn test_real_consts() {
     let ln_10: f32 = consts::LN_10;
 
     assert_approx_eq!(frac_pi_2, pi / 2f32);
-    assert_approx_eq!(frac_pi_3, pi / 3f32);
+    assert_approx_eq!(frac_pi_3, pi / 3f32, APPROX_DELTA);
     assert_approx_eq!(frac_pi_4, pi / 4f32);
     assert_approx_eq!(frac_pi_6, pi / 6f32);
     assert_approx_eq!(frac_pi_8, pi / 8f32);
@@ -249,5 +254,5 @@ fn test_real_consts() {
     assert_approx_eq!(log2_e, e.log2());
     assert_approx_eq!(log10_e, e.log10());
     assert_approx_eq!(ln_2, 2f32.ln());
-    assert_approx_eq!(ln_10, 10f32.ln());
+    assert_approx_eq!(ln_10, 10f32.ln(), APPROX_DELTA);
 }
diff --git a/library/std/tests/floats/f64.rs b/library/std/tests/floats/f64.rs
index 2d8dd1cf091..fccf2009727 100644
--- a/library/std/tests/floats/f64.rs
+++ b/library/std/tests/floats/f64.rs
@@ -43,7 +43,7 @@ fn test_exp() {
 
 #[test]
 fn test_exp2() {
-    assert_eq!(32.0, 5.0f64.exp2());
+    assert_approx_eq!(32.0, 5.0f64.exp2());
     assert_eq!(1.0, 0.0f64.exp2());
 
     let inf: f64 = f64::INFINITY;
@@ -74,9 +74,9 @@ fn test_log() {
     let nan: f64 = f64::NAN;
     let inf: f64 = f64::INFINITY;
     let neg_inf: f64 = f64::NEG_INFINITY;
-    assert_eq!(10.0f64.log(10.0), 1.0);
+    assert_approx_eq!(10.0f64.log(10.0), 1.0);
     assert_approx_eq!(2.3f64.log(3.5), 0.664858);
-    assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
+    assert_approx_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
     assert!(1.0f64.log(1.0).is_nan());
     assert!(1.0f64.log(-13.9).is_nan());
     assert!(nan.log(2.3).is_nan());
@@ -108,7 +108,7 @@ fn test_log10() {
     let nan: f64 = f64::NAN;
     let inf: f64 = f64::INFINITY;
     let neg_inf: f64 = f64::NEG_INFINITY;
-    assert_eq!(10.0f64.log10(), 1.0);
+    assert_approx_eq!(10.0f64.log10(), 1.0);
     assert_approx_eq!(2.3f64.log10(), 0.361728);
     assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
     assert_eq!(1.0f64.log10(), 0.0);
diff --git a/library/std/tests/path.rs b/library/std/tests/path.rs
index 781855a2d14..be0dda1d426 100644
--- a/library/std/tests/path.rs
+++ b/library/std/tests/path.rs
@@ -3,7 +3,6 @@
     path_add_extension,
     path_file_prefix,
     maybe_uninit_slice,
-    os_string_pathbuf_leak,
     normalize_lexically
 )]
 
diff --git a/library/std/tests/sync/mpmc.rs b/library/std/tests/sync/mpmc.rs
index 78abcb3bcbe..594fc2180d8 100644
--- a/library/std/tests/sync/mpmc.rs
+++ b/library/std/tests/sync/mpmc.rs
@@ -462,8 +462,8 @@ fn oneshot_single_thread_recv_timeout() {
 #[test]
 fn stress_recv_timeout_two_threads() {
     let (tx, rx) = channel();
-    let stress = stress_factor() + 100;
-    let timeout = Duration::from_millis(100);
+    let stress = stress_factor() + 50;
+    let timeout = Duration::from_millis(5);
 
     thread::spawn(move || {
         for i in 0..stress {
@@ -475,18 +475,23 @@ fn stress_recv_timeout_two_threads() {
     });
 
     let mut recv_count = 0;
+    let mut got_timeout = false;
     loop {
         match rx.recv_timeout(timeout) {
             Ok(n) => {
                 assert_eq!(n, 1usize);
                 recv_count += 1;
             }
-            Err(RecvTimeoutError::Timeout) => continue,
+            Err(RecvTimeoutError::Timeout) => {
+                got_timeout = true;
+                continue;
+            }
             Err(RecvTimeoutError::Disconnected) => break,
         }
     }
 
     assert_eq!(recv_count, stress);
+    assert!(got_timeout);
 }
 
 #[test]
diff --git a/library/std/tests/sync/mpsc.rs b/library/std/tests/sync/mpsc.rs
index 1d8edfde44b..9de4a71987b 100644
--- a/library/std/tests/sync/mpsc.rs
+++ b/library/std/tests/sync/mpsc.rs
@@ -425,8 +425,8 @@ fn oneshot_single_thread_recv_timeout() {
 #[test]
 fn stress_recv_timeout_two_threads() {
     let (tx, rx) = channel();
-    let stress = stress_factor() + 100;
-    let timeout = Duration::from_millis(100);
+    let stress = stress_factor() + 50;
+    let timeout = Duration::from_millis(5);
 
     thread::spawn(move || {
         for i in 0..stress {
@@ -438,18 +438,23 @@ fn stress_recv_timeout_two_threads() {
     });
 
     let mut recv_count = 0;
+    let mut got_timeout = false;
     loop {
         match rx.recv_timeout(timeout) {
             Ok(n) => {
                 assert_eq!(n, 1usize);
                 recv_count += 1;
             }
-            Err(RecvTimeoutError::Timeout) => continue,
+            Err(RecvTimeoutError::Timeout) => {
+                got_timeout = true;
+                continue;
+            }
             Err(RecvTimeoutError::Disconnected) => break,
         }
     }
 
     assert_eq!(recv_count, stress);
+    assert!(got_timeout);
 }
 
 #[test]
diff --git a/library/stdarch b/library/stdarch
-Subproject b6e2249e388f520627544812649b77b0944e1a2
+Subproject 5c1c436524c0bbc8db83577f42f8bea9006a7b7
diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml
index df43e6ae80f..ad373420a96 100644
--- a/library/unwind/Cargo.toml
+++ b/library/unwind/Cargo.toml
@@ -15,7 +15,7 @@ doc = false
 
 [dependencies]
 core = { path = "../core" }
-compiler_builtins = "0.1.0"
+compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
 cfg-if = "1.0"
 
 [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
@@ -37,4 +37,4 @@ system-llvm-libunwind = []
 
 [lints.rust.unexpected_cfgs]
 level = "warn"
-check-cfg = ['cfg(emscripten_wasm_eh)']
+check-cfg = ['cfg(emscripten_wasm_eh)', 'cfg(target_arch, values("loongarch32"))']
diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs
index 12582569a57..b350003cbb1 100644
--- a/library/unwind/src/libunwind.rs
+++ b/library/unwind/src/libunwind.rs
@@ -81,7 +81,7 @@ pub const unwinder_private_data_size: usize = 2;
 #[cfg(all(target_arch = "hexagon", target_os = "linux"))]
 pub const unwinder_private_data_size: usize = 35;
 
-#[cfg(target_arch = "loongarch64")]
+#[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))]
 pub const unwinder_private_data_size: usize = 2;
 
 #[repr(C)]
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index c60c6b8db64..d8c6be78247 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -394,6 +394,7 @@ def default_build_triple(verbose):
         "i686": "i686",
         "i686-AT386": "i686",
         "i786": "i686",
+        "loongarch32": "loongarch32",
         "loongarch64": "loongarch64",
         "m68k": "m68k",
         "csky": "csky",
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index a3bac5bfe7a..911a51b0e16 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -77,6 +77,13 @@ impl Step for Std {
     }
 
     fn run(self, builder: &Builder<'_>) {
+        if !builder.download_rustc() && builder.config.skip_std_check_if_no_download_rustc {
+            eprintln!(
+                "WARNING: `--skip-std-check-if-no-download-rustc` flag was passed and `rust.download-rustc` is not available. Skipping."
+            );
+            return;
+        }
+
         builder.require_submodule("library/stdarch", None);
 
         let stage = self.custom_stage.unwrap_or(builder.top_stage);
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index d52b9dd1f3a..5ecce31fe15 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -668,7 +668,8 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
 
     // Enable frame pointers by default for the library. Note that they are still controlled by a
     // separate setting for the compiler.
-    cargo.rustflag("-Cforce-frame-pointers=yes");
+    cargo.rustflag("-Zunstable-options");
+    cargo.rustflag("-Cforce-frame-pointers=non-leaf");
 
     let html_root =
         format!("-Zcrate-attr=doc(html_root_url=\"{}/\")", builder.doc_rust_lang_org_channel(),);
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 587fca80374..7aa9e6cc2b5 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -1681,7 +1681,8 @@ impl Step for Extended {
             cmd.run(builder);
         }
 
-        if target.is_windows() {
+        // FIXME(mati865): `gnullvm` here is temporary, remove it once it can host itself
+        if target.is_windows() && !target.contains("gnullvm") {
             let exe = tmp.join("exe");
             let _ = fs::remove_dir_all(&exe);
 
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 20a4d1a1515..2b7703000cb 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -443,23 +443,26 @@ impl Step for Llvm {
         // See https://github.com/rust-lang/rust/pull/50104
         cfg.define("LLVM_ENABLE_LIBXML2", "OFF");
 
-        if !enabled_llvm_projects.is_empty() {
-            enabled_llvm_projects.sort();
-            enabled_llvm_projects.dedup();
-            cfg.define("LLVM_ENABLE_PROJECTS", enabled_llvm_projects.join(";"));
-        }
-
         let mut enabled_llvm_runtimes = Vec::new();
 
         if helpers::forcing_clang_based_tests() {
             enabled_llvm_runtimes.push("compiler-rt");
         }
 
+        // This is an experimental flag, which likely builds more than necessary.
+        // We will optimize it when we get closer to releasing it on nightly.
         if builder.config.llvm_offload {
             enabled_llvm_runtimes.push("offload");
             //FIXME(ZuseZ4): LLVM intends to drop the offload dependency on openmp.
             //Remove this line once they achieved it.
             enabled_llvm_runtimes.push("openmp");
+            enabled_llvm_projects.push("compiler-rt");
+        }
+
+        if !enabled_llvm_projects.is_empty() {
+            enabled_llvm_projects.sort();
+            enabled_llvm_projects.dedup();
+            cfg.define("LLVM_ENABLE_PROJECTS", enabled_llvm_projects.join(";"));
         }
 
         if !enabled_llvm_runtimes.is_empty() {
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 21a119e331e..717accb399a 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -23,7 +23,6 @@ use crate::core::builder::{
     Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step, cargo_profile_var,
 };
 use crate::core::config::{DebuginfoLevel, RustcLto, TargetSelection};
-use crate::utils::channel::GitInfo;
 use crate::utils::exec::{BootstrapCommand, command};
 use crate::utils::helpers::{add_dylib_path, exe, t};
 use crate::{Compiler, FileType, Kind, Mode, gha};
@@ -278,7 +277,7 @@ pub fn prepare_tool_cargo(
         cargo.env("CFG_VER_DESCRIPTION", description);
     }
 
-    let info = GitInfo::new(builder.config.omit_git_hash, &dir);
+    let info = builder.config.git_info(builder.config.omit_git_hash, &dir);
     if let Some(sha) = info.sha() {
         cargo.env("CFG_COMMIT_HASH", sha);
     }
@@ -1313,10 +1312,8 @@ impl Builder<'_> {
         //
         // Notably this munges the dynamic library lookup path to point to the
         // right location to run `compiler`.
-        let mut lib_paths: Vec<PathBuf> = vec![
-            self.build.rustc_snapshot_libdir(),
-            self.cargo_out(compiler, Mode::ToolBootstrap, *host).join("deps"),
-        ];
+        let mut lib_paths: Vec<PathBuf> =
+            vec![self.cargo_out(compiler, Mode::ToolBootstrap, *host).join("deps")];
 
         // On MSVC a tool may invoke a C compiler (e.g., compiletest in run-make
         // mode) and that C compiler may need some extra PATH modification. Do
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 1e9af68a92d..c6cfdb69356 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -11,7 +11,7 @@ use crate::utils::build_stamp;
 use crate::utils::helpers::{self, LldThreads, check_cfg_arg, linker_args, linker_flags};
 use crate::{
     BootstrapCommand, CLang, Compiler, Config, DocTests, DryRun, EXTRA_CHECK_CFGS, GitRepo, Mode,
-    TargetSelection, command, prepare_behaviour_dump_dir, t,
+    RemapScheme, TargetSelection, command, prepare_behaviour_dump_dir, t,
 };
 
 /// Represents flag values in `String` form with whitespace delimiter to pass it to the compiler
@@ -551,7 +551,7 @@ impl Builder<'_> {
         let libdir = self.rustc_libdir(compiler);
 
         let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8");
-        if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) {
+        if self.is_verbose() && !matches!(self.config.get_dry_run(), DryRun::SelfCheck) {
             println!("using sysroot {sysroot_str}");
         }
 
@@ -636,6 +636,15 @@ impl Builder<'_> {
         for (restricted_mode, name, values) in EXTRA_CHECK_CFGS {
             if restricted_mode.is_none() || *restricted_mode == Some(mode) {
                 rustflags.arg(&check_cfg_arg(name, *values));
+
+                if *name == "bootstrap" {
+                    // Cargo doesn't pass RUSTFLAGS to proc_macros:
+                    // https://github.com/rust-lang/cargo/issues/4423
+                    // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`.
+                    // We also declare that the flag is expected, which we need to do to not
+                    // get warnings about it being unexpected.
+                    hostflags.arg(check_cfg_arg(name, *values));
+                }
             }
         }
 
@@ -645,13 +654,6 @@ impl Builder<'_> {
         if stage == 0 {
             hostflags.arg("--cfg=bootstrap");
         }
-        // Cargo doesn't pass RUSTFLAGS to proc_macros:
-        // https://github.com/rust-lang/cargo/issues/4423
-        // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`.
-        // We also declare that the flag is expected, which we need to do to not
-        // get warnings about it being unexpected.
-        hostflags.arg("-Zunstable-options");
-        hostflags.arg("--check-cfg=cfg(bootstrap)");
 
         // FIXME: It might be better to use the same value for both `RUSTFLAGS` and `RUSTDOCFLAGS`,
         // but this breaks CI. At the very least, stage0 `rustdoc` needs `--cfg bootstrap`. See
@@ -920,13 +922,46 @@ impl Builder<'_> {
             hostflags.arg(format!("-Ctarget-feature={sign}crt-static"));
         }
 
-        if let Some(map_to) = self.build.debuginfo_map_to(GitRepo::Rustc) {
-            let map = format!("{}={}", self.build.src.display(), map_to);
-            cargo.env("RUSTC_DEBUGINFO_MAP", map);
+        // `rustc` needs to know the remapping scheme, in order to know how to reverse it (unremap)
+        // later. Two env vars are set and made available to the compiler
+        //
+        // - `CFG_VIRTUAL_RUST_SOURCE_BASE_DIR`: `rust-src` remap scheme (`NonCompiler`)
+        // - `CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR`: `rustc-dev` remap scheme (`Compiler`)
+        //
+        // Keep this scheme in sync with `rustc_metadata::rmeta::decoder`'s
+        // `try_to_translate_virtual_to_real`.
+        //
+        // `RUSTC_DEBUGINFO_MAP` is used to pass through to the underlying rustc
+        // `--remap-path-prefix`.
+        match mode {
+            Mode::Rustc | Mode::Codegen => {
+                if let Some(ref map_to) =
+                    self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::NonCompiler)
+                {
+                    cargo.env("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR", map_to);
+                }
 
-            // `rustc` needs to know the virtual `/rustc/$hash` we're mapping to,
-            // in order to opportunistically reverse it later.
-            cargo.env("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR", map_to);
+                if let Some(ref map_to) =
+                    self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::Compiler)
+                {
+                    // When building compiler sources, we want to apply the compiler remap scheme.
+                    cargo.env(
+                        "RUSTC_DEBUGINFO_MAP",
+                        format!("{}={}", self.build.src.display(), map_to),
+                    );
+                    cargo.env("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR", map_to);
+                }
+            }
+            Mode::Std | Mode::ToolBootstrap | Mode::ToolRustc | Mode::ToolStd => {
+                if let Some(ref map_to) =
+                    self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::NonCompiler)
+                {
+                    cargo.env(
+                        "RUSTC_DEBUGINFO_MAP",
+                        format!("{}={}", self.build.src.display(), map_to),
+                    );
+                }
+            }
         }
 
         if self.config.rust_remap_debuginfo {
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 19b79bfe818..8b1520de3a8 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -22,6 +22,7 @@ use crate::core::config::flags::Subcommand;
 use crate::core::config::{DryRun, TargetSelection};
 use crate::utils::cache::Cache;
 use crate::utils::exec::{BootstrapCommand, command};
+use crate::utils::execution_context::ExecutionContext;
 use crate::utils::helpers::{self, LldThreads, add_dylib_path, exe, libdir, linker_args, t};
 use crate::{Build, Crate, trace};
 
@@ -442,13 +443,15 @@ impl StepDescription {
 
     fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool {
         if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) {
-            if !matches!(builder.config.dry_run, DryRun::SelfCheck) {
+            if !matches!(builder.config.get_dry_run(), DryRun::SelfCheck) {
                 println!("Skipping {pathset:?} because it is excluded");
             }
             return true;
         }
 
-        if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) {
+        if !builder.config.skip.is_empty()
+            && !matches!(builder.config.get_dry_run(), DryRun::SelfCheck)
+        {
             builder.verbose(|| {
                 println!(
                     "{:?} not skipped for {:?} -- not in {:?}",
@@ -1633,4 +1636,14 @@ impl<'a> Builder<'a> {
             self.info(&format!("{err}\n"));
         }
     }
+
+    pub fn exec_ctx(&self) -> &ExecutionContext {
+        &self.config.exec_ctx
+    }
+}
+
+impl<'a> AsRef<ExecutionContext> for Builder<'a> {
+    fn as_ref(&self) -> &ExecutionContext {
+        self.exec_ctx()
+    }
 }
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index baa22fc7f72..a264d772c56 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -22,7 +22,7 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config
     let mut config = Config::parse(Flags::parse(cmd));
     // don't save toolstates
     config.save_toolstates = None;
-    config.dry_run = DryRun::SelfCheck;
+    config.set_dry_run(DryRun::SelfCheck);
 
     // Ignore most submodules, since we don't need them for a dry run, and the
     // tests run much faster without them.
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 03044d4fc80..7f52697e6c7 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -1,188 +1,89 @@
-//! Serialized configuration of a build.
+//! This module defines the central `Config` struct, which aggregates all components
+//! of the bootstrap configuration into a single unit.
 //!
-//! This module implements parsing `bootstrap.toml` configuration files to tweak
-//! how the build runs.
+//! It serves as the primary public interface for accessing the bootstrap configuration.
+//! The module coordinates the overall configuration parsing process using logic from `parsing.rs`
+//! and provides top-level methods such as `Config::parse()` for initialization, as well as
+//! utility methods for querying and manipulating the complete configuration state.
+//!
+//! Additionally, this module contains the core logic for parsing, validating, and inferring
+//! the final `Config` from various raw inputs.
+//!
+//! It manages the process of reading command-line arguments, environment variables,
+//! and the `bootstrap.toml` file—merging them, applying defaults, and performing
+//! cross-component validation. The main `parse_inner` function and its supporting
+//! helpers reside here, transforming raw `Toml` data into the structured `Config` type.
 
 use std::cell::Cell;
 use std::collections::{BTreeSet, HashMap, HashSet};
-use std::fmt::{self, Display};
-use std::hash::Hash;
 use std::io::IsTerminal;
 use std::path::{Path, PathBuf, absolute};
-use std::process::Command;
 use std::str::FromStr;
-use std::sync::{Arc, Mutex, OnceLock};
+use std::sync::{Arc, Mutex};
 use std::{cmp, env, fs};
 
 use build_helper::ci::CiEnv;
 use build_helper::exit;
-use build_helper::git::{GitConfig, PathFreshness, check_path_modifications, output_result};
-use serde::{Deserialize, Deserializer};
-use serde_derive::Deserialize;
+use build_helper::git::{GitConfig, PathFreshness, check_path_modifications};
+use serde::Deserialize;
 #[cfg(feature = "tracing")]
 use tracing::{instrument, span};
 
-use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX;
 use crate::core::build_steps::llvm;
 use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS;
 pub use crate::core::config::flags::Subcommand;
-use crate::core::config::flags::{Color, Flags, Warnings};
+use crate::core::config::flags::{Color, Flags};
+use crate::core::config::target_selection::TargetSelectionList;
+use crate::core::config::toml::TomlConfig;
+use crate::core::config::toml::build::Build;
+use crate::core::config::toml::change_id::ChangeId;
+use crate::core::config::toml::rust::{
+    LldMode, RustOptimize, check_incompatible_options_for_ci_rustc,
+};
+use crate::core::config::toml::target::Target;
+use crate::core::config::{
+    DebuginfoLevel, DryRun, GccCiMode, LlvmLibunwind, Merge, ReplaceOpt, RustcLto, SplitDebuginfo,
+    StringOrBool, set, threads_from_config,
+};
 use crate::core::download::is_download_ci_available;
-use crate::utils::cache::{INTERNER, Interned};
-use crate::utils::channel::{self, GitInfo};
-use crate::utils::helpers::{self, exe, output, t};
+use crate::utils::channel;
+use crate::utils::exec::command;
+use crate::utils::execution_context::ExecutionContext;
+use crate::utils::helpers::exe;
+use crate::{GitInfo, OnceLock, TargetSelection, check_ci_llvm, helpers, t};
 
-/// Each path in this list is considered "allowed" in the `download-rustc="if-unchanged"` logic.
+/// Each path from this function is considered "allowed" in the `download-rustc="if-unchanged"` logic.
 /// This means they can be modified and changes to these paths should never trigger a compiler build
 /// when "if-unchanged" is set.
-///
-/// NOTE: Paths must have the ":!" prefix to tell git to ignore changes in those paths during
-/// the diff check.
-///
-/// WARNING: Be cautious when adding paths to this list. If a path that influences the compiler build
-/// is added here, it will cause bootstrap to skip necessary rebuilds, which may lead to risky results.
-/// For example, "src/bootstrap" should never be included in this list as it plays a crucial role in the
-/// final output/compiler, which can be significantly affected by changes made to the bootstrap sources.
-#[rustfmt::skip] // We don't want rustfmt to oneline this list
-pub(crate) const RUSTC_IF_UNCHANGED_ALLOWED_PATHS: &[&str] = &[
-    ":!library",
-    ":!src/tools",
-    ":!src/librustdoc",
-    ":!src/rustdoc-json-types",
-    ":!tests",
-    ":!triagebot.toml",
-];
-
-macro_rules! check_ci_llvm {
-    ($name:expr) => {
-        assert!(
-            $name.is_none(),
-            "setting {} is incompatible with download-ci-llvm.",
-            stringify!($name).replace("_", "-")
-        );
-    };
-}
-
-/// This file is embedded in the overlay directory of the tarball sources. It is
-/// useful in scenarios where developers want to see how the tarball sources were
-/// generated.
-///
-/// We also use this file to compare the host's bootstrap.toml against the CI rustc builder
-/// configuration to detect any incompatible options.
-pub(crate) const BUILDER_CONFIG_FILENAME: &str = "builder-config";
-
-#[derive(Clone, Default)]
-pub enum DryRun {
-    /// This isn't a dry run.
-    #[default]
-    Disabled,
-    /// This is a dry run enabled by bootstrap itself, so it can verify that no work is done.
-    SelfCheck,
-    /// This is a dry run enabled by the `--dry-run` flag.
-    UserSelected,
-}
-
-#[derive(Copy, Clone, Default, Debug, Eq, PartialEq)]
-pub enum DebuginfoLevel {
-    #[default]
-    None,
-    LineDirectivesOnly,
-    LineTablesOnly,
-    Limited,
-    Full,
-}
-
-// NOTE: can't derive(Deserialize) because the intermediate trip through toml::Value only
-// deserializes i64, and derive() only generates visit_u64
-impl<'de> Deserialize<'de> for DebuginfoLevel {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        use serde::de::Error;
-
-        Ok(match Deserialize::deserialize(deserializer)? {
-            StringOrInt::String(s) if s == "none" => DebuginfoLevel::None,
-            StringOrInt::Int(0) => DebuginfoLevel::None,
-            StringOrInt::String(s) if s == "line-directives-only" => {
-                DebuginfoLevel::LineDirectivesOnly
-            }
-            StringOrInt::String(s) if s == "line-tables-only" => DebuginfoLevel::LineTablesOnly,
-            StringOrInt::String(s) if s == "limited" => DebuginfoLevel::Limited,
-            StringOrInt::Int(1) => DebuginfoLevel::Limited,
-            StringOrInt::String(s) if s == "full" => DebuginfoLevel::Full,
-            StringOrInt::Int(2) => DebuginfoLevel::Full,
-            StringOrInt::Int(n) => {
-                let other = serde::de::Unexpected::Signed(n);
-                return Err(D::Error::invalid_value(other, &"expected 0, 1, or 2"));
-            }
-            StringOrInt::String(s) => {
-                let other = serde::de::Unexpected::Str(&s);
-                return Err(D::Error::invalid_value(
-                    other,
-                    &"expected none, line-tables-only, limited, or full",
-                ));
-            }
-        })
-    }
-}
-
-/// Suitable for passing to `-C debuginfo`
-impl Display for DebuginfoLevel {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use DebuginfoLevel::*;
-        f.write_str(match self {
-            None => "0",
-            LineDirectivesOnly => "line-directives-only",
-            LineTablesOnly => "line-tables-only",
-            Limited => "1",
-            Full => "2",
-        })
-    }
-}
-
-/// LLD in bootstrap works like this:
-/// - Self-contained lld: use `rust-lld` from the compiler's sysroot
-/// - External: use an external `lld` binary
-///
-/// It is configured depending on the target:
-/// 1) Everything except MSVC
-/// - Self-contained: `-Clinker-flavor=gnu-lld-cc -Clink-self-contained=+linker`
-/// - External: `-Clinker-flavor=gnu-lld-cc`
-/// 2) MSVC
-/// - Self-contained: `-Clinker=<path to rust-lld>`
-/// - External: `-Clinker=lld`
-#[derive(Copy, Clone, Default, Debug, PartialEq)]
-pub enum LldMode {
-    /// Do not use LLD
-    #[default]
-    Unused,
-    /// Use `rust-lld` from the compiler's sysroot
-    SelfContained,
-    /// Use an externally provided `lld` binary.
-    /// Note that the linker name cannot be overridden, the binary has to be named `lld` and it has
-    /// to be in $PATH.
-    External,
-}
-
-impl LldMode {
-    pub fn is_used(&self) -> bool {
-        match self {
-            LldMode::SelfContained | LldMode::External => true,
-            LldMode::Unused => false,
-        }
+pub fn rustc_if_unchanged_allowed_paths() -> Vec<&'static str> {
+    // NOTE: Paths must have the ":!" prefix to tell git to ignore changes in those paths during
+    // the diff check.
+    //
+    // WARNING: Be cautious when adding paths to this list. If a path that influences the compiler build
+    // is added here, it will cause bootstrap to skip necessary rebuilds, which may lead to risky results.
+    // For example, "src/bootstrap" should never be included in this list as it plays a crucial role in the
+    // final output/compiler, which can be significantly affected by changes made to the bootstrap sources.
+    let mut paths = vec![
+        ":!library",
+        ":!src/tools",
+        ":!src/librustdoc",
+        ":!src/rustdoc-json-types",
+        ":!tests",
+        ":!triagebot.toml",
+    ];
+
+    if !CiEnv::is_ci() {
+        // When a dependency is added/updated/removed in the library tree (or in some tools),
+        // `Cargo.lock` will be updated by `cargo`. This update will incorrectly invalidate the
+        // `download-rustc=if-unchanged` cache.
+        //
+        // To prevent this, add `Cargo.lock` to the list of allowed paths when not running on CI.
+        // This is generally safe because changes to dependencies typically involve modifying
+        // `Cargo.toml`, which would already invalidate the CI-rustc cache on non-allowed paths.
+        paths.push(":!Cargo.lock");
     }
-}
 
-/// Determines how will GCC be provided.
-#[derive(Default, Clone)]
-pub enum GccCiMode {
-    /// Build GCC from the local `src/gcc` submodule.
-    #[default]
-    BuildLocally,
-    /// Try to download GCC from CI.
-    /// If it is not available on CI, it will be built locally instead.
-    DownloadFromCi,
+    paths
 }
 
 /// Global configuration for the entire build and/or bootstrap.
@@ -243,16 +144,12 @@ pub struct Config {
     pub jobs: Option<u32>,
     pub cmd: Subcommand,
     pub incremental: bool,
-    pub dry_run: DryRun,
     pub dump_bootstrap_shims: bool,
     /// Arguments appearing after `--` to be forwarded to tools,
     /// e.g. `--fix-broken` or test arguments.
     pub free_args: Vec<String>,
 
     /// `None` if we shouldn't download CI compiler artifacts, or the commit to download if we should.
-    #[cfg(not(test))]
-    download_rustc_commit: Option<String>,
-    #[cfg(test)]
     pub download_rustc_commit: Option<String>,
 
     pub deny_warnings: bool,
@@ -269,10 +166,6 @@ pub struct Config {
     pub llvm_release_debuginfo: bool,
     pub llvm_static_stdcpp: bool,
     pub llvm_libzstd: bool,
-    /// `None` if `llvm_from_ci` is true and we haven't yet downloaded llvm.
-    #[cfg(not(test))]
-    llvm_link_shared: Cell<Option<bool>>,
-    #[cfg(test)]
     pub llvm_link_shared: Cell<Option<bool>>,
     pub llvm_clang_cl: Option<String>,
     pub llvm_targets: Option<String>,
@@ -345,9 +238,6 @@ pub struct Config {
     pub hosts: Vec<TargetSelection>,
     pub targets: Vec<TargetSelection>,
     pub local_rebuild: bool,
-    #[cfg(not(test))]
-    jemalloc: bool,
-    #[cfg(test)]
     pub jemalloc: bool,
     pub control_flow_guard: bool,
     pub ehcont_guard: bool,
@@ -423,932 +313,13 @@ pub struct Config {
 
     /// Cache for determining path modifications
     pub path_modification_cache: Arc<Mutex<HashMap<Vec<&'static str>, PathFreshness>>>,
-}
-
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
-pub enum LlvmLibunwind {
-    #[default]
-    No,
-    InTree,
-    System,
-}
-
-impl FromStr for LlvmLibunwind {
-    type Err = String;
-
-    fn from_str(value: &str) -> Result<Self, Self::Err> {
-        match value {
-            "no" => Ok(Self::No),
-            "in-tree" => Ok(Self::InTree),
-            "system" => Ok(Self::System),
-            invalid => Err(format!("Invalid value '{invalid}' for rust.llvm-libunwind config.")),
-        }
-    }
-}
 
-#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub enum SplitDebuginfo {
-    Packed,
-    Unpacked,
-    #[default]
-    Off,
-}
-
-impl std::str::FromStr for SplitDebuginfo {
-    type Err = ();
+    /// Skip checking the standard library if `rust.download-rustc` isn't available.
+    /// This is mostly for RA as building the stage1 compiler to check the library tree
+    /// on each code change might be too much for some computers.
+    pub skip_std_check_if_no_download_rustc: bool,
 
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        match s {
-            "packed" => Ok(SplitDebuginfo::Packed),
-            "unpacked" => Ok(SplitDebuginfo::Unpacked),
-            "off" => Ok(SplitDebuginfo::Off),
-            _ => Err(()),
-        }
-    }
-}
-
-impl SplitDebuginfo {
-    /// Returns the default `-Csplit-debuginfo` value for the current target. See the comment for
-    /// `rust.split-debuginfo` in `bootstrap.example.toml`.
-    fn default_for_platform(target: TargetSelection) -> Self {
-        if target.contains("apple") {
-            SplitDebuginfo::Unpacked
-        } else if target.is_windows() {
-            SplitDebuginfo::Packed
-        } else {
-            SplitDebuginfo::Off
-        }
-    }
-}
-
-/// LTO mode used for compiling rustc itself.
-#[derive(Default, Clone, PartialEq, Debug)]
-pub enum RustcLto {
-    Off,
-    #[default]
-    ThinLocal,
-    Thin,
-    Fat,
-}
-
-impl std::str::FromStr for RustcLto {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        match s {
-            "thin-local" => Ok(RustcLto::ThinLocal),
-            "thin" => Ok(RustcLto::Thin),
-            "fat" => Ok(RustcLto::Fat),
-            "off" => Ok(RustcLto::Off),
-            _ => Err(format!("Invalid value for rustc LTO: {s}")),
-        }
-    }
-}
-
-#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
-// N.B.: This type is used everywhere, and the entire codebase relies on it being Copy.
-// Making !Copy is highly nontrivial!
-pub struct TargetSelection {
-    pub triple: Interned<String>,
-    file: Option<Interned<String>>,
-    synthetic: bool,
-}
-
-/// Newtype over `Vec<TargetSelection>` so we can implement custom parsing logic
-#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-pub struct TargetSelectionList(Vec<TargetSelection>);
-
-pub fn target_selection_list(s: &str) -> Result<TargetSelectionList, String> {
-    Ok(TargetSelectionList(
-        s.split(',').filter(|s| !s.is_empty()).map(TargetSelection::from_user).collect(),
-    ))
-}
-
-impl TargetSelection {
-    pub fn from_user(selection: &str) -> Self {
-        let path = Path::new(selection);
-
-        let (triple, file) = if path.exists() {
-            let triple = path
-                .file_stem()
-                .expect("Target specification file has no file stem")
-                .to_str()
-                .expect("Target specification file stem is not UTF-8");
-
-            (triple, Some(selection))
-        } else {
-            (selection, None)
-        };
-
-        let triple = INTERNER.intern_str(triple);
-        let file = file.map(|f| INTERNER.intern_str(f));
-
-        Self { triple, file, synthetic: false }
-    }
-
-    pub fn create_synthetic(triple: &str, file: &str) -> Self {
-        Self {
-            triple: INTERNER.intern_str(triple),
-            file: Some(INTERNER.intern_str(file)),
-            synthetic: true,
-        }
-    }
-
-    pub fn rustc_target_arg(&self) -> &str {
-        self.file.as_ref().unwrap_or(&self.triple)
-    }
-
-    pub fn contains(&self, needle: &str) -> bool {
-        self.triple.contains(needle)
-    }
-
-    pub fn starts_with(&self, needle: &str) -> bool {
-        self.triple.starts_with(needle)
-    }
-
-    pub fn ends_with(&self, needle: &str) -> bool {
-        self.triple.ends_with(needle)
-    }
-
-    // See src/bootstrap/synthetic_targets.rs
-    pub fn is_synthetic(&self) -> bool {
-        self.synthetic
-    }
-
-    pub fn is_msvc(&self) -> bool {
-        self.contains("msvc")
-    }
-
-    pub fn is_windows(&self) -> bool {
-        self.contains("windows")
-    }
-
-    pub fn is_windows_gnu(&self) -> bool {
-        self.ends_with("windows-gnu")
-    }
-
-    pub fn is_cygwin(&self) -> bool {
-        self.is_windows() &&
-        // ref. https://cygwin.com/pipermail/cygwin/2022-February/250802.html
-        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)
-    }
-}
-
-impl fmt::Display for TargetSelection {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.triple)?;
-        if let Some(file) = self.file {
-            write!(f, "({file})")?;
-        }
-        Ok(())
-    }
-}
-
-impl fmt::Debug for TargetSelection {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{self}")
-    }
-}
-
-impl PartialEq<&str> for TargetSelection {
-    fn eq(&self, other: &&str) -> bool {
-        self.triple == *other
-    }
-}
-
-// Targets are often used as directory names throughout bootstrap.
-// This impl makes it more ergonomics to use them as such.
-impl AsRef<Path> for TargetSelection {
-    fn as_ref(&self) -> &Path {
-        self.triple.as_ref()
-    }
-}
-
-/// Per-target configuration stored in the global configuration structure.
-#[derive(Debug, Default, Clone, PartialEq, Eq)]
-pub struct Target {
-    /// Some(path to llvm-config) if using an external LLVM.
-    pub llvm_config: Option<PathBuf>,
-    pub llvm_has_rust_patches: Option<bool>,
-    /// Some(path to FileCheck) if one was specified.
-    pub llvm_filecheck: Option<PathBuf>,
-    pub llvm_libunwind: Option<LlvmLibunwind>,
-    pub cc: Option<PathBuf>,
-    pub cxx: Option<PathBuf>,
-    pub ar: Option<PathBuf>,
-    pub ranlib: Option<PathBuf>,
-    pub default_linker: Option<PathBuf>,
-    pub linker: Option<PathBuf>,
-    pub split_debuginfo: Option<SplitDebuginfo>,
-    pub sanitizers: Option<bool>,
-    pub profiler: Option<StringOrBool>,
-    pub rpath: Option<bool>,
-    pub crt_static: Option<bool>,
-    pub musl_root: Option<PathBuf>,
-    pub musl_libdir: Option<PathBuf>,
-    pub wasi_root: Option<PathBuf>,
-    pub qemu_rootfs: Option<PathBuf>,
-    pub runner: Option<String>,
-    pub no_std: bool,
-    pub codegen_backends: Option<Vec<String>>,
-    pub optimized_compiler_builtins: Option<bool>,
-    pub jemalloc: Option<bool>,
-}
-
-impl Target {
-    pub fn from_triple(triple: &str) -> Self {
-        let mut target: Self = Default::default();
-        if triple.contains("-none") || triple.contains("nvptx") || triple.contains("switch") {
-            target.no_std = true;
-        }
-        if triple.contains("emscripten") {
-            target.runner = Some("node".into());
-        }
-        target
-    }
-}
-/// Structure of the `bootstrap.toml` file that configuration is read from.
-///
-/// This structure uses `Decodable` to automatically decode a TOML configuration
-/// file into this format, and then this is traversed and written into the above
-/// `Config` structure.
-#[derive(Deserialize, Default)]
-#[serde(deny_unknown_fields, rename_all = "kebab-case")]
-pub(crate) struct TomlConfig {
-    #[serde(flatten)]
-    change_id: ChangeIdWrapper,
-    build: Option<Build>,
-    install: Option<Install>,
-    llvm: Option<Llvm>,
-    gcc: Option<Gcc>,
-    rust: Option<Rust>,
-    target: Option<HashMap<String, TomlTarget>>,
-    dist: Option<Dist>,
-    profile: Option<String>,
-    include: Option<Vec<PathBuf>>,
-}
-
-/// This enum is used for deserializing change IDs from TOML, allowing both numeric values and the string `"ignore"`.
-#[derive(Clone, Debug, PartialEq)]
-pub enum ChangeId {
-    Ignore,
-    Id(usize),
-}
-
-/// Since we use `#[serde(deny_unknown_fields)]` on `TomlConfig`, we need a wrapper type
-/// for the "change-id" field to parse it even if other fields are invalid. This ensures
-/// that if deserialization fails due to other fields, we can still provide the changelogs
-/// to allow developers to potentially find the reason for the failure in the logs..
-#[derive(Deserialize, Default)]
-pub(crate) struct ChangeIdWrapper {
-    #[serde(alias = "change-id", default, deserialize_with = "deserialize_change_id")]
-    pub(crate) inner: Option<ChangeId>,
-}
-
-fn deserialize_change_id<'de, D: Deserializer<'de>>(
-    deserializer: D,
-) -> Result<Option<ChangeId>, D::Error> {
-    let value = toml::Value::deserialize(deserializer)?;
-    Ok(match value {
-        toml::Value::String(s) if s == "ignore" => Some(ChangeId::Ignore),
-        toml::Value::Integer(i) => Some(ChangeId::Id(i as usize)),
-        _ => {
-            return Err(serde::de::Error::custom(
-                "expected \"ignore\" or an integer for change-id",
-            ));
-        }
-    })
-}
-
-/// Describes how to handle conflicts in merging two [`TomlConfig`]
-#[derive(Copy, Clone, Debug)]
-enum ReplaceOpt {
-    /// Silently ignore a duplicated value
-    IgnoreDuplicate,
-    /// Override the current value, even if it's `Some`
-    Override,
-    /// Exit with an error on duplicate values
-    ErrorOnDuplicate,
-}
-
-trait Merge {
-    fn merge(
-        &mut self,
-        parent_config_path: Option<PathBuf>,
-        included_extensions: &mut HashSet<PathBuf>,
-        other: Self,
-        replace: ReplaceOpt,
-    );
-}
-
-impl Merge for TomlConfig {
-    fn merge(
-        &mut self,
-        parent_config_path: Option<PathBuf>,
-        included_extensions: &mut HashSet<PathBuf>,
-        TomlConfig { build, install, llvm, gcc, rust, dist, target, profile, change_id, include }: Self,
-        replace: ReplaceOpt,
-    ) {
-        fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) {
-            if let Some(new) = y {
-                if let Some(original) = x {
-                    original.merge(None, &mut Default::default(), new, replace);
-                } else {
-                    *x = Some(new);
-                }
-            }
-        }
-
-        self.change_id.inner.merge(None, &mut Default::default(), change_id.inner, replace);
-        self.profile.merge(None, &mut Default::default(), profile, replace);
-
-        do_merge(&mut self.build, build, replace);
-        do_merge(&mut self.install, install, replace);
-        do_merge(&mut self.llvm, llvm, replace);
-        do_merge(&mut self.gcc, gcc, replace);
-        do_merge(&mut self.rust, rust, replace);
-        do_merge(&mut self.dist, dist, replace);
-
-        match (self.target.as_mut(), target) {
-            (_, None) => {}
-            (None, Some(target)) => self.target = Some(target),
-            (Some(original_target), Some(new_target)) => {
-                for (triple, new) in new_target {
-                    if let Some(original) = original_target.get_mut(&triple) {
-                        original.merge(None, &mut Default::default(), new, replace);
-                    } else {
-                        original_target.insert(triple, new);
-                    }
-                }
-            }
-        }
-
-        let parent_dir = parent_config_path
-            .as_ref()
-            .and_then(|p| p.parent().map(ToOwned::to_owned))
-            .unwrap_or_default();
-
-        // `include` handled later since we ignore duplicates using `ReplaceOpt::IgnoreDuplicate` to
-        // keep the upper-level configuration to take precedence.
-        for include_path in include.clone().unwrap_or_default().iter().rev() {
-            let include_path = parent_dir.join(include_path);
-            let include_path = include_path.canonicalize().unwrap_or_else(|e| {
-                eprintln!("ERROR: Failed to canonicalize '{}' path: {e}", include_path.display());
-                exit!(2);
-            });
-
-            let included_toml = Config::get_toml_inner(&include_path).unwrap_or_else(|e| {
-                eprintln!("ERROR: Failed to parse '{}': {e}", include_path.display());
-                exit!(2);
-            });
-
-            assert!(
-                included_extensions.insert(include_path.clone()),
-                "Cyclic inclusion detected: '{}' is being included again before its previous inclusion was fully processed.",
-                include_path.display()
-            );
-
-            self.merge(
-                Some(include_path.clone()),
-                included_extensions,
-                included_toml,
-                // Ensures that parent configuration always takes precedence
-                // over child configurations.
-                ReplaceOpt::IgnoreDuplicate,
-            );
-
-            included_extensions.remove(&include_path);
-        }
-    }
-}
-
-// We are using a decl macro instead of a derive proc macro here to reduce the compile time of bootstrap.
-macro_rules! define_config {
-    ($(#[$attr:meta])* struct $name:ident {
-        $($field:ident: Option<$field_ty:ty> = $field_key:literal,)*
-    }) => {
-        $(#[$attr])*
-        struct $name {
-            $($field: Option<$field_ty>,)*
-        }
-
-        impl Merge for $name {
-            fn merge(
-                &mut self,
-                _parent_config_path: Option<PathBuf>,
-                _included_extensions: &mut HashSet<PathBuf>,
-                other: Self,
-                replace: ReplaceOpt
-            ) {
-                $(
-                    match replace {
-                        ReplaceOpt::IgnoreDuplicate => {
-                            if self.$field.is_none() {
-                                self.$field = other.$field;
-                            }
-                        },
-                        ReplaceOpt::Override => {
-                            if other.$field.is_some() {
-                                self.$field = other.$field;
-                            }
-                        }
-                        ReplaceOpt::ErrorOnDuplicate => {
-                            if other.$field.is_some() {
-                                if self.$field.is_some() {
-                                    if cfg!(test) {
-                                        panic!("overriding existing option")
-                                    } else {
-                                        eprintln!("overriding existing option: `{}`", stringify!($field));
-                                        exit!(2);
-                                    }
-                                } else {
-                                    self.$field = other.$field;
-                                }
-                            }
-                        }
-                    }
-                )*
-            }
-        }
-
-        // The following is a trimmed version of what serde_derive generates. All parts not relevant
-        // for toml deserialization have been removed. This reduces the binary size and improves
-        // compile time of bootstrap.
-        impl<'de> Deserialize<'de> for $name {
-            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-            where
-                D: Deserializer<'de>,
-            {
-                struct Field;
-                impl<'de> serde::de::Visitor<'de> for Field {
-                    type Value = $name;
-                    fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-                        f.write_str(concat!("struct ", stringify!($name)))
-                    }
-
-                    #[inline]
-                    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
-                    where
-                        A: serde::de::MapAccess<'de>,
-                    {
-                        $(let mut $field: Option<$field_ty> = None;)*
-                        while let Some(key) =
-                            match serde::de::MapAccess::next_key::<String>(&mut map) {
-                                Ok(val) => val,
-                                Err(err) => {
-                                    return Err(err);
-                                }
-                            }
-                        {
-                            match &*key {
-                                $($field_key => {
-                                    if $field.is_some() {
-                                        return Err(<A::Error as serde::de::Error>::duplicate_field(
-                                            $field_key,
-                                        ));
-                                    }
-                                    $field = match serde::de::MapAccess::next_value::<$field_ty>(
-                                        &mut map,
-                                    ) {
-                                        Ok(val) => Some(val),
-                                        Err(err) => {
-                                            return Err(err);
-                                        }
-                                    };
-                                })*
-                                key => {
-                                    return Err(serde::de::Error::unknown_field(key, FIELDS));
-                                }
-                            }
-                        }
-                        Ok($name { $($field),* })
-                    }
-                }
-                const FIELDS: &'static [&'static str] = &[
-                    $($field_key,)*
-                ];
-                Deserializer::deserialize_struct(
-                    deserializer,
-                    stringify!($name),
-                    FIELDS,
-                    Field,
-                )
-            }
-        }
-    }
-}
-
-impl<T> Merge for Option<T> {
-    fn merge(
-        &mut self,
-        _parent_config_path: Option<PathBuf>,
-        _included_extensions: &mut HashSet<PathBuf>,
-        other: Self,
-        replace: ReplaceOpt,
-    ) {
-        match replace {
-            ReplaceOpt::IgnoreDuplicate => {
-                if self.is_none() {
-                    *self = other;
-                }
-            }
-            ReplaceOpt::Override => {
-                if other.is_some() {
-                    *self = other;
-                }
-            }
-            ReplaceOpt::ErrorOnDuplicate => {
-                if other.is_some() {
-                    if self.is_some() {
-                        if cfg!(test) {
-                            panic!("overriding existing option")
-                        } else {
-                            eprintln!("overriding existing option");
-                            exit!(2);
-                        }
-                    } else {
-                        *self = other;
-                    }
-                }
-            }
-        }
-    }
-}
-
-define_config! {
-    /// TOML representation of various global build decisions.
-    #[derive(Default)]
-    struct Build {
-        build: Option<String> = "build",
-        description: Option<String> = "description",
-        host: Option<Vec<String>> = "host",
-        target: Option<Vec<String>> = "target",
-        build_dir: Option<String> = "build-dir",
-        cargo: Option<PathBuf> = "cargo",
-        rustc: Option<PathBuf> = "rustc",
-        rustfmt: Option<PathBuf> = "rustfmt",
-        cargo_clippy: Option<PathBuf> = "cargo-clippy",
-        docs: Option<bool> = "docs",
-        compiler_docs: Option<bool> = "compiler-docs",
-        library_docs_private_items: Option<bool> = "library-docs-private-items",
-        docs_minification: Option<bool> = "docs-minification",
-        submodules: Option<bool> = "submodules",
-        gdb: Option<String> = "gdb",
-        lldb: Option<String> = "lldb",
-        nodejs: Option<String> = "nodejs",
-        npm: Option<String> = "npm",
-        python: Option<String> = "python",
-        reuse: Option<String> = "reuse",
-        locked_deps: Option<bool> = "locked-deps",
-        vendor: Option<bool> = "vendor",
-        full_bootstrap: Option<bool> = "full-bootstrap",
-        bootstrap_cache_path: Option<PathBuf> = "bootstrap-cache-path",
-        extended: Option<bool> = "extended",
-        tools: Option<HashSet<String>> = "tools",
-        verbose: Option<usize> = "verbose",
-        sanitizers: Option<bool> = "sanitizers",
-        profiler: Option<bool> = "profiler",
-        cargo_native_static: Option<bool> = "cargo-native-static",
-        low_priority: Option<bool> = "low-priority",
-        configure_args: Option<Vec<String>> = "configure-args",
-        local_rebuild: Option<bool> = "local-rebuild",
-        print_step_timings: Option<bool> = "print-step-timings",
-        print_step_rusage: Option<bool> = "print-step-rusage",
-        check_stage: Option<u32> = "check-stage",
-        doc_stage: Option<u32> = "doc-stage",
-        build_stage: Option<u32> = "build-stage",
-        test_stage: Option<u32> = "test-stage",
-        install_stage: Option<u32> = "install-stage",
-        dist_stage: Option<u32> = "dist-stage",
-        bench_stage: Option<u32> = "bench-stage",
-        patch_binaries_for_nix: Option<bool> = "patch-binaries-for-nix",
-        // NOTE: only parsed by bootstrap.py, `--feature build-metrics` enables metrics unconditionally
-        metrics: Option<bool> = "metrics",
-        android_ndk: Option<PathBuf> = "android-ndk",
-        optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
-        jobs: Option<u32> = "jobs",
-        compiletest_diff_tool: Option<String> = "compiletest-diff-tool",
-        compiletest_use_stage0_libtest: Option<bool> = "compiletest-use-stage0-libtest",
-        ccache: Option<StringOrBool> = "ccache",
-        exclude: Option<Vec<PathBuf>> = "exclude",
-    }
-}
-
-define_config! {
-    /// TOML representation of various global install decisions.
-    struct Install {
-        prefix: Option<String> = "prefix",
-        sysconfdir: Option<String> = "sysconfdir",
-        docdir: Option<String> = "docdir",
-        bindir: Option<String> = "bindir",
-        libdir: Option<String> = "libdir",
-        mandir: Option<String> = "mandir",
-        datadir: Option<String> = "datadir",
-    }
-}
-
-define_config! {
-    /// TOML representation of how the LLVM build is configured.
-    struct Llvm {
-        optimize: Option<bool> = "optimize",
-        thin_lto: Option<bool> = "thin-lto",
-        release_debuginfo: Option<bool> = "release-debuginfo",
-        assertions: Option<bool> = "assertions",
-        tests: Option<bool> = "tests",
-        enzyme: Option<bool> = "enzyme",
-        plugins: Option<bool> = "plugins",
-        // FIXME: Remove this field at Q2 2025, it has been replaced by build.ccache
-        ccache: Option<StringOrBool> = "ccache",
-        static_libstdcpp: Option<bool> = "static-libstdcpp",
-        libzstd: Option<bool> = "libzstd",
-        ninja: Option<bool> = "ninja",
-        targets: Option<String> = "targets",
-        experimental_targets: Option<String> = "experimental-targets",
-        link_jobs: Option<u32> = "link-jobs",
-        link_shared: Option<bool> = "link-shared",
-        version_suffix: Option<String> = "version-suffix",
-        clang_cl: Option<String> = "clang-cl",
-        cflags: Option<String> = "cflags",
-        cxxflags: Option<String> = "cxxflags",
-        ldflags: Option<String> = "ldflags",
-        use_libcxx: Option<bool> = "use-libcxx",
-        use_linker: Option<String> = "use-linker",
-        allow_old_toolchain: Option<bool> = "allow-old-toolchain",
-        offload: Option<bool> = "offload",
-        polly: Option<bool> = "polly",
-        clang: Option<bool> = "clang",
-        enable_warnings: Option<bool> = "enable-warnings",
-        download_ci_llvm: Option<StringOrBool> = "download-ci-llvm",
-        build_config: Option<HashMap<String, String>> = "build-config",
-    }
-}
-
-define_config! {
-    /// TOML representation of how the GCC build is configured.
-    struct Gcc {
-        download_ci_gcc: Option<bool> = "download-ci-gcc",
-    }
-}
-
-define_config! {
-    struct Dist {
-        sign_folder: Option<String> = "sign-folder",
-        upload_addr: Option<String> = "upload-addr",
-        src_tarball: Option<bool> = "src-tarball",
-        compression_formats: Option<Vec<String>> = "compression-formats",
-        compression_profile: Option<String> = "compression-profile",
-        include_mingw_linker: Option<bool> = "include-mingw-linker",
-        vendor: Option<bool> = "vendor",
-    }
-}
-
-#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
-#[serde(untagged)]
-pub enum StringOrBool {
-    String(String),
-    Bool(bool),
-}
-
-impl Default for StringOrBool {
-    fn default() -> StringOrBool {
-        StringOrBool::Bool(false)
-    }
-}
-
-impl StringOrBool {
-    fn is_string_or_true(&self) -> bool {
-        matches!(self, Self::String(_) | Self::Bool(true))
-    }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub enum RustOptimize {
-    String(String),
-    Int(u8),
-    Bool(bool),
-}
-
-impl Default for RustOptimize {
-    fn default() -> RustOptimize {
-        RustOptimize::Bool(false)
-    }
-}
-
-impl<'de> Deserialize<'de> for RustOptimize {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        deserializer.deserialize_any(OptimizeVisitor)
-    }
-}
-
-struct OptimizeVisitor;
-
-impl serde::de::Visitor<'_> for OptimizeVisitor {
-    type Value = RustOptimize;
-
-    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        formatter.write_str(r#"one of: 0, 1, 2, 3, "s", "z", true, false"#)
-    }
-
-    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
-    where
-        E: serde::de::Error,
-    {
-        if matches!(value, "s" | "z") {
-            Ok(RustOptimize::String(value.to_string()))
-        } else {
-            Err(serde::de::Error::custom(format_optimize_error_msg(value)))
-        }
-    }
-
-    fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
-    where
-        E: serde::de::Error,
-    {
-        if matches!(value, 0..=3) {
-            Ok(RustOptimize::Int(value as u8))
-        } else {
-            Err(serde::de::Error::custom(format_optimize_error_msg(value)))
-        }
-    }
-
-    fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
-    where
-        E: serde::de::Error,
-    {
-        Ok(RustOptimize::Bool(value))
-    }
-}
-
-fn format_optimize_error_msg(v: impl std::fmt::Display) -> String {
-    format!(
-        r#"unrecognized option for rust optimize: "{v}", expected one of 0, 1, 2, 3, "s", "z", true, false"#
-    )
-}
-
-impl RustOptimize {
-    pub(crate) fn is_release(&self) -> bool {
-        match &self {
-            RustOptimize::Bool(true) | RustOptimize::String(_) => true,
-            RustOptimize::Int(i) => *i > 0,
-            RustOptimize::Bool(false) => false,
-        }
-    }
-
-    pub(crate) fn get_opt_level(&self) -> Option<String> {
-        match &self {
-            RustOptimize::String(s) => Some(s.clone()),
-            RustOptimize::Int(i) => Some(i.to_string()),
-            RustOptimize::Bool(_) => None,
-        }
-    }
-}
-
-#[derive(Deserialize)]
-#[serde(untagged)]
-enum StringOrInt {
-    String(String),
-    Int(i64),
-}
-
-impl<'de> Deserialize<'de> for LldMode {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        struct LldModeVisitor;
-
-        impl serde::de::Visitor<'_> for LldModeVisitor {
-            type Value = LldMode;
-
-            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-                formatter.write_str("one of true, 'self-contained' or 'external'")
-            }
-
-            fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
-            where
-                E: serde::de::Error,
-            {
-                Ok(if v { LldMode::External } else { LldMode::Unused })
-            }
-
-            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
-            where
-                E: serde::de::Error,
-            {
-                match v {
-                    "external" => Ok(LldMode::External),
-                    "self-contained" => Ok(LldMode::SelfContained),
-                    _ => Err(E::custom(format!("unknown mode {v}"))),
-                }
-            }
-        }
-
-        deserializer.deserialize_any(LldModeVisitor)
-    }
-}
-
-define_config! {
-    /// TOML representation of how the Rust build is configured.
-    struct Rust {
-        optimize: Option<RustOptimize> = "optimize",
-        debug: Option<bool> = "debug",
-        codegen_units: Option<u32> = "codegen-units",
-        codegen_units_std: Option<u32> = "codegen-units-std",
-        rustc_debug_assertions: Option<bool> = "debug-assertions",
-        randomize_layout: Option<bool> = "randomize-layout",
-        std_debug_assertions: Option<bool> = "debug-assertions-std",
-        tools_debug_assertions: Option<bool> = "debug-assertions-tools",
-        overflow_checks: Option<bool> = "overflow-checks",
-        overflow_checks_std: Option<bool> = "overflow-checks-std",
-        debug_logging: Option<bool> = "debug-logging",
-        debuginfo_level: Option<DebuginfoLevel> = "debuginfo-level",
-        debuginfo_level_rustc: Option<DebuginfoLevel> = "debuginfo-level-rustc",
-        debuginfo_level_std: Option<DebuginfoLevel> = "debuginfo-level-std",
-        debuginfo_level_tools: Option<DebuginfoLevel> = "debuginfo-level-tools",
-        debuginfo_level_tests: Option<DebuginfoLevel> = "debuginfo-level-tests",
-        backtrace: Option<bool> = "backtrace",
-        incremental: Option<bool> = "incremental",
-        default_linker: Option<String> = "default-linker",
-        channel: Option<String> = "channel",
-        // FIXME: Remove this field at Q2 2025, it has been replaced by build.description
-        description: Option<String> = "description",
-        musl_root: Option<String> = "musl-root",
-        rpath: Option<bool> = "rpath",
-        strip: Option<bool> = "strip",
-        frame_pointers: Option<bool> = "frame-pointers",
-        stack_protector: Option<String> = "stack-protector",
-        verbose_tests: Option<bool> = "verbose-tests",
-        optimize_tests: Option<bool> = "optimize-tests",
-        codegen_tests: Option<bool> = "codegen-tests",
-        omit_git_hash: Option<bool> = "omit-git-hash",
-        dist_src: Option<bool> = "dist-src",
-        save_toolstates: Option<String> = "save-toolstates",
-        codegen_backends: Option<Vec<String>> = "codegen-backends",
-        llvm_bitcode_linker: Option<bool> = "llvm-bitcode-linker",
-        lld: Option<bool> = "lld",
-        lld_mode: Option<LldMode> = "use-lld",
-        llvm_tools: Option<bool> = "llvm-tools",
-        deny_warnings: Option<bool> = "deny-warnings",
-        backtrace_on_ice: Option<bool> = "backtrace-on-ice",
-        verify_llvm_ir: Option<bool> = "verify-llvm-ir",
-        thin_lto_import_instr_limit: Option<u32> = "thin-lto-import-instr-limit",
-        remap_debuginfo: Option<bool> = "remap-debuginfo",
-        jemalloc: Option<bool> = "jemalloc",
-        test_compare_mode: Option<bool> = "test-compare-mode",
-        llvm_libunwind: Option<String> = "llvm-libunwind",
-        control_flow_guard: Option<bool> = "control-flow-guard",
-        ehcont_guard: Option<bool> = "ehcont-guard",
-        new_symbol_mangling: Option<bool> = "new-symbol-mangling",
-        profile_generate: Option<String> = "profile-generate",
-        profile_use: Option<String> = "profile-use",
-        // ignored; this is set from an env var set by bootstrap.py
-        download_rustc: Option<StringOrBool> = "download-rustc",
-        lto: Option<String> = "lto",
-        validate_mir_opts: Option<u32> = "validate-mir-opts",
-        std_features: Option<BTreeSet<String>> = "std-features",
-    }
-}
-
-define_config! {
-    /// TOML representation of how each build target is configured.
-    struct TomlTarget {
-        cc: Option<String> = "cc",
-        cxx: Option<String> = "cxx",
-        ar: Option<String> = "ar",
-        ranlib: Option<String> = "ranlib",
-        default_linker: Option<PathBuf> = "default-linker",
-        linker: Option<String> = "linker",
-        split_debuginfo: Option<String> = "split-debuginfo",
-        llvm_config: Option<String> = "llvm-config",
-        llvm_has_rust_patches: Option<bool> = "llvm-has-rust-patches",
-        llvm_filecheck: Option<String> = "llvm-filecheck",
-        llvm_libunwind: Option<String> = "llvm-libunwind",
-        sanitizers: Option<bool> = "sanitizers",
-        profiler: Option<StringOrBool> = "profiler",
-        rpath: Option<bool> = "rpath",
-        crt_static: Option<bool> = "crt-static",
-        musl_root: Option<String> = "musl-root",
-        musl_libdir: Option<String> = "musl-libdir",
-        wasi_root: Option<String> = "wasi-root",
-        qemu_rootfs: Option<String> = "qemu-rootfs",
-        no_std: Option<bool> = "no-std",
-        codegen_backends: Option<Vec<String>> = "codegen-backends",
-        runner: Option<String> = "runner",
-        optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
-        jemalloc: Option<bool> = "jemalloc",
-    }
+    pub exec_ctx: ExecutionContext,
 }
 
 impl Config {
@@ -1405,45 +376,12 @@ impl Config {
         }
     }
 
-    pub(crate) fn get_builder_toml(&self, build_name: &str) -> Result<TomlConfig, toml::de::Error> {
-        if self.dry_run() {
-            return Ok(TomlConfig::default());
-        }
-
-        let builder_config_path =
-            self.out.join(self.build.triple).join(build_name).join(BUILDER_CONFIG_FILENAME);
-        Self::get_toml(&builder_config_path)
-    }
-
-    pub(crate) fn get_toml(file: &Path) -> Result<TomlConfig, toml::de::Error> {
-        #[cfg(test)]
-        return Ok(TomlConfig::default());
-
-        #[cfg(not(test))]
-        Self::get_toml_inner(file)
+    pub fn set_dry_run(&mut self, dry_run: DryRun) {
+        self.exec_ctx.set_dry_run(dry_run);
     }
 
-    fn get_toml_inner(file: &Path) -> Result<TomlConfig, toml::de::Error> {
-        let contents =
-            t!(fs::read_to_string(file), format!("config file {} not found", file.display()));
-        // Deserialize to Value and then TomlConfig to prevent the Deserialize impl of
-        // TomlConfig and sub types to be monomorphized 5x by toml.
-        toml::from_str(&contents)
-            .and_then(|table: toml::Value| TomlConfig::deserialize(table))
-            .inspect_err(|_| {
-                if let Ok(ChangeIdWrapper { inner: Some(ChangeId::Id(id)) }) =
-                    toml::from_str::<toml::Value>(&contents)
-                        .and_then(|table: toml::Value| ChangeIdWrapper::deserialize(table))
-                {
-                    let changes = crate::find_recent_config_change_ids(id);
-                    if !changes.is_empty() {
-                        println!(
-                            "WARNING: There have been changes to x.py since you last updated:\n{}",
-                            crate::human_readable_changes(changes)
-                        );
-                    }
-                }
-            })
+    pub fn get_dry_run(&self) -> &DryRun {
+        self.exec_ctx.get_dry_run()
     }
 
     #[cfg_attr(
@@ -1468,6 +406,11 @@ impl Config {
         get_toml: impl Fn(&Path) -> Result<TomlConfig, toml::de::Error>,
     ) -> Config {
         let mut config = Config::default_opts();
+        let mut exec_ctx = ExecutionContext::new();
+        exec_ctx.set_verbose(flags.verbose);
+        exec_ctx.set_fail_fast(flags.cmd.fail_fast());
+
+        config.exec_ctx = exec_ctx;
 
         // Set flags.
         config.paths = std::mem::take(&mut flags.paths);
@@ -1496,7 +439,7 @@ impl Config {
         config.on_fail = flags.on_fail;
         config.cmd = flags.cmd;
         config.incremental = flags.incremental;
-        config.dry_run = if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled };
+        config.set_dry_run(if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled });
         config.dump_bootstrap_shims = flags.dump_bootstrap_shims;
         config.keep_stage = flags.keep_stage;
         config.keep_stage_std = flags.keep_stage_std;
@@ -1507,6 +450,7 @@ impl Config {
         config.enable_bolt_settings = flags.enable_bolt_settings;
         config.bypass_bootstrap_lock = flags.bypass_bootstrap_lock;
         config.is_running_on_ci = flags.ci.unwrap_or(CiEnv::is_ci());
+        config.skip_std_check_if_no_download_rustc = flags.skip_std_check_if_no_download_rustc;
 
         // Infer the rest of the configuration.
 
@@ -1525,14 +469,9 @@ impl Config {
             // has already been (kinda-cross-)compiled to Windows land, we require a normal Windows path.
             cmd.arg("rev-parse").arg("--show-cdup");
             // Discard stderr because we expect this to fail when building from a tarball.
-            let output = cmd
-                .as_command_mut()
-                .stderr(std::process::Stdio::null())
-                .output()
-                .ok()
-                .and_then(|output| if output.status.success() { Some(output) } else { None });
-            if let Some(output) = output {
-                let git_root_relative = String::from_utf8(output.stdout).unwrap();
+            let output = cmd.allow_failure().run_capture_stdout(&config);
+            if output.is_success() {
+                let git_root_relative = output.stdout();
                 // We need to canonicalize this path to make sure it uses backslashes instead of forward slashes,
                 // and to resolve any relative components.
                 let git_root = env::current_dir()
@@ -1627,7 +566,7 @@ 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() {
+        if config.git_info(false, &config.src).is_from_tarball() && toml.profile.is_none() {
             toml.profile = Some("dist".into());
         }
 
@@ -1834,7 +773,12 @@ impl Config {
         };
 
         config.initial_sysroot = t!(PathBuf::from_str(
-            output(Command::new(&config.initial_rustc).args(["--print", "sysroot"])).trim()
+            command(&config.initial_rustc)
+                .args(["--print", "sysroot"])
+                .run_always()
+                .run_capture_stdout(&config)
+                .stdout()
+                .trim()
         ));
 
         config.initial_cargo_clippy = cargo_clippy;
@@ -1906,42 +850,11 @@ impl Config {
         // Verbose flag is a good default for `rust.verbose-tests`.
         config.verbose_tests = config.is_verbose();
 
-        if let Some(install) = toml.install {
-            let Install { prefix, sysconfdir, docdir, bindir, libdir, mandir, datadir } = install;
-            config.prefix = prefix.map(PathBuf::from);
-            config.sysconfdir = sysconfdir.map(PathBuf::from);
-            config.datadir = datadir.map(PathBuf::from);
-            config.docdir = docdir.map(PathBuf::from);
-            set(&mut config.bindir, bindir.map(PathBuf::from));
-            config.libdir = libdir.map(PathBuf::from);
-            config.mandir = mandir.map(PathBuf::from);
-        }
+        config.apply_install_config(toml.install);
 
         config.llvm_assertions =
             toml.llvm.as_ref().is_some_and(|llvm| llvm.assertions.unwrap_or(false));
 
-        // Store off these values as options because if they're not provided
-        // we'll infer default values for them later
-        let mut llvm_tests = None;
-        let mut llvm_enzyme = None;
-        let mut llvm_offload = None;
-        let mut llvm_plugins = None;
-        let mut debug = None;
-        let mut rustc_debug_assertions = None;
-        let mut std_debug_assertions = None;
-        let mut tools_debug_assertions = None;
-        let mut overflow_checks = None;
-        let mut overflow_checks_std = None;
-        let mut debug_logging = None;
-        let mut debuginfo_level = None;
-        let mut debuginfo_level_rustc = None;
-        let mut debuginfo_level_std = None;
-        let mut debuginfo_level_tools = None;
-        let mut debuginfo_level_tests = None;
-        let mut optimize = None;
-        let mut lld_enabled = None;
-        let mut std_features = None;
-
         let file_content = t!(fs::read_to_string(config.src.join("src/ci/channel")));
         let ci_channel = file_content.trim_end();
 
@@ -1961,19 +874,21 @@ impl Config {
         let default = config.channel == "dev";
         config.omit_git_hash = toml.rust.as_ref().and_then(|r| r.omit_git_hash).unwrap_or(default);
 
-        config.rust_info = GitInfo::new(config.omit_git_hash, &config.src);
-        config.cargo_info = GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/cargo"));
+        config.rust_info = config.git_info(config.omit_git_hash, &config.src);
+        config.cargo_info =
+            config.git_info(config.omit_git_hash, &config.src.join("src/tools/cargo"));
         config.rust_analyzer_info =
-            GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/rust-analyzer"));
+            config.git_info(config.omit_git_hash, &config.src.join("src/tools/rust-analyzer"));
         config.clippy_info =
-            GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/clippy"));
-        config.miri_info = GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/miri"));
+            config.git_info(config.omit_git_hash, &config.src.join("src/tools/clippy"));
+        config.miri_info =
+            config.git_info(config.omit_git_hash, &config.src.join("src/tools/miri"));
         config.rustfmt_info =
-            GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/rustfmt"));
+            config.git_info(config.omit_git_hash, &config.src.join("src/tools/rustfmt"));
         config.enzyme_info =
-            GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/enzyme"));
-        config.in_tree_llvm_info = GitInfo::new(false, &config.src.join("src/llvm-project"));
-        config.in_tree_gcc_info = GitInfo::new(false, &config.src.join("src/gcc"));
+            config.git_info(config.omit_git_hash, &config.src.join("src/tools/enzyme"));
+        config.in_tree_llvm_info = config.git_info(false, &config.src.join("src/llvm-project"));
+        config.in_tree_gcc_info = config.git_info(false, &config.src.join("src/gcc"));
 
         config.vendor = vendor.unwrap_or(
             config.rust_info.is_from_tarball()
@@ -1985,190 +900,10 @@ impl Config {
             config.channel = ci_channel.into();
         }
 
-        if let Some(rust) = toml.rust {
-            let Rust {
-                optimize: optimize_toml,
-                debug: debug_toml,
-                codegen_units,
-                codegen_units_std,
-                rustc_debug_assertions: rustc_debug_assertions_toml,
-                std_debug_assertions: std_debug_assertions_toml,
-                tools_debug_assertions: tools_debug_assertions_toml,
-                overflow_checks: overflow_checks_toml,
-                overflow_checks_std: overflow_checks_std_toml,
-                debug_logging: debug_logging_toml,
-                debuginfo_level: debuginfo_level_toml,
-                debuginfo_level_rustc: debuginfo_level_rustc_toml,
-                debuginfo_level_std: debuginfo_level_std_toml,
-                debuginfo_level_tools: debuginfo_level_tools_toml,
-                debuginfo_level_tests: debuginfo_level_tests_toml,
-                backtrace,
-                incremental,
-                randomize_layout,
-                default_linker,
-                channel: _, // already handled above
-                description: rust_description,
-                musl_root,
-                rpath,
-                verbose_tests,
-                optimize_tests,
-                codegen_tests,
-                omit_git_hash: _, // already handled above
-                dist_src,
-                save_toolstates,
-                codegen_backends,
-                lld: lld_enabled_toml,
-                llvm_tools,
-                llvm_bitcode_linker,
-                deny_warnings,
-                backtrace_on_ice,
-                verify_llvm_ir,
-                thin_lto_import_instr_limit,
-                remap_debuginfo,
-                jemalloc,
-                test_compare_mode,
-                llvm_libunwind,
-                control_flow_guard,
-                ehcont_guard,
-                new_symbol_mangling,
-                profile_generate,
-                profile_use,
-                download_rustc,
-                lto,
-                validate_mir_opts,
-                frame_pointers,
-                stack_protector,
-                strip,
-                lld_mode,
-                std_features: std_features_toml,
-            } = rust;
-
-            // FIXME(#133381): alt rustc builds currently do *not* have rustc debug assertions
-            // enabled. We should not download a CI alt rustc if we need rustc to have debug
-            // assertions (e.g. for crashes test suite). This can be changed once something like
-            // [Enable debug assertions on alt
-            // builds](https://github.com/rust-lang/rust/pull/131077) lands.
-            //
-            // Note that `rust.debug = true` currently implies `rust.debug-assertions = true`!
-            //
-            // This relies also on the fact that the global default for `download-rustc` will be
-            // `false` if it's not explicitly set.
-            let debug_assertions_requested = matches!(rustc_debug_assertions_toml, Some(true))
-                || (matches!(debug_toml, Some(true))
-                    && !matches!(rustc_debug_assertions_toml, Some(false)));
-
-            if debug_assertions_requested
-                && let Some(ref opt) = download_rustc
-                && opt.is_string_or_true()
-            {
-                eprintln!(
-                    "WARN: currently no CI rustc builds have rustc debug assertions \
-                            enabled. Please either set `rust.debug-assertions` to `false` if you \
-                            want to use download CI rustc or set `rust.download-rustc` to `false`."
-                );
-            }
+        config.rust_profile_use = flags.rust_profile_use;
+        config.rust_profile_generate = flags.rust_profile_generate;
 
-            config.download_rustc_commit = config.download_ci_rustc_commit(
-                download_rustc,
-                debug_assertions_requested,
-                config.llvm_assertions,
-            );
-
-            debug = debug_toml;
-            rustc_debug_assertions = rustc_debug_assertions_toml;
-            std_debug_assertions = std_debug_assertions_toml;
-            tools_debug_assertions = tools_debug_assertions_toml;
-            overflow_checks = overflow_checks_toml;
-            overflow_checks_std = overflow_checks_std_toml;
-            debug_logging = debug_logging_toml;
-            debuginfo_level = debuginfo_level_toml;
-            debuginfo_level_rustc = debuginfo_level_rustc_toml;
-            debuginfo_level_std = debuginfo_level_std_toml;
-            debuginfo_level_tools = debuginfo_level_tools_toml;
-            debuginfo_level_tests = debuginfo_level_tests_toml;
-            lld_enabled = lld_enabled_toml;
-            std_features = std_features_toml;
-
-            optimize = optimize_toml;
-            config.rust_new_symbol_mangling = new_symbol_mangling;
-            set(&mut config.rust_optimize_tests, optimize_tests);
-            set(&mut config.codegen_tests, codegen_tests);
-            set(&mut config.rust_rpath, rpath);
-            set(&mut config.rust_strip, strip);
-            set(&mut config.rust_frame_pointers, frame_pointers);
-            config.rust_stack_protector = stack_protector;
-            set(&mut config.jemalloc, jemalloc);
-            set(&mut config.test_compare_mode, test_compare_mode);
-            set(&mut config.backtrace, backtrace);
-            if rust_description.is_some() {
-                eprintln!(
-                    "Warning: rust.description is deprecated. Use build.description instead."
-                );
-            }
-            description = description.or(rust_description);
-            set(&mut config.rust_dist_src, dist_src);
-            set(&mut config.verbose_tests, verbose_tests);
-            // in the case "false" is set explicitly, do not overwrite the command line args
-            if let Some(true) = incremental {
-                config.incremental = true;
-            }
-            set(&mut config.lld_mode, lld_mode);
-            set(&mut config.llvm_bitcode_linker_enabled, llvm_bitcode_linker);
-
-            config.rust_randomize_layout = randomize_layout.unwrap_or_default();
-            config.llvm_tools_enabled = llvm_tools.unwrap_or(true);
-
-            config.llvm_enzyme =
-                llvm_enzyme.unwrap_or(config.channel == "dev" || config.channel == "nightly");
-            config.rustc_default_linker = default_linker;
-            config.musl_root = musl_root.map(PathBuf::from);
-            config.save_toolstates = save_toolstates.map(PathBuf::from);
-            set(
-                &mut config.deny_warnings,
-                match flags.warnings {
-                    Warnings::Deny => Some(true),
-                    Warnings::Warn => Some(false),
-                    Warnings::Default => deny_warnings,
-                },
-            );
-            set(&mut config.backtrace_on_ice, backtrace_on_ice);
-            set(&mut config.rust_verify_llvm_ir, verify_llvm_ir);
-            config.rust_thin_lto_import_instr_limit = thin_lto_import_instr_limit;
-            set(&mut config.rust_remap_debuginfo, remap_debuginfo);
-            set(&mut config.control_flow_guard, control_flow_guard);
-            set(&mut config.ehcont_guard, ehcont_guard);
-            config.llvm_libunwind_default =
-                llvm_libunwind.map(|v| v.parse().expect("failed to parse rust.llvm-libunwind"));
-
-            if let Some(ref backends) = codegen_backends {
-                let available_backends = ["llvm", "cranelift", "gcc"];
-
-                config.rust_codegen_backends = backends.iter().map(|s| {
-                    if let Some(backend) = s.strip_prefix(CODEGEN_BACKEND_PREFIX) {
-                        if available_backends.contains(&backend) {
-                            panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'.");
-                        } else {
-                            println!("HELP: '{s}' for 'rust.codegen-backends' might fail. \
-                                Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
-                                In this case, it would be referred to as '{backend}'.");
-                        }
-                    }
-
-                    s.clone()
-                }).collect();
-            }
-
-            config.rust_codegen_units = codegen_units.map(threads_from_config);
-            config.rust_codegen_units_std = codegen_units_std.map(threads_from_config);
-            config.rust_profile_use = flags.rust_profile_use.or(profile_use);
-            config.rust_profile_generate = flags.rust_profile_generate.or(profile_generate);
-            config.rust_lto =
-                lto.as_deref().map(|value| RustcLto::from_str(value).unwrap()).unwrap_or_default();
-            config.rust_validate_mir_opts = validate_mir_opts;
-        } else {
-            config.rust_profile_use = flags.rust_profile_use;
-            config.rust_profile_generate = flags.rust_profile_generate;
-        }
+        config.apply_rust_config(toml.rust, flags.warnings, &mut description);
 
         config.reproducible_artifacts = flags.reproducible_artifact;
         config.description = description;
@@ -2189,206 +924,11 @@ impl Config {
             config.channel = channel;
         }
 
-        if let Some(llvm) = toml.llvm {
-            let Llvm {
-                optimize: optimize_toml,
-                thin_lto,
-                release_debuginfo,
-                assertions: _,
-                tests,
-                enzyme,
-                plugins,
-                ccache: llvm_ccache,
-                static_libstdcpp,
-                libzstd,
-                ninja,
-                targets,
-                experimental_targets,
-                link_jobs,
-                link_shared,
-                version_suffix,
-                clang_cl,
-                cflags,
-                cxxflags,
-                ldflags,
-                use_libcxx,
-                use_linker,
-                allow_old_toolchain,
-                offload,
-                polly,
-                clang,
-                enable_warnings,
-                download_ci_llvm,
-                build_config,
-            } = llvm;
-            if llvm_ccache.is_some() {
-                eprintln!("Warning: llvm.ccache is deprecated. Use build.ccache instead.");
-            }
-
-            ccache = ccache.or(llvm_ccache);
-            set(&mut config.ninja_in_file, ninja);
-            llvm_tests = tests;
-            llvm_enzyme = enzyme;
-            llvm_offload = offload;
-            llvm_plugins = plugins;
-            set(&mut config.llvm_optimize, optimize_toml);
-            set(&mut config.llvm_thin_lto, thin_lto);
-            set(&mut config.llvm_release_debuginfo, release_debuginfo);
-            set(&mut config.llvm_static_stdcpp, static_libstdcpp);
-            set(&mut config.llvm_libzstd, libzstd);
-            if let Some(v) = link_shared {
-                config.llvm_link_shared.set(Some(v));
-            }
-            config.llvm_targets.clone_from(&targets);
-            config.llvm_experimental_targets.clone_from(&experimental_targets);
-            config.llvm_link_jobs = link_jobs;
-            config.llvm_version_suffix.clone_from(&version_suffix);
-            config.llvm_clang_cl.clone_from(&clang_cl);
-
-            config.llvm_cflags.clone_from(&cflags);
-            config.llvm_cxxflags.clone_from(&cxxflags);
-            config.llvm_ldflags.clone_from(&ldflags);
-            set(&mut config.llvm_use_libcxx, use_libcxx);
-            config.llvm_use_linker.clone_from(&use_linker);
-            config.llvm_allow_old_toolchain = allow_old_toolchain.unwrap_or(false);
-            config.llvm_offload = offload.unwrap_or(false);
-            config.llvm_polly = polly.unwrap_or(false);
-            config.llvm_clang = clang.unwrap_or(false);
-            config.llvm_enable_warnings = enable_warnings.unwrap_or(false);
-            config.llvm_build_config = build_config.clone().unwrap_or(Default::default());
-
-            config.llvm_from_ci =
-                config.parse_download_ci_llvm(download_ci_llvm, config.llvm_assertions);
-
-            if config.llvm_from_ci {
-                let warn = |option: &str| {
-                    println!(
-                        "WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build."
-                    );
-                    println!(
-                        "HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false."
-                    );
-                };
-
-                if static_libstdcpp.is_some() {
-                    warn("static-libstdcpp");
-                }
-
-                if link_shared.is_some() {
-                    warn("link-shared");
-                }
-
-                // FIXME(#129153): instead of all the ad-hoc `download-ci-llvm` checks that follow,
-                // use the `builder-config` present in tarballs since #128822 to compare the local
-                // config to the ones used to build the LLVM artifacts on CI, and only notify users
-                // if they've chosen a different value.
-
-                if libzstd.is_some() {
-                    println!(
-                        "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \
-                        like almost all `llvm.*` options, will be ignored and set by the LLVM CI \
-                        artifacts builder config."
-                    );
-                    println!(
-                        "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false."
-                    );
-                }
-            }
-
-            if !config.llvm_from_ci && config.llvm_thin_lto && link_shared.is_none() {
-                // If we're building with ThinLTO on, by default we want to link
-                // to LLVM shared, to avoid re-doing ThinLTO (which happens in
-                // the link step) with each stage.
-                config.llvm_link_shared.set(Some(true));
-            }
-        } else {
-            config.llvm_from_ci = config.parse_download_ci_llvm(None, false);
-        }
-
-        if let Some(gcc) = toml.gcc {
-            config.gcc_ci_mode = match gcc.download_ci_gcc {
-                Some(value) => match value {
-                    true => GccCiMode::DownloadFromCi,
-                    false => GccCiMode::BuildLocally,
-                },
-                None => GccCiMode::default(),
-            };
-        }
+        config.apply_llvm_config(toml.llvm, &mut ccache);
 
-        if let Some(t) = toml.target {
-            for (triple, cfg) in t {
-                let mut target = Target::from_triple(&triple);
+        config.apply_gcc_config(toml.gcc);
 
-                if let Some(ref s) = cfg.llvm_config {
-                    if config.download_rustc_commit.is_some() && triple == *config.build.triple {
-                        panic!(
-                            "setting llvm_config for the host is incompatible with download-rustc"
-                        );
-                    }
-                    target.llvm_config = Some(config.src.join(s));
-                }
-                if let Some(patches) = cfg.llvm_has_rust_patches {
-                    assert!(
-                        config.submodules == Some(false) || cfg.llvm_config.is_some(),
-                        "use of `llvm-has-rust-patches` is restricted to cases where either submodules are disabled or llvm-config been provided"
-                    );
-                    target.llvm_has_rust_patches = Some(patches);
-                }
-                if let Some(ref s) = cfg.llvm_filecheck {
-                    target.llvm_filecheck = Some(config.src.join(s));
-                }
-                target.llvm_libunwind = cfg.llvm_libunwind.as_ref().map(|v| {
-                    v.parse().unwrap_or_else(|_| {
-                        panic!("failed to parse target.{triple}.llvm-libunwind")
-                    })
-                });
-                if let Some(s) = cfg.no_std {
-                    target.no_std = s;
-                }
-                target.cc = cfg.cc.map(PathBuf::from);
-                target.cxx = cfg.cxx.map(PathBuf::from);
-                target.ar = cfg.ar.map(PathBuf::from);
-                target.ranlib = cfg.ranlib.map(PathBuf::from);
-                target.linker = cfg.linker.map(PathBuf::from);
-                target.crt_static = cfg.crt_static;
-                target.musl_root = cfg.musl_root.map(PathBuf::from);
-                target.musl_libdir = cfg.musl_libdir.map(PathBuf::from);
-                target.wasi_root = cfg.wasi_root.map(PathBuf::from);
-                target.qemu_rootfs = cfg.qemu_rootfs.map(PathBuf::from);
-                target.runner = cfg.runner;
-                target.sanitizers = cfg.sanitizers;
-                target.profiler = cfg.profiler;
-                target.rpath = cfg.rpath;
-                target.optimized_compiler_builtins = cfg.optimized_compiler_builtins;
-                target.jemalloc = cfg.jemalloc;
-
-                if let Some(ref backends) = cfg.codegen_backends {
-                    let available_backends = ["llvm", "cranelift", "gcc"];
-
-                    target.codegen_backends = Some(backends.iter().map(|s| {
-                        if let Some(backend) = s.strip_prefix(CODEGEN_BACKEND_PREFIX) {
-                            if available_backends.contains(&backend) {
-                                panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'.");
-                            } else {
-                                println!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \
-                                    Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
-                                    In this case, it would be referred to as '{backend}'.");
-                            }
-                        }
-
-                        s.clone()
-                    }).collect());
-                }
-
-                target.split_debuginfo = cfg.split_debuginfo.as_ref().map(|v| {
-                    v.parse().unwrap_or_else(|_| {
-                        panic!("invalid value for target.{triple}.split-debuginfo")
-                    })
-                });
-
-                config.target_config.insert(TargetSelection::from_user(&triple), target);
-            }
-        }
+        config.apply_target_config(toml.target);
 
         match ccache {
             Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()),
@@ -2412,69 +952,11 @@ impl Config {
             build_target.llvm_filecheck = Some(ci_llvm_bin.join(exe("FileCheck", config.build)));
         }
 
-        if let Some(dist) = toml.dist {
-            let Dist {
-                sign_folder,
-                upload_addr,
-                src_tarball,
-                compression_formats,
-                compression_profile,
-                include_mingw_linker,
-                vendor,
-            } = dist;
-            config.dist_sign_folder = sign_folder.map(PathBuf::from);
-            config.dist_upload_addr = upload_addr;
-            config.dist_compression_formats = compression_formats;
-            set(&mut config.dist_compression_profile, compression_profile);
-            set(&mut config.rust_dist_src, src_tarball);
-            set(&mut config.dist_include_mingw_linker, include_mingw_linker);
-            config.dist_vendor = vendor.unwrap_or_else(|| {
-                // If we're building from git or tarball sources, enable it by default.
-                config.rust_info.is_managed_git_subrepository()
-                    || config.rust_info.is_from_tarball()
-            });
-        }
+        config.apply_dist_config(toml.dist);
 
         config.initial_rustfmt =
             if let Some(r) = rustfmt { Some(r) } else { config.maybe_download_rustfmt() };
 
-        // Now that we've reached the end of our configuration, infer the
-        // default values for all options that we haven't otherwise stored yet.
-
-        config.llvm_tests = llvm_tests.unwrap_or(false);
-        config.llvm_enzyme = llvm_enzyme.unwrap_or(false);
-        config.llvm_offload = llvm_offload.unwrap_or(false);
-        config.llvm_plugins = llvm_plugins.unwrap_or(false);
-        config.rust_optimize = optimize.unwrap_or(RustOptimize::Bool(true));
-
-        // We make `x86_64-unknown-linux-gnu` use the self-contained linker by default, so we will
-        // build our internal lld and use it as the default linker, by setting the `rust.lld` config
-        // to true by default:
-        // - on the `x86_64-unknown-linux-gnu` target
-        // - on the `dev` and `nightly` channels
-        // - when building our in-tree llvm (i.e. the target has not set an `llvm-config`), so that
-        //   we're also able to build the corresponding lld
-        // - or when using an external llvm that's downloaded from CI, which also contains our prebuilt
-        //   lld
-        // - otherwise, we'd be using an external llvm, and lld would not necessarily available and
-        //   thus, disabled
-        // - similarly, lld will not be built nor used by default when explicitly asked not to, e.g.
-        //   when the config sets `rust.lld = false`
-        if config.build.triple == "x86_64-unknown-linux-gnu"
-            && config.hosts == [config.build]
-            && (config.channel == "dev" || config.channel == "nightly")
-        {
-            let no_llvm_config = config
-                .target_config
-                .get(&config.build)
-                .is_some_and(|target_config| target_config.llvm_config.is_none());
-            let enable_lld = config.llvm_from_ci || no_llvm_config;
-            // Prefer the config setting in case an explicit opt-out is needed.
-            config.lld_enabled = lld_enabled.unwrap_or(enable_lld);
-        } else {
-            set(&mut config.lld_enabled, lld_enabled);
-        }
-
         if matches!(config.lld_mode, LldMode::SelfContained)
             && !config.lld_enabled
             && flags.stage.unwrap_or(0) > 0
@@ -2490,31 +972,6 @@ impl Config {
             );
         }
 
-        let default_std_features = BTreeSet::from([String::from("panic-unwind")]);
-        config.rust_std_features = std_features.unwrap_or(default_std_features);
-
-        let default = debug == Some(true);
-        config.rustc_debug_assertions = rustc_debug_assertions.unwrap_or(default);
-        config.std_debug_assertions = std_debug_assertions.unwrap_or(config.rustc_debug_assertions);
-        config.tools_debug_assertions =
-            tools_debug_assertions.unwrap_or(config.rustc_debug_assertions);
-        config.rust_overflow_checks = overflow_checks.unwrap_or(default);
-        config.rust_overflow_checks_std =
-            overflow_checks_std.unwrap_or(config.rust_overflow_checks);
-
-        config.rust_debug_logging = debug_logging.unwrap_or(config.rustc_debug_assertions);
-
-        let with_defaults = |debuginfo_level_specific: Option<_>| {
-            debuginfo_level_specific.or(debuginfo_level).unwrap_or(if debug == Some(true) {
-                DebuginfoLevel::Limited
-            } else {
-                DebuginfoLevel::None
-            })
-        };
-        config.rust_debuginfo_level_rustc = with_defaults(debuginfo_level_rustc);
-        config.rust_debuginfo_level_std = with_defaults(debuginfo_level_std);
-        config.rust_debuginfo_level_tools = with_defaults(debuginfo_level_tools);
-        config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(DebuginfoLevel::None);
         config.optimized_compiler_builtins =
             optimized_compiler_builtins.unwrap_or(config.channel != "dev");
         config.compiletest_diff_tool = compiletest_diff_tool;
@@ -2591,28 +1048,13 @@ impl Config {
     }
 
     pub fn dry_run(&self) -> bool {
-        match self.dry_run {
-            DryRun::Disabled => false,
-            DryRun::SelfCheck | DryRun::UserSelected => true,
-        }
+        self.exec_ctx.dry_run()
     }
 
     pub fn is_explicit_stage(&self) -> bool {
         self.explicit_stage_from_cli || self.explicit_stage_from_config
     }
 
-    /// Runs a command, printing out nice contextual information if it fails.
-    /// Exits if the command failed to execute at all, otherwise returns its
-    /// `status.success()`.
-    #[deprecated = "use `Builder::try_run` instead where possible"]
-    pub(crate) fn try_run(&self, cmd: &mut Command) -> Result<(), ()> {
-        if self.dry_run() {
-            return Ok(());
-        }
-        self.verbose(|| println!("running: {cmd:?}"));
-        build_helper::util::try_run(cmd, self.is_verbose())
-    }
-
     pub(crate) fn test_args(&self) -> Vec<&str> {
         let mut test_args = match self.cmd {
             Subcommand::Test { ref test_args, .. }
@@ -2646,7 +1088,7 @@ impl Config {
 
         let mut git = helpers::git(Some(&self.src));
         git.arg("show").arg(format!("{commit}:{}", file.to_str().unwrap()));
-        output(git.as_command_mut())
+        git.run_capture_stdout(self).stdout()
     }
 
     /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI.
@@ -2834,18 +1276,7 @@ impl Config {
 
     /// Runs a function if verbosity is greater than 0
     pub fn verbose(&self, f: impl Fn()) {
-        if self.is_verbose() {
-            f()
-        }
-    }
-
-    pub fn sanitizers_enabled(&self, target: TargetSelection) -> bool {
-        self.target_config.get(&target).and_then(|t| t.sanitizers).unwrap_or(self.sanitizers)
-    }
-
-    pub fn needs_sanitizer_runtime_built(&self, target: TargetSelection) -> bool {
-        // MSVC uses the Microsoft-provided sanitizer runtime, but all other runtimes we build.
-        !target.is_msvc() && self.sanitizers_enabled(target)
+        self.exec_ctx.verbose(f);
     }
 
     pub fn any_sanitizers_to_build(&self) -> bool {
@@ -2854,60 +1285,11 @@ impl Config {
             .any(|(ts, t)| !ts.is_msvc() && t.sanitizers.unwrap_or(self.sanitizers))
     }
 
-    pub fn profiler_path(&self, target: TargetSelection) -> Option<&str> {
-        match self.target_config.get(&target)?.profiler.as_ref()? {
-            StringOrBool::String(s) => Some(s),
-            StringOrBool::Bool(_) => None,
-        }
-    }
-
-    pub fn profiler_enabled(&self, target: TargetSelection) -> bool {
-        self.target_config
-            .get(&target)
-            .and_then(|t| t.profiler.as_ref())
-            .map(StringOrBool::is_string_or_true)
-            .unwrap_or(self.profiler)
-    }
-
     pub fn any_profiler_enabled(&self) -> bool {
         self.target_config.values().any(|t| matches!(&t.profiler, Some(p) if p.is_string_or_true()))
             || self.profiler
     }
 
-    pub fn rpath_enabled(&self, target: TargetSelection) -> bool {
-        self.target_config.get(&target).and_then(|t| t.rpath).unwrap_or(self.rust_rpath)
-    }
-
-    pub fn optimized_compiler_builtins(&self, target: TargetSelection) -> bool {
-        self.target_config
-            .get(&target)
-            .and_then(|t| t.optimized_compiler_builtins)
-            .unwrap_or(self.optimized_compiler_builtins)
-    }
-
-    pub fn llvm_enabled(&self, target: TargetSelection) -> bool {
-        self.codegen_backends(target).contains(&"llvm".to_owned())
-    }
-
-    pub fn llvm_libunwind(&self, target: TargetSelection) -> LlvmLibunwind {
-        self.target_config
-            .get(&target)
-            .and_then(|t| t.llvm_libunwind)
-            .or(self.llvm_libunwind_default)
-            .unwrap_or(if target.contains("fuchsia") {
-                LlvmLibunwind::InTree
-            } else {
-                LlvmLibunwind::No
-            })
-    }
-
-    pub fn split_debuginfo(&self, target: TargetSelection) -> SplitDebuginfo {
-        self.target_config
-            .get(&target)
-            .and_then(|t| t.split_debuginfo)
-            .unwrap_or_else(|| SplitDebuginfo::default_for_platform(target))
-    }
-
     /// Returns whether or not submodules should be managed by bootstrap.
     pub fn submodules(&self) -> bool {
         // If not specified in config, the default is to only manage
@@ -2915,21 +1297,6 @@ impl Config {
         self.submodules.unwrap_or(self.rust_info.is_managed_git_subrepository())
     }
 
-    pub fn codegen_backends(&self, target: TargetSelection) -> &[String] {
-        self.target_config
-            .get(&target)
-            .and_then(|cfg| cfg.codegen_backends.as_deref())
-            .unwrap_or(&self.rust_codegen_backends)
-    }
-
-    pub fn jemalloc(&self, target: TargetSelection) -> bool {
-        self.target_config.get(&target).and_then(|cfg| cfg.jemalloc).unwrap_or(self.jemalloc)
-    }
-
-    pub fn default_codegen_backend(&self, target: TargetSelection) -> Option<String> {
-        self.codegen_backends(target).first().cloned()
-    }
-
     pub fn git_config(&self) -> GitConfig<'_> {
         GitConfig {
             nightly_branch: &self.stage0_metadata.config.nightly_branch,
@@ -2971,7 +1338,7 @@ impl Config {
 
         // NOTE: The check for the empty directory is here because when running x.py the first time,
         // the submodule won't be checked out. Check it out now so we can build it.
-        if !GitInfo::new(false, &absolute_path).is_managed_git_subrepository()
+        if !self.git_info(false, &absolute_path).is_managed_git_subrepository()
             && !helpers::dir_is_empty(&absolute_path)
         {
             return;
@@ -2990,16 +1357,16 @@ impl Config {
         };
 
         // Determine commit checked out in submodule.
-        let checked_out_hash = output(submodule_git().args(["rev-parse", "HEAD"]).as_command_mut());
+        let checked_out_hash =
+            submodule_git().args(["rev-parse", "HEAD"]).run_capture_stdout(self).stdout();
         let checked_out_hash = checked_out_hash.trim_end();
         // Determine commit that the submodule *should* have.
-        let recorded = output(
-            helpers::git(Some(&self.src))
-                .run_always()
-                .args(["ls-tree", "HEAD"])
-                .arg(relative_path)
-                .as_command_mut(),
-        );
+        let recorded = helpers::git(Some(&self.src))
+            .run_always()
+            .args(["ls-tree", "HEAD"])
+            .arg(relative_path)
+            .run_capture_stdout(self)
+            .stdout();
 
         let actual_hash = recorded
             .split_whitespace()
@@ -3023,20 +1390,18 @@ impl Config {
         let update = |progress: bool| {
             // Git is buggy and will try to fetch submodules from the tracking branch for *this* repository,
             // even though that has no relation to the upstream for the submodule.
-            let current_branch = output_result(
-                helpers::git(Some(&self.src))
-                    .allow_failure()
-                    .run_always()
-                    .args(["symbolic-ref", "--short", "HEAD"])
-                    .as_command_mut(),
-            )
-            .map(|b| b.trim().to_owned());
+            let current_branch = helpers::git(Some(&self.src))
+                .allow_failure()
+                .run_always()
+                .args(["symbolic-ref", "--short", "HEAD"])
+                .run_capture(self);
 
             let mut git = helpers::git(Some(&self.src)).allow_failure();
             git.run_always();
-            if let Ok(branch) = current_branch {
+            if current_branch.is_success() {
                 // If there is a tag named after the current branch, git will try to disambiguate by prepending `heads/` to the branch name.
                 // This syntax isn't accepted by `branch.{branch}`. Strip it.
+                let branch = current_branch.stdout();
                 let branch = branch.strip_prefix("heads/").unwrap_or(&branch);
                 git.arg("-c").arg(format!("branch.{branch}.remote=origin"));
             }
@@ -3082,7 +1447,8 @@ impl Config {
             return;
         }
 
-        let stage0_output = output(Command::new(program_path).arg("--version"));
+        let stage0_output =
+            command(program_path).arg("--version").run_capture_stdout(self).stdout();
         let mut stage0_output = stage0_output.lines().next().unwrap().split(' ');
 
         let stage0_name = stage0_output.next().unwrap();
@@ -3113,7 +1479,7 @@ impl Config {
     }
 
     /// Returns the commit to download, or `None` if we shouldn't download CI artifacts.
-    fn download_ci_rustc_commit(
+    pub fn download_ci_rustc_commit(
         &self,
         download_rustc: Option<StringOrBool>,
         debug_assertions_requested: bool,
@@ -3150,7 +1516,7 @@ impl Config {
         let commit = if self.rust_info.is_managed_git_subrepository() {
             // Look for a version to compare to based on the current commit.
             // Only commits merged by bors will have CI artifacts.
-            let freshness = self.check_path_modifications(RUSTC_IF_UNCHANGED_ALLOWED_PATHS);
+            let freshness = self.check_path_modifications(&rustc_if_unchanged_allowed_paths());
             self.verbose(|| {
                 eprintln!("rustc freshness: {freshness:?}");
             });
@@ -3193,7 +1559,7 @@ impl Config {
         Some(commit)
     }
 
-    fn parse_download_ci_llvm(
+    pub fn parse_download_ci_llvm(
         &self,
         download_ci_llvm: Option<StringOrBool>,
         asserts: bool,
@@ -3276,6 +1642,83 @@ impl Config {
             .clone()
     }
 
+    pub fn ci_env(&self) -> CiEnv {
+        if self.is_running_on_ci { CiEnv::GitHubActions } else { CiEnv::None }
+    }
+
+    pub fn sanitizers_enabled(&self, target: TargetSelection) -> bool {
+        self.target_config.get(&target).and_then(|t| t.sanitizers).unwrap_or(self.sanitizers)
+    }
+
+    pub fn needs_sanitizer_runtime_built(&self, target: TargetSelection) -> bool {
+        // MSVC uses the Microsoft-provided sanitizer runtime, but all other runtimes we build.
+        !target.is_msvc() && self.sanitizers_enabled(target)
+    }
+
+    pub fn profiler_path(&self, target: TargetSelection) -> Option<&str> {
+        match self.target_config.get(&target)?.profiler.as_ref()? {
+            StringOrBool::String(s) => Some(s),
+            StringOrBool::Bool(_) => None,
+        }
+    }
+
+    pub fn profiler_enabled(&self, target: TargetSelection) -> bool {
+        self.target_config
+            .get(&target)
+            .and_then(|t| t.profiler.as_ref())
+            .map(StringOrBool::is_string_or_true)
+            .unwrap_or(self.profiler)
+    }
+
+    pub fn codegen_backends(&self, target: TargetSelection) -> &[String] {
+        self.target_config
+            .get(&target)
+            .and_then(|cfg| cfg.codegen_backends.as_deref())
+            .unwrap_or(&self.rust_codegen_backends)
+    }
+
+    pub fn jemalloc(&self, target: TargetSelection) -> bool {
+        self.target_config.get(&target).and_then(|cfg| cfg.jemalloc).unwrap_or(self.jemalloc)
+    }
+
+    pub fn default_codegen_backend(&self, target: TargetSelection) -> Option<String> {
+        self.codegen_backends(target).first().cloned()
+    }
+
+    pub fn rpath_enabled(&self, target: TargetSelection) -> bool {
+        self.target_config.get(&target).and_then(|t| t.rpath).unwrap_or(self.rust_rpath)
+    }
+
+    pub fn optimized_compiler_builtins(&self, target: TargetSelection) -> bool {
+        self.target_config
+            .get(&target)
+            .and_then(|t| t.optimized_compiler_builtins)
+            .unwrap_or(self.optimized_compiler_builtins)
+    }
+
+    pub fn llvm_enabled(&self, target: TargetSelection) -> bool {
+        self.codegen_backends(target).contains(&"llvm".to_owned())
+    }
+
+    pub fn llvm_libunwind(&self, target: TargetSelection) -> LlvmLibunwind {
+        self.target_config
+            .get(&target)
+            .and_then(|t| t.llvm_libunwind)
+            .or(self.llvm_libunwind_default)
+            .unwrap_or(if target.contains("fuchsia") {
+                LlvmLibunwind::InTree
+            } else {
+                LlvmLibunwind::No
+            })
+    }
+
+    pub fn split_debuginfo(&self, target: TargetSelection) -> SplitDebuginfo {
+        self.target_config
+            .get(&target)
+            .and_then(|t| t.split_debuginfo)
+            .unwrap_or_else(|| SplitDebuginfo::default_for_platform(target))
+    }
+
     /// Checks if the given target is the same as the host target.
     pub fn is_host_target(&self, target: TargetSelection) -> bool {
         self.build == target
@@ -3312,289 +1755,17 @@ impl Config {
         }
     }
 
-    pub fn ci_env(&self) -> CiEnv {
-        if self.is_running_on_ci { CiEnv::GitHubActions } else { CiEnv::None }
-    }
-}
-
-/// Compares the current `Llvm` options against those in the CI LLVM builder and detects any incompatible options.
-/// It does this by destructuring the `Llvm` instance to make sure every `Llvm` field is covered and not missing.
-#[cfg(not(test))]
-pub(crate) fn check_incompatible_options_for_ci_llvm(
-    current_config_toml: TomlConfig,
-    ci_config_toml: TomlConfig,
-) -> Result<(), String> {
-    macro_rules! err {
-        ($current:expr, $expected:expr) => {
-            if let Some(current) = &$current {
-                if Some(current) != $expected.as_ref() {
-                    return Err(format!(
-                        "ERROR: Setting `llvm.{}` is incompatible with `llvm.download-ci-llvm`. \
-                        Current value: {:?}, Expected value(s): {}{:?}",
-                        stringify!($expected).replace("_", "-"),
-                        $current,
-                        if $expected.is_some() { "None/" } else { "" },
-                        $expected,
-                    ));
-                };
-            };
-        };
-    }
-
-    macro_rules! warn {
-        ($current:expr, $expected:expr) => {
-            if let Some(current) = &$current {
-                if Some(current) != $expected.as_ref() {
-                    println!(
-                        "WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \
-                        Current value: {:?}, Expected value(s): {}{:?}",
-                        stringify!($expected).replace("_", "-"),
-                        $current,
-                        if $expected.is_some() { "None/" } else { "" },
-                        $expected,
-                    );
-                };
-            };
-        };
-    }
-
-    let (Some(current_llvm_config), Some(ci_llvm_config)) =
-        (current_config_toml.llvm, ci_config_toml.llvm)
-    else {
-        return Ok(());
-    };
-
-    let Llvm {
-        optimize,
-        thin_lto,
-        release_debuginfo,
-        assertions: _,
-        tests: _,
-        plugins,
-        ccache: _,
-        static_libstdcpp: _,
-        libzstd,
-        ninja: _,
-        targets,
-        experimental_targets,
-        link_jobs: _,
-        link_shared: _,
-        version_suffix,
-        clang_cl,
-        cflags,
-        cxxflags,
-        ldflags,
-        use_libcxx,
-        use_linker,
-        allow_old_toolchain,
-        offload,
-        polly,
-        clang,
-        enable_warnings,
-        download_ci_llvm: _,
-        build_config,
-        enzyme,
-    } = ci_llvm_config;
-
-    err!(current_llvm_config.optimize, optimize);
-    err!(current_llvm_config.thin_lto, thin_lto);
-    err!(current_llvm_config.release_debuginfo, release_debuginfo);
-    err!(current_llvm_config.libzstd, libzstd);
-    err!(current_llvm_config.targets, targets);
-    err!(current_llvm_config.experimental_targets, experimental_targets);
-    err!(current_llvm_config.clang_cl, clang_cl);
-    err!(current_llvm_config.version_suffix, version_suffix);
-    err!(current_llvm_config.cflags, cflags);
-    err!(current_llvm_config.cxxflags, cxxflags);
-    err!(current_llvm_config.ldflags, ldflags);
-    err!(current_llvm_config.use_libcxx, use_libcxx);
-    err!(current_llvm_config.use_linker, use_linker);
-    err!(current_llvm_config.allow_old_toolchain, allow_old_toolchain);
-    err!(current_llvm_config.offload, offload);
-    err!(current_llvm_config.polly, polly);
-    err!(current_llvm_config.clang, clang);
-    err!(current_llvm_config.build_config, build_config);
-    err!(current_llvm_config.plugins, plugins);
-    err!(current_llvm_config.enzyme, enzyme);
-
-    warn!(current_llvm_config.enable_warnings, enable_warnings);
-
-    Ok(())
-}
-
-/// Compares the current Rust options against those in the CI rustc builder and detects any incompatible options.
-/// It does this by destructuring the `Rust` instance to make sure every `Rust` field is covered and not missing.
-fn check_incompatible_options_for_ci_rustc(
-    host: TargetSelection,
-    current_config_toml: TomlConfig,
-    ci_config_toml: TomlConfig,
-) -> Result<(), String> {
-    macro_rules! err {
-        ($current:expr, $expected:expr, $config_section:expr) => {
-            if let Some(current) = &$current {
-                if Some(current) != $expected.as_ref() {
-                    return Err(format!(
-                        "ERROR: Setting `{}` is incompatible with `rust.download-rustc`. \
-                        Current value: {:?}, Expected value(s): {}{:?}",
-                        format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")),
-                        $current,
-                        if $expected.is_some() { "None/" } else { "" },
-                        $expected,
-                    ));
-                };
-            };
-        };
+    pub fn exec_ctx(&self) -> &ExecutionContext {
+        &self.exec_ctx
     }
 
-    macro_rules! warn {
-        ($current:expr, $expected:expr, $config_section:expr) => {
-            if let Some(current) = &$current {
-                if Some(current) != $expected.as_ref() {
-                    println!(
-                        "WARNING: `{}` has no effect with `rust.download-rustc`. \
-                        Current value: {:?}, Expected value(s): {}{:?}",
-                        format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")),
-                        $current,
-                        if $expected.is_some() { "None/" } else { "" },
-                        $expected,
-                    );
-                };
-            };
-        };
-    }
-
-    let current_profiler = current_config_toml.build.as_ref().and_then(|b| b.profiler);
-    let profiler = ci_config_toml.build.as_ref().and_then(|b| b.profiler);
-    err!(current_profiler, profiler, "build");
-
-    let current_optimized_compiler_builtins =
-        current_config_toml.build.as_ref().and_then(|b| b.optimized_compiler_builtins);
-    let optimized_compiler_builtins =
-        ci_config_toml.build.as_ref().and_then(|b| b.optimized_compiler_builtins);
-    err!(current_optimized_compiler_builtins, optimized_compiler_builtins, "build");
-
-    // We always build the in-tree compiler on cross targets, so we only care
-    // about the host target here.
-    let host_str = host.to_string();
-    if let Some(current_cfg) = current_config_toml.target.as_ref().and_then(|c| c.get(&host_str))
-        && current_cfg.profiler.is_some()
-    {
-        let ci_target_toml = ci_config_toml.target.as_ref().and_then(|c| c.get(&host_str));
-        let ci_cfg = ci_target_toml.ok_or(format!(
-            "Target specific config for '{host_str}' is not present for CI-rustc"
-        ))?;
-
-        let profiler = &ci_cfg.profiler;
-        err!(current_cfg.profiler, profiler, "build");
-
-        let optimized_compiler_builtins = &ci_cfg.optimized_compiler_builtins;
-        err!(current_cfg.optimized_compiler_builtins, optimized_compiler_builtins, "build");
-    }
-
-    let (Some(current_rust_config), Some(ci_rust_config)) =
-        (current_config_toml.rust, ci_config_toml.rust)
-    else {
-        return Ok(());
-    };
-
-    let Rust {
-        // Following options are the CI rustc incompatible ones.
-        optimize,
-        randomize_layout,
-        debug_logging,
-        debuginfo_level_rustc,
-        llvm_tools,
-        llvm_bitcode_linker,
-        lto,
-        stack_protector,
-        strip,
-        lld_mode,
-        jemalloc,
-        rpath,
-        channel,
-        description,
-        incremental,
-        default_linker,
-        std_features,
-
-        // Rest of the options can simply be ignored.
-        debug: _,
-        codegen_units: _,
-        codegen_units_std: _,
-        rustc_debug_assertions: _,
-        std_debug_assertions: _,
-        tools_debug_assertions: _,
-        overflow_checks: _,
-        overflow_checks_std: _,
-        debuginfo_level: _,
-        debuginfo_level_std: _,
-        debuginfo_level_tools: _,
-        debuginfo_level_tests: _,
-        backtrace: _,
-        musl_root: _,
-        verbose_tests: _,
-        optimize_tests: _,
-        codegen_tests: _,
-        omit_git_hash: _,
-        dist_src: _,
-        save_toolstates: _,
-        codegen_backends: _,
-        lld: _,
-        deny_warnings: _,
-        backtrace_on_ice: _,
-        verify_llvm_ir: _,
-        thin_lto_import_instr_limit: _,
-        remap_debuginfo: _,
-        test_compare_mode: _,
-        llvm_libunwind: _,
-        control_flow_guard: _,
-        ehcont_guard: _,
-        new_symbol_mangling: _,
-        profile_generate: _,
-        profile_use: _,
-        download_rustc: _,
-        validate_mir_opts: _,
-        frame_pointers: _,
-    } = ci_rust_config;
-
-    // There are two kinds of checks for CI rustc incompatible options:
-    //    1. Checking an option that may change the compiler behaviour/output.
-    //    2. Checking an option that have no effect on the compiler behaviour/output.
-    //
-    // If the option belongs to the first category, we call `err` macro for a hard error;
-    // otherwise, we just print a warning with `warn` macro.
-
-    err!(current_rust_config.optimize, optimize, "rust");
-    err!(current_rust_config.randomize_layout, randomize_layout, "rust");
-    err!(current_rust_config.debug_logging, debug_logging, "rust");
-    err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc, "rust");
-    err!(current_rust_config.rpath, rpath, "rust");
-    err!(current_rust_config.strip, strip, "rust");
-    err!(current_rust_config.lld_mode, lld_mode, "rust");
-    err!(current_rust_config.llvm_tools, llvm_tools, "rust");
-    err!(current_rust_config.llvm_bitcode_linker, llvm_bitcode_linker, "rust");
-    err!(current_rust_config.jemalloc, jemalloc, "rust");
-    err!(current_rust_config.default_linker, default_linker, "rust");
-    err!(current_rust_config.stack_protector, stack_protector, "rust");
-    err!(current_rust_config.lto, lto, "rust");
-    err!(current_rust_config.std_features, std_features, "rust");
-
-    warn!(current_rust_config.channel, channel, "rust");
-    warn!(current_rust_config.description, description, "rust");
-    warn!(current_rust_config.incremental, incremental, "rust");
-
-    Ok(())
-}
-
-fn set<T>(field: &mut T, val: Option<T>) {
-    if let Some(v) = val {
-        *field = v;
+    pub fn git_info(&self, omit_git_hash: bool, dir: &Path) -> GitInfo {
+        GitInfo::new(omit_git_hash, dir, self)
     }
 }
 
-fn threads_from_config(v: u32) -> u32 {
-    match v {
-        0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32,
-        n => n,
+impl AsRef<ExecutionContext> for Config {
+    fn as_ref(&self) -> &ExecutionContext {
+        &self.exec_ctx
     }
 }
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index 08bd87e03a1..bc4fa73a362 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -12,7 +12,8 @@ use tracing::instrument;
 use crate::core::build_steps::perf::PerfArgs;
 use crate::core::build_steps::setup::Profile;
 use crate::core::builder::{Builder, Kind};
-use crate::core::config::{Config, TargetSelectionList, target_selection_list};
+use crate::core::config::Config;
+use crate::core::config::target_selection::{TargetSelectionList, target_selection_list};
 use crate::{Build, DocTests};
 
 #[derive(Copy, Clone, Default, Debug, ValueEnum)]
@@ -182,6 +183,11 @@ pub struct Flags {
     /// Make bootstrap to behave as it's running on the CI environment or not.
     #[arg(global = true, long, value_name = "bool")]
     pub ci: Option<bool>,
+    /// Skip checking the standard library if `rust.download-rustc` isn't available.
+    /// This is mostly for RA as building the stage1 compiler to check the library tree
+    /// on each code change might be too much for some computers.
+    #[arg(global = true, long)]
+    pub skip_std_check_if_no_download_rustc: bool,
 }
 
 impl Flags {
@@ -203,7 +209,8 @@ impl Flags {
             HelpVerboseOnly::try_parse_from(normalize_args(args))
         {
             println!("NOTE: updating submodules before printing available paths");
-            let config = Config::parse(Self::parse(&[String::from("build")]));
+            let flags = Self::parse(&[String::from("build")]);
+            let config = Config::parse(flags);
             let build = Build::new(config);
             let paths = Builder::get_help(&build, subcommand);
             if let Some(s) = paths {
diff --git a/src/bootstrap/src/core/config/mod.rs b/src/bootstrap/src/core/config/mod.rs
index 179e15e778b..285d20917e7 100644
--- a/src/bootstrap/src/core/config/mod.rs
+++ b/src/bootstrap/src/core/config/mod.rs
@@ -1,7 +1,416 @@
+//! Entry point for the `config` module.
+//!
+//! This module defines two macros:
+//!
+//! - `define_config!`: A declarative macro used instead of `#[derive(Deserialize)]` to reduce
+//!   compile time and binary size, especially for the bootstrap binary.
+//!
+//! - `check_ci_llvm!`: A compile-time assertion macro that ensures certain settings are
+//!   not enabled when `download-ci-llvm` is active.
+//!
+//! A declarative macro is used here in place of a procedural derive macro to minimize
+//! the compile time of the bootstrap process.
+//!
+//! Additionally, this module defines common types, enums, and helper functions used across
+//! various TOML configuration sections in `bootstrap.toml`.
+//!
+//! It provides shared definitions for:
+//! - Data types deserialized from TOML.
+//! - Utility enums for specific configuration options.
+//! - Helper functions for managing configuration values.
+
 #[expect(clippy::module_inception)]
 mod config;
 pub mod flags;
+pub mod target_selection;
 #[cfg(test)]
 mod tests;
+pub mod toml;
+
+use std::collections::HashSet;
+use std::path::PathBuf;
 
+use build_helper::exit;
 pub use config::*;
+use serde::{Deserialize, Deserializer};
+use serde_derive::Deserialize;
+pub use target_selection::TargetSelection;
+pub use toml::BUILDER_CONFIG_FILENAME;
+pub use toml::change_id::ChangeId;
+pub use toml::rust::LldMode;
+pub use toml::target::Target;
+
+use crate::Display;
+use crate::str::FromStr;
+
+// We are using a decl macro instead of a derive proc macro here to reduce the compile time of bootstrap.
+#[macro_export]
+macro_rules! define_config {
+    ($(#[$attr:meta])* struct $name:ident {
+        $($field:ident: Option<$field_ty:ty> = $field_key:literal,)*
+    }) => {
+        $(#[$attr])*
+        pub struct $name {
+            $(pub $field: Option<$field_ty>,)*
+        }
+
+        impl Merge for $name {
+            fn merge(
+                &mut self,
+                _parent_config_path: Option<PathBuf>,
+                _included_extensions: &mut HashSet<PathBuf>,
+                other: Self,
+                replace: ReplaceOpt
+            ) {
+                $(
+                    match replace {
+                        ReplaceOpt::IgnoreDuplicate => {
+                            if self.$field.is_none() {
+                                self.$field = other.$field;
+                            }
+                        },
+                        ReplaceOpt::Override => {
+                            if other.$field.is_some() {
+                                self.$field = other.$field;
+                            }
+                        }
+                        ReplaceOpt::ErrorOnDuplicate => {
+                            if other.$field.is_some() {
+                                if self.$field.is_some() {
+                                    if cfg!(test) {
+                                        panic!("overriding existing option")
+                                    } else {
+                                        eprintln!("overriding existing option: `{}`", stringify!($field));
+                                        exit!(2);
+                                    }
+                                } else {
+                                    self.$field = other.$field;
+                                }
+                            }
+                        }
+                    }
+                )*
+            }
+        }
+
+        // The following is a trimmed version of what serde_derive generates. All parts not relevant
+        // for toml deserialization have been removed. This reduces the binary size and improves
+        // compile time of bootstrap.
+        impl<'de> Deserialize<'de> for $name {
+            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                struct Field;
+                impl<'de> serde::de::Visitor<'de> for Field {
+                    type Value = $name;
+                    fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+                        f.write_str(concat!("struct ", stringify!($name)))
+                    }
+
+                    #[inline]
+                    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
+                    where
+                        A: serde::de::MapAccess<'de>,
+                    {
+                        $(let mut $field: Option<$field_ty> = None;)*
+                        while let Some(key) =
+                            match serde::de::MapAccess::next_key::<String>(&mut map) {
+                                Ok(val) => val,
+                                Err(err) => {
+                                    return Err(err);
+                                }
+                            }
+                        {
+                            match &*key {
+                                $($field_key => {
+                                    if $field.is_some() {
+                                        return Err(<A::Error as serde::de::Error>::duplicate_field(
+                                            $field_key,
+                                        ));
+                                    }
+                                    $field = match serde::de::MapAccess::next_value::<$field_ty>(
+                                        &mut map,
+                                    ) {
+                                        Ok(val) => Some(val),
+                                        Err(err) => {
+                                            return Err(err);
+                                        }
+                                    };
+                                })*
+                                key => {
+                                    return Err(serde::de::Error::unknown_field(key, FIELDS));
+                                }
+                            }
+                        }
+                        Ok($name { $($field),* })
+                    }
+                }
+                const FIELDS: &'static [&'static str] = &[
+                    $($field_key,)*
+                ];
+                Deserializer::deserialize_struct(
+                    deserializer,
+                    stringify!($name),
+                    FIELDS,
+                    Field,
+                )
+            }
+        }
+    }
+}
+
+#[macro_export]
+macro_rules! check_ci_llvm {
+    ($name:expr) => {
+        assert!(
+            $name.is_none(),
+            "setting {} is incompatible with download-ci-llvm.",
+            stringify!($name).replace("_", "-")
+        );
+    };
+}
+
+pub(crate) trait Merge {
+    fn merge(
+        &mut self,
+        parent_config_path: Option<PathBuf>,
+        included_extensions: &mut HashSet<PathBuf>,
+        other: Self,
+        replace: ReplaceOpt,
+    );
+}
+
+impl<T> Merge for Option<T> {
+    fn merge(
+        &mut self,
+        _parent_config_path: Option<PathBuf>,
+        _included_extensions: &mut HashSet<PathBuf>,
+        other: Self,
+        replace: ReplaceOpt,
+    ) {
+        match replace {
+            ReplaceOpt::IgnoreDuplicate => {
+                if self.is_none() {
+                    *self = other;
+                }
+            }
+            ReplaceOpt::Override => {
+                if other.is_some() {
+                    *self = other;
+                }
+            }
+            ReplaceOpt::ErrorOnDuplicate => {
+                if other.is_some() {
+                    if self.is_some() {
+                        if cfg!(test) {
+                            panic!("overriding existing option")
+                        } else {
+                            eprintln!("overriding existing option");
+                            exit!(2);
+                        }
+                    } else {
+                        *self = other;
+                    }
+                }
+            }
+        }
+    }
+}
+
+#[derive(Copy, Clone, Default, Debug, Eq, PartialEq)]
+pub enum DebuginfoLevel {
+    #[default]
+    None,
+    LineDirectivesOnly,
+    LineTablesOnly,
+    Limited,
+    Full,
+}
+
+// NOTE: can't derive(Deserialize) because the intermediate trip through toml::Value only
+// deserializes i64, and derive() only generates visit_u64
+impl<'de> Deserialize<'de> for DebuginfoLevel {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        use serde::de::Error;
+
+        Ok(match Deserialize::deserialize(deserializer)? {
+            StringOrInt::String(s) if s == "none" => DebuginfoLevel::None,
+            StringOrInt::Int(0) => DebuginfoLevel::None,
+            StringOrInt::String(s) if s == "line-directives-only" => {
+                DebuginfoLevel::LineDirectivesOnly
+            }
+            StringOrInt::String(s) if s == "line-tables-only" => DebuginfoLevel::LineTablesOnly,
+            StringOrInt::String(s) if s == "limited" => DebuginfoLevel::Limited,
+            StringOrInt::Int(1) => DebuginfoLevel::Limited,
+            StringOrInt::String(s) if s == "full" => DebuginfoLevel::Full,
+            StringOrInt::Int(2) => DebuginfoLevel::Full,
+            StringOrInt::Int(n) => {
+                let other = serde::de::Unexpected::Signed(n);
+                return Err(D::Error::invalid_value(other, &"expected 0, 1, or 2"));
+            }
+            StringOrInt::String(s) => {
+                let other = serde::de::Unexpected::Str(&s);
+                return Err(D::Error::invalid_value(
+                    other,
+                    &"expected none, line-tables-only, limited, or full",
+                ));
+            }
+        })
+    }
+}
+
+/// Suitable for passing to `-C debuginfo`
+impl Display for DebuginfoLevel {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        use DebuginfoLevel::*;
+        f.write_str(match self {
+            None => "0",
+            LineDirectivesOnly => "line-directives-only",
+            LineTablesOnly => "line-tables-only",
+            Limited => "1",
+            Full => "2",
+        })
+    }
+}
+
+#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
+#[serde(untagged)]
+pub enum StringOrBool {
+    String(String),
+    Bool(bool),
+}
+
+impl Default for StringOrBool {
+    fn default() -> StringOrBool {
+        StringOrBool::Bool(false)
+    }
+}
+
+impl StringOrBool {
+    pub fn is_string_or_true(&self) -> bool {
+        matches!(self, Self::String(_) | Self::Bool(true))
+    }
+}
+
+#[derive(Deserialize)]
+#[serde(untagged)]
+pub enum StringOrInt {
+    String(String),
+    Int(i64),
+}
+
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
+pub enum LlvmLibunwind {
+    #[default]
+    No,
+    InTree,
+    System,
+}
+
+impl FromStr for LlvmLibunwind {
+    type Err = String;
+
+    fn from_str(value: &str) -> Result<Self, Self::Err> {
+        match value {
+            "no" => Ok(Self::No),
+            "in-tree" => Ok(Self::InTree),
+            "system" => Ok(Self::System),
+            invalid => Err(format!("Invalid value '{invalid}' for rust.llvm-libunwind config.")),
+        }
+    }
+}
+
+#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub enum SplitDebuginfo {
+    Packed,
+    Unpacked,
+    #[default]
+    Off,
+}
+
+impl std::str::FromStr for SplitDebuginfo {
+    type Err = ();
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s {
+            "packed" => Ok(SplitDebuginfo::Packed),
+            "unpacked" => Ok(SplitDebuginfo::Unpacked),
+            "off" => Ok(SplitDebuginfo::Off),
+            _ => Err(()),
+        }
+    }
+}
+
+/// Describes how to handle conflicts in merging two `TomlConfig`
+#[derive(Copy, Clone, Debug)]
+pub enum ReplaceOpt {
+    /// Silently ignore a duplicated value
+    IgnoreDuplicate,
+    /// Override the current value, even if it's `Some`
+    Override,
+    /// Exit with an error on duplicate values
+    ErrorOnDuplicate,
+}
+
+#[derive(Clone, Default)]
+pub enum DryRun {
+    /// This isn't a dry run.
+    #[default]
+    Disabled,
+    /// This is a dry run enabled by bootstrap itself, so it can verify that no work is done.
+    SelfCheck,
+    /// This is a dry run enabled by the `--dry-run` flag.
+    UserSelected,
+}
+
+/// LTO mode used for compiling rustc itself.
+#[derive(Default, Clone, PartialEq, Debug)]
+pub enum RustcLto {
+    Off,
+    #[default]
+    ThinLocal,
+    Thin,
+    Fat,
+}
+
+impl std::str::FromStr for RustcLto {
+    type Err = String;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s {
+            "thin-local" => Ok(RustcLto::ThinLocal),
+            "thin" => Ok(RustcLto::Thin),
+            "fat" => Ok(RustcLto::Fat),
+            "off" => Ok(RustcLto::Off),
+            _ => Err(format!("Invalid value for rustc LTO: {s}")),
+        }
+    }
+}
+
+/// Determines how will GCC be provided.
+#[derive(Default, Clone)]
+pub enum GccCiMode {
+    /// Build GCC from the local `src/gcc` submodule.
+    #[default]
+    BuildLocally,
+    /// Try to download GCC from CI.
+    /// If it is not available on CI, it will be built locally instead.
+    DownloadFromCi,
+}
+
+pub fn set<T>(field: &mut T, val: Option<T>) {
+    if let Some(v) = val {
+        *field = v;
+    }
+}
+
+pub fn threads_from_config(v: u32) -> u32 {
+    match v {
+        0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32,
+        n => n,
+    }
+}
diff --git a/src/bootstrap/src/core/config/target_selection.rs b/src/bootstrap/src/core/config/target_selection.rs
new file mode 100644
index 00000000000..ebd3fe7a8c6
--- /dev/null
+++ b/src/bootstrap/src/core/config/target_selection.rs
@@ -0,0 +1,147 @@
+use std::fmt;
+
+use crate::core::config::SplitDebuginfo;
+use crate::utils::cache::{INTERNER, Interned};
+use crate::{Path, env};
+
+#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
+// N.B.: This type is used everywhere, and the entire codebase relies on it being Copy.
+// Making !Copy is highly nontrivial!
+pub struct TargetSelection {
+    pub triple: Interned<String>,
+    pub file: Option<Interned<String>>,
+    pub synthetic: bool,
+}
+
+/// Newtype over `Vec<TargetSelection>` so we can implement custom parsing logic
+#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub struct TargetSelectionList(pub Vec<TargetSelection>);
+
+pub fn target_selection_list(s: &str) -> Result<TargetSelectionList, String> {
+    Ok(TargetSelectionList(
+        s.split(',').filter(|s| !s.is_empty()).map(TargetSelection::from_user).collect(),
+    ))
+}
+
+impl TargetSelection {
+    pub fn from_user(selection: &str) -> Self {
+        let path = Path::new(selection);
+
+        let (triple, file) = if path.exists() {
+            let triple = path
+                .file_stem()
+                .expect("Target specification file has no file stem")
+                .to_str()
+                .expect("Target specification file stem is not UTF-8");
+
+            (triple, Some(selection))
+        } else {
+            (selection, None)
+        };
+
+        let triple = INTERNER.intern_str(triple);
+        let file = file.map(|f| INTERNER.intern_str(f));
+
+        Self { triple, file, synthetic: false }
+    }
+
+    pub fn create_synthetic(triple: &str, file: &str) -> Self {
+        Self {
+            triple: INTERNER.intern_str(triple),
+            file: Some(INTERNER.intern_str(file)),
+            synthetic: true,
+        }
+    }
+
+    pub fn rustc_target_arg(&self) -> &str {
+        self.file.as_ref().unwrap_or(&self.triple)
+    }
+
+    pub fn contains(&self, needle: &str) -> bool {
+        self.triple.contains(needle)
+    }
+
+    pub fn starts_with(&self, needle: &str) -> bool {
+        self.triple.starts_with(needle)
+    }
+
+    pub fn ends_with(&self, needle: &str) -> bool {
+        self.triple.ends_with(needle)
+    }
+
+    // See src/bootstrap/synthetic_targets.rs
+    pub fn is_synthetic(&self) -> bool {
+        self.synthetic
+    }
+
+    pub fn is_msvc(&self) -> bool {
+        self.contains("msvc")
+    }
+
+    pub fn is_windows(&self) -> bool {
+        self.contains("windows")
+    }
+
+    pub fn is_windows_gnu(&self) -> bool {
+        self.ends_with("windows-gnu")
+    }
+
+    pub fn is_cygwin(&self) -> bool {
+        self.is_windows() &&
+        // ref. https://cygwin.com/pipermail/cygwin/2022-February/250802.html
+        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)
+    }
+}
+
+impl fmt::Display for TargetSelection {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.triple)?;
+        if let Some(file) = self.file {
+            write!(f, "({file})")?;
+        }
+        Ok(())
+    }
+}
+
+impl fmt::Debug for TargetSelection {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{self}")
+    }
+}
+
+impl PartialEq<&str> for TargetSelection {
+    fn eq(&self, other: &&str) -> bool {
+        self.triple == *other
+    }
+}
+
+// Targets are often used as directory names throughout bootstrap.
+// This impl makes it more ergonomics to use them as such.
+impl AsRef<Path> for TargetSelection {
+    fn as_ref(&self) -> &Path {
+        self.triple.as_ref()
+    }
+}
+
+impl SplitDebuginfo {
+    /// Returns the default `-Csplit-debuginfo` value for the current target. See the comment for
+    /// `rust.split-debuginfo` in `bootstrap.example.toml`.
+    pub fn default_for_platform(target: TargetSelection) -> Self {
+        if target.contains("apple") {
+            SplitDebuginfo::Unpacked
+        } else if target.is_windows() {
+            SplitDebuginfo::Packed
+        } else {
+            SplitDebuginfo::Off
+        }
+    }
+}
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index 96ac8a6d52f..e660addfb2c 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -10,12 +10,14 @@ use clap::CommandFactory;
 use serde::Deserialize;
 
 use super::flags::Flags;
-use super::{ChangeIdWrapper, Config, RUSTC_IF_UNCHANGED_ALLOWED_PATHS};
+use super::toml::change_id::ChangeIdWrapper;
+use super::{Config, rustc_if_unchanged_allowed_paths};
 use crate::ChangeId;
 use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order};
 use crate::core::build_steps::llvm;
 use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS;
-use crate::core::config::{LldMode, Target, TargetSelection, TomlConfig};
+use crate::core::config::toml::TomlConfig;
+use crate::core::config::{LldMode, Target, TargetSelection};
 use crate::utils::tests::git::git_test;
 
 pub(crate) fn parse(config: &str) -> Config {
@@ -457,7 +459,7 @@ fn jobs_precedence() {
 #[test]
 fn check_rustc_if_unchanged_paths() {
     let config = parse("");
-    let normalised_allowed_paths: Vec<_> = RUSTC_IF_UNCHANGED_ALLOWED_PATHS
+    let normalised_allowed_paths: Vec<_> = rustc_if_unchanged_allowed_paths()
         .iter()
         .map(|t| {
             t.strip_prefix(":!").expect(&format!("{t} doesn't have ':!' prefix, but it should."))
diff --git a/src/bootstrap/src/core/config/toml/build.rs b/src/bootstrap/src/core/config/toml/build.rs
new file mode 100644
index 00000000000..85ded3c87d9
--- /dev/null
+++ b/src/bootstrap/src/core/config/toml/build.rs
@@ -0,0 +1,72 @@
+//! This module defines the `Build` struct, which represents the `[build]` table
+//! in the `bootstrap.toml` configuration file.
+//!
+//! The `[build]` table contains global options that influence the overall build process,
+//! such as default host and target triples, paths to tools, build directories, and
+//! various feature flags. These options apply across different stages and components
+//! unless specifically overridden by other configuration sections or command-line flags.
+
+use serde::{Deserialize, Deserializer};
+
+use crate::core::config::toml::ReplaceOpt;
+use crate::core::config::{Merge, StringOrBool};
+use crate::{HashSet, PathBuf, define_config, exit};
+
+define_config! {
+    /// TOML representation of various global build decisions.
+    #[derive(Default)]
+    struct Build {
+        build: Option<String> = "build",
+        description: Option<String> = "description",
+        host: Option<Vec<String>> = "host",
+        target: Option<Vec<String>> = "target",
+        build_dir: Option<String> = "build-dir",
+        cargo: Option<PathBuf> = "cargo",
+        rustc: Option<PathBuf> = "rustc",
+        rustfmt: Option<PathBuf> = "rustfmt",
+        cargo_clippy: Option<PathBuf> = "cargo-clippy",
+        docs: Option<bool> = "docs",
+        compiler_docs: Option<bool> = "compiler-docs",
+        library_docs_private_items: Option<bool> = "library-docs-private-items",
+        docs_minification: Option<bool> = "docs-minification",
+        submodules: Option<bool> = "submodules",
+        gdb: Option<String> = "gdb",
+        lldb: Option<String> = "lldb",
+        nodejs: Option<String> = "nodejs",
+        npm: Option<String> = "npm",
+        python: Option<String> = "python",
+        reuse: Option<String> = "reuse",
+        locked_deps: Option<bool> = "locked-deps",
+        vendor: Option<bool> = "vendor",
+        full_bootstrap: Option<bool> = "full-bootstrap",
+        bootstrap_cache_path: Option<PathBuf> = "bootstrap-cache-path",
+        extended: Option<bool> = "extended",
+        tools: Option<HashSet<String>> = "tools",
+        verbose: Option<usize> = "verbose",
+        sanitizers: Option<bool> = "sanitizers",
+        profiler: Option<bool> = "profiler",
+        cargo_native_static: Option<bool> = "cargo-native-static",
+        low_priority: Option<bool> = "low-priority",
+        configure_args: Option<Vec<String>> = "configure-args",
+        local_rebuild: Option<bool> = "local-rebuild",
+        print_step_timings: Option<bool> = "print-step-timings",
+        print_step_rusage: Option<bool> = "print-step-rusage",
+        check_stage: Option<u32> = "check-stage",
+        doc_stage: Option<u32> = "doc-stage",
+        build_stage: Option<u32> = "build-stage",
+        test_stage: Option<u32> = "test-stage",
+        install_stage: Option<u32> = "install-stage",
+        dist_stage: Option<u32> = "dist-stage",
+        bench_stage: Option<u32> = "bench-stage",
+        patch_binaries_for_nix: Option<bool> = "patch-binaries-for-nix",
+        // NOTE: only parsed by bootstrap.py, `--feature build-metrics` enables metrics unconditionally
+        metrics: Option<bool> = "metrics",
+        android_ndk: Option<PathBuf> = "android-ndk",
+        optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
+        jobs: Option<u32> = "jobs",
+        compiletest_diff_tool: Option<String> = "compiletest-diff-tool",
+        compiletest_use_stage0_libtest: Option<bool> = "compiletest-use-stage0-libtest",
+        ccache: Option<StringOrBool> = "ccache",
+        exclude: Option<Vec<PathBuf>> = "exclude",
+    }
+}
diff --git a/src/bootstrap/src/core/config/toml/change_id.rs b/src/bootstrap/src/core/config/toml/change_id.rs
new file mode 100644
index 00000000000..41dd2531d43
--- /dev/null
+++ b/src/bootstrap/src/core/config/toml/change_id.rs
@@ -0,0 +1,34 @@
+use serde::{Deserialize, Deserializer};
+use serde_derive::Deserialize;
+
+/// This enum is used for deserializing change IDs from TOML, allowing both numeric values and the string `"ignore"`.
+#[derive(Clone, Debug, PartialEq)]
+pub enum ChangeId {
+    Ignore,
+    Id(usize),
+}
+
+/// Since we use `#[serde(deny_unknown_fields)]` on `TomlConfig`, we need a wrapper type
+/// for the "change-id" field to parse it even if other fields are invalid. This ensures
+/// that if deserialization fails due to other fields, we can still provide the changelogs
+/// to allow developers to potentially find the reason for the failure in the logs..
+#[derive(Deserialize, Default)]
+pub(crate) struct ChangeIdWrapper {
+    #[serde(alias = "change-id", default, deserialize_with = "deserialize_change_id")]
+    pub(crate) inner: Option<ChangeId>,
+}
+
+fn deserialize_change_id<'de, D: Deserializer<'de>>(
+    deserializer: D,
+) -> Result<Option<ChangeId>, D::Error> {
+    let value = toml::Value::deserialize(deserializer)?;
+    Ok(match value {
+        toml::Value::String(s) if s == "ignore" => Some(ChangeId::Ignore),
+        toml::Value::Integer(i) => Some(ChangeId::Id(i as usize)),
+        _ => {
+            return Err(serde::de::Error::custom(
+                "expected \"ignore\" or an integer for change-id",
+            ));
+        }
+    })
+}
diff --git a/src/bootstrap/src/core/config/toml/dist.rs b/src/bootstrap/src/core/config/toml/dist.rs
new file mode 100644
index 00000000000..b1429ef1861
--- /dev/null
+++ b/src/bootstrap/src/core/config/toml/dist.rs
@@ -0,0 +1,52 @@
+//! This module defines the `Dist` struct, which represents the `[dist]` table
+//! in the `bootstrap.toml` configuration file.
+//!
+//! The `[dist]` table contains options related to the distribution process,
+//! including signing, uploading artifacts, source tarballs, compression settings,
+//! and inclusion of specific tools.
+
+use serde::{Deserialize, Deserializer};
+
+use crate::core::config::toml::ReplaceOpt;
+use crate::core::config::{Merge, set};
+use crate::{Config, HashSet, PathBuf, define_config, exit};
+
+define_config! {
+    struct Dist {
+        sign_folder: Option<String> = "sign-folder",
+        upload_addr: Option<String> = "upload-addr",
+        src_tarball: Option<bool> = "src-tarball",
+        compression_formats: Option<Vec<String>> = "compression-formats",
+        compression_profile: Option<String> = "compression-profile",
+        include_mingw_linker: Option<bool> = "include-mingw-linker",
+        vendor: Option<bool> = "vendor",
+    }
+}
+
+impl Config {
+    /// Applies distribution-related configuration from the `Dist` struct
+    /// to the global `Config` structure.
+    pub fn apply_dist_config(&mut self, toml_dist: Option<Dist>) {
+        if let Some(dist) = toml_dist {
+            let Dist {
+                sign_folder,
+                upload_addr,
+                src_tarball,
+                compression_formats,
+                compression_profile,
+                include_mingw_linker,
+                vendor,
+            } = dist;
+            self.dist_sign_folder = sign_folder.map(PathBuf::from);
+            self.dist_upload_addr = upload_addr;
+            self.dist_compression_formats = compression_formats;
+            set(&mut self.dist_compression_profile, compression_profile);
+            set(&mut self.rust_dist_src, src_tarball);
+            set(&mut self.dist_include_mingw_linker, include_mingw_linker);
+            self.dist_vendor = vendor.unwrap_or_else(|| {
+                // If we're building from git or tarball sources, enable it by default.
+                self.rust_info.is_managed_git_subrepository() || self.rust_info.is_from_tarball()
+            });
+        }
+    }
+}
diff --git a/src/bootstrap/src/core/config/toml/gcc.rs b/src/bootstrap/src/core/config/toml/gcc.rs
new file mode 100644
index 00000000000..bb817c2aaef
--- /dev/null
+++ b/src/bootstrap/src/core/config/toml/gcc.rs
@@ -0,0 +1,34 @@
+//! This module defines the `Gcc` struct, which represents the `[gcc]` table
+//! in the `bootstrap.toml` configuration file.
+//!
+//! The `[gcc]` table contains options specifically related to building or
+//! acquiring the GCC compiler for use within the Rust build process.
+
+use serde::{Deserialize, Deserializer};
+
+use crate::core::config::toml::ReplaceOpt;
+use crate::core::config::{GccCiMode, Merge};
+use crate::{Config, HashSet, PathBuf, define_config, exit};
+
+define_config! {
+    /// TOML representation of how the GCC build is configured.
+    struct Gcc {
+        download_ci_gcc: Option<bool> = "download-ci-gcc",
+    }
+}
+
+impl Config {
+    /// Applies GCC-related configuration from the `TomlGcc` struct to the
+    /// global `Config` structure.
+    pub fn apply_gcc_config(&mut self, toml_gcc: Option<Gcc>) {
+        if let Some(gcc) = toml_gcc {
+            self.gcc_ci_mode = match gcc.download_ci_gcc {
+                Some(value) => match value {
+                    true => GccCiMode::DownloadFromCi,
+                    false => GccCiMode::BuildLocally,
+                },
+                None => GccCiMode::default(),
+            };
+        }
+    }
+}
diff --git a/src/bootstrap/src/core/config/toml/install.rs b/src/bootstrap/src/core/config/toml/install.rs
new file mode 100644
index 00000000000..6b9ab87a0b6
--- /dev/null
+++ b/src/bootstrap/src/core/config/toml/install.rs
@@ -0,0 +1,43 @@
+//! This module defines the `Install` struct, which represents the `[install]` table
+//! in the `bootstrap.toml` configuration file.
+//!
+//! The `[install]` table contains options that specify the installation paths
+//! for various components of the Rust toolchain. These paths determine where
+//! executables, libraries, documentation, and other files will be placed
+//! during the `install` stage of the build.
+
+use serde::{Deserialize, Deserializer};
+
+use crate::core::config::toml::ReplaceOpt;
+use crate::core::config::{Merge, set};
+use crate::{Config, HashSet, PathBuf, define_config, exit};
+
+define_config! {
+    /// TOML representation of various global install decisions.
+    struct Install {
+        prefix: Option<String> = "prefix",
+        sysconfdir: Option<String> = "sysconfdir",
+        docdir: Option<String> = "docdir",
+        bindir: Option<String> = "bindir",
+        libdir: Option<String> = "libdir",
+        mandir: Option<String> = "mandir",
+        datadir: Option<String> = "datadir",
+    }
+}
+
+impl Config {
+    /// Applies installation-related configuration from the `Install` struct
+    /// to the global `Config` structure.
+    pub fn apply_install_config(&mut self, toml_install: Option<Install>) {
+        if let Some(install) = toml_install {
+            let Install { prefix, sysconfdir, docdir, bindir, libdir, mandir, datadir } = install;
+            self.prefix = prefix.map(PathBuf::from);
+            self.sysconfdir = sysconfdir.map(PathBuf::from);
+            self.datadir = datadir.map(PathBuf::from);
+            self.docdir = docdir.map(PathBuf::from);
+            set(&mut self.bindir, bindir.map(PathBuf::from));
+            self.libdir = libdir.map(PathBuf::from);
+            self.mandir = mandir.map(PathBuf::from);
+        }
+    }
+}
diff --git a/src/bootstrap/src/core/config/toml/llvm.rs b/src/bootstrap/src/core/config/toml/llvm.rs
new file mode 100644
index 00000000000..4774e202bd8
--- /dev/null
+++ b/src/bootstrap/src/core/config/toml/llvm.rs
@@ -0,0 +1,284 @@
+//! This module defines the `Llvm` struct, which represents the `[llvm]` table
+//! in the `bootstrap.toml` configuration file.
+
+use serde::{Deserialize, Deserializer};
+
+use crate::core::config::toml::{Merge, ReplaceOpt, TomlConfig};
+use crate::core::config::{StringOrBool, set};
+use crate::{Config, HashMap, HashSet, PathBuf, define_config, exit};
+
+define_config! {
+    /// TOML representation of how the LLVM build is configured.
+    struct Llvm {
+        optimize: Option<bool> = "optimize",
+        thin_lto: Option<bool> = "thin-lto",
+        release_debuginfo: Option<bool> = "release-debuginfo",
+        assertions: Option<bool> = "assertions",
+        tests: Option<bool> = "tests",
+        enzyme: Option<bool> = "enzyme",
+        plugins: Option<bool> = "plugins",
+        // FIXME: Remove this field at Q2 2025, it has been replaced by build.ccache
+        ccache: Option<StringOrBool> = "ccache",
+        static_libstdcpp: Option<bool> = "static-libstdcpp",
+        libzstd: Option<bool> = "libzstd",
+        ninja: Option<bool> = "ninja",
+        targets: Option<String> = "targets",
+        experimental_targets: Option<String> = "experimental-targets",
+        link_jobs: Option<u32> = "link-jobs",
+        link_shared: Option<bool> = "link-shared",
+        version_suffix: Option<String> = "version-suffix",
+        clang_cl: Option<String> = "clang-cl",
+        cflags: Option<String> = "cflags",
+        cxxflags: Option<String> = "cxxflags",
+        ldflags: Option<String> = "ldflags",
+        use_libcxx: Option<bool> = "use-libcxx",
+        use_linker: Option<String> = "use-linker",
+        allow_old_toolchain: Option<bool> = "allow-old-toolchain",
+        offload: Option<bool> = "offload",
+        polly: Option<bool> = "polly",
+        clang: Option<bool> = "clang",
+        enable_warnings: Option<bool> = "enable-warnings",
+        download_ci_llvm: Option<StringOrBool> = "download-ci-llvm",
+        build_config: Option<HashMap<String, String>> = "build-config",
+    }
+}
+
+/// Compares the current `Llvm` options against those in the CI LLVM builder and detects any incompatible options.
+/// It does this by destructuring the `Llvm` instance to make sure every `Llvm` field is covered and not missing.
+#[cfg(not(test))]
+pub fn check_incompatible_options_for_ci_llvm(
+    current_config_toml: TomlConfig,
+    ci_config_toml: TomlConfig,
+) -> Result<(), String> {
+    macro_rules! err {
+        ($current:expr, $expected:expr) => {
+            if let Some(current) = &$current {
+                if Some(current) != $expected.as_ref() {
+                    return Err(format!(
+                        "ERROR: Setting `llvm.{}` is incompatible with `llvm.download-ci-llvm`. \
+                        Current value: {:?}, Expected value(s): {}{:?}",
+                        stringify!($expected).replace("_", "-"),
+                        $current,
+                        if $expected.is_some() { "None/" } else { "" },
+                        $expected,
+                    ));
+                };
+            };
+        };
+    }
+
+    macro_rules! warn {
+        ($current:expr, $expected:expr) => {
+            if let Some(current) = &$current {
+                if Some(current) != $expected.as_ref() {
+                    println!(
+                        "WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \
+                        Current value: {:?}, Expected value(s): {}{:?}",
+                        stringify!($expected).replace("_", "-"),
+                        $current,
+                        if $expected.is_some() { "None/" } else { "" },
+                        $expected,
+                    );
+                };
+            };
+        };
+    }
+
+    let (Some(current_llvm_config), Some(ci_llvm_config)) =
+        (current_config_toml.llvm, ci_config_toml.llvm)
+    else {
+        return Ok(());
+    };
+
+    let Llvm {
+        optimize,
+        thin_lto,
+        release_debuginfo,
+        assertions: _,
+        tests: _,
+        plugins,
+        ccache: _,
+        static_libstdcpp: _,
+        libzstd,
+        ninja: _,
+        targets,
+        experimental_targets,
+        link_jobs: _,
+        link_shared: _,
+        version_suffix,
+        clang_cl,
+        cflags,
+        cxxflags,
+        ldflags,
+        use_libcxx,
+        use_linker,
+        allow_old_toolchain,
+        offload,
+        polly,
+        clang,
+        enable_warnings,
+        download_ci_llvm: _,
+        build_config,
+        enzyme,
+    } = ci_llvm_config;
+
+    err!(current_llvm_config.optimize, optimize);
+    err!(current_llvm_config.thin_lto, thin_lto);
+    err!(current_llvm_config.release_debuginfo, release_debuginfo);
+    err!(current_llvm_config.libzstd, libzstd);
+    err!(current_llvm_config.targets, targets);
+    err!(current_llvm_config.experimental_targets, experimental_targets);
+    err!(current_llvm_config.clang_cl, clang_cl);
+    err!(current_llvm_config.version_suffix, version_suffix);
+    err!(current_llvm_config.cflags, cflags);
+    err!(current_llvm_config.cxxflags, cxxflags);
+    err!(current_llvm_config.ldflags, ldflags);
+    err!(current_llvm_config.use_libcxx, use_libcxx);
+    err!(current_llvm_config.use_linker, use_linker);
+    err!(current_llvm_config.allow_old_toolchain, allow_old_toolchain);
+    err!(current_llvm_config.offload, offload);
+    err!(current_llvm_config.polly, polly);
+    err!(current_llvm_config.clang, clang);
+    err!(current_llvm_config.build_config, build_config);
+    err!(current_llvm_config.plugins, plugins);
+    err!(current_llvm_config.enzyme, enzyme);
+
+    warn!(current_llvm_config.enable_warnings, enable_warnings);
+
+    Ok(())
+}
+
+impl Config {
+    pub fn apply_llvm_config(
+        &mut self,
+        toml_llvm: Option<Llvm>,
+        ccache: &mut Option<StringOrBool>,
+    ) {
+        let mut llvm_tests = None;
+        let mut llvm_enzyme = None;
+        let mut llvm_offload = None;
+        let mut llvm_plugins = None;
+
+        if let Some(llvm) = toml_llvm {
+            let Llvm {
+                optimize: optimize_toml,
+                thin_lto,
+                release_debuginfo,
+                assertions: _,
+                tests,
+                enzyme,
+                plugins,
+                ccache: llvm_ccache,
+                static_libstdcpp,
+                libzstd,
+                ninja,
+                targets,
+                experimental_targets,
+                link_jobs,
+                link_shared,
+                version_suffix,
+                clang_cl,
+                cflags,
+                cxxflags,
+                ldflags,
+                use_libcxx,
+                use_linker,
+                allow_old_toolchain,
+                offload,
+                polly,
+                clang,
+                enable_warnings,
+                download_ci_llvm,
+                build_config,
+            } = llvm;
+            if llvm_ccache.is_some() {
+                eprintln!("Warning: llvm.ccache is deprecated. Use build.ccache instead.");
+            }
+
+            if ccache.is_none() {
+                *ccache = llvm_ccache;
+            }
+            set(&mut self.ninja_in_file, ninja);
+            llvm_tests = tests;
+            llvm_enzyme = enzyme;
+            llvm_offload = offload;
+            llvm_plugins = plugins;
+            set(&mut self.llvm_optimize, optimize_toml);
+            set(&mut self.llvm_thin_lto, thin_lto);
+            set(&mut self.llvm_release_debuginfo, release_debuginfo);
+            set(&mut self.llvm_static_stdcpp, static_libstdcpp);
+            set(&mut self.llvm_libzstd, libzstd);
+            if let Some(v) = link_shared {
+                self.llvm_link_shared.set(Some(v));
+            }
+            self.llvm_targets.clone_from(&targets);
+            self.llvm_experimental_targets.clone_from(&experimental_targets);
+            self.llvm_link_jobs = link_jobs;
+            self.llvm_version_suffix.clone_from(&version_suffix);
+            self.llvm_clang_cl.clone_from(&clang_cl);
+
+            self.llvm_cflags.clone_from(&cflags);
+            self.llvm_cxxflags.clone_from(&cxxflags);
+            self.llvm_ldflags.clone_from(&ldflags);
+            set(&mut self.llvm_use_libcxx, use_libcxx);
+            self.llvm_use_linker.clone_from(&use_linker);
+            self.llvm_allow_old_toolchain = allow_old_toolchain.unwrap_or(false);
+            self.llvm_offload = offload.unwrap_or(false);
+            self.llvm_polly = polly.unwrap_or(false);
+            self.llvm_clang = clang.unwrap_or(false);
+            self.llvm_enable_warnings = enable_warnings.unwrap_or(false);
+            self.llvm_build_config = build_config.clone().unwrap_or(Default::default());
+
+            self.llvm_from_ci = self.parse_download_ci_llvm(download_ci_llvm, self.llvm_assertions);
+
+            if self.llvm_from_ci {
+                let warn = |option: &str| {
+                    println!(
+                        "WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build."
+                    );
+                    println!(
+                        "HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false."
+                    );
+                };
+
+                if static_libstdcpp.is_some() {
+                    warn("static-libstdcpp");
+                }
+
+                if link_shared.is_some() {
+                    warn("link-shared");
+                }
+
+                // FIXME(#129153): instead of all the ad-hoc `download-ci-llvm` checks that follow,
+                // use the `builder-config` present in tarballs since #128822 to compare the local
+                // config to the ones used to build the LLVM artifacts on CI, and only notify users
+                // if they've chosen a different value.
+
+                if libzstd.is_some() {
+                    println!(
+                        "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \
+                        like almost all `llvm.*` options, will be ignored and set by the LLVM CI \
+                        artifacts builder config."
+                    );
+                    println!(
+                        "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false."
+                    );
+                }
+            }
+
+            if !self.llvm_from_ci && self.llvm_thin_lto && link_shared.is_none() {
+                // If we're building with ThinLTO on, by default we want to link
+                // to LLVM shared, to avoid re-doing ThinLTO (which happens in
+                // the link step) with each stage.
+                self.llvm_link_shared.set(Some(true));
+            }
+        } else {
+            self.llvm_from_ci = self.parse_download_ci_llvm(None, false);
+        }
+
+        self.llvm_tests = llvm_tests.unwrap_or(false);
+        self.llvm_enzyme = llvm_enzyme.unwrap_or(false);
+        self.llvm_offload = llvm_offload.unwrap_or(false);
+        self.llvm_plugins = llvm_plugins.unwrap_or(false);
+    }
+}
diff --git a/src/bootstrap/src/core/config/toml/mod.rs b/src/bootstrap/src/core/config/toml/mod.rs
new file mode 100644
index 00000000000..ac4e249e580
--- /dev/null
+++ b/src/bootstrap/src/core/config/toml/mod.rs
@@ -0,0 +1,184 @@
+//! This module defines the structures that directly mirror the `bootstrap.toml`
+//! file's format. These types are used for `serde` deserialization.
+//!
+//! Crucially, this module also houses the core logic for loading, parsing, and merging
+//! these raw TOML configurations from various sources (the main `bootstrap.toml`,
+//! included files, profile defaults, and command-line overrides). This processed
+//! TOML data then serves as an intermediate representation, which is further
+//! transformed and applied to the final [`Config`] struct.
+
+use serde::Deserialize;
+use serde_derive::Deserialize;
+pub mod build;
+pub mod change_id;
+pub mod dist;
+pub mod gcc;
+pub mod install;
+pub mod llvm;
+pub mod rust;
+pub mod target;
+
+use build::Build;
+use change_id::{ChangeId, ChangeIdWrapper};
+use dist::Dist;
+use gcc::Gcc;
+use install::Install;
+use llvm::Llvm;
+use rust::Rust;
+use target::TomlTarget;
+
+use crate::core::config::{Merge, ReplaceOpt};
+use crate::{Config, HashMap, HashSet, Path, PathBuf, exit, fs, t};
+
+/// Structure of the `bootstrap.toml` file that configuration is read from.
+///
+/// This structure uses `Decodable` to automatically decode a TOML configuration
+/// file into this format, and then this is traversed and written into the above
+/// `Config` structure.
+#[derive(Deserialize, Default)]
+#[serde(deny_unknown_fields, rename_all = "kebab-case")]
+pub(crate) struct TomlConfig {
+    #[serde(flatten)]
+    pub(crate) change_id: ChangeIdWrapper,
+    pub(super) build: Option<Build>,
+    pub(super) install: Option<Install>,
+    pub(super) llvm: Option<Llvm>,
+    pub(super) gcc: Option<Gcc>,
+    pub(super) rust: Option<Rust>,
+    pub(super) target: Option<HashMap<String, TomlTarget>>,
+    pub(super) dist: Option<Dist>,
+    pub(super) profile: Option<String>,
+    pub(super) include: Option<Vec<PathBuf>>,
+}
+
+impl Merge for TomlConfig {
+    fn merge(
+        &mut self,
+        parent_config_path: Option<PathBuf>,
+        included_extensions: &mut HashSet<PathBuf>,
+        TomlConfig { build, install, llvm, gcc, rust, dist, target, profile, change_id, include }: Self,
+        replace: ReplaceOpt,
+    ) {
+        fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) {
+            if let Some(new) = y {
+                if let Some(original) = x {
+                    original.merge(None, &mut Default::default(), new, replace);
+                } else {
+                    *x = Some(new);
+                }
+            }
+        }
+
+        self.change_id.inner.merge(None, &mut Default::default(), change_id.inner, replace);
+        self.profile.merge(None, &mut Default::default(), profile, replace);
+
+        do_merge(&mut self.build, build, replace);
+        do_merge(&mut self.install, install, replace);
+        do_merge(&mut self.llvm, llvm, replace);
+        do_merge(&mut self.gcc, gcc, replace);
+        do_merge(&mut self.rust, rust, replace);
+        do_merge(&mut self.dist, dist, replace);
+
+        match (self.target.as_mut(), target) {
+            (_, None) => {}
+            (None, Some(target)) => self.target = Some(target),
+            (Some(original_target), Some(new_target)) => {
+                for (triple, new) in new_target {
+                    if let Some(original) = original_target.get_mut(&triple) {
+                        original.merge(None, &mut Default::default(), new, replace);
+                    } else {
+                        original_target.insert(triple, new);
+                    }
+                }
+            }
+        }
+
+        let parent_dir = parent_config_path
+            .as_ref()
+            .and_then(|p| p.parent().map(ToOwned::to_owned))
+            .unwrap_or_default();
+
+        // `include` handled later since we ignore duplicates using `ReplaceOpt::IgnoreDuplicate` to
+        // keep the upper-level configuration to take precedence.
+        for include_path in include.clone().unwrap_or_default().iter().rev() {
+            let include_path = parent_dir.join(include_path);
+            let include_path = include_path.canonicalize().unwrap_or_else(|e| {
+                eprintln!("ERROR: Failed to canonicalize '{}' path: {e}", include_path.display());
+                exit!(2);
+            });
+
+            let included_toml = Config::get_toml_inner(&include_path).unwrap_or_else(|e| {
+                eprintln!("ERROR: Failed to parse '{}': {e}", include_path.display());
+                exit!(2);
+            });
+
+            assert!(
+                included_extensions.insert(include_path.clone()),
+                "Cyclic inclusion detected: '{}' is being included again before its previous inclusion was fully processed.",
+                include_path.display()
+            );
+
+            self.merge(
+                Some(include_path.clone()),
+                included_extensions,
+                included_toml,
+                // Ensures that parent configuration always takes precedence
+                // over child configurations.
+                ReplaceOpt::IgnoreDuplicate,
+            );
+
+            included_extensions.remove(&include_path);
+        }
+    }
+}
+
+/// This file is embedded in the overlay directory of the tarball sources. It is
+/// useful in scenarios where developers want to see how the tarball sources were
+/// generated.
+///
+/// We also use this file to compare the host's bootstrap.toml against the CI rustc builder
+/// configuration to detect any incompatible options.
+pub const BUILDER_CONFIG_FILENAME: &str = "builder-config";
+
+impl Config {
+    pub(crate) fn get_builder_toml(&self, build_name: &str) -> Result<TomlConfig, toml::de::Error> {
+        if self.dry_run() {
+            return Ok(TomlConfig::default());
+        }
+
+        let builder_config_path =
+            self.out.join(self.build.triple).join(build_name).join(BUILDER_CONFIG_FILENAME);
+        Self::get_toml(&builder_config_path)
+    }
+
+    pub(crate) fn get_toml(file: &Path) -> Result<TomlConfig, toml::de::Error> {
+        #[cfg(test)]
+        return Ok(TomlConfig::default());
+
+        #[cfg(not(test))]
+        Self::get_toml_inner(file)
+    }
+
+    pub(crate) fn get_toml_inner(file: &Path) -> Result<TomlConfig, toml::de::Error> {
+        let contents =
+            t!(fs::read_to_string(file), format!("config file {} not found", file.display()));
+        // Deserialize to Value and then TomlConfig to prevent the Deserialize impl of
+        // TomlConfig and sub types to be monomorphized 5x by toml.
+        toml::from_str(&contents)
+            .and_then(|table: toml::Value| TomlConfig::deserialize(table))
+            .inspect_err(|_| {
+                if let Ok(ChangeIdWrapper { inner: Some(ChangeId::Id(id)) }) =
+                    toml::from_str::<toml::Value>(&contents)
+                        .and_then(|table: toml::Value| ChangeIdWrapper::deserialize(table))
+                {
+                    let changes = crate::find_recent_config_change_ids(id);
+                    if !changes.is_empty() {
+                        println!(
+                            "WARNING: There have been changes to x.py since you last updated:\n{}",
+                            crate::human_readable_changes(changes)
+                        );
+                    }
+                }
+            })
+    }
+}
diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs
new file mode 100644
index 00000000000..81f95f356a5
--- /dev/null
+++ b/src/bootstrap/src/core/config/toml/rust.rs
@@ -0,0 +1,664 @@
+//! This module defines the `Rust` struct, which represents the `[rust]` table
+//! in the `bootstrap.toml` configuration file.
+
+use std::str::FromStr;
+
+use serde::{Deserialize, Deserializer};
+
+use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX;
+use crate::core::config::toml::TomlConfig;
+use crate::core::config::{
+    DebuginfoLevel, Merge, ReplaceOpt, RustcLto, StringOrBool, set, threads_from_config,
+};
+use crate::flags::Warnings;
+use crate::{BTreeSet, Config, HashSet, PathBuf, TargetSelection, define_config, exit};
+
+define_config! {
+    /// TOML representation of how the Rust build is configured.
+    struct Rust {
+        optimize: Option<RustOptimize> = "optimize",
+        debug: Option<bool> = "debug",
+        codegen_units: Option<u32> = "codegen-units",
+        codegen_units_std: Option<u32> = "codegen-units-std",
+        rustc_debug_assertions: Option<bool> = "debug-assertions",
+        randomize_layout: Option<bool> = "randomize-layout",
+        std_debug_assertions: Option<bool> = "debug-assertions-std",
+        tools_debug_assertions: Option<bool> = "debug-assertions-tools",
+        overflow_checks: Option<bool> = "overflow-checks",
+        overflow_checks_std: Option<bool> = "overflow-checks-std",
+        debug_logging: Option<bool> = "debug-logging",
+        debuginfo_level: Option<DebuginfoLevel> = "debuginfo-level",
+        debuginfo_level_rustc: Option<DebuginfoLevel> = "debuginfo-level-rustc",
+        debuginfo_level_std: Option<DebuginfoLevel> = "debuginfo-level-std",
+        debuginfo_level_tools: Option<DebuginfoLevel> = "debuginfo-level-tools",
+        debuginfo_level_tests: Option<DebuginfoLevel> = "debuginfo-level-tests",
+        backtrace: Option<bool> = "backtrace",
+        incremental: Option<bool> = "incremental",
+        default_linker: Option<String> = "default-linker",
+        channel: Option<String> = "channel",
+        // FIXME: Remove this field at Q2 2025, it has been replaced by build.description
+        description: Option<String> = "description",
+        musl_root: Option<String> = "musl-root",
+        rpath: Option<bool> = "rpath",
+        strip: Option<bool> = "strip",
+        frame_pointers: Option<bool> = "frame-pointers",
+        stack_protector: Option<String> = "stack-protector",
+        verbose_tests: Option<bool> = "verbose-tests",
+        optimize_tests: Option<bool> = "optimize-tests",
+        codegen_tests: Option<bool> = "codegen-tests",
+        omit_git_hash: Option<bool> = "omit-git-hash",
+        dist_src: Option<bool> = "dist-src",
+        save_toolstates: Option<String> = "save-toolstates",
+        codegen_backends: Option<Vec<String>> = "codegen-backends",
+        llvm_bitcode_linker: Option<bool> = "llvm-bitcode-linker",
+        lld: Option<bool> = "lld",
+        lld_mode: Option<LldMode> = "use-lld",
+        llvm_tools: Option<bool> = "llvm-tools",
+        deny_warnings: Option<bool> = "deny-warnings",
+        backtrace_on_ice: Option<bool> = "backtrace-on-ice",
+        verify_llvm_ir: Option<bool> = "verify-llvm-ir",
+        thin_lto_import_instr_limit: Option<u32> = "thin-lto-import-instr-limit",
+        remap_debuginfo: Option<bool> = "remap-debuginfo",
+        jemalloc: Option<bool> = "jemalloc",
+        test_compare_mode: Option<bool> = "test-compare-mode",
+        llvm_libunwind: Option<String> = "llvm-libunwind",
+        control_flow_guard: Option<bool> = "control-flow-guard",
+        ehcont_guard: Option<bool> = "ehcont-guard",
+        new_symbol_mangling: Option<bool> = "new-symbol-mangling",
+        profile_generate: Option<String> = "profile-generate",
+        profile_use: Option<String> = "profile-use",
+        // ignored; this is set from an env var set by bootstrap.py
+        download_rustc: Option<StringOrBool> = "download-rustc",
+        lto: Option<String> = "lto",
+        validate_mir_opts: Option<u32> = "validate-mir-opts",
+        std_features: Option<BTreeSet<String>> = "std-features",
+    }
+}
+
+/// LLD in bootstrap works like this:
+/// - Self-contained lld: use `rust-lld` from the compiler's sysroot
+/// - External: use an external `lld` binary
+///
+/// It is configured depending on the target:
+/// 1) Everything except MSVC
+/// - Self-contained: `-Clinker-flavor=gnu-lld-cc -Clink-self-contained=+linker`
+/// - External: `-Clinker-flavor=gnu-lld-cc`
+/// 2) MSVC
+/// - Self-contained: `-Clinker=<path to rust-lld>`
+/// - External: `-Clinker=lld`
+#[derive(Copy, Clone, Default, Debug, PartialEq)]
+pub enum LldMode {
+    /// Do not use LLD
+    #[default]
+    Unused,
+    /// Use `rust-lld` from the compiler's sysroot
+    SelfContained,
+    /// Use an externally provided `lld` binary.
+    /// Note that the linker name cannot be overridden, the binary has to be named `lld` and it has
+    /// to be in $PATH.
+    External,
+}
+
+impl LldMode {
+    pub fn is_used(&self) -> bool {
+        match self {
+            LldMode::SelfContained | LldMode::External => true,
+            LldMode::Unused => false,
+        }
+    }
+}
+
+impl<'de> Deserialize<'de> for LldMode {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        struct LldModeVisitor;
+
+        impl serde::de::Visitor<'_> for LldModeVisitor {
+            type Value = LldMode;
+
+            fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+                formatter.write_str("one of true, 'self-contained' or 'external'")
+            }
+
+            fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
+            where
+                E: serde::de::Error,
+            {
+                Ok(if v { LldMode::External } else { LldMode::Unused })
+            }
+
+            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+            where
+                E: serde::de::Error,
+            {
+                match v {
+                    "external" => Ok(LldMode::External),
+                    "self-contained" => Ok(LldMode::SelfContained),
+                    _ => Err(E::custom(format!("unknown mode {v}"))),
+                }
+            }
+        }
+
+        deserializer.deserialize_any(LldModeVisitor)
+    }
+}
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum RustOptimize {
+    String(String),
+    Int(u8),
+    Bool(bool),
+}
+
+impl Default for RustOptimize {
+    fn default() -> RustOptimize {
+        RustOptimize::Bool(false)
+    }
+}
+
+impl<'de> Deserialize<'de> for RustOptimize {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        deserializer.deserialize_any(OptimizeVisitor)
+    }
+}
+
+struct OptimizeVisitor;
+
+impl serde::de::Visitor<'_> for OptimizeVisitor {
+    type Value = RustOptimize;
+
+    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        formatter.write_str(r#"one of: 0, 1, 2, 3, "s", "z", true, false"#)
+    }
+
+    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+    where
+        E: serde::de::Error,
+    {
+        if matches!(value, "s" | "z") {
+            Ok(RustOptimize::String(value.to_string()))
+        } else {
+            Err(serde::de::Error::custom(format_optimize_error_msg(value)))
+        }
+    }
+
+    fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+    where
+        E: serde::de::Error,
+    {
+        if matches!(value, 0..=3) {
+            Ok(RustOptimize::Int(value as u8))
+        } else {
+            Err(serde::de::Error::custom(format_optimize_error_msg(value)))
+        }
+    }
+
+    fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
+    where
+        E: serde::de::Error,
+    {
+        Ok(RustOptimize::Bool(value))
+    }
+}
+
+fn format_optimize_error_msg(v: impl std::fmt::Display) -> String {
+    format!(
+        r#"unrecognized option for rust optimize: "{v}", expected one of 0, 1, 2, 3, "s", "z", true, false"#
+    )
+}
+
+impl RustOptimize {
+    pub(crate) fn is_release(&self) -> bool {
+        match &self {
+            RustOptimize::Bool(true) | RustOptimize::String(_) => true,
+            RustOptimize::Int(i) => *i > 0,
+            RustOptimize::Bool(false) => false,
+        }
+    }
+
+    pub(crate) fn get_opt_level(&self) -> Option<String> {
+        match &self {
+            RustOptimize::String(s) => Some(s.clone()),
+            RustOptimize::Int(i) => Some(i.to_string()),
+            RustOptimize::Bool(_) => None,
+        }
+    }
+}
+
+/// Compares the current Rust options against those in the CI rustc builder and detects any incompatible options.
+/// It does this by destructuring the `Rust` instance to make sure every `Rust` field is covered and not missing.
+pub fn check_incompatible_options_for_ci_rustc(
+    host: TargetSelection,
+    current_config_toml: TomlConfig,
+    ci_config_toml: TomlConfig,
+) -> Result<(), String> {
+    macro_rules! err {
+        ($current:expr, $expected:expr, $config_section:expr) => {
+            if let Some(current) = &$current {
+                if Some(current) != $expected.as_ref() {
+                    return Err(format!(
+                        "ERROR: Setting `{}` is incompatible with `rust.download-rustc`. \
+                        Current value: {:?}, Expected value(s): {}{:?}",
+                        format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")),
+                        $current,
+                        if $expected.is_some() { "None/" } else { "" },
+                        $expected,
+                    ));
+                };
+            };
+        };
+    }
+
+    macro_rules! warn {
+        ($current:expr, $expected:expr, $config_section:expr) => {
+            if let Some(current) = &$current {
+                if Some(current) != $expected.as_ref() {
+                    println!(
+                        "WARNING: `{}` has no effect with `rust.download-rustc`. \
+                        Current value: {:?}, Expected value(s): {}{:?}",
+                        format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")),
+                        $current,
+                        if $expected.is_some() { "None/" } else { "" },
+                        $expected,
+                    );
+                };
+            };
+        };
+    }
+
+    let current_profiler = current_config_toml.build.as_ref().and_then(|b| b.profiler);
+    let profiler = ci_config_toml.build.as_ref().and_then(|b| b.profiler);
+    err!(current_profiler, profiler, "build");
+
+    let current_optimized_compiler_builtins =
+        current_config_toml.build.as_ref().and_then(|b| b.optimized_compiler_builtins);
+    let optimized_compiler_builtins =
+        ci_config_toml.build.as_ref().and_then(|b| b.optimized_compiler_builtins);
+    err!(current_optimized_compiler_builtins, optimized_compiler_builtins, "build");
+
+    // We always build the in-tree compiler on cross targets, so we only care
+    // about the host target here.
+    let host_str = host.to_string();
+    if let Some(current_cfg) = current_config_toml.target.as_ref().and_then(|c| c.get(&host_str))
+        && current_cfg.profiler.is_some()
+    {
+        let ci_target_toml = ci_config_toml.target.as_ref().and_then(|c| c.get(&host_str));
+        let ci_cfg = ci_target_toml.ok_or(format!(
+            "Target specific config for '{host_str}' is not present for CI-rustc"
+        ))?;
+
+        let profiler = &ci_cfg.profiler;
+        err!(current_cfg.profiler, profiler, "build");
+
+        let optimized_compiler_builtins = &ci_cfg.optimized_compiler_builtins;
+        err!(current_cfg.optimized_compiler_builtins, optimized_compiler_builtins, "build");
+    }
+
+    let (Some(current_rust_config), Some(ci_rust_config)) =
+        (current_config_toml.rust, ci_config_toml.rust)
+    else {
+        return Ok(());
+    };
+
+    let Rust {
+        // Following options are the CI rustc incompatible ones.
+        optimize,
+        randomize_layout,
+        debug_logging,
+        debuginfo_level_rustc,
+        llvm_tools,
+        llvm_bitcode_linker,
+        lto,
+        stack_protector,
+        strip,
+        lld_mode,
+        jemalloc,
+        rpath,
+        channel,
+        description,
+        incremental,
+        default_linker,
+        std_features,
+
+        // Rest of the options can simply be ignored.
+        debug: _,
+        codegen_units: _,
+        codegen_units_std: _,
+        rustc_debug_assertions: _,
+        std_debug_assertions: _,
+        tools_debug_assertions: _,
+        overflow_checks: _,
+        overflow_checks_std: _,
+        debuginfo_level: _,
+        debuginfo_level_std: _,
+        debuginfo_level_tools: _,
+        debuginfo_level_tests: _,
+        backtrace: _,
+        musl_root: _,
+        verbose_tests: _,
+        optimize_tests: _,
+        codegen_tests: _,
+        omit_git_hash: _,
+        dist_src: _,
+        save_toolstates: _,
+        codegen_backends: _,
+        lld: _,
+        deny_warnings: _,
+        backtrace_on_ice: _,
+        verify_llvm_ir: _,
+        thin_lto_import_instr_limit: _,
+        remap_debuginfo: _,
+        test_compare_mode: _,
+        llvm_libunwind: _,
+        control_flow_guard: _,
+        ehcont_guard: _,
+        new_symbol_mangling: _,
+        profile_generate: _,
+        profile_use: _,
+        download_rustc: _,
+        validate_mir_opts: _,
+        frame_pointers: _,
+    } = ci_rust_config;
+
+    // There are two kinds of checks for CI rustc incompatible options:
+    //    1. Checking an option that may change the compiler behaviour/output.
+    //    2. Checking an option that have no effect on the compiler behaviour/output.
+    //
+    // If the option belongs to the first category, we call `err` macro for a hard error;
+    // otherwise, we just print a warning with `warn` macro.
+
+    err!(current_rust_config.optimize, optimize, "rust");
+    err!(current_rust_config.randomize_layout, randomize_layout, "rust");
+    err!(current_rust_config.debug_logging, debug_logging, "rust");
+    err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc, "rust");
+    err!(current_rust_config.rpath, rpath, "rust");
+    err!(current_rust_config.strip, strip, "rust");
+    err!(current_rust_config.lld_mode, lld_mode, "rust");
+    err!(current_rust_config.llvm_tools, llvm_tools, "rust");
+    err!(current_rust_config.llvm_bitcode_linker, llvm_bitcode_linker, "rust");
+    err!(current_rust_config.jemalloc, jemalloc, "rust");
+    err!(current_rust_config.default_linker, default_linker, "rust");
+    err!(current_rust_config.stack_protector, stack_protector, "rust");
+    err!(current_rust_config.lto, lto, "rust");
+    err!(current_rust_config.std_features, std_features, "rust");
+
+    warn!(current_rust_config.channel, channel, "rust");
+    warn!(current_rust_config.description, description, "rust");
+    warn!(current_rust_config.incremental, incremental, "rust");
+
+    Ok(())
+}
+
+impl Config {
+    pub fn apply_rust_config(
+        &mut self,
+        toml_rust: Option<Rust>,
+        warnings: Warnings,
+        description: &mut Option<String>,
+    ) {
+        let mut debug = None;
+        let mut rustc_debug_assertions = None;
+        let mut std_debug_assertions = None;
+        let mut tools_debug_assertions = None;
+        let mut overflow_checks = None;
+        let mut overflow_checks_std = None;
+        let mut debug_logging = None;
+        let mut debuginfo_level = None;
+        let mut debuginfo_level_rustc = None;
+        let mut debuginfo_level_std = None;
+        let mut debuginfo_level_tools = None;
+        let mut debuginfo_level_tests = None;
+        let mut optimize = None;
+        let mut lld_enabled = None;
+        let mut std_features = None;
+
+        if let Some(rust) = toml_rust {
+            let Rust {
+                optimize: optimize_toml,
+                debug: debug_toml,
+                codegen_units,
+                codegen_units_std,
+                rustc_debug_assertions: rustc_debug_assertions_toml,
+                std_debug_assertions: std_debug_assertions_toml,
+                tools_debug_assertions: tools_debug_assertions_toml,
+                overflow_checks: overflow_checks_toml,
+                overflow_checks_std: overflow_checks_std_toml,
+                debug_logging: debug_logging_toml,
+                debuginfo_level: debuginfo_level_toml,
+                debuginfo_level_rustc: debuginfo_level_rustc_toml,
+                debuginfo_level_std: debuginfo_level_std_toml,
+                debuginfo_level_tools: debuginfo_level_tools_toml,
+                debuginfo_level_tests: debuginfo_level_tests_toml,
+                backtrace,
+                incremental,
+                randomize_layout,
+                default_linker,
+                channel: _, // already handled above
+                description: rust_description,
+                musl_root,
+                rpath,
+                verbose_tests,
+                optimize_tests,
+                codegen_tests,
+                omit_git_hash: _, // already handled above
+                dist_src,
+                save_toolstates,
+                codegen_backends,
+                lld: lld_enabled_toml,
+                llvm_tools,
+                llvm_bitcode_linker,
+                deny_warnings,
+                backtrace_on_ice,
+                verify_llvm_ir,
+                thin_lto_import_instr_limit,
+                remap_debuginfo,
+                jemalloc,
+                test_compare_mode,
+                llvm_libunwind,
+                control_flow_guard,
+                ehcont_guard,
+                new_symbol_mangling,
+                profile_generate,
+                profile_use,
+                download_rustc,
+                lto,
+                validate_mir_opts,
+                frame_pointers,
+                stack_protector,
+                strip,
+                lld_mode,
+                std_features: std_features_toml,
+            } = rust;
+
+            // FIXME(#133381): alt rustc builds currently do *not* have rustc debug assertions
+            // enabled. We should not download a CI alt rustc if we need rustc to have debug
+            // assertions (e.g. for crashes test suite). This can be changed once something like
+            // [Enable debug assertions on alt
+            // builds](https://github.com/rust-lang/rust/pull/131077) lands.
+            //
+            // Note that `rust.debug = true` currently implies `rust.debug-assertions = true`!
+            //
+            // This relies also on the fact that the global default for `download-rustc` will be
+            // `false` if it's not explicitly set.
+            let debug_assertions_requested = matches!(rustc_debug_assertions_toml, Some(true))
+                || (matches!(debug_toml, Some(true))
+                    && !matches!(rustc_debug_assertions_toml, Some(false)));
+
+            if debug_assertions_requested
+                && let Some(ref opt) = download_rustc
+                && opt.is_string_or_true()
+            {
+                eprintln!(
+                    "WARN: currently no CI rustc builds have rustc debug assertions \
+                            enabled. Please either set `rust.debug-assertions` to `false` if you \
+                            want to use download CI rustc or set `rust.download-rustc` to `false`."
+                );
+            }
+
+            self.download_rustc_commit = self.download_ci_rustc_commit(
+                download_rustc,
+                debug_assertions_requested,
+                self.llvm_assertions,
+            );
+
+            debug = debug_toml;
+            rustc_debug_assertions = rustc_debug_assertions_toml;
+            std_debug_assertions = std_debug_assertions_toml;
+            tools_debug_assertions = tools_debug_assertions_toml;
+            overflow_checks = overflow_checks_toml;
+            overflow_checks_std = overflow_checks_std_toml;
+            debug_logging = debug_logging_toml;
+            debuginfo_level = debuginfo_level_toml;
+            debuginfo_level_rustc = debuginfo_level_rustc_toml;
+            debuginfo_level_std = debuginfo_level_std_toml;
+            debuginfo_level_tools = debuginfo_level_tools_toml;
+            debuginfo_level_tests = debuginfo_level_tests_toml;
+            lld_enabled = lld_enabled_toml;
+            std_features = std_features_toml;
+
+            optimize = optimize_toml;
+            self.rust_new_symbol_mangling = new_symbol_mangling;
+            set(&mut self.rust_optimize_tests, optimize_tests);
+            set(&mut self.codegen_tests, codegen_tests);
+            set(&mut self.rust_rpath, rpath);
+            set(&mut self.rust_strip, strip);
+            set(&mut self.rust_frame_pointers, frame_pointers);
+            self.rust_stack_protector = stack_protector;
+            set(&mut self.jemalloc, jemalloc);
+            set(&mut self.test_compare_mode, test_compare_mode);
+            set(&mut self.backtrace, backtrace);
+            if rust_description.is_some() {
+                eprintln!(
+                    "Warning: rust.description is deprecated. Use build.description instead."
+                );
+            }
+            if description.is_none() {
+                *description = rust_description;
+            }
+            set(&mut self.rust_dist_src, dist_src);
+            set(&mut self.verbose_tests, verbose_tests);
+            // in the case "false" is set explicitly, do not overwrite the command line args
+            if let Some(true) = incremental {
+                self.incremental = true;
+            }
+            set(&mut self.lld_mode, lld_mode);
+            set(&mut self.llvm_bitcode_linker_enabled, llvm_bitcode_linker);
+
+            self.rust_randomize_layout = randomize_layout.unwrap_or_default();
+            self.llvm_tools_enabled = llvm_tools.unwrap_or(true);
+
+            self.llvm_enzyme = self.channel == "dev" || self.channel == "nightly";
+            self.rustc_default_linker = default_linker;
+            self.musl_root = musl_root.map(PathBuf::from);
+            self.save_toolstates = save_toolstates.map(PathBuf::from);
+            set(
+                &mut self.deny_warnings,
+                match warnings {
+                    Warnings::Deny => Some(true),
+                    Warnings::Warn => Some(false),
+                    Warnings::Default => deny_warnings,
+                },
+            );
+            set(&mut self.backtrace_on_ice, backtrace_on_ice);
+            set(&mut self.rust_verify_llvm_ir, verify_llvm_ir);
+            self.rust_thin_lto_import_instr_limit = thin_lto_import_instr_limit;
+            set(&mut self.rust_remap_debuginfo, remap_debuginfo);
+            set(&mut self.control_flow_guard, control_flow_guard);
+            set(&mut self.ehcont_guard, ehcont_guard);
+            self.llvm_libunwind_default =
+                llvm_libunwind.map(|v| v.parse().expect("failed to parse rust.llvm-libunwind"));
+
+            if let Some(ref backends) = codegen_backends {
+                let available_backends = ["llvm", "cranelift", "gcc"];
+
+                self.rust_codegen_backends = backends.iter().map(|s| {
+                    if let Some(backend) = s.strip_prefix(CODEGEN_BACKEND_PREFIX) {
+                        if available_backends.contains(&backend) {
+                            panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'.");
+                        } else {
+                            println!("HELP: '{s}' for 'rust.codegen-backends' might fail. \
+                                Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
+                                In this case, it would be referred to as '{backend}'.");
+                        }
+                    }
+
+                    s.clone()
+                }).collect();
+            }
+
+            self.rust_codegen_units = codegen_units.map(threads_from_config);
+            self.rust_codegen_units_std = codegen_units_std.map(threads_from_config);
+
+            if self.rust_profile_use.is_none() {
+                self.rust_profile_use = profile_use;
+            }
+
+            if self.rust_profile_generate.is_none() {
+                self.rust_profile_generate = profile_generate;
+            }
+
+            self.rust_lto =
+                lto.as_deref().map(|value| RustcLto::from_str(value).unwrap()).unwrap_or_default();
+            self.rust_validate_mir_opts = validate_mir_opts;
+        }
+
+        self.rust_optimize = optimize.unwrap_or(RustOptimize::Bool(true));
+
+        // We make `x86_64-unknown-linux-gnu` use the self-contained linker by default, so we will
+        // build our internal lld and use it as the default linker, by setting the `rust.lld` config
+        // to true by default:
+        // - on the `x86_64-unknown-linux-gnu` target
+        // - on the `dev` and `nightly` channels
+        // - when building our in-tree llvm (i.e. the target has not set an `llvm-config`), so that
+        //   we're also able to build the corresponding lld
+        // - or when using an external llvm that's downloaded from CI, which also contains our prebuilt
+        //   lld
+        // - otherwise, we'd be using an external llvm, and lld would not necessarily available and
+        //   thus, disabled
+        // - similarly, lld will not be built nor used by default when explicitly asked not to, e.g.
+        //   when the config sets `rust.lld = false`
+        if self.build.triple == "x86_64-unknown-linux-gnu"
+            && self.hosts == [self.build]
+            && (self.channel == "dev" || self.channel == "nightly")
+        {
+            let no_llvm_config = self
+                .target_config
+                .get(&self.build)
+                .is_some_and(|target_config| target_config.llvm_config.is_none());
+            let enable_lld = self.llvm_from_ci || no_llvm_config;
+            // Prefer the config setting in case an explicit opt-out is needed.
+            self.lld_enabled = lld_enabled.unwrap_or(enable_lld);
+        } else {
+            set(&mut self.lld_enabled, lld_enabled);
+        }
+
+        let default_std_features = BTreeSet::from([String::from("panic-unwind")]);
+        self.rust_std_features = std_features.unwrap_or(default_std_features);
+
+        let default = debug == Some(true);
+        self.rustc_debug_assertions = rustc_debug_assertions.unwrap_or(default);
+        self.std_debug_assertions = std_debug_assertions.unwrap_or(self.rustc_debug_assertions);
+        self.tools_debug_assertions = tools_debug_assertions.unwrap_or(self.rustc_debug_assertions);
+        self.rust_overflow_checks = overflow_checks.unwrap_or(default);
+        self.rust_overflow_checks_std = overflow_checks_std.unwrap_or(self.rust_overflow_checks);
+
+        self.rust_debug_logging = debug_logging.unwrap_or(self.rustc_debug_assertions);
+
+        let with_defaults = |debuginfo_level_specific: Option<_>| {
+            debuginfo_level_specific.or(debuginfo_level).unwrap_or(if debug == Some(true) {
+                DebuginfoLevel::Limited
+            } else {
+                DebuginfoLevel::None
+            })
+        };
+        self.rust_debuginfo_level_rustc = with_defaults(debuginfo_level_rustc);
+        self.rust_debuginfo_level_std = with_defaults(debuginfo_level_std);
+        self.rust_debuginfo_level_tools = with_defaults(debuginfo_level_tools);
+        self.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(DebuginfoLevel::None);
+    }
+}
diff --git a/src/bootstrap/src/core/config/toml/target.rs b/src/bootstrap/src/core/config/toml/target.rs
new file mode 100644
index 00000000000..7f074d1b25e
--- /dev/null
+++ b/src/bootstrap/src/core/config/toml/target.rs
@@ -0,0 +1,174 @@
+//! This module defines the structures and logic for handling target-specific configuration
+//! within the `bootstrap.toml` file. This allows you to customize build settings, tools,
+//! and flags for individual compilation targets.
+//!
+//! It includes:
+//!
+//! * [`TomlTarget`]: This struct directly mirrors the `[target.<triple>]` sections in your
+//!   `bootstrap.toml`. It's used for deserializing raw TOML data for a specific target.
+//! * [`Target`]: This struct represents the processed and validated configuration for a
+//!   build target, which is is stored in the main [`Config`] structure.
+//! * [`Config::apply_target_config`]: This method processes the `TomlTarget` data and
+//!   applies it to the global [`Config`], ensuring proper path resolution, validation,
+//!   and integration with other build settings.
+
+use std::collections::HashMap;
+
+use serde::{Deserialize, Deserializer};
+
+use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX;
+use crate::core::config::{LlvmLibunwind, Merge, ReplaceOpt, SplitDebuginfo, StringOrBool};
+use crate::{Config, HashSet, PathBuf, TargetSelection, define_config, exit};
+
+define_config! {
+    /// TOML representation of how each build target is configured.
+    struct TomlTarget {
+        cc: Option<String> = "cc",
+        cxx: Option<String> = "cxx",
+        ar: Option<String> = "ar",
+        ranlib: Option<String> = "ranlib",
+        default_linker: Option<PathBuf> = "default-linker",
+        linker: Option<String> = "linker",
+        split_debuginfo: Option<String> = "split-debuginfo",
+        llvm_config: Option<String> = "llvm-config",
+        llvm_has_rust_patches: Option<bool> = "llvm-has-rust-patches",
+        llvm_filecheck: Option<String> = "llvm-filecheck",
+        llvm_libunwind: Option<String> = "llvm-libunwind",
+        sanitizers: Option<bool> = "sanitizers",
+        profiler: Option<StringOrBool> = "profiler",
+        rpath: Option<bool> = "rpath",
+        crt_static: Option<bool> = "crt-static",
+        musl_root: Option<String> = "musl-root",
+        musl_libdir: Option<String> = "musl-libdir",
+        wasi_root: Option<String> = "wasi-root",
+        qemu_rootfs: Option<String> = "qemu-rootfs",
+        no_std: Option<bool> = "no-std",
+        codegen_backends: Option<Vec<String>> = "codegen-backends",
+        runner: Option<String> = "runner",
+        optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
+        jemalloc: Option<bool> = "jemalloc",
+    }
+}
+
+/// Per-target configuration stored in the global configuration structure.
+#[derive(Debug, Default, Clone, PartialEq, Eq)]
+pub struct Target {
+    /// Some(path to llvm-config) if using an external LLVM.
+    pub llvm_config: Option<PathBuf>,
+    pub llvm_has_rust_patches: Option<bool>,
+    /// Some(path to FileCheck) if one was specified.
+    pub llvm_filecheck: Option<PathBuf>,
+    pub llvm_libunwind: Option<LlvmLibunwind>,
+    pub cc: Option<PathBuf>,
+    pub cxx: Option<PathBuf>,
+    pub ar: Option<PathBuf>,
+    pub ranlib: Option<PathBuf>,
+    pub default_linker: Option<PathBuf>,
+    pub linker: Option<PathBuf>,
+    pub split_debuginfo: Option<SplitDebuginfo>,
+    pub sanitizers: Option<bool>,
+    pub profiler: Option<StringOrBool>,
+    pub rpath: Option<bool>,
+    pub crt_static: Option<bool>,
+    pub musl_root: Option<PathBuf>,
+    pub musl_libdir: Option<PathBuf>,
+    pub wasi_root: Option<PathBuf>,
+    pub qemu_rootfs: Option<PathBuf>,
+    pub runner: Option<String>,
+    pub no_std: bool,
+    pub codegen_backends: Option<Vec<String>>,
+    pub optimized_compiler_builtins: Option<bool>,
+    pub jemalloc: Option<bool>,
+}
+
+impl Target {
+    pub fn from_triple(triple: &str) -> Self {
+        let mut target: Self = Default::default();
+        if triple.contains("-none") || triple.contains("nvptx") || triple.contains("switch") {
+            target.no_std = true;
+        }
+        if triple.contains("emscripten") {
+            target.runner = Some("node".into());
+        }
+        target
+    }
+}
+
+impl Config {
+    pub fn apply_target_config(&mut self, toml_target: Option<HashMap<String, TomlTarget>>) {
+        if let Some(t) = toml_target {
+            for (triple, cfg) in t {
+                let mut target = Target::from_triple(&triple);
+
+                if let Some(ref s) = cfg.llvm_config {
+                    if self.download_rustc_commit.is_some() && triple == *self.build.triple {
+                        panic!(
+                            "setting llvm_config for the host is incompatible with download-rustc"
+                        );
+                    }
+                    target.llvm_config = Some(self.src.join(s));
+                }
+                if let Some(patches) = cfg.llvm_has_rust_patches {
+                    assert!(
+                        self.submodules == Some(false) || cfg.llvm_config.is_some(),
+                        "use of `llvm-has-rust-patches` is restricted to cases where either submodules are disabled or llvm-config been provided"
+                    );
+                    target.llvm_has_rust_patches = Some(patches);
+                }
+                if let Some(ref s) = cfg.llvm_filecheck {
+                    target.llvm_filecheck = Some(self.src.join(s));
+                }
+                target.llvm_libunwind = cfg.llvm_libunwind.as_ref().map(|v| {
+                    v.parse().unwrap_or_else(|_| {
+                        panic!("failed to parse target.{triple}.llvm-libunwind")
+                    })
+                });
+                if let Some(s) = cfg.no_std {
+                    target.no_std = s;
+                }
+                target.cc = cfg.cc.map(PathBuf::from);
+                target.cxx = cfg.cxx.map(PathBuf::from);
+                target.ar = cfg.ar.map(PathBuf::from);
+                target.ranlib = cfg.ranlib.map(PathBuf::from);
+                target.linker = cfg.linker.map(PathBuf::from);
+                target.crt_static = cfg.crt_static;
+                target.musl_root = cfg.musl_root.map(PathBuf::from);
+                target.musl_libdir = cfg.musl_libdir.map(PathBuf::from);
+                target.wasi_root = cfg.wasi_root.map(PathBuf::from);
+                target.qemu_rootfs = cfg.qemu_rootfs.map(PathBuf::from);
+                target.runner = cfg.runner;
+                target.sanitizers = cfg.sanitizers;
+                target.profiler = cfg.profiler;
+                target.rpath = cfg.rpath;
+                target.optimized_compiler_builtins = cfg.optimized_compiler_builtins;
+                target.jemalloc = cfg.jemalloc;
+
+                if let Some(ref backends) = cfg.codegen_backends {
+                    let available_backends = ["llvm", "cranelift", "gcc"];
+
+                    target.codegen_backends = Some(backends.iter().map(|s| {
+                        if let Some(backend) = s.strip_prefix(CODEGEN_BACKEND_PREFIX) {
+                            if available_backends.contains(&backend) {
+                                panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'.");
+                            } else {
+                                println!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \
+                                    Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
+                                    In this case, it would be referred to as '{backend}'.");
+                            }
+                        }
+
+                        s.clone()
+                    }).collect());
+                }
+
+                target.split_debuginfo = cfg.split_debuginfo.as_ref().map(|v| {
+                    v.parse().unwrap_or_else(|_| {
+                        panic!("invalid value for target.{triple}.split-debuginfo")
+                    })
+                });
+
+                self.target_config.insert(TargetSelection::from_user(&triple), target);
+            }
+        }
+    }
+}
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index d942334d1c3..f349b9a87ed 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -3,7 +3,6 @@ use std::ffi::OsString;
 use std::fs::{self, File};
 use std::io::{BufRead, BufReader, BufWriter, ErrorKind, Write};
 use std::path::{Path, PathBuf};
-use std::process::{Command, Stdio};
 use std::sync::OnceLock;
 
 use xz2::bufread::XzDecoder;
@@ -16,14 +15,7 @@ use crate::{Config, t};
 
 static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock<bool> = OnceLock::new();
 
-/// `Config::try_run` wrapper for this module to avoid warnings on `try_run`, since we don't have access to a `builder` yet.
-fn try_run(config: &Config, cmd: &mut Command) -> Result<(), ()> {
-    #[expect(deprecated)]
-    config.try_run(cmd)
-}
-
-fn extract_curl_version(out: &[u8]) -> semver::Version {
-    let out = String::from_utf8_lossy(out);
+fn extract_curl_version(out: String) -> semver::Version {
     // The output should look like this: "curl <major>.<minor>.<patch> ..."
     out.lines()
         .next()
@@ -32,18 +24,21 @@ fn extract_curl_version(out: &[u8]) -> semver::Version {
         .unwrap_or(semver::Version::new(1, 0, 0))
 }
 
-fn curl_version() -> semver::Version {
-    let mut curl = Command::new("curl");
+fn curl_version(config: &Config) -> semver::Version {
+    let mut curl = command("curl");
     curl.arg("-V");
-    let Ok(out) = curl.output() else { return semver::Version::new(1, 0, 0) };
-    let out = out.stdout;
-    extract_curl_version(&out)
+    let curl = curl.run_capture_stdout(config);
+    if curl.is_failure() {
+        return semver::Version::new(1, 0, 0);
+    }
+    let output = curl.stdout();
+    extract_curl_version(output)
 }
 
 /// Generic helpers that are useful anywhere in bootstrap.
 impl Config {
     pub fn is_verbose(&self) -> bool {
-        self.verbose > 0
+        self.exec_ctx.is_verbose()
     }
 
     pub(crate) fn create<P: AsRef<Path>>(&self, path: P, s: &str) {
@@ -85,20 +80,14 @@ impl Config {
     /// on NixOS
     fn should_fix_bins_and_dylibs(&self) -> bool {
         let val = *SHOULD_FIX_BINS_AND_DYLIBS.get_or_init(|| {
-            match Command::new("uname").arg("-s").stderr(Stdio::inherit()).output() {
-                Err(_) => return false,
-                Ok(output) if !output.status.success() => return false,
-                Ok(output) => {
-                    let mut os_name = output.stdout;
-                    if os_name.last() == Some(&b'\n') {
-                        os_name.pop();
-                    }
-                    if os_name != b"Linux" {
-                        return false;
-                    }
-                }
+            let uname = command("uname").allow_failure().arg("-s").run_capture_stdout(self);
+            if uname.is_failure() {
+                return false;
+            }
+            let output = uname.stdout();
+            if !output.starts_with("Linux") {
+                return false;
             }
-
             // If the user has asked binaries to be patched for Nix, then
             // don't check for NixOS or `/lib`.
             // NOTE: this intentionally comes after the Linux check:
@@ -173,23 +162,18 @@ impl Config {
                 ];
             }
             ";
-            nix_build_succeeded = try_run(
-                self,
-                Command::new("nix-build").args([
-                    Path::new("-E"),
-                    Path::new(NIX_EXPR),
-                    Path::new("-o"),
-                    &nix_deps_dir,
-                ]),
-            )
-            .is_ok();
+            nix_build_succeeded = command("nix-build")
+                .allow_failure()
+                .args([Path::new("-E"), Path::new(NIX_EXPR), Path::new("-o"), &nix_deps_dir])
+                .run_capture_stdout(self)
+                .is_success();
             nix_deps_dir
         });
         if !nix_build_succeeded {
             return;
         }
 
-        let mut patchelf = Command::new(nix_deps_dir.join("bin/patchelf"));
+        let mut patchelf = command(nix_deps_dir.join("bin/patchelf"));
         patchelf.args(&[
             OsString::from("--add-rpath"),
             OsString::from(t!(fs::canonicalize(nix_deps_dir)).join("lib")),
@@ -200,8 +184,8 @@ impl Config {
             let dynamic_linker = t!(fs::read_to_string(dynamic_linker_path));
             patchelf.args(["--set-interpreter", dynamic_linker.trim_end()]);
         }
-
-        let _ = try_run(self, patchelf.arg(fname));
+        patchelf.arg(fname);
+        let _ = patchelf.allow_failure().run_capture_stdout(self);
     }
 
     fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) {
@@ -267,7 +251,7 @@ impl Config {
             curl.arg("--progress-bar");
         }
         // --retry-all-errors was added in 7.71.0, don't use it if curl is old.
-        if curl_version() >= semver::Version::new(7, 71, 0) {
+        if curl_version(self) >= semver::Version::new(7, 71, 0) {
             curl.arg("--retry-all-errors");
         }
         curl.arg(url);
@@ -275,7 +259,7 @@ impl Config {
             if self.build.contains("windows-msvc") {
                 eprintln!("Fallback to PowerShell");
                 for _ in 0..3 {
-                    if try_run(self, Command::new("PowerShell.exe").args([
+                    let powershell = command("PowerShell.exe").allow_failure().args([
                         "/nologo",
                         "-Command",
                         "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;",
@@ -283,9 +267,12 @@ impl Config {
                             "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
                             url, tempfile.to_str().expect("invalid UTF-8 not supported with powershell downloads"),
                         ),
-                    ])).is_err() {
+                    ]).run_capture_stdout(self);
+
+                    if powershell.is_failure() {
                         return;
                     }
+
                     eprintln!("\nspurious failure, trying again");
                 }
             }
@@ -727,7 +714,7 @@ download-rustc = false
         use build_helper::git::PathFreshness;
 
         use crate::core::build_steps::llvm::detect_llvm_freshness;
-        use crate::core::config::check_incompatible_options_for_ci_llvm;
+        use crate::core::config::toml::llvm::check_incompatible_options_for_ci_llvm;
 
         if !self.llvm_from_ci {
             return;
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index af4ec679d08..b7bbd294f0e 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -34,6 +34,8 @@ pub struct Finder {
 // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
 const STAGE0_MISSING_TARGETS: &[&str] = &[
     // just a dummy comment so the list doesn't get onelined
+    "loongarch32-unknown-none",
+    "loongarch32-unknown-none-softfloat",
 ];
 
 /// Minimum version threshold for libstdc++ required when using prebuilt LLVM
@@ -362,7 +364,7 @@ than building it.
             // Cygwin. The Cygwin build does not have generators for Visual
             // Studio, so detect that here and error.
             let out =
-                command("cmake").arg("--help").run_always().run_capture_stdout(build).stdout();
+                command("cmake").arg("--help").run_always().run_capture_stdout(&build).stdout();
             if !out.contains("Visual Studio") {
                 panic!(
                     "
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index cfb968f79ba..88d5d026820 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -32,6 +32,7 @@ use cc::Tool;
 use termcolor::{ColorChoice, StandardStream, WriteColor};
 use utils::build_stamp::BuildStamp;
 use utils::channel::GitInfo;
+use utils::execution_context::ExecutionContext;
 
 use crate::core::builder;
 use crate::core::builder::Kind;
@@ -81,7 +82,10 @@ const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"];
 /// (Mode restriction, config name, config values (if any))
 #[expect(clippy::type_complexity)] // It's fine for hard-coded list and type is explained above.
 const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
-    (None, "bootstrap", None),
+    (Some(Mode::Rustc), "bootstrap", None),
+    (Some(Mode::Codegen), "bootstrap", None),
+    (Some(Mode::ToolRustc), "bootstrap", None),
+    (Some(Mode::ToolStd), "bootstrap", None),
     (Some(Mode::Rustc), "llvm_enzyme", None),
     (Some(Mode::Codegen), "llvm_enzyme", None),
     (Some(Mode::ToolRustc), "llvm_enzyme", None),
@@ -195,7 +199,6 @@ pub struct Build {
     crates: HashMap<String, Crate>,
     crate_paths: HashMap<PathBuf, String>,
     is_sudo: bool,
-    delayed_failures: RefCell<Vec<String>>,
     prerelease_version: Cell<Option<u32>>,
 
     #[cfg(feature = "build-metrics")]
@@ -272,6 +275,16 @@ impl Mode {
     }
 }
 
+/// When `rust.rust_remap_debuginfo` is requested, the compiler needs to know how to
+/// opportunistically unremap compiler vs non-compiler sources. We use two schemes,
+/// [`RemapScheme::Compiler`] and [`RemapScheme::NonCompiler`].
+pub enum RemapScheme {
+    /// The [`RemapScheme::Compiler`] scheme will remap to `/rustc-dev/{hash}`.
+    Compiler,
+    /// The [`RemapScheme::NonCompiler`] scheme will remap to `/rustc/{hash}`.
+    NonCompiler,
+}
+
 #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub enum CLang {
     C,
@@ -456,7 +469,6 @@ impl Build {
             crates: HashMap::new(),
             crate_paths: HashMap::new(),
             is_sudo,
-            delayed_failures: RefCell::new(Vec::new()),
             prerelease_version: Cell::new(None),
 
             #[cfg(feature = "build-metrics")]
@@ -616,7 +628,7 @@ impl Build {
             return;
         }
 
-        if GitInfo::new(false, Path::new(submodule)).is_managed_git_subrepository() {
+        if config.git_info(false, Path::new(submodule)).is_managed_git_subrepository() {
             config.update_submodule(submodule);
         }
     }
@@ -671,7 +683,7 @@ impl Build {
                 #[cfg(feature = "tracing")]
                 let _sanity_check_span =
                     span!(tracing::Level::DEBUG, "(1) executing dry-run sanity-check").entered();
-                self.config.dry_run = DryRun::SelfCheck;
+                self.config.set_dry_run(DryRun::SelfCheck);
                 let builder = builder::Builder::new(self);
                 builder.execute_cli();
             }
@@ -681,7 +693,7 @@ impl Build {
                 #[cfg(feature = "tracing")]
                 let _actual_run_span =
                     span!(tracing::Level::DEBUG, "(2) executing actual run").entered();
-                self.config.dry_run = DryRun::Disabled;
+                self.config.set_dry_run(DryRun::Disabled);
                 let builder = builder::Builder::new(self);
                 builder.execute_cli();
             }
@@ -697,14 +709,7 @@ impl Build {
         debug!("checking for postponed test failures from `test  --no-fail-fast`");
 
         // Check for postponed failures from `test --no-fail-fast`.
-        let failures = self.delayed_failures.borrow();
-        if !failures.is_empty() {
-            eprintln!("\n{} command(s) did not execute successfully:\n", failures.len());
-            for failure in failures.iter() {
-                eprintln!("  - {failure}\n");
-            }
-            exit!(1);
-        }
+        self.config.exec_ctx().report_failures_and_exit();
 
         #[cfg(feature = "build-metrics")]
         self.metrics.persist(self);
@@ -940,133 +945,6 @@ impl Build {
         })
     }
 
-    /// Execute a command and return its output.
-    /// Note: Ideally, you should use one of the BootstrapCommand::run* functions to
-    /// execute commands. They internally call this method.
-    #[track_caller]
-    fn run(
-        &self,
-        command: &mut BootstrapCommand,
-        stdout: OutputMode,
-        stderr: OutputMode,
-    ) -> CommandOutput {
-        command.mark_as_executed();
-        if self.config.dry_run() && !command.run_always {
-            return CommandOutput::default();
-        }
-
-        #[cfg(feature = "tracing")]
-        let _run_span = trace_cmd!(command);
-
-        let created_at = command.get_created_location();
-        let executed_at = std::panic::Location::caller();
-
-        self.verbose(|| {
-            println!("running: {command:?} (created at {created_at}, executed at {executed_at})")
-        });
-
-        let cmd = command.as_command_mut();
-        cmd.stdout(stdout.stdio());
-        cmd.stderr(stderr.stdio());
-
-        let output = cmd.output();
-
-        use std::fmt::Write;
-
-        let mut message = String::new();
-        let output: CommandOutput = match output {
-            // Command has succeeded
-            Ok(output) if output.status.success() => {
-                CommandOutput::from_output(output, stdout, stderr)
-            }
-            // Command has started, but then it failed
-            Ok(output) => {
-                writeln!(
-                    message,
-                    r#"
-Command {command:?} did not execute successfully.
-Expected success, got {}
-Created at: {created_at}
-Executed at: {executed_at}"#,
-                    output.status,
-                )
-                .unwrap();
-
-                let output: CommandOutput = CommandOutput::from_output(output, stdout, stderr);
-
-                // If the output mode is OutputMode::Capture, we can now print the output.
-                // If it is OutputMode::Print, then the output has already been printed to
-                // stdout/stderr, and we thus don't have anything captured to print anyway.
-                if stdout.captures() {
-                    writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap();
-                }
-                if stderr.captures() {
-                    writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap();
-                }
-                output
-            }
-            // The command did not even start
-            Err(e) => {
-                writeln!(
-                    message,
-                    "\n\nCommand {command:?} did not execute successfully.\
-            \nIt was not possible to execute the command: {e:?}"
-                )
-                .unwrap();
-                CommandOutput::did_not_start(stdout, stderr)
-            }
-        };
-
-        let fail = |message: &str, output: CommandOutput| -> ! {
-            if self.is_verbose() {
-                println!("{message}");
-            } else {
-                let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present());
-                // If the command captures output, the user would not see any indication that
-                // it has failed. In this case, print a more verbose error, since to provide more
-                // context.
-                if stdout.is_some() || stderr.is_some() {
-                    if let Some(stdout) =
-                        output.stdout_if_present().take_if(|s| !s.trim().is_empty())
-                    {
-                        println!("STDOUT:\n{stdout}\n");
-                    }
-                    if let Some(stderr) =
-                        output.stderr_if_present().take_if(|s| !s.trim().is_empty())
-                    {
-                        println!("STDERR:\n{stderr}\n");
-                    }
-                    println!("Command {command:?} has failed. Rerun with -v to see more details.");
-                } else {
-                    println!("Command has failed. Rerun with -v to see more details.");
-                }
-            }
-            exit!(1);
-        };
-
-        if !output.is_success() {
-            match command.failure_behavior {
-                BehaviorOnFailure::DelayFail => {
-                    if self.fail_fast {
-                        fail(&message, output);
-                    }
-
-                    let mut failures = self.delayed_failures.borrow_mut();
-                    failures.push(message);
-                }
-                BehaviorOnFailure::Exit => {
-                    fail(&message, output);
-                }
-                BehaviorOnFailure::Ignore => {
-                    // If failures are allowed, either the error has been printed already
-                    // (OutputMode::Print) or the user used a capture output mode and wants to
-                    // handle the error output on their own.
-                }
-            }
-        }
-        output
-    }
-
     /// Check if verbosity is greater than the `level`
     pub fn is_verbose_than(&self, level: usize) -> bool {
         self.verbosity > level
@@ -1080,7 +958,7 @@ Executed at: {executed_at}"#,
     }
 
     fn info(&self, msg: &str) {
-        match self.config.dry_run {
+        match self.config.get_dry_run() {
             DryRun::SelfCheck => (),
             DryRun::Disabled | DryRun::UserSelected => {
                 println!("{msg}");
@@ -1203,7 +1081,7 @@ Executed at: {executed_at}"#,
 
     #[track_caller]
     fn group(&self, msg: &str) -> Option<gha::Group> {
-        match self.config.dry_run {
+        match self.config.get_dry_run() {
             DryRun::SelfCheck => None,
             DryRun::Disabled | DryRun::UserSelected => Some(gha::group(msg)),
         }
@@ -1217,7 +1095,7 @@ Executed at: {executed_at}"#,
         })
     }
 
-    fn debuginfo_map_to(&self, which: GitRepo) -> Option<String> {
+    fn debuginfo_map_to(&self, which: GitRepo, remap_scheme: RemapScheme) -> Option<String> {
         if !self.config.rust_remap_debuginfo {
             return None;
         }
@@ -1225,7 +1103,24 @@ Executed at: {executed_at}"#,
         match which {
             GitRepo::Rustc => {
                 let sha = self.rust_sha().unwrap_or(&self.version);
-                Some(format!("/rustc/{sha}"))
+
+                match remap_scheme {
+                    RemapScheme::Compiler => {
+                        // For compiler sources, remap via `/rustc-dev/{sha}` to allow
+                        // distinguishing between compiler sources vs library sources, since
+                        // `rustc-dev` dist component places them under
+                        // `$sysroot/lib/rustlib/rustc-src/rust` as opposed to `rust-src`'s
+                        // `$sysroot/lib/rustlib/src/rust`.
+                        //
+                        // Keep this scheme in sync with `rustc_metadata::rmeta::decoder`'s
+                        // `try_to_translate_virtual_to_real`.
+                        Some(format!("/rustc-dev/{sha}"))
+                    }
+                    RemapScheme::NonCompiler => {
+                        // For non-compiler sources, use `/rustc/{sha}` remapping scheme.
+                        Some(format!("/rustc/{sha}"))
+                    }
+                }
             }
             GitRepo::Llvm => Some(String::from("/rustc/llvm")),
         }
@@ -1292,7 +1187,7 @@ Executed at: {executed_at}"#,
             base.push("-fno-omit-frame-pointer".into());
         }
 
-        if let Some(map_to) = self.debuginfo_map_to(which) {
+        if let Some(map_to) = self.debuginfo_map_to(which, RemapScheme::NonCompiler) {
             let map = format!("{}={}", self.src.display(), map_to);
             let cc = self.cc(target);
             if cc.ends_with("clang") || cc.ends_with("gcc") {
@@ -1795,11 +1690,12 @@ Executed at: {executed_at}"#,
             let now = t!(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH));
             let _ = fs::rename(dst, format!("{}-{}", dst.display(), now.as_nanos()));
         }
-        let metadata = t!(src.symlink_metadata(), format!("src = {}", src.display()));
+        let mut metadata = t!(src.symlink_metadata(), format!("src = {}", src.display()));
         let mut src = src.to_path_buf();
         if metadata.file_type().is_symlink() {
             if dereference_symlinks {
                 src = t!(fs::canonicalize(src));
+                metadata = t!(fs::metadata(&src), format!("target = {}", src.display()));
             } else {
                 let link = t!(fs::read_link(src));
                 t!(self.symlink_file(link, dst));
@@ -2014,6 +1910,16 @@ to download LLVM rather than building it.
         stream.reset().unwrap();
         result
     }
+
+    pub fn exec_ctx(&self) -> &ExecutionContext {
+        &self.config.exec_ctx
+    }
+}
+
+impl AsRef<ExecutionContext> for Build {
+    fn as_ref(&self) -> &ExecutionContext {
+        &self.config.exec_ctx
+    }
 }
 
 #[cfg(unix)]
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 459a34d14cc..e939a8362ad 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -416,4 +416,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Warning,
         summary: "Stage0 library no longer matches the in-tree library, which means stage1 compiler now uses the beta library.",
     },
+    ChangeInfo {
+        change_id: 141970,
+        severity: ChangeSeverity::Info,
+        summary: "Added new bootstrap flag `--skip-std-check-if-no-download-rustc` that skips std checks when download-rustc is unavailable. Mainly intended for developers to reduce RA overhead.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/channel.rs b/src/bootstrap/src/utils/channel.rs
index 4a9ecc7a4f8..38f250af42f 100644
--- a/src/bootstrap/src/utils/channel.rs
+++ b/src/bootstrap/src/utils/channel.rs
@@ -8,6 +8,7 @@
 use std::fs;
 use std::path::Path;
 
+use super::execution_context::ExecutionContext;
 use super::helpers;
 use crate::Build;
 use crate::utils::helpers::{start_process, t};
@@ -34,7 +35,7 @@ pub struct Info {
 }
 
 impl GitInfo {
-    pub fn new(omit_git_hash: bool, dir: &Path) -> GitInfo {
+    pub fn new(omit_git_hash: bool, dir: &Path, exec_ctx: impl AsRef<ExecutionContext>) -> GitInfo {
         // See if this even begins to look like a git dir
         if !dir.join(".git").exists() {
             match read_commit_info_file(dir) {
@@ -43,10 +44,12 @@ impl GitInfo {
             }
         }
 
-        // Make sure git commands work
-        match helpers::git(Some(dir)).arg("rev-parse").as_command_mut().output() {
-            Ok(ref out) if out.status.success() => {}
-            _ => return GitInfo::Absent,
+        let mut git_command = helpers::git(Some(dir));
+        git_command.arg("rev-parse");
+        let output = git_command.allow_failure().run_capture(exec_ctx);
+
+        if output.is_failure() {
+            return GitInfo::Absent;
         }
 
         // If we're ignoring the git info, we don't actually need to collect it, just make sure this
diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs
index 64e46f10563..f297300e34a 100644
--- a/src/bootstrap/src/utils/exec.rs
+++ b/src/bootstrap/src/utils/exec.rs
@@ -11,7 +11,7 @@ use std::process::{Command, CommandArgs, CommandEnvs, ExitStatus, Output, Stdio}
 use build_helper::ci::CiEnv;
 use build_helper::drop_bomb::DropBomb;
 
-use crate::Build;
+use super::execution_context::ExecutionContext;
 
 /// What should be done when the command fails.
 #[derive(Debug, Copy, Clone)]
@@ -125,7 +125,6 @@ impl BootstrapCommand {
         Self { failure_behavior: BehaviorOnFailure::DelayFail, ..self }
     }
 
-    #[expect(dead_code)]
     pub fn fail_fast(self) -> Self {
         Self { failure_behavior: BehaviorOnFailure::Exit, ..self }
     }
@@ -143,20 +142,20 @@ impl BootstrapCommand {
     /// Run the command, while printing stdout and stderr.
     /// Returns true if the command has succeeded.
     #[track_caller]
-    pub fn run(&mut self, builder: &Build) -> bool {
-        builder.run(self, OutputMode::Print, OutputMode::Print).is_success()
+    pub fn run(&mut self, exec_ctx: impl AsRef<ExecutionContext>) -> bool {
+        exec_ctx.as_ref().run(self, OutputMode::Print, OutputMode::Print).is_success()
     }
 
     /// Run the command, while capturing and returning all its output.
     #[track_caller]
-    pub fn run_capture(&mut self, builder: &Build) -> CommandOutput {
-        builder.run(self, OutputMode::Capture, OutputMode::Capture)
+    pub fn run_capture(&mut self, exec_ctx: impl AsRef<ExecutionContext>) -> CommandOutput {
+        exec_ctx.as_ref().run(self, OutputMode::Capture, OutputMode::Capture)
     }
 
     /// Run the command, while capturing and returning stdout, and printing stderr.
     #[track_caller]
-    pub fn run_capture_stdout(&mut self, builder: &Build) -> CommandOutput {
-        builder.run(self, OutputMode::Capture, OutputMode::Print)
+    pub fn run_capture_stdout(&mut self, exec_ctx: impl AsRef<ExecutionContext>) -> CommandOutput {
+        exec_ctx.as_ref().run(self, OutputMode::Capture, OutputMode::Print)
     }
 
     /// Provides access to the stdlib Command inside.
@@ -280,7 +279,6 @@ impl CommandOutput {
         !self.is_success()
     }
 
-    #[expect(dead_code)]
     pub fn status(&self) -> Option<ExitStatus> {
         match self.status {
             CommandStatus::Finished(status) => Some(status),
diff --git a/src/bootstrap/src/utils/execution_context.rs b/src/bootstrap/src/utils/execution_context.rs
new file mode 100644
index 00000000000..d12c02c161d
--- /dev/null
+++ b/src/bootstrap/src/utils/execution_context.rs
@@ -0,0 +1,202 @@
+//! Shared execution context for running bootstrap commands.
+//!
+//! This module provides the [`ExecutionContext`] type, which holds global configuration
+//! relevant during the execution of commands in bootstrap. This includes dry-run
+//! mode, verbosity level, and behavior on failure.
+use std::sync::{Arc, Mutex};
+
+use crate::core::config::DryRun;
+use crate::{BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode, exit};
+
+#[derive(Clone, Default)]
+pub struct ExecutionContext {
+    dry_run: DryRun,
+    verbose: u8,
+    pub fail_fast: bool,
+    delayed_failures: Arc<Mutex<Vec<String>>>,
+}
+
+impl ExecutionContext {
+    pub fn new() -> Self {
+        ExecutionContext::default()
+    }
+
+    pub fn dry_run(&self) -> bool {
+        match self.dry_run {
+            DryRun::Disabled => false,
+            DryRun::SelfCheck | DryRun::UserSelected => true,
+        }
+    }
+
+    pub fn get_dry_run(&self) -> &DryRun {
+        &self.dry_run
+    }
+
+    pub fn verbose(&self, f: impl Fn()) {
+        if self.is_verbose() {
+            f()
+        }
+    }
+
+    pub fn is_verbose(&self) -> bool {
+        self.verbose > 0
+    }
+
+    pub fn fail_fast(&self) -> bool {
+        self.fail_fast
+    }
+
+    pub fn set_dry_run(&mut self, value: DryRun) {
+        self.dry_run = value;
+    }
+
+    pub fn set_verbose(&mut self, value: u8) {
+        self.verbose = value;
+    }
+
+    pub fn set_fail_fast(&mut self, value: bool) {
+        self.fail_fast = value;
+    }
+
+    pub fn add_to_delay_failure(&self, message: String) {
+        self.delayed_failures.lock().unwrap().push(message);
+    }
+
+    pub fn report_failures_and_exit(&self) {
+        let failures = self.delayed_failures.lock().unwrap();
+        if failures.is_empty() {
+            return;
+        }
+        eprintln!("\n{} command(s) did not execute successfully:\n", failures.len());
+        for failure in &*failures {
+            eprintln!("  - {failure}");
+        }
+        exit!(1);
+    }
+
+    /// Execute a command and return its output.
+    /// Note: Ideally, you should use one of the BootstrapCommand::run* functions to
+    /// execute commands. They internally call this method.
+    #[track_caller]
+    pub fn run(
+        &self,
+        command: &mut BootstrapCommand,
+        stdout: OutputMode,
+        stderr: OutputMode,
+    ) -> CommandOutput {
+        command.mark_as_executed();
+        if self.dry_run() && !command.run_always {
+            return CommandOutput::default();
+        }
+
+        #[cfg(feature = "tracing")]
+        let _run_span = trace_cmd!(command);
+
+        let created_at = command.get_created_location();
+        let executed_at = std::panic::Location::caller();
+
+        self.verbose(|| {
+            println!("running: {command:?} (created at {created_at}, executed at {executed_at})")
+        });
+
+        let cmd = command.as_command_mut();
+        cmd.stdout(stdout.stdio());
+        cmd.stderr(stderr.stdio());
+
+        let output = cmd.output();
+
+        use std::fmt::Write;
+
+        let mut message = String::new();
+        let output: CommandOutput = match output {
+            // Command has succeeded
+            Ok(output) if output.status.success() => {
+                CommandOutput::from_output(output, stdout, stderr)
+            }
+            // Command has started, but then it failed
+            Ok(output) => {
+                writeln!(
+                    message,
+                    r#"
+Command {command:?} did not execute successfully.
+Expected success, got {}
+Created at: {created_at}
+Executed at: {executed_at}"#,
+                    output.status,
+                )
+                .unwrap();
+
+                let output: CommandOutput = CommandOutput::from_output(output, stdout, stderr);
+
+                // If the output mode is OutputMode::Capture, we can now print the output.
+                // If it is OutputMode::Print, then the output has already been printed to
+                // stdout/stderr, and we thus don't have anything captured to print anyway.
+                if stdout.captures() {
+                    writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap();
+                }
+                if stderr.captures() {
+                    writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap();
+                }
+                output
+            }
+            // The command did not even start
+            Err(e) => {
+                writeln!(
+                    message,
+                    "\n\nCommand {command:?} did not execute successfully.\
+            \nIt was not possible to execute the command: {e:?}"
+                )
+                .unwrap();
+                CommandOutput::did_not_start(stdout, stderr)
+            }
+        };
+
+        let fail = |message: &str, output: CommandOutput| -> ! {
+            if self.is_verbose() {
+                println!("{message}");
+            } else {
+                let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present());
+                // If the command captures output, the user would not see any indication that
+                // it has failed. In this case, print a more verbose error, since to provide more
+                // context.
+                if stdout.is_some() || stderr.is_some() {
+                    if let Some(stdout) =
+                        output.stdout_if_present().take_if(|s| !s.trim().is_empty())
+                    {
+                        println!("STDOUT:\n{stdout}\n");
+                    }
+                    if let Some(stderr) =
+                        output.stderr_if_present().take_if(|s| !s.trim().is_empty())
+                    {
+                        println!("STDERR:\n{stderr}\n");
+                    }
+                    println!("Command {command:?} has failed. Rerun with -v to see more details.");
+                } else {
+                    println!("Command has failed. Rerun with -v to see more details.");
+                }
+            }
+            exit!(1);
+        };
+
+        if !output.is_success() {
+            match command.failure_behavior {
+                BehaviorOnFailure::DelayFail => {
+                    if self.fail_fast {
+                        fail(&message, output);
+                    }
+
+                    self.add_to_delay_failure(message);
+                }
+                BehaviorOnFailure::Exit => {
+                    fail(&message, output);
+                }
+                BehaviorOnFailure::Ignore => {
+                    // If failures are allowed, either the error has been printed already
+                    // (OutputMode::Print) or the user used a capture output mode and wants to
+                    // handle the error output on their own.
+                }
+            }
+        }
+        output
+    }
+}
diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs
index 169fcec303e..5a0b90801e7 100644
--- a/src/bootstrap/src/utils/mod.rs
+++ b/src/bootstrap/src/utils/mod.rs
@@ -8,6 +8,7 @@ pub(crate) mod cc_detect;
 pub(crate) mod change_tracker;
 pub(crate) mod channel;
 pub(crate) mod exec;
+pub(crate) mod execution_context;
 pub(crate) mod helpers;
 pub(crate) mod job;
 pub(crate) mod render_tests;
diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs
index 418f3ff975d..77e645a9e3c 100644
--- a/src/bootstrap/src/utils/render_tests.rs
+++ b/src/bootstrap/src/utils/render_tests.rs
@@ -43,8 +43,7 @@ pub(crate) fn try_run_tests(
         if builder.fail_fast {
             crate::exit!(1);
         } else {
-            let mut failures = builder.delayed_failures.borrow_mut();
-            failures.push(format!("{cmd:?}"));
+            builder.config.exec_ctx().add_to_delay_failure(format!("{cmd:?}"));
             false
         }
     } else {
diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs
index 2884ae08ea8..81e002edb15 100644
--- a/src/ci/citool/src/jobs.rs
+++ b/src/ci/citool/src/jobs.rs
@@ -161,6 +161,8 @@ pub enum RunType {
     TryJob { job_patterns: Option<Vec<String>> },
     /// Merge attempt workflow
     AutoJob,
+    /// Fake job only used for sharing Github Actions cache.
+    MasterJob,
 }
 
 /// Maximum number of custom try jobs that can be requested in a single
@@ -210,6 +212,7 @@ fn calculate_jobs(
             (jobs, "try", &db.envs.try_env)
         }
         RunType::AutoJob => (db.auto_jobs.clone(), "auto", &db.envs.auto_env),
+        RunType::MasterJob => return Ok(vec![]),
     };
     let jobs = substitute_github_vars(jobs.clone())
         .context("Failed to substitute GitHub context variables in jobs")?;
@@ -262,7 +265,7 @@ pub fn calculate_job_matrix(
     eprintln!("Run type: {run_type:?}");
 
     let jobs = calculate_jobs(&run_type, &db, channel)?;
-    if jobs.is_empty() {
+    if jobs.is_empty() && !matches!(run_type, RunType::MasterJob) {
         return Err(anyhow::anyhow!("Computed job list is empty"));
     }
 
@@ -270,6 +273,7 @@ pub fn calculate_job_matrix(
         RunType::PullRequest => "pr",
         RunType::TryJob { .. } => "try",
         RunType::AutoJob => "auto",
+        RunType::MasterJob => "master",
     };
 
     eprintln!("Output");
diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs
index bb73a5ef909..fe1b36673a1 100644
--- a/src/ci/citool/src/main.rs
+++ b/src/ci/citool/src/main.rs
@@ -47,6 +47,7 @@ impl GitHubContext {
                 Some(RunType::TryJob { job_patterns: patterns })
             }
             ("push", "refs/heads/auto") => Some(RunType::AutoJob),
+            ("push", "refs/heads/master") => Some(RunType::MasterJob),
             _ => None,
         }
     }
diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs
index fcdca899e06..83f2fc0ed1f 100644
--- a/src/ci/citool/tests/jobs.rs
+++ b/src/ci/citool/tests/jobs.rs
@@ -45,17 +45,31 @@ fn pr_jobs() {
     "#);
 }
 
+#[test]
+fn master_jobs() {
+    let stdout = get_matrix("push", "commit", "refs/heads/master");
+    insta::assert_snapshot!(stdout, @r#"
+    jobs=[]
+    run_type=master
+    "#);
+}
+
 fn get_matrix(event_name: &str, commit_msg: &str, branch_ref: &str) -> String {
-    let output = Command::new("cargo")
-        .args(["run", "-q", "calculate-job-matrix", "--jobs-file", TEST_JOBS_YML_PATH])
+    let path = std::env::var("PATH");
+    let mut cmd = Command::new("cargo");
+    cmd.args(["run", "-q", "calculate-job-matrix", "--jobs-file", TEST_JOBS_YML_PATH])
+        .env_clear()
         .env("GITHUB_EVENT_NAME", event_name)
         .env("COMMIT_MESSAGE", commit_msg)
         .env("GITHUB_REF", branch_ref)
         .env("GITHUB_RUN_ID", "123")
         .env("GITHUB_RUN_ATTEMPT", "1")
-        .stdout(Stdio::piped())
-        .output()
-        .expect("Failed to execute command");
+        .stdout(Stdio::piped());
+    if let Ok(path) = path {
+        cmd.env("PATH", path);
+    }
+
+    let output = cmd.output().expect("Failed to execute command");
 
     let stdout = String::from_utf8(output.stdout).unwrap();
     let stderr = String::from_utf8(output.stderr).unwrap();
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index bedf45c8630..44f6a8d2a15 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -96,14 +96,13 @@ ENV RUST_CONFIGURE_ARGS \
       --set rust.lto=thin \
       --set rust.codegen-units=1
 
-# Note that `rust.debug` is set to true *only* for `opt-dist`
-ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \
-    ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \
-    --host $HOSTS --target $HOSTS \
-    --include-default-paths \
-    build-manifest bootstrap && \
-    # Use GCC for building GCC, as it seems to behave badly when built with Clang
-    CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc
+ARG SCRIPT_ARG
+
+COPY host-x86_64/dist-x86_64-linux/dist.sh /scripts/
+COPY host-x86_64/dist-x86_64-linux/dist-alt.sh /scripts/
+
+ENV SCRIPT /scripts/${SCRIPT_ARG}
+
 ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang
 
 # This is the only builder which will create source tarballs
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist-alt.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist-alt.sh
new file mode 100755
index 00000000000..8e756c32431
--- /dev/null
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist-alt.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -eux
+
+python3 ../x.py dist \
+    --host $HOSTS --target $HOSTS \
+    --include-default-paths \
+    build-manifest bootstrap
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh
new file mode 100755
index 00000000000..064ac5b0a5e
--- /dev/null
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+set -eux
+
+python3 ../x.py build --set rust.debug=true opt-dist
+
+./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \
+    --host $HOSTS --target $HOSTS \
+    --include-default-paths \
+    build-manifest bootstrap
+
+# Use GCC for building GCC, as it seems to behave badly when built with Clang
+CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc
diff --git a/src/ci/docker/host-x86_64/mingw-check-2/Dockerfile b/src/ci/docker/host-x86_64/mingw-check-2/Dockerfile
index 11a66a1c013..a1d04bd984c 100644
--- a/src/ci/docker/host-x86_64/mingw-check-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check-2/Dockerfile
@@ -30,6 +30,7 @@ ENV SCRIPT \
         python3 ../x.py check && \
         python3 ../x.py clippy ci && \
         python3 ../x.py test --stage 1 core alloc std test proc_macro && \
+        python3 ../x.py doc --stage 0 bootstrap && \
         # Build both public and internal documentation.
         RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 0 compiler && \
         RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 1 library && \
diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh
index fa18f67583f..c5992891398 100755
--- a/src/ci/docker/scripts/rfl-build.sh
+++ b/src/ci/docker/scripts/rfl-build.sh
@@ -2,8 +2,7 @@
 
 set -euo pipefail
 
-# https://github.com/Rust-for-Linux/linux/issues/1163
-LINUX_VERSION=3ca02fc80cc4fdac63aaa6796642f1e07be591d6
+LINUX_VERSION=v6.16-rc1
 
 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt
 ../x.py build --stage 2 library rustdoc clippy rustfmt
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index d59e440fb68..43c77d1ddf7 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -10,6 +10,10 @@ runners:
     free_disk: true
     <<: *base-job
 
+  - &job-linux-4c-largedisk
+    os: ubuntu-24.04-4core-16gb
+    <<: *base-job
+
   - &job-linux-8c
     os: ubuntu-24.04-8core-32gb
     <<: *base-job
@@ -105,6 +109,15 @@ envs:
   pr:
     PR_CI_JOB: 1
 
+jobs:
+  dist-x86_64-linux: &job-dist-x86_64-linux
+    name: dist-x86_64-linux
+    env:
+      CODEGEN_BACKENDS: llvm,cranelift
+      DOCKER_SCRIPT: dist.sh
+    <<: *job-linux-36c-codebuild
+
+
 # Jobs that run on each push to a pull request (PR)
 # These jobs automatically inherit envs.pr, to avoid repeating
 # it in each job definition.
@@ -115,6 +128,11 @@ pr:
     <<: *job-linux-4c
   - name: mingw-check-tidy
     continue_on_error: true
+    free_disk: false
+    env:
+      # This submodule is expensive to checkout, and it should not be needed for
+      # tidy. This speeds up the PR CI job by ~1 minute.
+      SKIP_SUBMODULES: src/gcc
     <<: *job-linux-4c
   - name: x86_64-gnu-llvm-19
     env:
@@ -138,10 +156,7 @@ pr:
 # These jobs automatically inherit envs.try, to avoid repeating
 # it in each job definition.
 try:
-  - name: dist-x86_64-linux
-    env:
-      CODEGEN_BACKENDS: llvm,cranelift
-    <<: *job-linux-36c-codebuild
+  - <<: *job-dist-x86_64-linux
 
 # Main CI jobs that have to be green to merge a commit into master
 # These jobs automatically inherit envs.auto, to avoid repeating
@@ -234,16 +249,14 @@ auto:
   - name: dist-x86_64-illumos
     <<: *job-linux-4c
 
-  - name: dist-x86_64-linux
-    env:
-      CODEGEN_BACKENDS: llvm,cranelift
-    <<: *job-linux-36c-codebuild
+  - <<: *job-dist-x86_64-linux
 
   - name: dist-x86_64-linux-alt
     env:
       IMAGE: dist-x86_64-linux
       CODEGEN_BACKENDS: llvm,cranelift
-    <<: *job-linux-16c
+      DOCKER_SCRIPT: dist-alt.sh
+    <<: *job-linux-4c-largedisk
 
   - name: dist-x86_64-musl
     env:
@@ -297,6 +310,10 @@ auto:
   - name: mingw-check-2
     <<: *job-linux-4c
 
+  - name: mingw-check-tidy
+    free_disk: false
+    <<: *job-linux-4c
+
   - name: test-various
     <<: *job-linux-4c
 
diff --git a/src/ci/run.sh b/src/ci/run.sh
index b6143af632d..e0c00dc1925 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -186,9 +186,11 @@ else
   # Download GCC from CI on test builders
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set gcc.download-ci-gcc=true"
 
-  if [ "$NO_DOWNLOAD_CI_RUSTC" = "" ]; then
-    RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.download-rustc=if-unchanged"
-  fi
+  # download-rustc seems to be broken on CI after the stage0 redesign
+  # Disable it until these issues are debugged and resolved
+#  if [ "$NO_DOWNLOAD_CI_RUSTC" = "" ]; then
+#    RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.download-rustc=if-unchanged"
+#  fi
 fi
 
 if [ "$ENABLE_GCC_CODEGEN" = "1" ]; then
diff --git a/src/ci/scripts/checkout-submodules.sh b/src/ci/scripts/checkout-submodules.sh
index 5bb343241ae..3b646587dc2 100755
--- a/src/ci/scripts/checkout-submodules.sh
+++ b/src/ci/scripts/checkout-submodules.sh
@@ -55,7 +55,11 @@ for i in ${!modules[@]}; do
         bg_pids[${i}]=$!
         continue
     else
+      # Submodule paths contained in SKIP_SUBMODULES (comma-separated list) will not be
+      # checked out.
+      if [ -z "${SKIP_SUBMODULES:-}" ] || [[ ! ",$SKIP_SUBMODULES," = *",$module,"* ]]; then
         use_git="$use_git $module"
+      fi
     fi
 done
 retry sh -c "git submodule deinit -f $use_git && \
diff --git a/src/ci/scripts/create-doc-artifacts.sh b/src/ci/scripts/create-doc-artifacts.sh
index 2516b0d8505..487a9ba428f 100755
--- a/src/ci/scripts/create-doc-artifacts.sh
+++ b/src/ci/scripts/create-doc-artifacts.sh
@@ -15,7 +15,8 @@ fi
 branch=$(git branch --show-current || echo)
 
 if [ -n "$branch" ]; then
-    branch="${branch}-"
+    # Strip automation/bors/ prefix if present
+    branch="${branch#automation/bors/}-"
 fi
 
 if [ "${GITHUB_EVENT_NAME:=none}" = "pull_request" ]; then
diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version
index b1e9eec529e..c8721bb3600 100644
--- a/src/doc/rustc-dev-guide/rust-version
+++ b/src/doc/rustc-dev-guide/rust-version
@@ -1 +1 @@
-99e7c15e81385b38a8186b51edc4577d5d7b5bdd
+c31cccb7b5cc098b1a8c1794ed38d7fdbec0ccb0
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index a7b76233d19..cba8eac617d 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -63,10 +63,8 @@
 - [Notification groups](notification-groups/about.md)
     - [Apple](notification-groups/apple.md)
     - [ARM](notification-groups/arm.md)
-    - [Cleanup Crew](notification-groups/cleanup-crew.md)
     - [Emscripten](notification-groups/emscripten.md)
     - [Fuchsia](notification-groups/fuchsia.md)
-    - [LLVM](notification-groups/llvm.md)
     - [RISC-V](notification-groups/risc-v.md)
     - [Rust for Linux](notification-groups/rust-for-linux.md)
     - [WASI](notification-groups/wasi.md)
@@ -101,6 +99,8 @@
 - [Rustdoc internals](./rustdoc-internals.md)
     - [Search](./rustdoc-internals/search.md)
 	- [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md)
+	- [The `rustdoc-gui` test suite](./rustdoc-internals/rustdoc-gui-test-suite.md)
+	- [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md)
 - [Autodiff internals](./autodiff/internals.md)
     - [Installation](./autodiff/installation.md)
     - [How to debug](./autodiff/debugging.md)
diff --git a/src/doc/rustc-dev-guide/src/autodiff/flags.md b/src/doc/rustc-dev-guide/src/autodiff/flags.md
index 946ae1d03ae..65287d9ba4c 100644
--- a/src/doc/rustc-dev-guide/src/autodiff/flags.md
+++ b/src/doc/rustc-dev-guide/src/autodiff/flags.md
@@ -16,7 +16,9 @@ LooseTypes // Risk incorrect derivatives instead of aborting when missing Type I
 ```
 
 <div class="warning">
+
 `LooseTypes` is often helpful to get rid of Enzyme errors stating `Can not deduce type of <X>` and to be able to run some code. But please keep in mind that this flag absolutely has the chance to cause incorrect gradients. Even worse, the gradients might be correct for certain input values, but not for others. So please create issues about such bugs and only use this flag temporarily while you wait for your bug to be fixed.
+
 </div>
 
 ### Benchmark flags
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
index 35d33ebdb0e..ed267850401 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
@@ -55,7 +55,7 @@ Bootstrap will conditionally build `tracing` support and enable `tracing` output
 
 Example basic usage[^just-trace]:
 
-[^just-trace]: It is not recommend to use *just* `BOOTSTRAP_TRACING=TRACE` because that will dump *everything* at `TRACE` level, including logs intentionally gated behind custom targets as they are too verbose even for `TRACE` level by default.
+[^just-trace]: It is not recommended to use *just* `BOOTSTRAP_TRACING=TRACE` because that will dump *everything* at `TRACE` level, including logs intentionally gated behind custom targets as they are too verbose even for `TRACE` level by default.
 
 ```bash
 $ BOOTSTRAP_TRACING=bootstrap=TRACE ./x build library --stage 1
diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md
index 76c39608449..bfb2f4d1084 100644
--- a/src/doc/rustc-dev-guide/src/building/suggested.md
+++ b/src/doc/rustc-dev-guide/src/building/suggested.md
@@ -59,6 +59,14 @@ always overrides the inner ones.
 
 ## Configuring `rust-analyzer` for `rustc`
 
+### Checking the "library" tree
+
+Checking the "library" tree requires a stage1 compiler, which can be a heavy process on some computers.
+For this reason, bootstrap has a flag called `--skip-std-check-if-no-download-rustc` that skips checking the
+"library" tree if `rust.download-rustc` isn't available. If you want to avoid putting a heavy load on your computer
+with `rust-analyzer`, you can add the `--skip-std-check-if-no-download-rustc` flag to your `./x check` command in
+the `rust-analyzer` configuration.
+
 ### Project-local rust-analyzer setup
 
 `rust-analyzer` can help you check and format your code whenever you save a
diff --git a/src/doc/rustc-dev-guide/src/coroutine-closures.md b/src/doc/rustc-dev-guide/src/coroutine-closures.md
index 04742d03c50..48cdba44a9f 100644
--- a/src/doc/rustc-dev-guide/src/coroutine-closures.md
+++ b/src/doc/rustc-dev-guide/src/coroutine-closures.md
@@ -1,6 +1,10 @@
+# Async closures/"coroutine-closures"
+
+<!-- toc -->
+
 Please read [RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html) to understand the general motivation of the feature. This is a very technical and somewhat "vertical" chapter; ideally we'd split this and sprinkle it across all the relevant chapters, but for the purposes of understanding async closures *holistically*, I've put this together all here in one chapter.
 
-# Coroutine-closures -- a technical deep dive
+## Coroutine-closures -- a technical deep dive
 
 Coroutine-closures are a generalization of async closures, being special syntax for closure expressions which return a coroutine, notably one that is allowed to capture from the closure's upvars.
 
@@ -8,9 +12,11 @@ For now, the only usable kind of coroutine-closure is the async closure, and sup
 
 As a consequence of the code being somewhat general, this document may flip between calling them "async closures" and "coroutine-closures". The future that is returned by the async closure will generally be called the "coroutine" or the "child coroutine".
 
-## HIR
+### HIR
 
-Async closures (and in the future, other coroutine flavors such as `gen`) are represented in HIR as a `hir::Closure` whose closure-kind is `ClosureKind::CoroutineClosure(_)`[^k1], which wraps an async block, which is also represented in HIR as a `hir::Closure`) and whose closure-kind is `ClosureKind::Closure(CoroutineKind::Desugared(_, CoroutineSource::Closure))`[^k2].
+Async closures (and in the future, other coroutine flavors such as `gen`) are represented in HIR as a `hir::Closure`.
+The closure-kind of the `hir::Closure` is `ClosureKind::CoroutineClosure(_)`[^k1], which wraps an async block, which is also represented in HIR as a `hir::Closure`.
+The closure-kind of the async block is `ClosureKind::Closure(CoroutineKind::Desugared(_, CoroutineSource::Closure))`[^k2].
 
 [^k1]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_ast_lowering/src/expr.rs#L1147>
 
@@ -24,7 +30,7 @@ Like `async fn`, when lowering an async closure's body, we need to unconditional
 
 [^l3]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_hir_typeck/src/upvar.rs#L250-L256>
 
-## `rustc_middle::ty` Representation
+### `rustc_middle::ty` Representation
 
 For the purposes of keeping the implementation mostly future-compatible (i.e. with gen `|| {}` and `async gen || {}`), most of this section calls async closures "coroutine-closures".
 
@@ -72,7 +78,7 @@ To most easily construct the `Coroutine` that a coroutine-closure returns, you c
 
 Most of the args to that function will be components that you can get out of the `CoroutineArgs`, except for the `goal_kind: ClosureKind` which controls which flavor of coroutine to return based off of the `ClosureKind` passed in -- i.e. it will prepare the by-ref coroutine if `ClosureKind::Fn | ClosureKind::FnMut`, and the by-move coroutine if `ClosureKind::FnOnce`.
 
-## Trait Hierarchy
+### Trait Hierarchy
 
 We introduce a parallel hierarchy of `Fn*` traits that are implemented for . The motivation for the introduction was covered in a blog post: [Async Closures](https://hackmd.io/@compiler-errors/async-closures).
 
@@ -98,11 +104,11 @@ We mention above that "regular" callable types can implement `AsyncFn*`, but the
 
 See the "follow-up: when do..." section below for an elaborated answer. The full answer describes a pretty interesting and hopefully thorough heuristic that is used to ensure that most async closures "just work".
 
-## Tale of two bodies...
+### Tale of two bodies...
 
 When async closures are called with `AsyncFn`/`AsyncFnMut`, they return a coroutine that borrows from the closure. However, when they are called via `AsyncFnOnce`, we consume that closure, and cannot return a coroutine that borrows from data that is now dropped.
 
-To work around around this limitation, we synthesize a separate by-move MIR body for calling `AsyncFnOnce::call_once` on a coroutine-closure that can be called by-ref.
+To work around this limitation, we synthesize a separate by-move MIR body for calling `AsyncFnOnce::call_once` on a coroutine-closure that can be called by-ref.
 
 This body operates identically to the "normal" coroutine returned from calling the coroutine-closure, except for the fact that it has a different set of upvars, since we must *move* the captures from the parent coroutine-closure into the child coroutine.
 
@@ -120,7 +126,7 @@ Since we've synthesized a new def id, this query is also responsible for feeding
 
 [^b3]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_mir_transform/src/lib.rs#L339-L342>
 
-## Closure signature inference
+### Closure signature inference
 
 The closure signature inference algorithm for async closures is a bit more complicated than the inference algorithm for "traditional" closures. Like closures, we iterate through all of the clauses that may be relevant (for the expectation type passed in)[^deduce1].
 
@@ -173,7 +179,7 @@ s.as_bytes();
 
 So *instead*, we use this alias (in this case, a projection: `AsyncFnKindHelper::Upvars<'env, ...>`) to delay the computation of the *tupled upvars* and give us something to put in its place, while still allowing us to return a `TyKind::Coroutine` (which is a rigid type) and we may successfully confirm the built-in traits we need (in our case, `Future`), since the `Future` implementation doesn't depend on the upvars at all.
 
-## Upvar analysis
+### Upvar analysis
 
 By and large, the upvar analysis for coroutine-closures and their child coroutines proceeds like normal upvar analysis. However, there are several interesting bits that happen to account for async closures' special natures:
 
@@ -262,7 +268,7 @@ let c = async || {
 
 If either of these cases apply, then we should capture the borrow with the lifetime of the parent coroutine-closure's env. Luckily, if this function is not correct, then the program is not unsound, since we still borrowck and validate the choices made from this function -- the only side-effect is that the user may receive unnecessary borrowck errors.
 
-## Instance resolution
+### Instance resolution
 
 If a coroutine-closure has a closure-kind of `FnOnce`, then its `AsyncFnOnce::call_once` and `FnOnce::call_once` implementations resolve to the coroutine-closure's body[^res1], and the `Future::poll` of the coroutine that gets returned resolves to the body of the child closure.
 
@@ -282,7 +288,7 @@ This is represented by the `ConstructCoroutineInClosureShim`[^i1]. The `receiver
 
 [^i3]: <https://github.com/rust-lang/rust/blob/07cbbdd69363da97075650e9be24b78af0bcdd23/compiler/rustc_middle/src/ty/instance.rs#L841>
 
-## Borrow-checking
+### Borrow-checking
 
 It turns out that borrow-checking async closures is pretty straightforward. After adding a new `DefiningTy::CoroutineClosure`[^bck1] variant, and teaching borrowck how to generate the signature of the coroutine-closure[^bck2], borrowck proceeds totally fine.
 
diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md
index 435202ca6c8..d6c5c3ac852 100644
--- a/src/doc/rustc-dev-guide/src/getting-started.md
+++ b/src/doc/rustc-dev-guide/src/getting-started.md
@@ -158,9 +158,6 @@ feel comfortable jumping straight into the large `rust-lang/rust` codebase.
 The following tasks are doable without much background knowledge but are
 incredibly helpful:
 
-- [Cleanup crew][iceb]: find minimal reproductions of ICEs, bisect
-  regressions, etc. This is a way of helping that saves a ton of time for
-  others to fix an error later.
 - [Writing documentation][wd]: if you are feeling a bit more intrepid, you could try
   to read a part of the code and write doc comments for it. This will help you
   to learn some part of the compiler while also producing a useful artifact!
@@ -179,7 +176,6 @@ incredibly helpful:
 [users]: https://users.rust-lang.org/
 [so]: http://stackoverflow.com/questions/tagged/rust
 [community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library
-[iceb]: ./notification-groups/cleanup-crew.md
 [wd]: ./contributing.md#writing-documentation
 [wg]: https://rust-lang.github.io/compiler-team/working-groups/
 [triage]: ./contributing.md#issue-triage
diff --git a/src/doc/rustc-dev-guide/src/normalization.md b/src/doc/rustc-dev-guide/src/normalization.md
index 9705b1a244a..eb0962a4122 100644
--- a/src/doc/rustc-dev-guide/src/normalization.md
+++ b/src/doc/rustc-dev-guide/src/normalization.md
@@ -265,13 +265,13 @@ Another problem was that it was not possible to normalize `ParamEnv`s correctly
 
 Given a type such as `for<'a> fn(<?x as Trait<'a>::Assoc>)`, it is not possible to correctly handle this with the old solver's approach to normalization.
 
-If we were to normalize it to `for<'a> fn(?y)` and register a goal to normalize `for<'a> <?x as Trait<'a>>::Assoc -> ?y`, this would result in errors in cases where `<?x as Trait<'a>>::Assoc` normalized to `&'a u32`. The inference variable `?y` would be in a lower [universe][universes] than the placeholders made when instantiating the `for<'a>` binder.
+If we were to normalize it to `for<'a> fn(?y)` and register a goal to normalize `for<'a> <?x as Trait<'a>>::Assoc -> ?y`, this would result in errors in cases where `<?x as Trait<'a>>::Assoc` normalized to `&'a u32`. The inference variable `?y` would be in a lower [universe] than the placeholders made when instantiating the `for<'a>` binder.
 
 Leaving the alias unnormalized would also be wrong as the old solver expects all aliases to be rigid. This was a soundness bug before the new solver was stabilized in coherence: [relating projection substs is unsound during coherence](https://github.com/rust-lang/rust/issues/102048).
 
 Ultimately this means that it is not always possible to ensure all aliases inside of a value are rigid.
 
-[universes]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/placeholders_and_universes.html#what-is-a-universe
+[universe]: borrow_check/region_inference/placeholders_and_universes.md#what-is-a-universe
 [deeply_normalize]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/normalize/trait.NormalizeExt.html#tymethod.deeply_normalize
 
 ## Handling uses of diverging aliases
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/about.md b/src/doc/rustc-dev-guide/src/notification-groups/about.md
index af305f0103a..d75891ecf7b 100644
--- a/src/doc/rustc-dev-guide/src/notification-groups/about.md
+++ b/src/doc/rustc-dev-guide/src/notification-groups/about.md
@@ -21,9 +21,7 @@ search for existing issues that haven't been claimed yet.
 Here's the list of the notification groups:
 - [Apple](./apple.md)
 - [ARM](./arm.md)
-- [Cleanup Crew](./cleanup-crew.md)
 - [Emscripten](./emscripten.md)
-- [LLVM Icebreakers](./llvm.md)
 - [RISC-V](./risc-v.md)
 - [WASI](./wasi.md)
 - [WebAssembly](./wasm.md)
@@ -64,9 +62,7 @@ Example PRs:
 
 * [Example of adding yourself to the Apple group.](https://github.com/rust-lang/team/pull/1434)
 * [Example of adding yourself to the ARM group.](https://github.com/rust-lang/team/pull/358)
-* [Example of adding yourself to the Cleanup Crew.](https://github.com/rust-lang/team/pull/221)
 * [Example of adding yourself to the Emscripten group.](https://github.com/rust-lang/team/pull/1579)
-* [Example of adding yourself to the LLVM group.](https://github.com/rust-lang/team/pull/140)
 * [Example of adding yourself to the RISC-V group.](https://github.com/rust-lang/team/pull/394)
 * [Example of adding yourself to the WASI group.](https://github.com/rust-lang/team/pull/1580)
 * [Example of adding yourself to the WebAssembly group.](https://github.com/rust-lang/team/pull/1581)
@@ -81,9 +77,7 @@ group. For example:
 ```text
 @rustbot ping apple
 @rustbot ping arm
-@rustbot ping cleanup-crew
 @rustbot ping emscripten
-@rustbot ping icebreakers-llvm
 @rustbot ping risc-v
 @rustbot ping wasi
 @rustbot ping wasm
@@ -92,12 +86,12 @@ group. For example:
 
 To make some commands shorter and easier to remember, there are aliases,
 defined in the [`triagebot.toml`] file. For example, all of these commands
-are equivalent and will ping the Cleanup Crew:
+are equivalent and will ping the Apple group:
 
 ```text
-@rustbot ping cleanup
-@rustbot ping bisect
-@rustbot ping reduce
+@rustbot ping apple
+@rustbot ping macos
+@rustbot ping ios
 ```
 
 Keep in mind that these aliases are meant to make humans' life easier.
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md b/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md
deleted file mode 100644
index 9cf4e512cbd..00000000000
--- a/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Cleanup Crew
-
-**Github Label:** [ICEBreaker-Cleanup-Crew] <br>
-**Ping command:** `@rustbot ping cleanup-crew`
-
-[ICEBreaker-Cleanup-Crew]: https://github.com/rust-lang/rust/labels/ICEBreaker-Cleanup-Crew
-
-The "Cleanup Crew" are focused on improving bug reports. Specifically,
-the goal is to try to ensure that every bug report has all the
-information that will be needed for someone to fix it:
-
-* a minimal, standalone example that shows the problem
-* links to duplicates or related bugs
-* if the bug is a regression (something that used to work, but no longer does),
-  then a bisection to the PR or nightly that caused the regression
-
-This kind of cleanup is invaluable in getting bugs fixed. Better
-still, it can be done by anybody who knows Rust, without any
-particularly deep knowledge of the compiler.
-
-Let's look a bit at the workflow for doing "cleanup crew" actions.
-
-## Finding a minimal, standalone example
-
-Here the ultimate goal is to produce an example that reproduces the same
-problem but without relying on any external crates. Such a test ought to contain
-as little code as possible, as well. This will make it much easier to isolate the problem.
-
-However, even if the "ultimate minimal test" cannot be achieved, it's
-still useful to post incremental minimizations. For example, if you
-can eliminate some of the external dependencies, that is helpful, and
-so forth. 
-
-It's particularly useful to reduce to an example that works
-in the [Rust playground](https://play.rust-lang.org/), rather than
-requiring people to checkout a cargo build.
-
-There are many resources for how to produce minimized test cases. Here
-are a few:
-
-* The [rust-reduce](https://github.com/jethrogb/rust-reduce) tool can try to reduce
-  code automatically.
-  * The [C-reduce](https://github.com/csmith-project/creduce) tool also works
-    on Rust code, though it requires that you start from a single
-    file. (A post explaining how to do it can be found [here](https://insaneinside.net/2017/09/12/whole-crate-bug-reduction-with-creduce.html).)
-* pnkfelix's [Rust Bug Minimization Patterns] blog post
-  * This post focuses on "heavy bore" techniques, where you are
-    starting with a large, complex cargo project that you wish to
-    narrow down to something standalone.
-
-[Rust Bug Minimization Patterns]: http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/
-
-## Links to duplicate or related bugs
-
-If you are on the "Cleanup Crew", you will sometimes see multiple bug
-reports that seem very similar. You can link one to the other just by
-mentioning the other bug number in a Github comment. Sometimes it is
-useful to close duplicate bugs. But if you do so, you should always
-copy any test case from the bug you are closing to the other bug that
-remains open, as sometimes duplicate-looking bugs will expose
-different facets of the same problem.
-
-## Bisecting regressions
-
-For regressions (something that used to work, but no longer does), it
-is super useful if we can figure out precisely when the code stopped
-working.  The gold standard is to be able to identify the precise
-**PR** that broke the code, so we can ping the author, but even
-narrowing it down to a nightly build is helpful, especially as that
-then gives us a range of PRs. (One other challenge is that we
-sometimes land "rollup" PRs, which combine multiple PRs into one.)
-
-### cargo-bisect-rustc
-
-To help in figuring out the cause of a regression we have a tool
-called [cargo-bisect-rustc]. It will automatically download and test
-various builds of rustc. For recent regressions, it is even able to
-use the builds from our CI to track down the regression to a specific
-PR; for older regressions, it will simply identify a nightly.
-
-To learn to use [cargo-bisect-rustc], check out [this blog post][learn], which
-gives a quick introduction to how it works. Additionally, there is a [Guide]
-which goes into more detail on how to use it. You can also ask questions at
-the Zulip stream [`#t-compiler/cargo-bisect-rustc`][zcbr], or help in
-improving the tool.
-
-[cargo-bisect-rustc]: https://github.com/rust-lang/cargo-bisect-rustc/
-[learn]: https://blog.rust-lang.org/inside-rust/2019/12/18/bisecting-rust-compiler.html
-[zcbr]: https://rust-lang.zulipchat.com/#narrow/stream/217417-t-compiler.2Fcargo-bisect-rustc
-[Guide]: https://rust-lang.github.io/cargo-bisect-rustc/
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/llvm.md b/src/doc/rustc-dev-guide/src/notification-groups/llvm.md
deleted file mode 100644
index 9d008728543..00000000000
--- a/src/doc/rustc-dev-guide/src/notification-groups/llvm.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# LLVM Icebreakers Notification group
-
-**Github Label:** [A-LLVM] <br>
-**Ping command:** `@rustbot ping icebreakers-llvm`
-
-[A-LLVM]: https://github.com/rust-lang/rust/labels/A-LLVM
-
-*Note*: this notification group is *not* the same as the LLVM working group
-(WG-llvm).
-
-The "LLVM Icebreakers Notification Group" are focused on bugs that center around
-LLVM. These bugs often arise because of LLVM optimizations gone awry, or as the
-result of an LLVM upgrade. The goal here is:
-
-- to determine whether the bug is a result of us generating invalid LLVM IR,
-  or LLVM misoptimizing;
-- if the former, to fix our IR;
-- if the latter, to try and file a bug on LLVM (or identify an existing bug).
-
-The group may also be asked to weigh in on other sorts of LLVM-focused
-questions.
-
-## Helpful tips and options
-
-The ["Debugging LLVM"][d] section of the
-rustc-dev-guide gives a step-by-step process for how to help debug bugs
-caused by LLVM. In particular, it discusses how to emit LLVM IR, run
-the LLVM IR optimization pipelines, and so forth. You may also find
-it useful to look at the various codegen options listed under `-C help`
-and the internal options under `-Z help` -- there are a number that
-pertain to LLVM (just search for LLVM).
-
-[d]: ../backend/debugging.md
-
-## If you do narrow to an LLVM bug
-
-The ["Debugging LLVM"][d] section also describes what to do once
-you've identified the bug.
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
index bc91c62d873..0234d4a920e 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
@@ -270,35 +270,6 @@ in `test.rs` is the function `make_test`, which is where hand-written
 Some extra reading about `make_test` can be found
 [here](https://quietmisdreavus.net/code/2018/02/23/how-the-doctests-get-made/).
 
-## Dotting i's And Crossing t's
-
-So that's `rustdoc`'s code in a nutshell, but there's more things in the
-compiler that deal with it. Since we have the full `compiletest` suite at hand,
-there's a set of tests in `tests/rustdoc` that make sure the final `HTML` is
-what we expect in various situations. These tests also use a supplementary
-script, `src/etc/htmldocck.py`, that allows it to look through the final `HTML`
-using `XPath` notation to get a precise look at the output. The full
-description of all the commands available to `rustdoc` tests (e.g. [`@has`] and
-[`@matches`]) is in [`htmldocck.py`].
-
-To use multiple crates in a `rustdoc` test, add `//@ aux-build:filename.rs`
-to the top of the test file. `filename.rs` should be placed in an `auxiliary`
-directory relative to the test file with the comment. If you need to build
-docs for the auxiliary file, use `//@ build-aux-docs`.
-
-In addition, there are separate tests for the search index and `rustdoc`'s
-ability to query it. The files in `tests/rustdoc-js` each contain a
-different search query and the expected results, broken out by search tab.
-These files are processed by a script in `src/tools/rustdoc-js` and the `Node.js`
-runtime. These tests don't have as thorough of a writeup, but a broad example
-that features results in all tabs can be found in `basic.js`. The basic idea is
-that you match a given `QUERY` with a set of `EXPECTED` results, complete with
-the full item path of each item.
-
-[`@has`]: https://github.com/rust-lang/rust/blob/master/src/etc/htmldocck.py#L39
-[`@matches`]: https://github.com/rust-lang/rust/blob/master/src/etc/htmldocck.py#L44
-[`htmldocck.py`]: https://github.com/rust-lang/rust/blob/master/src/etc/htmldocck.py
-
 ## Testing Locally
 
 Some features of the generated `HTML` documentation might require local
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-gui-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-gui-test-suite.md
new file mode 100644
index 00000000000..e155f960e3d
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-gui-test-suite.md
@@ -0,0 +1,14 @@
+# The `rustdoc-gui` test suite
+
+> **FIXME**: This section is a stub. Please help us flesh it out!
+
+This page is about the test suite named `rustdoc-gui` used to test the "GUI" of `rustdoc` (i.e., the HTML/JS/CSS as rendered in a browser).
+For other rustdoc-specific test suites, see [Rustdoc test suites].
+
+These use a NodeJS-based tool called [`browser-UI-test`] that uses [puppeteer] to run tests in a headless browser and check rendering and interactivity. For information on how to write this form of test, see [`tests/rustdoc-gui/README.md`][rustdoc-gui-readme] as well as [the description of the `.goml` format][goml-script]
+
+[Rustdoc test suites]: ../tests/compiletest.md#rustdoc-test-suites
+[`browser-UI-test`]: https://github.com/GuillaumeGomez/browser-UI-test/
+[puppeteer]: https://pptr.dev/
+[rustdoc-gui-readme]: https://github.com/rust-lang/rust/blob/master/tests/rustdoc-gui/README.md
+[goml-script]: https://github.com/GuillaumeGomez/browser-UI-test/blob/master/goml-script.md
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md
new file mode 100644
index 00000000000..e08f7709506
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md
@@ -0,0 +1,3 @@
+# The `rustdoc-json` test suite
+
+> **FIXME**: This section is a stub. It will be populated by [PR #2422](https://github.com/rust-lang/rustc-dev-guide/pull/2422/).
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md
index bad7ac19da2..b05318ce9e6 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md
@@ -1,112 +1,191 @@
 # The `rustdoc` test suite
 
-This page is specifically about the test suite named `rustdoc`.
-For other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.md#tests).
+This page is about the test suite named `rustdoc` used to test the HTML output of `rustdoc`.
+For other rustdoc-specific test suites, see [Rustdoc test suites].
 
-The `rustdoc` test suite is specifically used to test the HTML output of rustdoc.
+Each test file in this test suite is simply a Rust source file `file.rs` sprinkled with
+so-called *directives* located inside normal Rust code comments.
+These come in two flavors: *Compiletest* and *HtmlDocCk*.
 
-This is achieved by means of `htmldocck.py`, a custom checker script that leverages [XPath].
+To learn more about the former, read [Compiletest directives].
+For the latter, continue reading.
 
-[XPath]: https://en.wikipedia.org/wiki/XPath
+Internally, [`compiletest`] invokes the supplementary checker script [`htmldocck.py`].
 
-## Directives
-Directives to htmldocck are similar to those given to `compiletest` in that they take the form of `//@` comments.
+[Rustdoc test suites]: ../tests/compiletest.md#rustdoc-test-suites
+[`compiletest`]: ../tests/compiletest.md
+[`htmldocck.py`]: https://github.com/rust-lang/rust/blob/master/src/etc/htmldocck.py
 
-In addition to the directives listed here,
-`rustdoc` tests also support most
-[compiletest directives](../tests/directives.html).
+## HtmlDocCk Directives
 
-All `PATH`s in directives are relative to the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`),
-so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid
-having to write a long crate name multiple times.
-To avoid repetition, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument.
+Directives to HtmlDocCk are assertions that place constraints on the generated HTML.
+They look similar to those given to `compiletest` in that they take the form of `//@` comments
+but ultimately, they are completey distinct and processed by different programs.
 
-All arguments take the form of quoted strings
-(both single and double quotes are supported),
-with the exception of `COUNT` and the special `-` form of `PATH`.
+[XPath] is used to query parts of the HTML document tree.
+
+**Introductory example**:
+
+```rust,ignore (illustrative)
+//@ has file/type.Alias.html
+//@ has - '//*[@class="rust item-decl"]//code' 'type Alias = Option<i32>;'
+pub type Alias = Option<i32>;
+```
+
+Here, we check that documentation generated for crate `file` contains a page for the
+public type alias `Alias` where the code block that is found at the top contains the
+expected rendering of the item. The `//*[@class="rust item-decl"]//code` is an XPath
+expression.
 
-Directives are assertions that place constraints on the generated HTML.
+Conventionally, you place these directives directly above the thing they are meant to test.
+Technically speaking however, they don't need to be as HtmlDocCk only looks for the directives.
 
-All directives (except `files`) can be negated by putting a `!` in front of their name.
+All directives take a `PATH` argument.
+To avoid repetition, `-` can be passed to it to re-use the previous `PATH` argument.
+Since the path contains the name of the crate, it is conventional to add a
+`#![crate_name = "foo"]` attribute to the crate root to shorten the resulting path.
+
+All arguments take the form of shell-style (single or double) quoted strings,
+with the exception of `COUNT` and the special `-` form of `PATH`.
+
+All directives (except `files`) can be *negated* by putting a `!` in front of their name.
+Before you add negated directives, please read about [their caveats](#caveats).
 
 Similar to shell commands,
 directives can extend across multiple lines if their last char is `\`.
 In this case, the start of the next line should be `//`, with no `@`.
 
-For example, `//@ !has 'foo/struct.Bar.html'` checks that crate `foo` does not have a page for a struct named `Bar` in the crate root.
+Use the special string `{{channel}}` in XPaths, `PATTERN` arguments and [snapshot files](#snapshot)
+if you'd like to refer to the URL `https://doc.rust-lang.org/CHANNEL` where `CHANNEL` refers to the
+current release channel (e.g, `stable` or `nightly`).
+
+Listed below are all possible directives:
+
+[XPath]: https://en.wikipedia.org/wiki/XPath
 
 ### `has`
 
-Usage 1: `//@ has PATH`
-Usage 2: `//@ has PATH XPATH PATTERN`
+> Usage 1: `//@ has PATH`
 
-In the first form, `has` checks that a given file exists.
+Check that the file given by `PATH` exists.
 
-In the second form, `has` is an alias for `matches`,
-except `PATTERN` is a whitespace-normalized[^1] string instead of a regex.
+> Usage 2: `//@ has PATH XPATH PATTERN`
 
-### `matches`
+Checks that the text of each element / attribute / text selected by `XPATH` in the
+whitespace-normalized[^1] file given by `PATH` matches the
+(also whitespace-normalized) string `PATTERN`.
+
+**Tip**: If you'd like to avoid whitespace normalization and/or if you'd like to match with a regex,
+use `matches` instead.
 
-Usage: `//@ matches PATH XPATH PATTERN`
+### `hasraw`
 
-Checks that the text of each element selected by `XPATH` in `PATH` matches the python-flavored regex `PATTERN`.
+> Usage: `//@ hasraw PATH PATTERN`
 
-### `matchesraw`
+Checks that the contents of the whitespace-normalized[^1] file given by `PATH`
+matches the (also whitespace-normalized) string `PATTERN`.
 
-Usage: `//@ matchesraw PATH PATTERN`
+**Tip**: If you'd like to avoid whitespace normalization and / or if you'd like to match with a
+regex, use `matchesraw` instead.
 
-Checks that the contents of the file `PATH` matches the regex `PATTERN`.
+### `matches`
 
-### `hasraw`
+> Usage: `//@ matches PATH XPATH PATTERN`
 
-Usage: `//@ hasraw PATH PATTERN`
+Checks that the text of each element / attribute / text selected by `XPATH` in the
+file given by `PATH` matches the Python-flavored[^2] regex `PATTERN`.
 
-Same as `matchesraw`, except `PATTERN` is a whitespace-normalized[^1] string instead of a regex.
+### `matchesraw`
+
+> Usage: `//@ matchesraw PATH PATTERN`
+
+Checks that the contents of the file given by `PATH` matches the
+Python-flavored[^2] regex `PATTERN`.
 
 ### `count`
 
-Usage: `//@ count PATH XPATH COUNT`
+> Usage: `//@ count PATH XPATH COUNT`
 
-Checks that there are exactly `COUNT` matches for `XPATH` within the file `PATH`.
+Checks that there are exactly `COUNT` matches for `XPATH` within the file given by `PATH`.
 
 ### `snapshot`
 
-Usage: `//@ snapshot NAME PATH XPATH`
+> Usage: `//@ snapshot NAME PATH XPATH`
 
-Creates a snapshot test named NAME.
-A snapshot test captures a subtree of the DOM, at the location
-determined by the XPath, and compares it to a pre-recorded value
-in a file. The file's name is the test's name with the `.rs` extension
-replaced with `.NAME.html`, where NAME is the snapshot's name.
+Checks that the element / text selected by `XPATH` in the file given by `PATH` matches the
+pre-recorded subtree or text (the "snapshot") in file `FILE_STEM.NAME.html` where `FILE_STEM`
+is the file stem of the test file.
 
-htmldocck supports the `--bless` option to accept the current subtree
-as expected, saving it to the file determined by the snapshot's name.
-compiletest's `--bless` flag is forwarded to htmldocck.
+Pass the `--bless` option to `compiletest` to accept the current subtree/text as expected.
+This will overwrite the aforementioned file (or create it if it doesn't exist). It will
+automatically normalize the channel-dependent URL `https://doc.rust-lang.org/CHANNEL` to
+the special string `{{channel}}`.
 
 ### `has-dir`
 
-Usage: `//@ has-dir PATH`
+> Usage: `//@ has-dir PATH`
 
-Checks for the existence of directory `PATH`.
+Checks for the existence of the directory given by `PATH`.
 
 ### `files`
 
-Usage: `//@ files PATH ENTRIES`
+> Usage: `//@ files PATH ENTRIES`
+
+Checks that the directory given by `PATH` contains exactly `ENTRIES`.
+`ENTRIES` is a Python-like list of strings inside a quoted string.
+
+**Example**: `//@ files "foo/bar" '["index.html", "sidebar-items.js"]'`
+
+[^1]: Whitespace normalization means that all spans of consecutive whitespace are replaced with a single space.
+[^2]: They are Unicode aware (flag `UNICODE` is set), match case-sensitively and in single-line mode.
+
+## Compiletest Directives (Brief)
+
+As mentioned in the introduction, you also have access to [compiletest directives].
+Most importantly, they allow you to register auxiliary crates and
+to pass flags to the `rustdoc` binary under test.
+It's *strongly recommended* to read that chapter if you don't know anything about them yet.
+
+Here are some details that are relevant to this test suite specifically:
 
-Checks that the directory `PATH` contains exactly `ENTRIES`.
-`ENTRIES` is a python list of strings inside a quoted string,
-as if it were to be parsed by `eval`.
-(note that the list is actually parsed by `shlex.split`,
-so it cannot contain arbitrary python expressions).
+* While you can use both `//@ compile-flags` and `//@ doc-flags` to pass flags to `rustdoc`,
+  prefer to user the latter to show intent. The former is meant for `rustc`.
+* Add `//@ build-aux-docs` to the test file that has auxiliary crates to not only compile the
+  auxiliaries with `rustc` but to also document them with `rustdoc`.
 
-Example: `//@ files "foo/bar" '["index.html", "sidebar-items.js"]'`
+## Caveats
 
-[^1]: Whitespace normalization means that all spans of consecutive whitespace are replaced with a single space.  The files themselves are also whitespace-normalized.
+Testing for the absence of an element or a piece of text is quite fragile and not very future proof.
+
+It's not unusual that the *shape* of the generated HTML document tree changes from time to time.
+This includes for example renamings of CSS classes.
+
+Whenever that happens, *positive* checks will either continue to match the intended element /
+attribute / text (if their XPath expression is general / loose enough) and
+thus continue to test the correct thing or they won't in which case they would fail thereby
+forcing the author of the change to look at them.
+
+Compare that to *negative* checks (e.g., `//@ !has PATH XPATH PATTERN`) which won't fail if their
+XPath expression "no longer" matches. The author who changed "the shape" thus won't get notified and
+as a result someone else can unintentionally reintroduce `PATTERN` into the generated docs without
+the original negative check failing.
+
+**Note**: Please avoid the use of *negated* checks!
+
+**Tip**: If you can't avoid it, please **always** pair it with an analogous positive check in the
+immediate vicinity, so people changing "the shape" have a chance to notice and to update the
+negated check!
 
 ## Limitations
-`htmldocck.py` uses the xpath implementation from the standard library.
+
+HtmlDocCk uses the XPath implementation from the Python standard library.
 This leads to several limitations:
+
 * All `XPATH` arguments must start with `//` due to a flaw in the implementation.
 * Many XPath features (functions, axies, etc.) are not supported.
 * Only well-formed HTML can be parsed (hopefully rustdoc doesn't output mismatched tags).
 
+Furthmore, compiletest [revisions] are not supported.
+
+[revisions]: ../tests/compiletest.md#revisions
+[compiletest directives]: ../tests/directives.md
diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md
index de70ba63823..52ae48c3735 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc.md
@@ -67,43 +67,29 @@ does is call the `main()` that's in this crate's `lib.rs`, though.)
 
 ## Code structure
 
-* All paths in this section are relative to `src/librustdoc` in the rust-lang/rust repository.
+All paths in this section are relative to `src/librustdoc/` in the rust-lang/rust repository.
+
 * Most of the HTML printing code is in `html/format.rs` and `html/render/mod.rs`.
-  It's in a bunch of `fmt::Display` implementations and supplementary
-  functions.
-* The types that got `Display` impls above are defined in `clean/mod.rs`, right
-  next to the custom `Clean` trait used to process them out of the rustc HIR.
+  It's in a bunch of functions returning `impl std::fmt::Display`.
+* The data types that get rendered by the functions mentioned above are defined in `clean/types.rs`.
+  The functions responsible for creating them from the `HIR` and the `rustc_middle::ty` IR
+  live in `clean/mod.rs`.
 * The bits specific to using rustdoc as a test harness are in
   `doctest.rs`.
 * The Markdown renderer is loaded up in `html/markdown.rs`, including functions
   for extracting doctests from a given block of Markdown.
 * Frontend CSS and JavaScript are stored in `html/static/`.
+  * Re. JavaScript, type annotations are written using [TypeScript-flavored JSDoc]
+comments and an external `.d.ts` file.
+    This way, the code itself remains plain, valid JavaScript.
+    We only use `tsc` as a linter.
 
-## Tests
+[TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
 
-* Tests on search engine and index are located in `tests/rustdoc-js` and `tests/rustdoc-js-std`.
-  The format is specified
-  [in the search guide](rustdoc-internals/search.md#testing-the-search-engine).
-* Tests on the "UI" of rustdoc (the terminal output it produces when run) are in
-  `tests/rustdoc-ui`
-* Tests on the "GUI" of rustdoc (the HTML, JS, and CSS as rendered in a browser)
-  are in `tests/rustdoc-gui`. These use a [NodeJS tool called
-  browser-UI-test](https://github.com/GuillaumeGomez/browser-UI-test/) that uses
-  puppeteer to run tests in a headless browser and check rendering and
-  interactivity.  For information on how to write this form of test,
-  see [`tests/rustdoc-gui/README.md`][rustdoc-gui-readme]
-  as well as [the description of the `.goml` format][goml-script]
-* Tests on the structure of rustdoc HTML output are located in `tests/rustdoc`,
-  where they're handled by the test runner of bootstrap and
-  the supplementary script `src/etc/htmldocck.py`.
-  [These tests have several extra directives available to them](./rustdoc-internals/rustdoc-test-suite.md).
-* Additionally, JavaScript type annotations are written using [TypeScript-flavored JSDoc]
-  comments and an external d.ts file. The code itself is plain, valid JavaScript; we only
-  use tsc as a linter.
+## Tests
 
-[TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
-[rustdoc-gui-readme]: https://github.com/rust-lang/rust/blob/master/tests/rustdoc-gui/README.md
-[goml-script]: https://github.com/GuillaumeGomez/browser-UI-test/blob/master/goml-script.md
+`rustdoc`'s integration tests are split across several test suites.
+See [Rustdoc tests suites](tests/compiletest.md#rustdoc-test-suites) for more details.
 
 ## Constraints
 
diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md
index ef3f4c7070c..96e4edc17a5 100644
--- a/src/doc/rustc-dev-guide/src/tests/ci.md
+++ b/src/doc/rustc-dev-guide/src/tests/ci.md
@@ -186,9 +186,11 @@ Note that if you start the default try job using `@bors try`, it will skip build
 Multiple try builds can execute concurrently across different PRs.
 
 <div class="warning">
-bors identify try jobs by commit hash. This means that if you have two PRs
+
+Bors identifies try jobs by commit hash. This means that if you have two PRs
 containing the same (latest) commits, running `@bors try` will result in the
 *same* try job and it really confuses `bors`. Please refrain from doing so.
+
 </div>
 
 [rustc-perf]: https://github.com/rust-lang/rustc-perf
diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md
index e1b23748de3..20dd16c81df 100644
--- a/src/doc/rustc-dev-guide/src/tests/compiletest.md
+++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md
@@ -56,6 +56,9 @@ incremental compilation. The various suites are defined in
 
 The following test suites are available, with links for more information:
 
+[`tests`]: https://github.com/rust-lang/rust/blob/master/tests
+[`src/tools/compiletest/src/common.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/common.rs
+
 ### Compiler-specific test suites
 
 | Test suite                                | Purpose                                                                                                             |
@@ -71,6 +74,7 @@ The following test suites are available, with links for more information:
 | [`mir-opt`](#mir-opt-tests)               | Check MIR generation and optimizations                                                                              |
 | [`coverage`](#coverage-tests)             | Check coverage instrumentation                                                                                      |
 | [`coverage-run-rustdoc`](#coverage-tests) | `coverage` tests that also run instrumented doctests                                                                |
+| [`crashes`](#crashes-tests)               | Check that the compiler ICEs/panics/crashes on certain inputs to catch accidental fixes                             |
 
 ### General purpose test suite
 
@@ -78,19 +82,23 @@ The following test suites are available, with links for more information:
 
 ### Rustdoc test suites
 
-See [Rustdoc tests](../rustdoc.md#tests) for more details.
+| Test suite                           | Purpose                                                                  |
+|--------------------------------------|--------------------------------------------------------------------------|
+| [`rustdoc`][rustdoc-html-tests]      | Check HTML output of `rustdoc`                                           |
+| [`rustdoc-gui`][rustdoc-gui-tests]   | Check `rustdoc`'s GUI using a web browser                                |
+| [`rustdoc-js`][rustdoc-js-tests]     | Check `rustdoc`'s search engine and index                                |
+| [`rustdoc-js-std`][rustdoc-js-tests] | Check `rustdoc`'s search engine and index on the std library docs        |
+| [`rustdoc-json`][rustdoc-json-tests] | Check JSON output of `rustdoc`                                           |
+| `rustdoc-ui`                         | Check terminal output of `rustdoc` ([see also](ui.md))                   |
 
-| Test suite       | Purpose                                                                  |
-|------------------|--------------------------------------------------------------------------|
-| `rustdoc`        | Check `rustdoc` generated files contain the expected documentation       |
-| `rustdoc-gui`    | Check `rustdoc`'s GUI using a web browser                                |
-| `rustdoc-js`     | Check `rustdoc` search is working as expected                            |
-| `rustdoc-js-std` | Check rustdoc search is working as expected specifically on the std docs |
-| `rustdoc-json`   | Check JSON output of `rustdoc`                                           |
-| `rustdoc-ui`     | Check terminal output of `rustdoc`                                       |
+Some rustdoc-specific tests can also be found in `ui/rustdoc/`.
+These check rustdoc-related or -specific lints that (also) run as part of `rustc`, not (only) `rustdoc`.
+Run-make tests pertaining to rustdoc are typically named `run-make/rustdoc-*/`.
 
-[`tests`]: https://github.com/rust-lang/rust/blob/master/tests
-[`src/tools/compiletest/src/common.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/common.rs
+[rustdoc-html-tests]: ../rustdoc-internals/rustdoc-test-suite.md
+[rustdoc-gui-tests]: ../rustdoc-internals/rustdoc-gui-test-suite.md
+[rustdoc-js-tests]: ../rustdoc-internals/search.md#testing-the-search-engine
+[rustdoc-json-tests]: ../rustdoc-internals/rustdoc-json-test-suite.md
 
 ### Pretty-printer tests
 
@@ -438,7 +446,9 @@ To work around this when working on a particular test, temporarily create a
 with these contents:
 
 <div class="warning">
+
 Be careful not to add this `Cargo.toml` or its `Cargo.lock` to your actual PR!
+
 </div>
 
 ```toml
diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
index 8a862417b0d..f73a2811d5a 100644
--- a/src/doc/rustc-dev-guide/src/tests/directives.md
+++ b/src/doc/rustc-dev-guide/src/tests/directives.md
@@ -248,18 +248,20 @@ ignoring debuggers.
 | `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes`           | N/A                                                                                        |
 
 <div class="warning">
+
 Tests (outside of `run-make`) that want to use incremental tests not in the
 incremental test-suite must not pass `-C incremental` via `compile-flags`, and
 must instead use the `//@ incremental` directive.
 
 Consider writing the test as a proper incremental test instead.
+
 </div>
 
 ### Rustdoc
 
 | Directive   | Explanation                                                  | Supported test suites                    | Possible values           |
 |-------------|--------------------------------------------------------------|------------------------------------------|---------------------------|
-| `doc-flags` | Flags passed to `rustdoc` when building the test or aux file | `rustdoc`, `rustdoc-js`, `rustdoc-json` | Any valid `rustdoc` flags |
+| `doc-flags` | Flags passed to `rustdoc` when building the test or aux file | `rustdoc`, `rustdoc-js`, `rustdoc-json`  | Any valid `rustdoc` flags |
 
 <!--
 **FIXME(rustdoc)**: what does `check-test-line-numbers-match` do?
@@ -267,6 +269,17 @@ Asked in
 <https://rust-lang.zulipchat.com/#narrow/stream/266220-t-rustdoc/topic/What.20is.20the.20.60check-test-line-numbers-match.60.20directive.3F>.
 -->
 
+#### Test-suite-specific directives
+
+The test suites [`rustdoc`][rustdoc-html-tests], [`rustdoc-js`/`rustdoc-js-std`][rustdoc-js-tests]
+and [`rustdoc-json`][rustdoc-json-tests] each feature an additional set of directives whose basic
+syntax resembles the one of compiletest directives but which are ultimately read and checked by
+separate tools. For more information, please read their respective chapters as linked above.
+
+[rustdoc-html-tests]: ../rustdoc-internals/rustdoc-test-suite.md
+[rustdoc-js-tests]: ../rustdoc-internals/search.html#testing-the-search-engine
+[rustdoc-json-tests]: ../rustdoc-internals/rustdoc-json-test-suite.md
+
 ### Pretty printing
 
 See [Pretty-printer](compiletest.md#pretty-printer-tests).
diff --git a/src/doc/rustc-dev-guide/src/tests/minicore.md b/src/doc/rustc-dev-guide/src/tests/minicore.md
index 507b259e027..def9aaf8733 100644
--- a/src/doc/rustc-dev-guide/src/tests/minicore.md
+++ b/src/doc/rustc-dev-guide/src/tests/minicore.md
@@ -7,9 +7,11 @@ ui/codegen/assembly test suites. It provides `core` stubs for tests that need to
 build for cross-compiled targets but do not need/want to run.
 
 <div class="warning">
+
 Please note that [`minicore`] is only intended for `core` items, and explicitly
 **not** `std` or `alloc` items because `core` items are applicable to a wider
 range of tests.
+
 </div>
 
 A test can use [`minicore`] by specifying the `//@ add-core-stubs` directive.
diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md
index 73c38736812..6526fe9c235 100644
--- a/src/doc/rustc-dev-guide/src/tests/running.md
+++ b/src/doc/rustc-dev-guide/src/tests/running.md
@@ -8,6 +8,7 @@ development because it takes a really long time. For local development, see the
 subsection after on how to run a subset of tests.
 
 <div class="warning">
+
 Running plain `./x test` will build the stage 1 compiler and then run the whole
 test suite. This not only include `tests/`, but also `library/`, `compiler/`,
 `src/tools/` package tests and more.
@@ -16,6 +17,7 @@ You usually only want to run a subset of the test suites (or even a smaller set
 of tests than that) which you expect will exercise your changes. PR CI exercises
 a subset of test collections, and merge queue CI will exercise all of the test
 collection.
+
 </div>
 
 ```text
@@ -116,8 +118,10 @@ By listing which test suites you want to run,
 you avoid having to run tests for components you did not change at all.
 
 <div class="warning">
+
 Note that bors only runs the tests with the full stage 2 build; therefore, while
 the tests **usually** work fine with stage 1, there are some limitations.
+
 </div>
 
 ### Run all tests using a stage 2 compiler
diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md
index 3402838da87..25d3efdbb82 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -220,8 +220,12 @@ negligible (i.e. there is no semantic difference between `//~ ERROR` and
 `//~ERROR` although the former is more common in the codebase).
 
 `~? <diagnostic kind>` (example being `~? ERROR`)
-is used to match diagnostics without line information.
-These can be placed on any line in the test file, but are conventionally placed at the end.
+is used to match diagnostics _without_ line info at all,
+or where the line info is outside the main test file[^main test file].
+These annotations can be placed on any line in the test file.
+
+[^main test file]: This is a file that has the `~?` annotations,
+as distinct from aux files, or sources that we have no control over.
 
 ### Error annotation examples
 
diff --git a/src/doc/rustc-dev-guide/triagebot.toml b/src/doc/rustc-dev-guide/triagebot.toml
index 978802edf3f..b3f4c2d281c 100644
--- a/src/doc/rustc-dev-guide/triagebot.toml
+++ b/src/doc/rustc-dev-guide/triagebot.toml
@@ -72,6 +72,23 @@ days-threshold = 7
 # Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment.html
 [assign]
 
+# NOTE: do not add `[assign.owners]` if we still wish to keep the opt-in
+# reviewer model, as `[assign.owners]` will cause triagebot auto-reviewer
+# assignment to kick in.
+
+# Custom PR welcome message for when no auto reviewer assignment is performed
+# and no explicit manual reviewer selection is made.
+# Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment.html#custom-welcome-messages
+[assign.custom_welcome_messages]
+welcome-message = ""
+welcome-message-no-reviewer = """\
+Thanks for the PR. If you have write access, feel free to merge this PR if it \
+does not need reviews. You can request a review using `r? rustc-dev-guide` or \
+`r? <username>`.
+"""
+
+# Groups for `r? <group>`.
+# Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment.html#usage
 # Keep members alphanumerically sorted.
 [assign.adhoc_groups]
 rustc-dev-guide = [
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index e7dfaaf4fd5..559e4867bbb 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -33,7 +33,7 @@ All tier 1 targets with host tools support the full standard library.
 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+)
+`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1+, glibc 2.17+)
 `i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI] [^win32-msvc-alignment]
 `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+)
@@ -91,20 +91,20 @@ target | notes
 `aarch64-pc-windows-msvc` | ARM64 Windows MSVC
 `aarch64-unknown-linux-musl` | ARM64 Linux with musl 1.2.3
 [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ARM64 OpenHarmony
-`arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2, glibc 2.17)
-`arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
-`armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2, glibc 2.17)
+`arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2+, glibc 2.17)
+`arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2+, glibc 2.17)
+`armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2+, glibc 2.17)
 [`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | Armv7-A OpenHarmony
-[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36)
-[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5)
+[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19+, glibc 2.36)
+[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19+, musl 1.2.5)
 [`i686-pc-windows-gnu`](platform-support/windows-gnu.md) | 32-bit MinGW (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI] [^win32-msvc-alignment]
-`powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17)
-`powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17)
-[`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10, glibc 2.17)
-[`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19, musl 1.2.3)
-[`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29)
-[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3)
-[`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2, glibc 2.17)
+`powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2+, glibc 2.17)
+`powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2+, glibc 2.17)
+[`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10+, glibc 2.17)
+[`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19+, musl 1.2.3)
+[`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20+, glibc 2.29)
+[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20+, musl 1.2.3)
+[`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2+, glibc 2.17)
 [`x86_64-unknown-freebsd`](platform-support/freebsd.md) | 64-bit x86 FreeBSD
 [`x86_64-unknown-illumos`](platform-support/illumos.md) | illumos
 `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3
@@ -158,16 +158,16 @@ target | std | notes
 [`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | ✓ | Arm64EC Windows MSVC
 [`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian
 [`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat
-[`armv5te-unknown-linux-gnueabi`](platform-support/armv5te-unknown-linux-gnueabi.md) | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23)
+[`armv5te-unknown-linux-gnueabi`](platform-support/armv5te-unknown-linux-gnueabi.md) | ✓ | Armv5TE Linux (kernel 4.4+, glibc 2.23)
 `armv5te-unknown-linux-musleabi` | ✓ | Armv5TE Linux with musl 1.2.3
 [`armv7-linux-androideabi`](platform-support/android.md) | ✓ | Armv7-A Android
-`armv7-unknown-linux-gnueabi` | ✓ | Armv7-A Linux (kernel 4.15, glibc 2.27)
+`armv7-unknown-linux-gnueabi` | ✓ | Armv7-A Linux (kernel 4.15+, glibc 2.27)
 `armv7-unknown-linux-musleabi` | ✓ | Armv7-A Linux with musl 1.2.3
 `armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.3, hardfloat
 [`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-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2, glibc 2.17, 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 ([Pentium 4 plus various extensions](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI]
 [`i686-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+, Pentium 4), LLVM ABI [^x86_32-floats-return-ABI]
@@ -184,13 +184,13 @@ target | std | notes
 [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA)
 `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA)
 `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA)
-`sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23)
+`sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4+, glibc 2.23)
 [`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M
 [`thumbv7em-none-eabi`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M
 [`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M, hardfloat
 [`thumbv7m-none-eabi`](platform-support/thumbv7m-none-eabi.md) | * | Bare Armv7-M
 [`thumbv7neon-linux-androideabi`](platform-support/android.md) | ✓ | Thumb2-mode Armv7-A Android with NEON
-`thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode Armv7-A Linux with NEON (kernel 4.4, glibc 2.23)
+`thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode Armv7-A Linux with NEON (kernel 4.4+, glibc 2.23)
 [`thumbv8m.base-none-eabi`](platform-support/thumbv8m.base-none-eabi.md) | * | Bare Armv8-M Baseline
 [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline
 [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat
@@ -206,7 +206,7 @@ target | std | notes
 [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android
 [`x86_64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ✓ | 64-bit x86 MinGW (Windows 10+), LLVM ABI
 [`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia
-`x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
+`x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15+, glibc 2.27)
 [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat
 [`x86_64-unknown-redox`](platform-support/redox.md) | ✓ | Redox OS
 [`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 64-bit UEFI
@@ -324,6 +324,8 @@ target | std | host | notes
 [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ |   | 32-bit Windows 7 support [^x86_32-floats-return-ABI] [^win32-msvc-alignment]
 [`i686-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  | [^x86_32-floats-return-ABI]
 [`loongarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ |   | LoongArch64 OpenHarmony
+[`loongarch32-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch32 Bare-metal (ILP32D ABI)
+[`loongarch32-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch32 Bare-metal (ILP32S ABI)
 [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? |  | Motorola 680x0 Linux
 [`m68k-unknown-none-elf`](platform-support/m68k-unknown-none-elf.md) |  |  | Motorola 680x0
 `mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23)
diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md
index a2bd6e5734c..fd90b0a2763 100644
--- a/src/doc/rustc/src/platform-support/loongarch-none.md
+++ b/src/doc/rustc/src/platform-support/loongarch-none.md
@@ -1,18 +1,18 @@
 # `loongarch*-unknown-none*`
 
-**Tier: 2**
+Freestanding/bare-metal LoongArch binaries in ELF format: firmware, kernels, etc.
 
-Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, etc.
-
-| Target | Description |
-|--------|-------------|
-| `loongarch64-unknown-none` | LoongArch 64-bit, LP64D ABI (freestanding, hard-float) |
-| `loongarch64-unknown-none-softfloat` | LoongArch 64-bit, LP64S ABI (freestanding, soft-float) |
+| Target | Description | Tier |
+|--------|-------------|------|
+| `loongarch32-unknown-none` | LoongArch 32-bit, ILP32D ABI (freestanding, hard-float) | Tier 3 |
+| `loongarch32-unknown-none-softfloat` | LoongArch 32-bit, ILP32S ABI (freestanding, soft-float) | Tier 3 |
+| `loongarch64-unknown-none` | LoongArch 64-bit, LP64D ABI (freestanding, hard-float) | Tier 2 |
+| `loongarch64-unknown-none-softfloat` | LoongArch 64-bit, LP64S ABI (freestanding, soft-float) | Tier 2 |
 
 ## Target maintainers
 
-[@heiher](https://github.com/heiher)
-[@xen0n](https://github.com/xen0n)
+- [@heiher](https://github.com/heiher)
+- [@xen0n](https://github.com/xen0n)
 
 ## Requirements
 
@@ -29,13 +29,13 @@ additional CPU features via the `-C target-feature=` codegen options to rustc, o
 via the `#[target_feature]` mechanism within Rust code.
 
 By default, code generated with the soft-float target should run on any
-LoongArch64 hardware, with the hard-float target additionally requiring an FPU;
+LoongArch hardware, with the hard-float target additionally requiring an FPU;
 enabling additional target features may raise this baseline.
 
 Code generated with the targets will use the `medium` code model by default.
 You can change this using the `-C code-model=` option to rustc.
 
-On `loongarch64-unknown-none*`, `extern "C"` uses the [architecture's standard calling convention][lapcs].
+On `loongarch*-unknown-none*`, `extern "C"` uses the [architecture's standard calling convention][lapcs].
 
 [lapcs]: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc
 
@@ -52,6 +52,8 @@ list in `bootstrap.toml`:
 [build]
 build-stage = 1
 target = [
+  "loongarch32-unknown-none",
+  "loongarch32-unknown-none-softfloat",
   "loongarch64-unknown-none",
   "loongarch64-unknown-none-softfloat",
 ]
@@ -64,13 +66,28 @@ As the targets support a variety of different environments and do not support
 
 ## Building Rust programs
 
+### loongarch32-unknown-none*
+
+The `loongarch32-unknown-none*` targets are Tier 3, so you must build the Rust
+compiler from source to use them.
+
+```sh
+# target flag may be used with any cargo or rustc command
+cargo build --target loongarch32-unknown-none
+cargo build --target loongarch32-unknown-none-softfloat
+```
+
+### loongarch64-unknown-none*
+
 Starting with Rust 1.74, precompiled artifacts are provided via `rustup`:
 
 ```sh
 # install cross-compile toolchain
 rustup target add loongarch64-unknown-none
+rustup target add loongarch64-unknown-none-softfloat
 # target flag may be used with any cargo or rustc command
 cargo build --target loongarch64-unknown-none
+cargo build --target loongarch64-unknown-none-softfloat
 ```
 
 ## Cross-compilation toolchains and C code
@@ -79,10 +96,10 @@ For cross builds, you will need an appropriate LoongArch C/C++ toolchain for
 linking, or if you want to compile C code along with Rust (such as for Rust
 crates with C dependencies).
 
-Rust *may* be able to use an `loongarch64-unknown-linux-gnu-` toolchain with
+Rust *may* be able to use an `loongarch{32,64}-unknown-linux-{gnu,musl}-` toolchain with
 appropriate standalone flags to build for this toolchain (depending on the assumptions
 of that toolchain, see below), or you may wish to use a separate
-`loongarch64-unknown-none` toolchain.
+`loongarch{32,64}-unknown-none` toolchain.
 
 On some LoongArch hosts that use ELF binaries, you *may* be able to use the host
 C toolchain, if it does not introduce assumptions about the host environment
diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
index 6ec93d1746c..65e6b417427 100644
--- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
+++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
@@ -143,15 +143,6 @@ But if you include this:
 
 it will not.
 
-### `test(attr(...))`
-
-This form of the `doc` attribute allows you to add arbitrary attributes to all your doctests. For
-example, if you want your doctests to fail if they have dead code, you could add this:
-
-```rust,no_run
-#![doc(test(attr(deny(dead_code))))]
-```
-
 ## At the item level
 
 These forms of the `#[doc]` attribute are used on individual items, to control how
@@ -283,3 +274,26 @@ To get around this limitation, we just add `#[doc(alias = "lib_name_do_something
 on the `do_something` method and then it's all good!
 Users can now look for `lib_name_do_something` in our crate directly and find
 `Obj::do_something`.
+
+### `test(attr(...))`
+
+This form of the `doc` attribute allows you to add arbitrary attributes to all your doctests. For
+example, if you want your doctests to fail if they have dead code, you could add this:
+
+```rust,no_run
+#![doc(test(attr(deny(dead_code))))]
+
+mod my_mod {
+    #![doc(test(attr(allow(dead_code))))] // but allow `dead_code` for this module
+}
+```
+
+`test(attr(..))` attributes are appended to the parent module's, they do not replace the current
+list of attributes. In the previous example, both attributes would be present:
+
+```rust,no_run
+// For every doctest in `my_mod`
+
+#![deny(dead_code)] // from the crate-root
+#![allow(dead_code)] // from `my_mod`
+```
diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish
index 4f22bc511de..10a4e684e33 100644
--- a/src/etc/completions/x.fish
+++ b/src/etc/completions/x.fish
@@ -1,6 +1,6 @@
 # Print an optspec for argparse to handle cmd's options that are independent of any subcommand.
 function __fish_x_global_optspecs
-	string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= error-format= json-output color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= ci= h/help
+	string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= error-format= json-output color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= ci= skip-std-check-if-no-download-rustc h/help
 end
 
 function __fish_x_needs_command
@@ -57,6 +57,7 @@ complete -c x -n "__fish_x_needs_command" -l bypass-bootstrap-lock -d 'Bootstrap
 complete -c x -n "__fish_x_needs_command" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_needs_command" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_needs_command" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_needs_command" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_needs_command" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_needs_command" -a "build" -d 'Compile either the compiler or libraries'
 complete -c x -n "__fish_x_needs_command" -a "check" -d 'Compile either the compiler or libraries, using cargo check'
@@ -108,6 +109,7 @@ complete -c x -n "__fish_x_using_subcommand build" -l bypass-bootstrap-lock -d '
 complete -c x -n "__fish_x_using_subcommand build" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand build" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand build" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand build" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand build" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand check" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand check" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -143,6 +145,7 @@ complete -c x -n "__fish_x_using_subcommand check" -l bypass-bootstrap-lock -d '
 complete -c x -n "__fish_x_using_subcommand check" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand check" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand check" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand check" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand check" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand clippy" -s A -d 'clippy lints to allow' -r
 complete -c x -n "__fish_x_using_subcommand clippy" -s D -d 'clippy lints to deny' -r
@@ -184,6 +187,7 @@ complete -c x -n "__fish_x_using_subcommand clippy" -l bypass-bootstrap-lock -d
 complete -c x -n "__fish_x_using_subcommand clippy" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand clippy" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand clippy" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand clippy" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand clippy" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand fix" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand fix" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -218,6 +222,7 @@ complete -c x -n "__fish_x_using_subcommand fix" -l bypass-bootstrap-lock -d 'Bo
 complete -c x -n "__fish_x_using_subcommand fix" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand fix" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand fix" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand fix" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand fix" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand fmt" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand fmt" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -254,6 +259,7 @@ complete -c x -n "__fish_x_using_subcommand fmt" -l bypass-bootstrap-lock -d 'Bo
 complete -c x -n "__fish_x_using_subcommand fmt" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand fmt" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand fmt" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand fmt" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand fmt" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand doc" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand doc" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -290,6 +296,7 @@ complete -c x -n "__fish_x_using_subcommand doc" -l bypass-bootstrap-lock -d 'Bo
 complete -c x -n "__fish_x_using_subcommand doc" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand doc" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand doc" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand doc" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand doc" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
 complete -c x -n "__fish_x_using_subcommand test" -l compiletest-rustc-args -d 'extra options to pass the compiler when running compiletest tests' -r
@@ -338,6 +345,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l bypass-bootstrap-lock -d 'B
 complete -c x -n "__fish_x_using_subcommand test" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand test" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand test" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand test" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand test" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand miri" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
 complete -c x -n "__fish_x_using_subcommand miri" -l config -d 'TOML configuration file for build' -r -F
@@ -376,6 +384,7 @@ complete -c x -n "__fish_x_using_subcommand miri" -l bypass-bootstrap-lock -d 'B
 complete -c x -n "__fish_x_using_subcommand miri" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand miri" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand miri" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand miri" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand miri" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand bench" -l test-args -r
 complete -c x -n "__fish_x_using_subcommand bench" -l config -d 'TOML configuration file for build' -r -F
@@ -411,6 +420,7 @@ complete -c x -n "__fish_x_using_subcommand bench" -l bypass-bootstrap-lock -d '
 complete -c x -n "__fish_x_using_subcommand bench" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand bench" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand bench" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand bench" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand bench" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand clean" -l stage -d 'Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used' -r
 complete -c x -n "__fish_x_using_subcommand clean" -l config -d 'TOML configuration file for build' -r -F
@@ -446,6 +456,7 @@ complete -c x -n "__fish_x_using_subcommand clean" -l bypass-bootstrap-lock -d '
 complete -c x -n "__fish_x_using_subcommand clean" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand clean" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand clean" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand clean" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand clean" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand dist" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand dist" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -480,6 +491,7 @@ complete -c x -n "__fish_x_using_subcommand dist" -l bypass-bootstrap-lock -d 'B
 complete -c x -n "__fish_x_using_subcommand dist" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand dist" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand dist" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand dist" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand dist" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand install" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand install" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -514,6 +526,7 @@ complete -c x -n "__fish_x_using_subcommand install" -l bypass-bootstrap-lock -d
 complete -c x -n "__fish_x_using_subcommand install" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand install" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand install" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand install" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand install" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand run" -l args -d 'arguments for the tool' -r
 complete -c x -n "__fish_x_using_subcommand run" -l config -d 'TOML configuration file for build' -r -F
@@ -549,6 +562,7 @@ complete -c x -n "__fish_x_using_subcommand run" -l bypass-bootstrap-lock -d 'Bo
 complete -c x -n "__fish_x_using_subcommand run" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand run" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand run" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand run" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand run" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand setup" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand setup" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -583,6 +597,7 @@ complete -c x -n "__fish_x_using_subcommand setup" -l bypass-bootstrap-lock -d '
 complete -c x -n "__fish_x_using_subcommand setup" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand setup" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand setup" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand setup" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand setup" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand suggest" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -618,6 +633,7 @@ complete -c x -n "__fish_x_using_subcommand suggest" -l bypass-bootstrap-lock -d
 complete -c x -n "__fish_x_using_subcommand suggest" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand suggest" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand suggest" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand suggest" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand suggest" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand vendor" -l sync -d 'Additional `Cargo.toml` to sync and vendor' -r -F
 complete -c x -n "__fish_x_using_subcommand vendor" -l config -d 'TOML configuration file for build' -r -F
@@ -654,6 +670,7 @@ complete -c x -n "__fish_x_using_subcommand vendor" -l bypass-bootstrap-lock -d
 complete -c x -n "__fish_x_using_subcommand vendor" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand vendor" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand vendor" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand vendor" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand vendor" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -688,6 +705,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "eprintln" -d 'Run `profile_local eprintln`. This executes the compiler on the given benchmarks and stores its stderr output'
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "samply" -d 'Run `profile_local samply` This executes the compiler on the given benchmarks and profiles it with `samply`. You need to install `samply`, e.g. using `cargo install samply`'
@@ -730,6 +748,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
@@ -767,6 +786,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
@@ -804,6 +824,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
@@ -841,6 +862,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -875,4 +897,5 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -s h -l help -d 'Print help (see more with \'--help\')'
diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1
index 638b87edfb2..23d8fe0cdd3 100644
--- a/src/etc/completions/x.ps1
+++ b/src/etc/completions/x.ps1
@@ -57,6 +57,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('build', 'build', [CompletionResultType]::ParameterValue, 'Compile either the compiler or libraries')
@@ -115,6 +116,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -157,6 +159,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -205,6 +208,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -246,6 +250,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -289,6 +294,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -332,6 +338,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -387,6 +394,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -432,6 +440,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -474,6 +483,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -516,6 +526,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -557,6 +568,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -598,6 +610,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -640,6 +653,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -681,6 +695,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -723,6 +738,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -766,6 +782,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -807,6 +824,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('eprintln', 'eprintln', [CompletionResultType]::ParameterValue, 'Run `profile_local eprintln`. This executes the compiler on the given benchmarks and stores its stderr output')
@@ -856,6 +874,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -900,6 +919,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -944,6 +964,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -988,6 +1009,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -1029,6 +1051,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index 75771ec9a81..1fc5bb12cfb 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -1,6 +1,6 @@
 # Print an optspec for argparse to handle cmd's options that are independent of any subcommand.
 function __fish_x.py_global_optspecs
-	string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= error-format= json-output color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= ci= h/help
+	string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= error-format= json-output color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= ci= skip-std-check-if-no-download-rustc h/help
 end
 
 function __fish_x.py_needs_command
@@ -57,6 +57,7 @@ complete -c x.py -n "__fish_x.py_needs_command" -l bypass-bootstrap-lock -d 'Boo
 complete -c x.py -n "__fish_x.py_needs_command" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_needs_command" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_needs_command" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_needs_command" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_needs_command" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_needs_command" -a "build" -d 'Compile either the compiler or libraries'
 complete -c x.py -n "__fish_x.py_needs_command" -a "check" -d 'Compile either the compiler or libraries, using cargo check'
@@ -108,6 +109,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand build" -l bypass-bootstrap-loc
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand build" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand build" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand check" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand check" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -143,6 +145,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand check" -l bypass-bootstrap-loc
 complete -c x.py -n "__fish_x.py_using_subcommand check" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand check" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand check" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand check" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand check" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -s A -d 'clippy lints to allow' -r
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -s D -d 'clippy lints to deny' -r
@@ -184,6 +187,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l bypass-bootstrap-lo
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -218,6 +222,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand fix" -l bypass-bootstrap-lock
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand fix" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -254,6 +259,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l bypass-bootstrap-lock
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -290,6 +296,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand doc" -l bypass-bootstrap-lock
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand doc" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l compiletest-rustc-args -d 'extra options to pass the compiler when running compiletest tests' -r
@@ -338,6 +345,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l bypass-bootstrap-lock
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand test" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand test" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l config -d 'TOML configuration file for build' -r -F
@@ -376,6 +384,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand miri" -l bypass-bootstrap-lock
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand miri" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -l test-args -r
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -l config -d 'TOML configuration file for build' -r -F
@@ -411,6 +420,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand bench" -l bypass-bootstrap-loc
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand bench" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -l stage -d 'Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used' -r
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -l config -d 'TOML configuration file for build' -r -F
@@ -446,6 +456,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clean" -l bypass-bootstrap-loc
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand clean" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -480,6 +491,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand dist" -l bypass-bootstrap-lock
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand dist" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand install" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand install" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -514,6 +526,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand install" -l bypass-bootstrap-l
 complete -c x.py -n "__fish_x.py_using_subcommand install" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand install" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand install" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand install" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand install" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand run" -l args -d 'arguments for the tool' -r
 complete -c x.py -n "__fish_x.py_using_subcommand run" -l config -d 'TOML configuration file for build' -r -F
@@ -549,6 +562,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand run" -l bypass-bootstrap-lock
 complete -c x.py -n "__fish_x.py_using_subcommand run" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand run" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand run" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand run" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand run" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -583,6 +597,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand setup" -l bypass-bootstrap-loc
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand setup" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -618,6 +633,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l bypass-bootstrap-l
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l sync -d 'Additional `Cargo.toml` to sync and vendor' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l config -d 'TOML configuration file for build' -r -F
@@ -654,6 +670,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l bypass-bootstrap-lo
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -688,6 +705,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subc
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "eprintln" -d 'Run `profile_local eprintln`. This executes the compiler on the given benchmarks and stores its stderr output'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -a "samply" -d 'Run `profile_local samply` This executes the compiler on the given benchmarks and profiles it with `samply`. You need to install `samply`, e.g. using `cargo install samply`'
@@ -730,6 +748,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
@@ -767,6 +786,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
@@ -804,6 +824,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l include -d 'Select the benchmarks that you want to run (separated by commas). If unspecified, all benchmarks will be executed' -r
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r
@@ -841,6 +862,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
@@ -875,4 +897,5 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -s h -l help -d 'Print help (see more with \'--help\')'
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index 0a716619106..5d224ac6df4 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -57,6 +57,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('build', 'build', [CompletionResultType]::ParameterValue, 'Compile either the compiler or libraries')
@@ -115,6 +116,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -157,6 +159,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -205,6 +208,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -246,6 +250,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -289,6 +294,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -332,6 +338,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -387,6 +394,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -432,6 +440,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -474,6 +483,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -516,6 +526,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -557,6 +568,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -598,6 +610,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -640,6 +653,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -681,6 +695,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -723,6 +738,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -766,6 +782,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -807,6 +824,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('eprintln', 'eprintln', [CompletionResultType]::ParameterValue, 'Run `profile_local eprintln`. This executes the compiler on the given benchmarks and stores its stderr output')
@@ -856,6 +874,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -900,6 +919,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -944,6 +964,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -988,6 +1009,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
@@ -1029,6 +1051,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
             [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
             [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
             [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
index 79b239c672d..568bf2fcc6d 100644
--- a/src/etc/completions/x.py.sh
+++ b/src/etc/completions/x.py.sh
@@ -85,7 +85,7 @@ _x.py() {
 
     case "${cmd}" in
         x.py)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -278,7 +278,7 @@ _x.py() {
             return 0
             ;;
         x.py__bench)
-            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -475,7 +475,7 @@ _x.py() {
             return 0
             ;;
         x.py__build)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -668,7 +668,7 @@ _x.py() {
             return 0
             ;;
         x.py__check)
-            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -861,7 +861,7 @@ _x.py() {
             return 0
             ;;
         x.py__clean)
-            opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1051,7 +1051,7 @@ _x.py() {
             return 0
             ;;
         x.py__clippy)
-            opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1260,7 +1260,7 @@ _x.py() {
             return 0
             ;;
         x.py__dist)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1453,7 +1453,7 @@ _x.py() {
             return 0
             ;;
         x.py__doc)
-            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1646,7 +1646,7 @@ _x.py() {
             return 0
             ;;
         x.py__fix)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1839,7 +1839,7 @@ _x.py() {
             return 0
             ;;
         x.py__fmt)
-            opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2032,7 +2032,7 @@ _x.py() {
             return 0
             ;;
         x.py__install)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2225,7 +2225,7 @@ _x.py() {
             return 0
             ;;
         x.py__miri)
-            opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2422,7 +2422,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2615,7 +2615,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf__benchmark)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help <benchmark-id> [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <benchmark-id> [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2820,7 +2820,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf__cachegrind)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3025,7 +3025,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf__compare)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help <BASE> <MODIFIED> [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <BASE> <MODIFIED> [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3218,7 +3218,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf__eprintln)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3423,7 +3423,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf__samply)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3628,7 +3628,7 @@ _x.py() {
             return 0
             ;;
         x.py__run)
-            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3825,7 +3825,7 @@ _x.py() {
             return 0
             ;;
         x.py__setup)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4018,7 +4018,7 @@ _x.py() {
             return 0
             ;;
         x.py__suggest)
-            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4211,7 +4211,7 @@ _x.py() {
             return 0
             ;;
         x.py__test)
-            opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4428,7 +4428,7 @@ _x.py() {
             return 0
             ;;
         x.py__vendor)
-            opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index fccea8484d7..bc55280d038 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -51,6 +51,7 @@ _x.py() {
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '::paths -- paths for the subcommand:_files' \
@@ -102,6 +103,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -146,6 +148,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -196,6 +199,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -239,6 +243,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -284,6 +289,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -329,6 +335,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -386,6 +393,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -433,6 +441,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -477,6 +486,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -521,6 +531,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -564,6 +575,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -607,6 +619,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -651,6 +664,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -694,6 +708,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '::profile -- Either the profile for `bootstrap.toml` or another setup action. May be omitted to set up interactively:_files' \
@@ -739,6 +754,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -784,6 +800,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -827,6 +844,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '::paths -- paths for the subcommand:_files' \
@@ -882,6 +900,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -928,6 +947,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -974,6 +994,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -1020,6 +1041,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 ':benchmark-id -- Identifier to associate benchmark results with:_default' \
@@ -1064,6 +1086,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 ':base -- The name of the base artifact to be compared:_default' \
diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh
index 2dd322bcfc1..d48c29e6298 100644
--- a/src/etc/completions/x.sh
+++ b/src/etc/completions/x.sh
@@ -85,7 +85,7 @@ _x() {
 
     case "${cmd}" in
         x)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -278,7 +278,7 @@ _x() {
             return 0
             ;;
         x__bench)
-            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -475,7 +475,7 @@ _x() {
             return 0
             ;;
         x__build)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -668,7 +668,7 @@ _x() {
             return 0
             ;;
         x__check)
-            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -861,7 +861,7 @@ _x() {
             return 0
             ;;
         x__clean)
-            opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1051,7 +1051,7 @@ _x() {
             return 0
             ;;
         x__clippy)
-            opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1260,7 +1260,7 @@ _x() {
             return 0
             ;;
         x__dist)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1453,7 +1453,7 @@ _x() {
             return 0
             ;;
         x__doc)
-            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1646,7 +1646,7 @@ _x() {
             return 0
             ;;
         x__fix)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1839,7 +1839,7 @@ _x() {
             return 0
             ;;
         x__fmt)
-            opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2032,7 +2032,7 @@ _x() {
             return 0
             ;;
         x__install)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2225,7 +2225,7 @@ _x() {
             return 0
             ;;
         x__miri)
-            opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2422,7 +2422,7 @@ _x() {
             return 0
             ;;
         x__perf)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2615,7 +2615,7 @@ _x() {
             return 0
             ;;
         x__perf__benchmark)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help <benchmark-id> [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <benchmark-id> [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2820,7 +2820,7 @@ _x() {
             return 0
             ;;
         x__perf__cachegrind)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3025,7 +3025,7 @@ _x() {
             return 0
             ;;
         x__perf__compare)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help <BASE> <MODIFIED> [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help <BASE> <MODIFIED> [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3218,7 +3218,7 @@ _x() {
             return 0
             ;;
         x__perf__eprintln)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3423,7 +3423,7 @@ _x() {
             return 0
             ;;
         x__perf__samply)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3628,7 +3628,7 @@ _x() {
             return 0
             ;;
         x__run)
-            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3825,7 +3825,7 @@ _x() {
             return 0
             ;;
         x__setup)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4018,7 +4018,7 @@ _x() {
             return 0
             ;;
         x__suggest)
-            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4211,7 +4211,7 @@ _x() {
             return 0
             ;;
         x__test)
-            opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4428,7 +4428,7 @@ _x() {
             return 0
             ;;
         x__vendor)
-            opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh
index 32b297b6cd5..2e3094fc379 100644
--- a/src/etc/completions/x.zsh
+++ b/src/etc/completions/x.zsh
@@ -51,6 +51,7 @@ _x() {
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '::paths -- paths for the subcommand:_files' \
@@ -102,6 +103,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -146,6 +148,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -196,6 +199,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -239,6 +243,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -284,6 +289,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -329,6 +335,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -386,6 +393,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -433,6 +441,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -477,6 +486,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -521,6 +531,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -564,6 +575,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -607,6 +619,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -651,6 +664,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -694,6 +708,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '::profile -- Either the profile for `bootstrap.toml` or another setup action. May be omitted to set up interactively:_files' \
@@ -739,6 +754,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -784,6 +800,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -827,6 +844,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '::paths -- paths for the subcommand:_files' \
@@ -882,6 +900,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -928,6 +947,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -974,6 +994,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 '*::paths -- paths for the subcommand:_files' \
@@ -1020,6 +1041,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 ':benchmark-id -- Identifier to associate benchmark results with:_default' \
@@ -1064,6 +1086,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
 '--enable-bolt-settings[Enable BOLT link flags]' \
 '--skip-stage0-validation[Skip stage0 compiler validation]' \
+'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
 '-h[Print help (see more with '\''--help'\'')]' \
 '--help[Print help (see more with '\''--help'\'')]' \
 ':base -- The name of the base artifact to be compared:_default' \
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 138ac3c97f7..a91ea55bcae 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -11,7 +11,7 @@ use tracing::{debug, instrument};
 
 use crate::clean::{
     self, Lifetime, clean_generic_param_def, clean_middle_ty, clean_predicate,
-    clean_trait_ref_with_constraints, clean_ty_generics, simplify,
+    clean_trait_ref_with_constraints, clean_ty_generics_inner, simplify,
 };
 use crate::core::DocContext;
 
@@ -101,7 +101,7 @@ fn synthesize_auto_trait_impl<'tcx>(
             // Instead, we generate `impl !Send for Foo<T>`, which better
             // expresses the fact that `Foo<T>` never implements `Send`,
             // regardless of the choice of `T`.
-            let mut generics = clean_ty_generics(
+            let mut generics = clean_ty_generics_inner(
                 cx,
                 tcx.generics_of(item_def_id),
                 ty::GenericPredicates::default(),
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 89245fee515..c889f52b789 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -90,11 +90,7 @@ pub(crate) fn synthesize_blanket_impls(
                     stability: None,
                     kind: clean::ImplItem(Box::new(clean::Impl {
                         safety: hir::Safety::Safe,
-                        generics: clean_ty_generics(
-                            cx,
-                            tcx.generics_of(impl_def_id),
-                            tcx.explicit_predicates_of(impl_def_id),
-                        ),
+                        generics: clean_ty_generics(cx, impl_def_id),
                         // FIXME(eddyb) compute both `trait_` and `for_` from
                         // the post-inference `trait_ref`, as it's more accurate.
                         trait_: Some(clean_trait_ref_with_constraints(
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index ebc276b38fb..a3762e4117d 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -508,6 +508,7 @@ impl fmt::Display for Display<'_> {
                     (sym::target_arch, Some(arch)) => match arch.as_str() {
                         "aarch64" => "AArch64",
                         "arm" => "ARM",
+                        "loongarch32" => "LoongArch LA32",
                         "loongarch64" => "LoongArch LA64",
                         "m68k" => "M68k",
                         "csky" => "CSKY",
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 55a116a018a..9b5491310b4 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -264,16 +264,13 @@ pub(crate) fn build_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
         .map(|item| clean_middle_assoc_item(item, cx))
         .collect();
 
-    let predicates = cx.tcx.predicates_of(did);
-    let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
-    let generics = filter_non_trait_generics(did, generics);
+    let generics = clean_ty_generics(cx, did);
     let (generics, supertrait_bounds) = separate_self_bounds(generics);
     clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds }
 }
 
 fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias {
-    let predicates = cx.tcx.predicates_of(did);
-    let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
+    let generics = clean_ty_generics(cx, did);
     let (generics, bounds) = separate_self_bounds(generics);
     clean::TraitAlias { generics, bounds }
 }
@@ -281,8 +278,7 @@ fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias {
 pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box<clean::Function> {
     let sig = cx.tcx.fn_sig(def_id).instantiate_identity();
     // The generics need to be cleaned before the signature.
-    let mut generics =
-        clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id));
+    let mut generics = clean_ty_generics(cx, def_id);
     let bound_vars = clean_bound_vars(sig.bound_vars());
 
     // At the time of writing early & late-bound params are stored separately in rustc,
@@ -311,30 +307,26 @@ pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box<clea
 }
 
 fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
-    let predicates = cx.tcx.explicit_predicates_of(did);
-
     clean::Enum {
-        generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
+        generics: clean_ty_generics(cx, did),
         variants: cx.tcx.adt_def(did).variants().iter().map(|v| clean_variant_def(v, cx)).collect(),
     }
 }
 
 fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct {
-    let predicates = cx.tcx.explicit_predicates_of(did);
     let variant = cx.tcx.adt_def(did).non_enum_variant();
 
     clean::Struct {
         ctor_kind: variant.ctor_kind(),
-        generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
+        generics: clean_ty_generics(cx, did),
         fields: variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(),
     }
 }
 
 fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union {
-    let predicates = cx.tcx.explicit_predicates_of(did);
     let variant = cx.tcx.adt_def(did).non_enum_variant();
 
-    let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
+    let generics = clean_ty_generics(cx, did);
     let fields = variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect();
     clean::Union { generics, fields }
 }
@@ -344,14 +336,13 @@ fn build_type_alias(
     did: DefId,
     ret: &mut Vec<Item>,
 ) -> Box<clean::TypeAlias> {
-    let predicates = cx.tcx.explicit_predicates_of(did);
     let ty = cx.tcx.type_of(did).instantiate_identity();
     let type_ = clean_middle_ty(ty::Binder::dummy(ty), cx, Some(did), None);
     let inner_type = clean_ty_alias_inner_type(ty, cx, ret);
 
     Box::new(clean::TypeAlias {
         type_,
-        generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
+        generics: clean_ty_generics(cx, did),
         inner_type,
         item_type: None,
     })
@@ -483,7 +474,6 @@ pub(crate) fn build_impl(
     }
 
     let document_hidden = cx.render_options.document_hidden;
-    let predicates = tcx.explicit_predicates_of(did);
     let (trait_items, generics) = match impl_item {
         Some(impl_) => (
             impl_
@@ -549,9 +539,7 @@ pub(crate) fn build_impl(
                 })
                 .map(|item| clean_middle_assoc_item(item, cx))
                 .collect::<Vec<_>>(),
-            clean::enter_impl_trait(cx, |cx| {
-                clean_ty_generics(cx, tcx.generics_of(did), predicates)
-            }),
+            clean::enter_impl_trait(cx, |cx| clean_ty_generics(cx, did)),
         ),
     };
     let polarity = tcx.impl_polarity(did);
@@ -713,8 +701,7 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
 }
 
 fn build_const_item(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant {
-    let mut generics =
-        clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id));
+    let mut generics = clean_ty_generics(cx, def_id);
     clean::simplify::move_bounds_to_generic_parameters(&mut generics);
     let ty = clean_middle_ty(
         ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()),
@@ -761,44 +748,6 @@ fn build_macro(
     }
 }
 
-/// A trait's generics clause actually contains all of the predicates for all of
-/// its associated types as well. We specifically move these clauses to the
-/// associated types instead when displaying, so when we're generating the
-/// generics for the trait itself we need to be sure to remove them.
-/// We also need to remove the implied "recursive" Self: Trait bound.
-///
-/// The inverse of this filtering logic can be found in the `Clean`
-/// implementation for `AssociatedType`
-fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics {
-    for pred in &mut g.where_predicates {
-        if let clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref mut bounds, .. } =
-            *pred
-        {
-            bounds.retain(|bound| match bound {
-                clean::GenericBound::TraitBound(clean::PolyTrait { trait_, .. }, _) => {
-                    trait_.def_id() != trait_did
-                }
-                _ => true,
-            });
-        }
-    }
-
-    g.where_predicates.retain(|pred| match pred {
-        clean::WherePredicate::BoundPredicate {
-            ty:
-                clean::QPath(box clean::QPathData {
-                    self_type: clean::Generic(_),
-                    trait_: Some(trait_),
-                    ..
-                }),
-            bounds,
-            ..
-        } => !bounds.is_empty() && trait_.def_id() != trait_did,
-        _ => true,
-    });
-    g
-}
-
 fn separate_self_bounds(mut g: clean::Generics) -> (clean::Generics, Vec<clean::GenericBound>) {
     let mut ty_bounds = Vec::new();
     g.where_predicates.retain(|pred| match *pred {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index e8cf25b1906..db4bcdaeb6c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -371,10 +371,9 @@ fn clean_where_predicate<'tcx>(
             bounds: wrp.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
         },
 
-        hir::WherePredicateKind::EqPredicate(wrp) => WherePredicate::EqPredicate {
-            lhs: clean_ty(wrp.lhs_ty, cx),
-            rhs: clean_ty(wrp.rhs_ty, cx).into(),
-        },
+        // We should never actually reach this case because these predicates should've already been
+        // rejected in an earlier compiler pass. This feature isn't fully implemented (#20041).
+        hir::WherePredicateKind::EqPredicate(_) => bug!("EqPredicate"),
     })
 }
 
@@ -470,49 +469,37 @@ fn clean_projection_predicate<'tcx>(
     cx: &mut DocContext<'tcx>,
 ) -> WherePredicate {
     WherePredicate::EqPredicate {
-        lhs: clean_projection(
-            pred.map_bound(|p| {
-                // FIXME: This needs to be made resilient for `AliasTerm`s that
-                // are associated consts.
-                p.projection_term.expect_ty(cx.tcx)
-            }),
-            cx,
-            None,
-        ),
+        lhs: clean_projection(pred.map_bound(|p| p.projection_term), cx, None),
         rhs: clean_middle_term(pred.map_bound(|p| p.term), cx),
     }
 }
 
 fn clean_projection<'tcx>(
-    ty: ty::Binder<'tcx, ty::AliasTy<'tcx>>,
+    proj: ty::Binder<'tcx, ty::AliasTerm<'tcx>>,
     cx: &mut DocContext<'tcx>,
-    def_id: Option<DefId>,
-) -> Type {
-    if cx.tcx.is_impl_trait_in_trait(ty.skip_binder().def_id) {
-        return clean_middle_opaque_bounds(cx, ty.skip_binder().def_id, ty.skip_binder().args);
-    }
-
+    parent_def_id: Option<DefId>,
+) -> QPathData {
     let trait_ = clean_trait_ref_with_constraints(
         cx,
-        ty.map_bound(|ty| ty.trait_ref(cx.tcx)),
+        proj.map_bound(|proj| proj.trait_ref(cx.tcx)),
         ThinVec::new(),
     );
-    let self_type = clean_middle_ty(ty.map_bound(|ty| ty.self_ty()), cx, None, None);
-    let self_def_id = if let Some(def_id) = def_id {
-        cx.tcx.opt_parent(def_id).or(Some(def_id))
-    } else {
-        self_type.def_id(&cx.cache)
+    let self_type = clean_middle_ty(proj.map_bound(|proj| proj.self_ty()), cx, None, None);
+    let self_def_id = match parent_def_id {
+        Some(parent_def_id) => cx.tcx.opt_parent(parent_def_id).or(Some(parent_def_id)),
+        None => self_type.def_id(&cx.cache),
     };
-    let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
-    Type::QPath(Box::new(QPathData {
-        assoc: projection_to_path_segment(ty, cx),
-        should_show_cast,
+    let should_fully_qualify = should_fully_qualify_path(self_def_id, &trait_, &self_type);
+
+    QPathData {
+        assoc: projection_to_path_segment(proj, cx),
         self_type,
+        should_fully_qualify,
         trait_: Some(trait_),
-    }))
+    }
 }
 
-fn compute_should_show_cast(self_def_id: Option<DefId>, trait_: &Path, self_type: &Type) -> bool {
+fn should_fully_qualify_path(self_def_id: Option<DefId>, trait_: &Path, self_type: &Type) -> bool {
     !trait_.segments.is_empty()
         && self_def_id
             .zip(Some(trait_.def_id()))
@@ -520,18 +507,17 @@ fn compute_should_show_cast(self_def_id: Option<DefId>, trait_: &Path, self_type
 }
 
 fn projection_to_path_segment<'tcx>(
-    ty: ty::Binder<'tcx, ty::AliasTy<'tcx>>,
+    proj: ty::Binder<'tcx, ty::AliasTerm<'tcx>>,
     cx: &mut DocContext<'tcx>,
 ) -> PathSegment {
-    let def_id = ty.skip_binder().def_id;
-    let item = cx.tcx.associated_item(def_id);
+    let def_id = proj.skip_binder().def_id;
     let generics = cx.tcx.generics_of(def_id);
     PathSegment {
-        name: item.name(),
+        name: cx.tcx.item_name(def_id),
         args: GenericArgs::AngleBracketed {
             args: clean_middle_generic_args(
                 cx,
-                ty.map_bound(|ty| &ty.args[generics.parent_count..]),
+                proj.map_bound(|ty| &ty.args[generics.parent_count..]),
                 false,
                 def_id,
             ),
@@ -807,7 +793,11 @@ pub(crate) fn clean_generics<'tcx>(
     }
 }
 
-fn clean_ty_generics<'tcx>(
+fn clean_ty_generics<'tcx>(cx: &mut DocContext<'tcx>, def_id: DefId) -> Generics {
+    clean_ty_generics_inner(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id))
+}
+
+fn clean_ty_generics_inner<'tcx>(
     cx: &mut DocContext<'tcx>,
     gens: &ty::Generics,
     preds: ty::GenericPredicates<'tcx>,
@@ -845,7 +835,7 @@ fn clean_ty_generics<'tcx>(
         .predicates
         .iter()
         .flat_map(|(pred, _)| {
-            let mut projection = None;
+            let mut proj_pred = None;
             let param_idx = {
                 let bound_p = pred.kind();
                 match bound_p.skip_binder() {
@@ -860,7 +850,7 @@ fn clean_ty_generics<'tcx>(
                     ty::ClauseKind::Projection(p)
                         if let ty::Param(param) = p.projection_term.self_ty().kind() =>
                     {
-                        projection = Some(bound_p.rebind(p));
+                        proj_pred = Some(bound_p.rebind(p));
                         Some(param.index)
                     }
                     _ => None,
@@ -874,22 +864,12 @@ fn clean_ty_generics<'tcx>(
 
                 bounds.extend(pred.get_bounds().into_iter().flatten().cloned());
 
-                if let Some(proj) = projection
-                    && let lhs = clean_projection(
-                        proj.map_bound(|p| {
-                            // FIXME: This needs to be made resilient for `AliasTerm`s that
-                            // are associated consts.
-                            p.projection_term.expect_ty(cx.tcx)
-                        }),
-                        cx,
-                        None,
-                    )
-                    && let Some((_, trait_did, name)) = lhs.projection()
-                {
+                if let Some(pred) = proj_pred {
+                    let lhs = clean_projection(pred.map_bound(|p| p.projection_term), cx, None);
                     impl_trait_proj.entry(param_idx).or_default().push((
-                        trait_did,
-                        name,
-                        proj.map_bound(|p| p.term),
+                        lhs.trait_.unwrap().def_id(),
+                        lhs.assoc,
+                        pred.map_bound(|p| p.term),
                     ));
                 }
 
@@ -1321,11 +1301,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
                 None,
             );
 
-            let mut generics = clean_ty_generics(
-                cx,
-                tcx.generics_of(assoc_item.def_id),
-                tcx.explicit_predicates_of(assoc_item.def_id),
-            );
+            let mut generics = clean_ty_generics(cx, assoc_item.def_id);
             simplify::move_bounds_to_generic_parameters(&mut generics);
 
             match assoc_item.container {
@@ -1413,7 +1389,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
                 let bounds = tcx.explicit_item_bounds(assoc_item.def_id).iter_identity_copied();
                 predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied()));
             }
-            let mut generics = clean_ty_generics(
+            let mut generics = clean_ty_generics_inner(
                 cx,
                 tcx.generics_of(assoc_item.def_id),
                 ty::GenericPredicates { parent: None, predicates },
@@ -1695,10 +1671,11 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
             register_res(cx, trait_.res);
             let self_def_id = DefId::local(qself.hir_id.owner.def_id.local_def_index);
             let self_type = clean_ty(qself, cx);
-            let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type);
+            let should_fully_qualify =
+                should_fully_qualify_path(Some(self_def_id), &trait_, &self_type);
             Type::QPath(Box::new(QPathData {
                 assoc: clean_path_segment(p.segments.last().expect("segments were empty"), cx),
-                should_show_cast,
+                should_fully_qualify,
                 self_type,
                 trait_: Some(trait_),
             }))
@@ -1707,16 +1684,16 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
             let ty = lower_ty(cx.tcx, hir_ty);
             let self_type = clean_ty(qself, cx);
 
-            let (trait_, should_show_cast) = match ty.kind() {
+            let (trait_, should_fully_qualify) = match ty.kind() {
                 ty::Alias(ty::Projection, proj) => {
                     let res = Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id);
                     let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
                     register_res(cx, trait_.res);
                     let self_def_id = res.opt_def_id();
-                    let should_show_cast =
-                        compute_should_show_cast(self_def_id, &trait_, &self_type);
+                    let should_fully_qualify =
+                        should_fully_qualify_path(self_def_id, &trait_, &self_type);
 
-                    (Some(trait_), should_show_cast)
+                    (Some(trait_), should_fully_qualify)
                 }
                 ty::Alias(ty::Inherent, _) => (None, false),
                 // Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
@@ -1726,7 +1703,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
 
             Type::QPath(Box::new(QPathData {
                 assoc: clean_path_segment(segment, cx),
-                should_show_cast,
+                should_fully_qualify,
                 self_type,
                 trait_,
             }))
@@ -2145,14 +2122,8 @@ pub(crate) fn clean_middle_ty<'tcx>(
                 .map(|pb| AssocItemConstraint {
                     assoc: projection_to_path_segment(
                         pb.map_bound(|pb| {
-                            pb
-                                // HACK(compiler-errors): Doesn't actually matter what self
-                                // type we put here, because we're only using the GAT's args.
-                                .with_self_ty(cx.tcx, cx.tcx.types.self_param)
+                            pb.with_self_ty(cx.tcx, cx.tcx.types.trait_object_dummy_self)
                                 .projection_term
-                                // FIXME: This needs to be made resilient for `AliasTerm`s
-                                // that are associated consts.
-                                .expect_ty(cx.tcx)
                         }),
                         cx,
                     ),
@@ -2185,18 +2156,25 @@ pub(crate) fn clean_middle_ty<'tcx>(
             Tuple(t.iter().map(|t| clean_middle_ty(bound_ty.rebind(t), cx, None, None)).collect())
         }
 
-        ty::Alias(ty::Projection, data) => {
-            clean_projection(bound_ty.rebind(data), cx, parent_def_id)
+        ty::Alias(ty::Projection, alias_ty @ ty::AliasTy { def_id, args, .. }) => {
+            if cx.tcx.is_impl_trait_in_trait(def_id) {
+                clean_middle_opaque_bounds(cx, def_id, args)
+            } else {
+                Type::QPath(Box::new(clean_projection(
+                    bound_ty.rebind(alias_ty.into()),
+                    cx,
+                    parent_def_id,
+                )))
+            }
         }
 
-        ty::Alias(ty::Inherent, alias_ty) => {
-            let def_id = alias_ty.def_id;
+        ty::Alias(ty::Inherent, alias_ty @ ty::AliasTy { def_id, .. }) => {
             let alias_ty = bound_ty.rebind(alias_ty);
             let self_type = clean_middle_ty(alias_ty.map_bound(|ty| ty.self_ty()), cx, None, None);
 
             Type::QPath(Box::new(QPathData {
                 assoc: PathSegment {
-                    name: cx.tcx.associated_item(def_id).name(),
+                    name: cx.tcx.item_name(def_id),
                     args: GenericArgs::AngleBracketed {
                         args: clean_middle_generic_args(
                             cx,
@@ -2207,26 +2185,21 @@ pub(crate) fn clean_middle_ty<'tcx>(
                         constraints: Default::default(),
                     },
                 },
-                should_show_cast: false,
+                should_fully_qualify: false,
                 self_type,
                 trait_: None,
             }))
         }
 
-        ty::Alias(ty::Free, data) => {
+        ty::Alias(ty::Free, ty::AliasTy { def_id, args, .. }) => {
             if cx.tcx.features().lazy_type_alias() {
                 // Free type alias `data` represents the `type X` in `type X = Y`. If we need `Y`,
                 // we need to use `type_of`.
-                let path = clean_middle_path(
-                    cx,
-                    data.def_id,
-                    false,
-                    ThinVec::new(),
-                    bound_ty.rebind(data.args),
-                );
+                let path =
+                    clean_middle_path(cx, def_id, false, ThinVec::new(), bound_ty.rebind(args));
                 Type::Path { path }
             } else {
-                let ty = cx.tcx.type_of(data.def_id).instantiate(cx.tcx, data.args);
+                let ty = cx.tcx.type_of(def_id).instantiate(cx.tcx, args);
                 clean_middle_ty(bound_ty.rebind(ty), cx, None, None)
             }
         }
@@ -2313,18 +2286,17 @@ fn clean_middle_opaque_bounds<'tcx>(
             let bindings: ThinVec<_> = bounds
                 .iter()
                 .filter_map(|(bound, _)| {
-                    if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder()
-                        && proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder()
+                    let bound = bound.kind();
+                    if let ty::ClauseKind::Projection(proj_pred) = bound.skip_binder()
+                        && proj_pred.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder()
                     {
                         return Some(AssocItemConstraint {
                             assoc: projection_to_path_segment(
-                                // FIXME: This needs to be made resilient for `AliasTerm`s that
-                                // are associated consts.
-                                bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)),
+                                bound.rebind(proj_pred.projection_term),
                                 cx,
                             ),
                             kind: AssocItemConstraintKind::Equality {
-                                term: clean_middle_term(bound.kind().rebind(proj.term), cx),
+                                term: clean_middle_term(bound.rebind(proj_pred.term), cx),
                             },
                         });
                     }
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 41943b94d1e..40efa997868 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -46,11 +46,8 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: ThinVec<WP>) -> ThinVe
     // Look for equality predicates on associated types that can be merged into
     // general bound predicates.
     equalities.retain(|(lhs, rhs)| {
-        let Some((ty, trait_did, name)) = lhs.projection() else {
-            return true;
-        };
-        let Some((bounds, _)) = tybounds.get_mut(ty) else { return true };
-        merge_bounds(cx, bounds, trait_did, name, rhs)
+        let Some((bounds, _)) = tybounds.get_mut(&lhs.self_type) else { return true };
+        merge_bounds(cx, bounds, lhs.trait_.as_ref().unwrap().def_id(), lhs.assoc.clone(), rhs)
     });
 
     // And finally, let's reassemble everything
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 9e46d0b47e9..bde1a2e5e66 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1277,7 +1277,7 @@ impl GenericBound {
     }
 
     fn sized_with(cx: &mut DocContext<'_>, modifiers: hir::TraitBoundModifiers) -> GenericBound {
-        let did = cx.tcx.require_lang_item(LangItem::Sized, None);
+        let did = cx.tcx.require_lang_item(LangItem::Sized, DUMMY_SP);
         let empty = ty::Binder::dummy(ty::GenericArgs::empty());
         let path = clean_middle_path(cx, did, false, ThinVec::new(), empty);
         inline::record_extern_fqn(cx, did, ItemType::Trait);
@@ -1341,7 +1341,7 @@ impl PreciseCapturingArg {
 pub(crate) enum WherePredicate {
     BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<GenericParamDef> },
     RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
-    EqPredicate { lhs: Type, rhs: Term },
+    EqPredicate { lhs: QPathData, rhs: Term },
 }
 
 impl WherePredicate {
@@ -1704,14 +1704,6 @@ impl Type {
         matches!(self, Type::Tuple(v) if v.is_empty())
     }
 
-    pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> {
-        if let QPath(box QPathData { self_type, trait_, assoc, .. }) = self {
-            Some((self_type, trait_.as_ref()?.def_id(), assoc.clone()))
-        } else {
-            None
-        }
-    }
-
     /// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s.
     ///
     /// [clean]: crate::clean
@@ -1746,7 +1738,7 @@ pub(crate) struct QPathData {
     pub assoc: PathSegment,
     pub self_type: Type,
     /// FIXME: compute this field on demand.
-    pub should_show_cast: bool,
+    pub should_fully_qualify: bool,
     pub trait_: Option<Path>,
 }
 
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index b2fe24db0a2..a81d6020f71 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -5,6 +5,7 @@ mod runner;
 mod rust;
 
 use std::fs::File;
+use std::hash::{Hash, Hasher};
 use std::io::{self, Write};
 use std::path::{Path, PathBuf};
 use std::process::{self, Command, Stdio};
@@ -14,7 +15,7 @@ use std::{panic, str};
 
 pub(crate) use make::{BuildDocTestBuilder, DocTestBuilder};
 pub(crate) use markdown::test as test_markdown;
-use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
+use rustc_data_structures::fx::{FxHashMap, FxHasher, FxIndexMap, FxIndexSet};
 use rustc_errors::emitter::HumanReadableErrorType;
 use rustc_errors::{ColorConfig, DiagCtxtHandle};
 use rustc_hir as hir;
@@ -45,8 +46,6 @@ pub(crate) struct GlobalTestOptions {
     /// Whether inserting extra indent spaces in code block,
     /// default is `false`, only `true` for generating code link of Rust playground
     pub(crate) insert_indent_space: bool,
-    /// Additional crate-level attributes to add to doctests.
-    pub(crate) attrs: Vec<String>,
     /// Path to file containing arguments for the invocation of rustc.
     pub(crate) args_file: PathBuf,
 }
@@ -283,7 +282,7 @@ pub(crate) fn run_tests(
     rustdoc_options: &Arc<RustdocOptions>,
     unused_extern_reports: &Arc<Mutex<Vec<UnusedExterns>>>,
     mut standalone_tests: Vec<test::TestDescAndFn>,
-    mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>,
+    mergeable_tests: FxIndexMap<MergeableTestKey, Vec<(DocTestBuilder, ScrapedDocTest)>>,
     // We pass this argument so we can drop it manually before using `exit`.
     mut temp_dir: Option<TempDir>,
 ) {
@@ -298,7 +297,7 @@ pub(crate) fn run_tests(
     let mut ran_edition_tests = 0;
     let target_str = rustdoc_options.target.to_string();
 
-    for (edition, mut doctests) in mergeable_tests {
+    for (MergeableTestKey { edition, global_crate_attrs_hash }, mut doctests) in mergeable_tests {
         if doctests.is_empty() {
             continue;
         }
@@ -308,8 +307,8 @@ pub(crate) fn run_tests(
 
         let rustdoc_test_options = IndividualTestOptions::new(
             rustdoc_options,
-            &Some(format!("merged_doctest_{edition}")),
-            PathBuf::from(format!("doctest_{edition}.rs")),
+            &Some(format!("merged_doctest_{edition}_{global_crate_attrs_hash}")),
+            PathBuf::from(format!("doctest_{edition}_{global_crate_attrs_hash}.rs")),
         );
 
         for (doctest, scraped_test) in &doctests {
@@ -371,12 +370,9 @@ fn scrape_test_config(
     attrs: &[hir::Attribute],
     args_file: PathBuf,
 ) -> GlobalTestOptions {
-    use rustc_ast_pretty::pprust;
-
     let mut opts = GlobalTestOptions {
         crate_name,
         no_crate_inject: false,
-        attrs: Vec::new(),
         insert_indent_space: false,
         args_file,
     };
@@ -393,13 +389,7 @@ fn scrape_test_config(
         if attr.has_name(sym::no_crate_inject) {
             opts.no_crate_inject = true;
         }
-        if attr.has_name(sym::attr)
-            && let Some(l) = attr.meta_item_list()
-        {
-            for item in l {
-                opts.attrs.push(pprust::meta_list_item_to_string(item));
-            }
-        }
+        // NOTE: `test(attr(..))` is handled when discovering the individual tests
     }
 
     opts
@@ -848,6 +838,7 @@ pub(crate) struct ScrapedDocTest {
     text: String,
     name: String,
     span: Span,
+    global_crate_attrs: Vec<String>,
 }
 
 impl ScrapedDocTest {
@@ -858,6 +849,7 @@ impl ScrapedDocTest {
         langstr: LangString,
         text: String,
         span: Span,
+        global_crate_attrs: Vec<String>,
     ) -> Self {
         let mut item_path = logical_path.join("::");
         item_path.retain(|c| c != ' ');
@@ -867,7 +859,7 @@ impl ScrapedDocTest {
         let name =
             format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionaly());
 
-        Self { filename, line, langstr, text, name, span }
+        Self { filename, line, langstr, text, name, span, global_crate_attrs }
     }
     fn edition(&self, opts: &RustdocOptions) -> Edition {
         self.langstr.edition.unwrap_or(opts.edition)
@@ -896,9 +888,15 @@ pub(crate) trait DocTestVisitor {
     fn visit_header(&mut self, _name: &str, _level: u32) {}
 }
 
+#[derive(Clone, Debug, Hash, Eq, PartialEq)]
+pub(crate) struct MergeableTestKey {
+    edition: Edition,
+    global_crate_attrs_hash: u64,
+}
+
 struct CreateRunnableDocTests {
     standalone_tests: Vec<test::TestDescAndFn>,
-    mergeable_tests: FxIndexMap<Edition, Vec<(DocTestBuilder, ScrapedDocTest)>>,
+    mergeable_tests: FxIndexMap<MergeableTestKey, Vec<(DocTestBuilder, ScrapedDocTest)>>,
 
     rustdoc_options: Arc<RustdocOptions>,
     opts: GlobalTestOptions,
@@ -949,6 +947,7 @@ impl CreateRunnableDocTests {
         let edition = scraped_test.edition(&self.rustdoc_options);
         let doctest = BuildDocTestBuilder::new(&scraped_test.text)
             .crate_name(&self.opts.crate_name)
+            .global_crate_attrs(scraped_test.global_crate_attrs.clone())
             .edition(edition)
             .can_merge_doctests(self.can_merge_doctests)
             .test_id(test_id)
@@ -965,7 +964,17 @@ impl CreateRunnableDocTests {
             let test_desc = self.generate_test_desc_and_fn(doctest, scraped_test);
             self.standalone_tests.push(test_desc);
         } else {
-            self.mergeable_tests.entry(edition).or_default().push((doctest, scraped_test));
+            self.mergeable_tests
+                .entry(MergeableTestKey {
+                    edition,
+                    global_crate_attrs_hash: {
+                        let mut hasher = FxHasher::default();
+                        scraped_test.global_crate_attrs.hash(&mut hasher);
+                        hasher.finish()
+                    },
+                })
+                .or_default()
+                .push((doctest, scraped_test));
         }
     }
 
diff --git a/src/librustdoc/doctest/extracted.rs b/src/librustdoc/doctest/extracted.rs
index 3b17ccc78c7..ebe6bfd22ba 100644
--- a/src/librustdoc/doctest/extracted.rs
+++ b/src/librustdoc/doctest/extracted.rs
@@ -35,13 +35,16 @@ impl ExtractedDocTests {
     ) {
         let edition = scraped_test.edition(options);
 
-        let ScrapedDocTest { filename, line, langstr, text, name, .. } = scraped_test;
+        let ScrapedDocTest { filename, line, langstr, text, name, global_crate_attrs, .. } =
+            scraped_test;
 
         let doctest = BuildDocTestBuilder::new(&text)
             .crate_name(&opts.crate_name)
+            .global_crate_attrs(global_crate_attrs)
             .edition(edition)
             .lang_str(&langstr)
             .build(None);
+
         let (full_test_code, size) = doctest.generate_unique_doctest(
             &text,
             langstr.test_harness,
diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs
index 66647b88018..5e571613d6f 100644
--- a/src/librustdoc/doctest/make.rs
+++ b/src/librustdoc/doctest/make.rs
@@ -45,6 +45,7 @@ pub(crate) struct BuildDocTestBuilder<'a> {
     test_id: Option<String>,
     lang_str: Option<&'a LangString>,
     span: Span,
+    global_crate_attrs: Vec<String>,
 }
 
 impl<'a> BuildDocTestBuilder<'a> {
@@ -57,6 +58,7 @@ impl<'a> BuildDocTestBuilder<'a> {
             test_id: None,
             lang_str: None,
             span: DUMMY_SP,
+            global_crate_attrs: Vec::new(),
         }
     }
 
@@ -96,6 +98,12 @@ impl<'a> BuildDocTestBuilder<'a> {
         self
     }
 
+    #[inline]
+    pub(crate) fn global_crate_attrs(mut self, global_crate_attrs: Vec<String>) -> Self {
+        self.global_crate_attrs = global_crate_attrs;
+        self
+    }
+
     pub(crate) fn build(self, dcx: Option<DiagCtxtHandle<'_>>) -> DocTestBuilder {
         let BuildDocTestBuilder {
             source,
@@ -106,6 +114,7 @@ impl<'a> BuildDocTestBuilder<'a> {
             test_id,
             lang_str,
             span,
+            global_crate_attrs,
         } = self;
         let can_merge_doctests = can_merge_doctests
             && lang_str.is_some_and(|lang_str| {
@@ -133,6 +142,7 @@ impl<'a> BuildDocTestBuilder<'a> {
             // If the AST returned an error, we don't want this doctest to be merged with the
             // others.
             return DocTestBuilder::invalid(
+                Vec::new(),
                 String::new(),
                 String::new(),
                 String::new(),
@@ -155,6 +165,7 @@ impl<'a> BuildDocTestBuilder<'a> {
         DocTestBuilder {
             supports_color,
             has_main_fn,
+            global_crate_attrs,
             crate_attrs,
             maybe_crate_attrs,
             crates,
@@ -173,6 +184,7 @@ pub(crate) struct DocTestBuilder {
     pub(crate) supports_color: bool,
     pub(crate) already_has_extern_crate: bool,
     pub(crate) has_main_fn: bool,
+    pub(crate) global_crate_attrs: Vec<String>,
     pub(crate) crate_attrs: String,
     /// If this is a merged doctest, it will be put into `everything_else`, otherwise it will
     /// put into `crate_attrs`.
@@ -186,6 +198,7 @@ pub(crate) struct DocTestBuilder {
 
 impl DocTestBuilder {
     fn invalid(
+        global_crate_attrs: Vec<String>,
         crate_attrs: String,
         maybe_crate_attrs: String,
         crates: String,
@@ -195,6 +208,7 @@ impl DocTestBuilder {
         Self {
             supports_color: false,
             has_main_fn: false,
+            global_crate_attrs,
             crate_attrs,
             maybe_crate_attrs,
             crates,
@@ -224,7 +238,8 @@ impl DocTestBuilder {
         let mut line_offset = 0;
         let mut prog = String::new();
         let everything_else = self.everything_else.trim();
-        if opts.attrs.is_empty() {
+
+        if self.global_crate_attrs.is_empty() {
             // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some
             // lints that are commonly triggered in doctests. The crate-level test attributes are
             // commonly used to make tests fail in case they trigger warnings, so having this there in
@@ -233,8 +248,8 @@ impl DocTestBuilder {
             line_offset += 1;
         }
 
-        // Next, any attributes that came from the crate root via #![doc(test(attr(...)))].
-        for attr in &opts.attrs {
+        // Next, any attributes that came from #![doc(test(attr(...)))].
+        for attr in &self.global_crate_attrs {
             prog.push_str(&format!("#![{attr}]\n"));
             line_offset += 1;
         }
diff --git a/src/librustdoc/doctest/markdown.rs b/src/librustdoc/doctest/markdown.rs
index e358a7e44e5..7f26605f256 100644
--- a/src/librustdoc/doctest/markdown.rs
+++ b/src/librustdoc/doctest/markdown.rs
@@ -31,6 +31,7 @@ impl DocTestVisitor for MdCollector {
             config,
             test,
             DUMMY_SP,
+            Vec::new(),
         ));
     }
 
@@ -96,7 +97,6 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> {
         crate_name,
         no_crate_inject: true,
         insert_indent_space: false,
-        attrs: vec![],
         args_file,
     };
 
diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs
index 39a4f23560a..f0914474c79 100644
--- a/src/librustdoc/doctest/runner.rs
+++ b/src/librustdoc/doctest/runner.rs
@@ -12,6 +12,7 @@ use crate::html::markdown::{Ignore, LangString};
 /// Convenient type to merge compatible doctests into one.
 pub(crate) struct DocTestRunner {
     crate_attrs: FxIndexSet<String>,
+    global_crate_attrs: FxIndexSet<String>,
     ids: String,
     output: String,
     output_merged_tests: String,
@@ -23,6 +24,7 @@ impl DocTestRunner {
     pub(crate) fn new() -> Self {
         Self {
             crate_attrs: FxIndexSet::default(),
+            global_crate_attrs: FxIndexSet::default(),
             ids: String::new(),
             output: String::new(),
             output_merged_tests: String::new(),
@@ -46,6 +48,9 @@ impl DocTestRunner {
             for line in doctest.crate_attrs.split('\n') {
                 self.crate_attrs.insert(line.to_string());
             }
+            for line in &doctest.global_crate_attrs {
+                self.global_crate_attrs.insert(line.to_string());
+            }
         }
         self.ids.push_str(&format!(
             "tests.push({}::TEST);\n",
@@ -85,7 +90,7 @@ impl DocTestRunner {
             code_prefix.push('\n');
         }
 
-        if opts.attrs.is_empty() {
+        if self.global_crate_attrs.is_empty() {
             // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some
             // lints that are commonly triggered in doctests. The crate-level test attributes are
             // commonly used to make tests fail in case they trigger warnings, so having this there in
@@ -93,8 +98,8 @@ impl DocTestRunner {
             code_prefix.push_str("#![allow(unused)]\n");
         }
 
-        // Next, any attributes that came from the crate root via #![doc(test(attr(...)))].
-        for attr in &opts.attrs {
+        // Next, any attributes that came from #![doc(test(attr(...)))].
+        for attr in &self.global_crate_attrs {
             code_prefix.push_str(&format!("#![{attr}]\n"));
         }
 
diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs
index f9d2aa3d3b4..96975105ac5 100644
--- a/src/librustdoc/doctest/rust.rs
+++ b/src/librustdoc/doctest/rust.rs
@@ -4,6 +4,7 @@ use std::cell::Cell;
 use std::env;
 use std::sync::Arc;
 
+use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
 use rustc_hir::{self as hir, CRATE_HIR_ID, intravisit};
@@ -11,7 +12,7 @@ use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
 use rustc_resolve::rustdoc::span_of_fragments;
 use rustc_span::source_map::SourceMap;
-use rustc_span::{BytePos, DUMMY_SP, FileName, Pos, Span};
+use rustc_span::{BytePos, DUMMY_SP, FileName, Pos, Span, sym};
 
 use super::{DocTestVisitor, ScrapedDocTest};
 use crate::clean::{Attributes, extract_cfg_from_attrs};
@@ -22,6 +23,7 @@ struct RustCollector {
     tests: Vec<ScrapedDocTest>,
     cur_path: Vec<String>,
     position: Span,
+    global_crate_attrs: Vec<String>,
 }
 
 impl RustCollector {
@@ -75,6 +77,7 @@ impl DocTestVisitor for RustCollector {
             config,
             test,
             span,
+            self.global_crate_attrs.clone(),
         ));
     }
 
@@ -94,6 +97,7 @@ impl<'tcx> HirCollector<'tcx> {
             cur_path: vec![],
             position: DUMMY_SP,
             tests: vec![],
+            global_crate_attrs: Vec::new(),
         };
         Self { codes, tcx, collector }
     }
@@ -123,6 +127,26 @@ impl HirCollector<'_> {
             return;
         }
 
+        // Try collecting `#[doc(test(attr(...)))]`
+        let old_global_crate_attrs_len = self.collector.global_crate_attrs.len();
+        for doc_test_attrs in ast_attrs
+            .iter()
+            .filter(|a| a.has_name(sym::doc))
+            .flat_map(|a| a.meta_item_list().unwrap_or_default())
+            .filter(|a| a.has_name(sym::test))
+        {
+            let Some(doc_test_attrs) = doc_test_attrs.meta_item_list() else { continue };
+            for attr in doc_test_attrs
+                .iter()
+                .filter(|a| a.has_name(sym::attr))
+                .flat_map(|a| a.meta_item_list().unwrap_or_default())
+                .map(|i| pprust::meta_list_item_to_string(i))
+            {
+                // Add the additional attributes to the global_crate_attrs vector
+                self.collector.global_crate_attrs.push(attr);
+            }
+        }
+
         let mut has_name = false;
         if let Some(name) = name {
             self.collector.cur_path.push(name);
@@ -157,6 +181,9 @@ impl HirCollector<'_> {
 
         nested(self);
 
+        // Restore global_crate_attrs to it's previous size/content
+        self.collector.global_crate_attrs.truncate(old_global_crate_attrs_len);
+
         if has_name {
             self.collector.cur_path.pop();
         }
diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs
index 08248fdf39b..ce2984ced79 100644
--- a/src/librustdoc/doctest/tests.rs
+++ b/src/librustdoc/doctest/tests.rs
@@ -7,9 +7,11 @@ fn make_test(
     crate_name: Option<&str>,
     dont_insert_main: bool,
     opts: &GlobalTestOptions,
+    global_crate_attrs: Vec<&str>,
     test_id: Option<&str>,
 ) -> (String, usize) {
-    let mut builder = BuildDocTestBuilder::new(test_code);
+    let mut builder = BuildDocTestBuilder::new(test_code)
+        .global_crate_attrs(global_crate_attrs.into_iter().map(|a| a.to_string()).collect());
     if let Some(crate_name) = crate_name {
         builder = builder.crate_name(crate_name);
     }
@@ -28,7 +30,6 @@ fn default_global_opts(crate_name: impl Into<String>) -> GlobalTestOptions {
         crate_name: crate_name.into(),
         no_crate_inject: false,
         insert_indent_space: false,
-        attrs: vec![],
         args_file: PathBuf::new(),
     }
 }
@@ -43,7 +44,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -58,7 +59,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, Some("asdf"), false, &opts, None);
+    let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -77,7 +78,7 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, Some("asdf"), false, &opts, None);
+    let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 3));
 }
 
@@ -94,7 +95,7 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, Some("asdf"), false, &opts, None);
+    let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -112,7 +113,7 @@ use std::*;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, Some("std"), false, &opts, None);
+    let (output, len) = make_test(input, Some("std"), false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -131,7 +132,7 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, Some("asdf"), false, &opts, None);
+    let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -148,7 +149,7 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, Some("asdf"), false, &opts, None);
+    let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -156,8 +157,7 @@ assert_eq!(2+2, 4);
 fn make_test_opts_attrs() {
     // If you supplied some doctest attributes with `#![doc(test(attr(...)))]`, it will use
     // those instead of the stock `#![allow(unused)]`.
-    let mut opts = default_global_opts("asdf");
-    opts.attrs.push("feature(sick_rad)".to_string());
+    let opts = default_global_opts("asdf");
     let input = "use asdf::qwop;
 assert_eq!(2+2, 4);";
     let expected = "#![feature(sick_rad)]
@@ -168,11 +168,10 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, Some("asdf"), false, &opts, None);
+    let (output, len) =
+        make_test(input, Some("asdf"), false, &opts, vec!["feature(sick_rad)"], None);
     assert_eq!((output, len), (expected, 3));
 
-    // Adding more will also bump the returned line offset.
-    opts.attrs.push("feature(hella_dope)".to_string());
     let expected = "#![feature(sick_rad)]
 #![feature(hella_dope)]
 #[allow(unused_extern_crates)]
@@ -182,7 +181,18 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, Some("asdf"), false, &opts, None);
+    let (output, len) = make_test(
+        input,
+        Some("asdf"),
+        false,
+        &opts,
+        vec![
+            "feature(sick_rad)",
+            // Adding more will also bump the returned line offset.
+            "feature(hella_dope)",
+        ],
+        None,
+    );
     assert_eq!((output, len), (expected, 4));
 }
 
@@ -200,7 +210,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -216,7 +226,7 @@ fn main() {
     assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 1));
 }
 
@@ -232,7 +242,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -246,7 +256,7 @@ assert_eq!(2+2, 4);";
 //Ceci n'est pas une `fn main`
 assert_eq!(2+2, 4);"
         .to_string();
-    let (output, len) = make_test(input, None, true, &opts, None);
+    let (output, len) = make_test(input, None, true, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 1));
 }
 
@@ -264,7 +274,7 @@ assert_eq!(2+2, 4);
 }"
     .to_string();
 
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -284,7 +294,7 @@ assert_eq!(asdf::foo, 4);
 }"
     .to_string();
 
-    let (output, len) = make_test(input, Some("asdf"), false, &opts, None);
+    let (output, len) = make_test(input, Some("asdf"), false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 3));
 }
 
@@ -302,7 +312,7 @@ test_wrapper! {
 }"
     .to_string();
 
-    let (output, len) = make_test(input, Some("my_crate"), false, &opts, None);
+    let (output, len) = make_test(input, Some("my_crate"), false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 1));
 }
 
@@ -322,7 +332,7 @@ io::stdin().read_line(&mut input)?;
 Ok::<(), io:Error>(())
 } _inner().unwrap() }"
         .to_string();
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -336,7 +346,7 @@ fn main() { #[allow(non_snake_case)] fn _doctest_main__some_unique_name() {
 assert_eq!(2+2, 4);
 } _doctest_main__some_unique_name() }"
         .to_string();
-    let (output, len) = make_test(input, None, false, &opts, Some("_some_unique_name"));
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), Some("_some_unique_name"));
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -355,7 +365,7 @@ fn main() {
     eprintln!(\"hello anan\");
 }"
     .to_string();
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -375,7 +385,7 @@ fn main() {
     eprintln!(\"hello anan\");
 }"
     .to_string();
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 1));
 }
 
@@ -400,7 +410,7 @@ fn main() {
 
 }"
     .to_string();
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 
     // And same, if there is a `main` function provided by the user, we ensure that it's
@@ -420,7 +430,7 @@ fn main() {}";
 
 fn main() {}"
         .to_string();
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 1));
 }
 
@@ -448,6 +458,6 @@ pub mod outer_module {
 }
 }"
     .to_string();
-    let (output, len) = make_test(input, None, false, &opts, None);
+    let (output, len) = make_test(input, None, false, &opts, Vec::new(), None);
     assert_eq!((output, len), (expected, 2));
 }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index e9a7f4367a3..6ab1520386d 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1019,18 +1019,33 @@ fn fmt_type(
             f.write_str("impl ")?;
             print_generic_bounds(bounds, cx).fmt(f)
         }
-        &clean::QPath(box clean::QPathData {
-            ref assoc,
-            ref self_type,
-            ref trait_,
-            should_show_cast,
-        }) => {
+        clean::QPath(qpath) => qpath.print(cx).fmt(f),
+    }
+}
+
+impl clean::Type {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
+        fmt::from_fn(move |f| fmt_type(self, f, false, cx))
+    }
+}
+
+impl clean::Path {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
+        fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
+    }
+}
+
+impl clean::QPathData {
+    fn print(&self, cx: &Context<'_>) -> impl Display {
+        let Self { ref assoc, ref self_type, should_fully_qualify, ref trait_ } = *self;
+
+        fmt::from_fn(move |f| {
             // FIXME(inherent_associated_types): Once we support non-ADT self-types (#106719),
             // we need to surround them with angle brackets in some cases (e.g. `<dyn …>::P`).
 
             if f.alternate() {
                 if let Some(trait_) = trait_
-                    && should_show_cast
+                    && should_fully_qualify
                 {
                     write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))?
                 } else {
@@ -1038,7 +1053,7 @@ fn fmt_type(
                 }
             } else {
                 if let Some(trait_) = trait_
-                    && should_show_cast
+                    && should_fully_qualify
                 {
                     write!(f, "&lt;{} as {}&gt;::", self_type.print(cx), trait_.print(cx))?
                 } else {
@@ -1090,19 +1105,7 @@ fn fmt_type(
             }?;
 
             assoc.args.print(cx).fmt(f)
-        }
-    }
-}
-
-impl clean::Type {
-    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
-        fmt::from_fn(move |f| fmt_type(self, f, false, cx))
-    }
-}
-
-impl clean::Path {
-    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
-        fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
+        })
     }
 }
 
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 68ba1245520..d3701784f9d 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -300,7 +300,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
                 crate_name: krate.map(String::from).unwrap_or_default(),
                 no_crate_inject: false,
                 insert_indent_space: true,
-                attrs: vec![],
                 args_file: PathBuf::new(),
             };
             let mut builder = doctest::BuildDocTestBuilder::new(&test).edition(edition);
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index bfcb794b89a..3ade40940bc 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -468,6 +468,9 @@ impl FromClean<clean::WherePredicate> for WherePredicate {
                     .collect(),
             },
             EqPredicate { lhs, rhs } => WherePredicate::EqPredicate {
+                // The LHS currently has type `Type` but it should be a `QualifiedPath` since it may
+                // refer to an associated const. However, `EqPredicate` shouldn't exist in the first
+                // place: <https://github.com/rust-lang/rust/141368>.
                 lhs: lhs.into_json(renderer),
                 rhs: rhs.into_json(renderer),
             },
@@ -557,12 +560,7 @@ impl FromClean<clean::Type> for Type {
                 is_mutable: mutability == ast::Mutability::Mut,
                 type_: Box::new((*type_).into_json(renderer)),
             },
-            QPath(box clean::QPathData { assoc, self_type, trait_, .. }) => Type::QualifiedPath {
-                name: assoc.name.to_string(),
-                args: Box::new(assoc.args.into_json(renderer)),
-                self_type: Box::new(self_type.into_json(renderer)),
-                trait_: trait_.map(|trait_| trait_.into_json(renderer)),
-            },
+            QPath(qpath) => (*qpath).into_json(renderer),
             // FIXME(unsafe_binder): Implement rustdoc-json.
             UnsafeBinder(_) => todo!(),
         }
@@ -579,6 +577,19 @@ impl FromClean<clean::Path> for Path {
     }
 }
 
+impl FromClean<clean::QPathData> for Type {
+    fn from_clean(qpath: clean::QPathData, renderer: &JsonRenderer<'_>) -> Self {
+        let clean::QPathData { assoc, self_type, should_fully_qualify: _, trait_ } = qpath;
+
+        Self::QualifiedPath {
+            name: assoc.name.to_string(),
+            args: Box::new(assoc.args.into_json(renderer)),
+            self_type: Box::new(self_type.into_json(renderer)),
+            trait_: trait_.map(|trait_| trait_.into_json(renderer)),
+        }
+    }
+}
+
 impl FromClean<clean::Term> for Term {
     fn from_clean(term: clean::Term, renderer: &JsonRenderer<'_>) -> Term {
         match term {
diff --git a/src/rustdoc-json-types/Cargo.toml b/src/rustdoc-json-types/Cargo.toml
index 14ff1d08816..a38d34ef0e7 100644
--- a/src/rustdoc-json-types/Cargo.toml
+++ b/src/rustdoc-json-types/Cargo.toml
@@ -10,7 +10,8 @@ path = "lib.rs"
 default = ["rustc-hash"]
 
 [dependencies]
-serde = { version = "1.0", features = ["derive"] }
+serde = "1.0"
+serde_derive = "1.0"
 rustc-hash = { version = "2.0", optional = true }
 
 [dev-dependencies]
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index f1c375bd2fe..8a3ab6f8640 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -21,7 +21,7 @@ use std::path::PathBuf;
 
 #[cfg(feature = "rustc-hash")]
 use rustc_hash::FxHashMap as HashMap;
-use serde::{Deserialize, Serialize};
+use serde_derive::{Deserialize, Serialize};
 
 pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
 
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 741d7e3fa16..4c53ea42793 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -40,7 +40,9 @@ static HOSTS: &[&str] = &[
     "powerpc64le-unknown-linux-musl",
     "riscv64gc-unknown-linux-gnu",
     "s390x-unknown-linux-gnu",
+    "sparcv9-sun-solaris",
     "x86_64-apple-darwin",
+    "x86_64-pc-solaris",
     "x86_64-pc-windows-gnu",
     "x86_64-pc-windows-msvc",
     "x86_64-unknown-freebsd",
@@ -111,6 +113,8 @@ static TARGETS: &[&str] = &[
     "i686-unknown-uefi",
     "loongarch64-unknown-linux-gnu",
     "loongarch64-unknown-linux-musl",
+    "loongarch32-unknown-none",
+    "loongarch32-unknown-none-softfloat",
     "loongarch64-unknown-none",
     "loongarch64-unknown-none-softfloat",
     "m68k-unknown-linux-gnu",
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 64a12460708cf146e16cc61f28aba5dc2463bbb
+Subproject fc1518ef02b77327d70d4026b95ea719dd9b8c5
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 9ad184450de..b839b6f5672 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -426,7 +426,7 @@ fn drain_matching(
         // Check if we should extract, but only if `idx >= start`.
         if idx > start && predicate(&alternatives[i].kind) {
             let pat = alternatives.remove(i);
-            tail_or.push(extract(pat.into_inner().kind));
+            tail_or.push(extract(pat.kind));
         } else {
             i += 1;
         }
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 5b4ec12cbec..8e16f943e9f 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
@@ -439,7 +439,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
             tcx,
             ObligationCause::dummy_with_span(body.span),
             param_env,
-            TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]),
+            TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, body.span), [ty]),
         );
 
         let mut selcx = SelectionContext::new(&infcx);
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
index f246ec61800..bffa1c4cf40 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
@@ -77,11 +77,11 @@ fn main() {
 
     struct NoIntoIter();
     impl NoIntoIter {
-        fn iter(&self) -> slice::Iter<u8> {
+        fn iter(&self) -> slice::Iter<'_, u8> {
             unimplemented!()
         }
 
-        fn iter_mut(&mut self) -> slice::IterMut<u8> {
+        fn iter_mut(&mut self) -> slice::IterMut<'_, u8> {
             unimplemented!()
         }
     }
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
index 35f4fb7097d..6a5a3dd00ba 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.rs
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
@@ -77,11 +77,11 @@ fn main() {
 
     struct NoIntoIter();
     impl NoIntoIter {
-        fn iter(&self) -> slice::Iter<u8> {
+        fn iter(&self) -> slice::Iter<'_, u8> {
             unimplemented!()
         }
 
-        fn iter_mut(&mut self) -> slice::IterMut<u8> {
+        fn iter_mut(&mut self) -> slice::IterMut<'_, u8> {
             unimplemented!()
         }
     }
diff --git a/src/tools/clippy/tests/ui/iter_next_loop.rs b/src/tools/clippy/tests/ui/iter_next_loop.rs
index 8e62ed963b9..969c51006af 100644
--- a/src/tools/clippy/tests/ui/iter_next_loop.rs
+++ b/src/tools/clippy/tests/ui/iter_next_loop.rs
@@ -8,7 +8,7 @@ fn main() {
 
     struct Unrelated(&'static [u8]);
     impl Unrelated {
-        fn next(&self) -> std::slice::Iter<u8> {
+        fn next(&self) -> std::slice::Iter<'_, u8> {
             self.0.iter()
         }
     }
diff --git a/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs b/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs
index 5c8c8eb4a43..d2497ed4330 100644
--- a/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs
+++ b/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs
@@ -71,7 +71,7 @@ impl S {
 
 struct S2([u8]);
 impl S2 {
-    fn iter(&self) -> core::slice::Iter<u8> {
+    fn iter(&self) -> core::slice::Iter<'_, u8> {
         self.0.iter()
     }
 }
diff --git a/src/tools/clippy/tests/ui/methods.rs b/src/tools/clippy/tests/ui/methods.rs
index 2f4004181f6..f73fe288b0f 100644
--- a/src/tools/clippy/tests/ui/methods.rs
+++ b/src/tools/clippy/tests/ui/methods.rs
@@ -49,7 +49,7 @@ struct Lt2<'a> {
 
 impl<'a> Lt2<'a> {
     // The lifetime is different, but that’s irrelevant; see issue #734.
-    pub fn new(s: &str) -> Lt2 {
+    pub fn new(s: &str) -> Lt2<'_> {
         unimplemented!()
     }
 }
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.fixed b/src/tools/clippy/tests/ui/needless_lifetimes.fixed
index e9d811986aa..ceea4480d0d 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.fixed
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.fixed
@@ -10,7 +10,7 @@
     clippy::unnecessary_wraps,
     dyn_drop,
     clippy::get_first,
-    elided_named_lifetimes
+    mismatched_lifetime_syntaxes,
 )]
 
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs
index 0b6eb9755b9..8432f9e6d2f 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs
@@ -10,7 +10,7 @@
     clippy::unnecessary_wraps,
     dyn_drop,
     clippy::get_first,
-    elided_named_lifetimes
+    mismatched_lifetime_syntaxes,
 )]
 
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/ptr_arg.rs b/src/tools/clippy/tests/ui/ptr_arg.rs
index 2d77bf06ff9..65f3f05d6cb 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.rs
+++ b/src/tools/clippy/tests/ui/ptr_arg.rs
@@ -312,7 +312,7 @@ mod issue_9218 {
 
     // Inferred to be `&'a str`, afaik.
     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str {
-        //~^ ERROR: elided lifetime has a name
+        //~^ ERROR: lifetime flowing from input to output with different syntax
         todo!()
     }
 }
diff --git a/src/tools/clippy/tests/ui/ptr_arg.stderr b/src/tools/clippy/tests/ui/ptr_arg.stderr
index 741e60cbd74..600343754e1 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.stderr
+++ b/src/tools/clippy/tests/ui/ptr_arg.stderr
@@ -1,12 +1,3 @@
-error: elided lifetime has a name
-  --> tests/ui/ptr_arg.rs:314:56
-   |
-LL |     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str {
-   |                        -- lifetime `'a` declared here  ^ this elided lifetime gets resolved as `'a`
-   |
-   = note: `-D elided-named-lifetimes` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(elided_named_lifetimes)]`
-
 error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
   --> tests/ui/ptr_arg.rs:13:14
    |
@@ -240,5 +231,21 @@ error: writing `&String` instead of `&str` involves a new object where a slice w
 LL |     fn good(v1: &String, v2: &String) {
    |                              ^^^^^^^ help: change this to: `&str`
 
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> tests/ui/ptr_arg.rs:314:36
+   |
+LL |     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str {
+   |                                    ^^     ^^           ---- the lifetime gets resolved as `'a`
+   |                                    |      |
+   |                                    |      these lifetimes flow to the output
+   |                                    these lifetimes flow to the output
+   |
+   = note: `-D mismatched-lifetime-syntaxes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(mismatched_lifetime_syntaxes)]`
+help: one option is to consistently use `'a`
+   |
+LL |     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &'a str {
+   |                                                         ++
+
 error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
index 4f65a06680d..78fc365bd5b 100644
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
@@ -191,7 +191,7 @@ struct CounterWrapper<'a> {
 }
 
 impl<'a> CounterWrapper<'a> {
-    fn new(counter: &Counter) -> CounterWrapper {
+    fn new(counter: &Counter) -> CounterWrapper<'_> {
         counter.i.fetch_add(1, Ordering::Relaxed);
         CounterWrapper { counter }
     }
@@ -204,7 +204,7 @@ impl<'a> Drop for CounterWrapper<'a> {
 }
 
 impl Counter {
-    fn temp_increment(&self) -> Vec<CounterWrapper> {
+    fn temp_increment(&self) -> Vec<CounterWrapper<'_>> {
         vec![CounterWrapper::new(self), CounterWrapper::new(self)]
     }
 }
@@ -480,7 +480,7 @@ impl StateWithBoxedMutexGuard {
     fn new() -> StateWithBoxedMutexGuard {
         StateWithBoxedMutexGuard { u: Mutex::new(42) }
     }
-    fn lock(&self) -> Box<MutexGuard<u64>> {
+    fn lock(&self) -> Box<MutexGuard<'_, u64>> {
         Box::new(self.u.lock().unwrap())
     }
 }
@@ -507,7 +507,7 @@ impl StateStringWithBoxedMutexGuard {
             s: Mutex::new("A String".to_owned()),
         }
     }
-    fn lock(&self) -> Box<MutexGuard<String>> {
+    fn lock(&self) -> Box<MutexGuard<'_, String>> {
         Box::new(self.s.lock().unwrap())
     }
 }
@@ -686,11 +686,11 @@ struct Guard<'a, T>(MutexGuard<'a, T>);
 struct Ref<'a, T>(&'a T);
 
 impl<'a, T> Guard<'a, T> {
-    fn guard(&self) -> &MutexGuard<T> {
+    fn guard(&self) -> &MutexGuard<'_, T> {
         &self.0
     }
 
-    fn guard_ref(&self) -> Ref<MutexGuard<T>> {
+    fn guard_ref(&self) -> Ref<'_, MutexGuard<'_, T>> {
         Ref(&self.0)
     }
 
diff --git a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.fixed b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.fixed
index af7d82130f0..1a07f119398 100644
--- a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.fixed
+++ b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.fixed
@@ -41,6 +41,7 @@ fn good_return_explicit_lt_ref<'a>(foo: &'a Foo) -> &'a u32 {
     &foo.0
 }
 
+#[allow(mismatched_lifetime_syntaxes)]
 fn good_return_implicit_lt_struct(foo: &Foo) -> FooRef {
     FooRef { foo }
 }
diff --git a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs
index 00e11a1ea28..07b1842bbf8 100644
--- a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs
+++ b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs
@@ -41,6 +41,7 @@ fn good_return_explicit_lt_ref<'a>(foo: &'a Foo) -> &'a u32 {
     &foo.0
 }
 
+#[allow(mismatched_lifetime_syntaxes)]
 fn good_return_implicit_lt_struct(foo: &Foo) -> FooRef {
     FooRef { foo }
 }
diff --git a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr
index f101ac5ccd6..36247d3fe0b 100644
--- a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr
+++ b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr
@@ -1,5 +1,5 @@
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:53:11
+  --> tests/ui/trivially_copy_pass_by_ref.rs:54:11
    |
 LL | fn bad(x: &u32, y: &Foo, z: &Baz) {}
    |           ^^^^ help: consider passing by value instead: `u32`
@@ -11,103 +11,103 @@ LL | #![deny(clippy::trivially_copy_pass_by_ref)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:53:20
+  --> tests/ui/trivially_copy_pass_by_ref.rs:54:20
    |
 LL | fn bad(x: &u32, y: &Foo, z: &Baz) {}
    |                    ^^^^ help: consider passing by value instead: `Foo`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:53:29
+  --> tests/ui/trivially_copy_pass_by_ref.rs:54:29
    |
 LL | fn bad(x: &u32, y: &Foo, z: &Baz) {}
    |                             ^^^^ help: consider passing by value instead: `Baz`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:63:12
+  --> tests/ui/trivially_copy_pass_by_ref.rs:64:12
    |
 LL |     fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
    |            ^^^^^ help: consider passing by value instead: `self`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:63:22
+  --> tests/ui/trivially_copy_pass_by_ref.rs:64:22
    |
 LL |     fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
    |                      ^^^^ help: consider passing by value instead: `u32`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:63:31
+  --> tests/ui/trivially_copy_pass_by_ref.rs:64:31
    |
 LL |     fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
    |                               ^^^^ help: consider passing by value instead: `Foo`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:63:40
+  --> tests/ui/trivially_copy_pass_by_ref.rs:64:40
    |
 LL |     fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
    |                                        ^^^^ help: consider passing by value instead: `Baz`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:69:16
+  --> tests/ui/trivially_copy_pass_by_ref.rs:70:16
    |
 LL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}
    |                ^^^^ help: consider passing by value instead: `u32`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:69:25
+  --> tests/ui/trivially_copy_pass_by_ref.rs:70:25
    |
 LL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}
    |                         ^^^^ help: consider passing by value instead: `Foo`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:69:34
+  --> tests/ui/trivially_copy_pass_by_ref.rs:70:34
    |
 LL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}
    |                                  ^^^^ help: consider passing by value instead: `Baz`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:74:35
+  --> tests/ui/trivially_copy_pass_by_ref.rs:75:35
    |
 LL |     fn bad_issue7518(self, other: &Self) {}
    |                                   ^^^^^ help: consider passing by value instead: `Self`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:87:16
+  --> tests/ui/trivially_copy_pass_by_ref.rs:88:16
    |
 LL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}
    |                ^^^^ help: consider passing by value instead: `u32`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:87:25
+  --> tests/ui/trivially_copy_pass_by_ref.rs:88:25
    |
 LL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}
    |                         ^^^^ help: consider passing by value instead: `Foo`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:87:34
+  --> tests/ui/trivially_copy_pass_by_ref.rs:88:34
    |
 LL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}
    |                                  ^^^^ help: consider passing by value instead: `Baz`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:94:33
+  --> tests/ui/trivially_copy_pass_by_ref.rs:95:33
    |
 LL |     fn trait_method(&self, foo: &Foo);
    |                                 ^^^^ help: consider passing by value instead: `Foo`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:132:21
+  --> tests/ui/trivially_copy_pass_by_ref.rs:133:21
    |
 LL |     fn foo_never(x: &i32) {
    |                     ^^^^ help: consider passing by value instead: `i32`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:138:15
+  --> tests/ui/trivially_copy_pass_by_ref.rs:139:15
    |
 LL |     fn foo(x: &i32) {
    |               ^^^^ help: consider passing by value instead: `i32`
 
 error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
-  --> tests/ui/trivially_copy_pass_by_ref.rs:164:36
+  --> tests/ui/trivially_copy_pass_by_ref.rs:165:36
    |
 LL | fn unrelated_lifetimes<'a, 'b>(_x: &'a u32, y: &'b u32) -> &'b u32 {
    |                                    ^^^^^^^ help: consider passing by value instead: `u32`
diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed
index f15e5e0a5bb..cccb6bffabb 100644
--- a/src/tools/clippy/tests/ui/use_self.fixed
+++ b/src/tools/clippy/tests/ui/use_self.fixed
@@ -69,7 +69,7 @@ mod lifetimes {
     impl<'a> Foo<'a> {
         // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) ->
         // Foo<'b>`
-        fn foo(s: &str) -> Foo {
+        fn foo(s: &str) -> Foo<'_> {
             Foo { foo_str: s }
         }
         // cannot replace with `Self`, because that's `Foo<'a>`
diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs
index b6376938611..09288677aa7 100644
--- a/src/tools/clippy/tests/ui/use_self.rs
+++ b/src/tools/clippy/tests/ui/use_self.rs
@@ -69,7 +69,7 @@ mod lifetimes {
     impl<'a> Foo<'a> {
         // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) ->
         // Foo<'b>`
-        fn foo(s: &str) -> Foo {
+        fn foo(s: &str) -> Foo<'_> {
             Foo { foo_str: s }
         }
         // cannot replace with `Self`, because that's `Foo<'a>`
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 4f93b498741..9b9d94bbead 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -495,6 +495,7 @@ impl Config {
             "arm64ec",
             "riscv32",
             "riscv64",
+            "loongarch32",
             "loongarch64",
             "s390x",
             // These targets require an additional asm_experimental_arch feature.
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs
index 5757e422ae2..1406553c9ea 100644
--- a/src/tools/compiletest/src/directive-list.rs
+++ b/src/tools/compiletest/src/directive-list.rs
@@ -73,6 +73,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "ignore-linux",
     "ignore-lldb",
     "ignore-llvm-version",
+    "ignore-loongarch32",
     "ignore-loongarch64",
     "ignore-macabi",
     "ignore-macos",
@@ -196,6 +197,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "only-i686-unknown-linux-gnu",
     "only-ios",
     "only-linux",
+    "only-loongarch32",
     "only-loongarch64",
     "only-loongarch64-unknown-linux-gnu",
     "only-macos",
diff --git a/src/tools/jsondocck/src/config.rs b/src/tools/jsondocck/src/config.rs
index 9b3ba3f3fbe..6bef37c2259 100644
--- a/src/tools/jsondocck/src/config.rs
+++ b/src/tools/jsondocck/src/config.rs
@@ -4,7 +4,7 @@ use getopts::Options;
 pub struct Config {
     /// The directory documentation output was generated in
     pub doc_dir: String,
-    /// The file documentation was generated for, with docck commands to check
+    /// The file documentation was generated for, with docck directives to check
     pub template: String,
 }
 
diff --git a/src/tools/jsondocck/src/directive.rs b/src/tools/jsondocck/src/directive.rs
new file mode 100644
index 00000000000..fdb2fa6dbbe
--- /dev/null
+++ b/src/tools/jsondocck/src/directive.rs
@@ -0,0 +1,232 @@
+use std::borrow::Cow;
+
+use serde_json::Value;
+
+use crate::cache::Cache;
+
+#[derive(Debug)]
+pub struct Directive {
+    pub kind: DirectiveKind,
+    pub path: String,
+    pub lineno: usize,
+}
+
+#[derive(Debug)]
+pub enum DirectiveKind {
+    /// `//@ has <path>`
+    ///
+    /// Checks the path exists.
+    HasPath,
+
+    /// `//@ has <path> <value>`
+    ///
+    /// Check one thing at the path  is equal to the value.
+    HasValue { value: String },
+
+    /// `//@ !has <path>`
+    ///
+    /// Checks the path doesn't exist.
+    HasNotPath,
+
+    /// `//@ !has <path> <value>`
+    ///
+    /// Checks the path exists, but doesn't have the given value.
+    HasNotValue { value: String },
+
+    /// `//@ is <path> <value>`
+    ///
+    /// Check the path is the given value.
+    Is { value: String },
+
+    /// `//@ is <path> <value> <value>...`
+    ///
+    /// Check that the path matches to exactly every given value.
+    IsMany { values: Vec<String> },
+
+    /// `//@ !is <path> <value>`
+    ///
+    /// Check the path isn't the given value.
+    IsNot { value: String },
+
+    /// `//@ count <path> <value>`
+    ///
+    /// Check the path has the expected number of matches.
+    CountIs { expected: usize },
+
+    /// `//@ set <name> = <path>`
+    Set { variable: String },
+}
+
+impl DirectiveKind {
+    /// Returns both the kind and the path.
+    ///
+    /// Returns `None` if the directive isn't from jsondocck (e.g. from compiletest).
+    pub fn parse<'a>(
+        directive_name: &str,
+        negated: bool,
+        args: &'a [String],
+    ) -> Option<(Self, &'a str)> {
+        let kind = match (directive_name, negated) {
+            ("count", false) => {
+                assert_eq!(args.len(), 2);
+                let expected = args[1].parse().expect("invalid number for `count`");
+                Self::CountIs { expected }
+            }
+
+            ("ismany", false) => {
+                // FIXME: Make this >= 3, and migrate len(values)==1 cases to @is
+                assert!(args.len() >= 2, "Not enough args to `ismany`");
+                let values = args[1..].to_owned();
+                Self::IsMany { values }
+            }
+
+            ("is", false) => {
+                assert_eq!(args.len(), 2);
+                Self::Is { value: args[1].clone() }
+            }
+            ("is", true) => {
+                assert_eq!(args.len(), 2);
+                Self::IsNot { value: args[1].clone() }
+            }
+
+            ("set", false) => {
+                assert_eq!(args.len(), 3);
+                assert_eq!(args[1], "=");
+                return Some((Self::Set { variable: args[0].clone() }, &args[2]));
+            }
+
+            ("has", false) => match args {
+                [_path] => Self::HasPath,
+                [_path, value] => Self::HasValue { value: value.clone() },
+                _ => panic!("`//@ has` must have 2 or 3 arguments, but got {args:?}"),
+            },
+            ("has", true) => match args {
+                [_path] => Self::HasNotPath,
+                [_path, value] => Self::HasNotValue { value: value.clone() },
+                _ => panic!("`//@ !has` must have 2 or 3 arguments, but got {args:?}"),
+            },
+            // Ignore compiletest directives, like //@ edition
+            (_, false) if KNOWN_DIRECTIVE_NAMES.contains(&directive_name) => {
+                return None;
+            }
+            _ => {
+                panic!("Invalid directive `//@ {}{directive_name}`", if negated { "!" } else { "" })
+            }
+        };
+
+        Some((kind, &args[0]))
+    }
+}
+
+impl Directive {
+    /// Performs the actual work of ensuring a directive passes.
+    pub fn check(&self, cache: &mut Cache) -> Result<(), String> {
+        let matches = cache.select(&self.path);
+        match &self.kind {
+            DirectiveKind::HasPath => {
+                if matches.is_empty() {
+                    return Err("matched to no values".to_owned());
+                }
+            }
+            DirectiveKind::HasNotPath => {
+                if !matches.is_empty() {
+                    return Err(format!("matched to {matches:?}, but wanted no matches"));
+                }
+            }
+            DirectiveKind::HasValue { value } => {
+                let want_value = string_to_value(value, cache);
+                if !matches.contains(&want_value.as_ref()) {
+                    return Err(format!(
+                        "matched to {matches:?}, which didn't contain {want_value:?}"
+                    ));
+                }
+            }
+            DirectiveKind::HasNotValue { value } => {
+                let wantnt_value = string_to_value(value, cache);
+                if matches.contains(&wantnt_value.as_ref()) {
+                    return Err(format!(
+                        "matched to {matches:?}, which contains unwanted {wantnt_value:?}"
+                    ));
+                } else if matches.is_empty() {
+                    return Err(format!(
+                        "got no matches, but expected some matched (not containing {wantnt_value:?}"
+                    ));
+                }
+            }
+
+            DirectiveKind::Is { value } => {
+                let want_value = string_to_value(value, cache);
+                let matched = get_one(&matches)?;
+                if matched != want_value.as_ref() {
+                    return Err(format!("matched to {matched:?} but want {want_value:?}"));
+                }
+            }
+            DirectiveKind::IsNot { value } => {
+                let wantnt_value = string_to_value(value, cache);
+                let matched = get_one(&matches)?;
+                if matched == wantnt_value.as_ref() {
+                    return Err(format!("got value {wantnt_value:?}, but want anything else"));
+                }
+            }
+
+            DirectiveKind::IsMany { values } => {
+                // Serde json doesn't implement Ord or Hash for Value, so we must
+                // use a Vec here. While in theory that makes setwize equality
+                // O(n^2), in practice n will never be large enough to matter.
+                let expected_values =
+                    values.iter().map(|v| string_to_value(v, cache)).collect::<Vec<_>>();
+                if expected_values.len() != matches.len() {
+                    return Err(format!(
+                        "Expected {} values, but matched to {} values ({:?})",
+                        expected_values.len(),
+                        matches.len(),
+                        matches
+                    ));
+                };
+                for got_value in matches {
+                    if !expected_values.iter().any(|exp| &**exp == got_value) {
+                        return Err(format!("has match {got_value:?}, which was not expected",));
+                    }
+                }
+            }
+            DirectiveKind::CountIs { expected } => {
+                if *expected != matches.len() {
+                    return Err(format!(
+                        "matched to `{matches:?}` with length {}, but expected length {expected}",
+                        matches.len(),
+                    ));
+                }
+            }
+            DirectiveKind::Set { variable } => {
+                let value = get_one(&matches)?;
+                let r = cache.variables.insert(variable.to_owned(), value.clone());
+                assert!(r.is_none(), "name collision: {variable:?} is duplicated");
+            }
+        }
+
+        Ok(())
+    }
+}
+
+fn get_one<'a>(matches: &[&'a Value]) -> Result<&'a Value, String> {
+    match matches {
+        [] => Err("matched to no values".to_owned()),
+        [matched] => Ok(matched),
+        _ => Err(format!("matched to multiple values {matches:?}, but want exactly 1")),
+    }
+}
+
+// FIXME: This setup is temporary until we figure out how to improve this situation.
+//        See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
+include!(concat!(env!("CARGO_MANIFEST_DIR"), "/../compiletest/src/directive-list.rs"));
+
+fn string_to_value<'a>(s: &str, cache: &'a Cache) -> Cow<'a, Value> {
+    if s.starts_with("$") {
+        Cow::Borrowed(&cache.variables.get(&s[1..]).unwrap_or_else(|| {
+            // FIXME(adotinthevoid): Show line number
+            panic!("No variable: `{}`. Current state: `{:?}`", &s[1..], cache.variables)
+        }))
+    } else {
+        Cow::Owned(serde_json::from_str(s).expect(&format!("Cannot convert `{}` to json", s)))
+    }
+}
diff --git a/src/tools/jsondocck/src/error.rs b/src/tools/jsondocck/src/error.rs
index 0a3e085b405..eb2932f7803 100644
--- a/src/tools/jsondocck/src/error.rs
+++ b/src/tools/jsondocck/src/error.rs
@@ -1,7 +1,7 @@
-use crate::Command;
+use crate::Directive;
 
 #[derive(Debug)]
 pub struct CkError {
     pub message: String,
-    pub command: Command,
+    pub directive: Directive,
 }
diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs
index 65ad38da98b..d84be4d3a3a 100644
--- a/src/tools/jsondocck/src/main.rs
+++ b/src/tools/jsondocck/src/main.rs
@@ -1,17 +1,17 @@
-use std::borrow::Cow;
 use std::process::ExitCode;
 use std::sync::LazyLock;
 use std::{env, fs};
 
 use regex::{Regex, RegexBuilder};
-use serde_json::Value;
 
 mod cache;
 mod config;
+mod directive;
 mod error;
 
 use cache::Cache;
 use config::parse_config;
+use directive::{Directive, DirectiveKind};
 use error::CkError;
 
 fn main() -> ExitCode {
@@ -19,14 +19,14 @@ fn main() -> ExitCode {
 
     let mut failed = Vec::new();
     let mut cache = Cache::new(&config);
-    let Ok(commands) = get_commands(&config.template) else {
+    let Ok(directives) = get_directives(&config.template) else {
         eprintln!("Jsondocck failed for {}", &config.template);
         return ExitCode::FAILURE;
     };
 
-    for command in commands {
-        if let Err(message) = check_command(&command, &mut cache) {
-            failed.push(CkError { command, message });
+    for directive in directives {
+        if let Err(message) = directive.check(&mut cache) {
+            failed.push(CkError { directive, message });
         }
     }
 
@@ -34,130 +34,20 @@ fn main() -> ExitCode {
         ExitCode::SUCCESS
     } else {
         for i in failed {
-            eprintln!("{}:{}, command failed", config.template, i.command.lineno);
+            eprintln!("{}:{}, directive failed", config.template, i.directive.lineno);
             eprintln!("{}", i.message)
         }
         ExitCode::FAILURE
     }
 }
 
-#[derive(Debug)]
-pub struct Command {
-    kind: CommandKind,
-    path: String,
-    lineno: usize,
-}
-
-#[derive(Debug)]
-enum CommandKind {
-    /// `//@ has <path>`
-    ///
-    /// Checks the path exists.
-    HasPath,
-
-    /// `//@ has <path> <value>`
-    ///
-    /// Check one thing at the path  is equal to the value.
-    HasValue { value: String },
-
-    /// `//@ !has <path>`
-    ///
-    /// Checks the path doesn't exist.
-    HasNotPath,
-
-    /// `//@ !has <path> <value>`
-    ///
-    /// Checks the path exists, but doesn't have the given value.
-    HasNotValue { value: String },
-
-    /// `//@ is <path> <value>`
-    ///
-    /// Check the path is the given value.
-    Is { value: String },
-
-    /// `//@ is <path> <value> <value>...`
-    ///
-    /// Check that the path matches to exactly every given value.
-    IsMany { values: Vec<String> },
-
-    /// `//@ !is <path> <value>`
-    ///
-    /// Check the path isn't the given value.
-    IsNot { value: String },
-
-    /// `//@ count <path> <value>`
-    ///
-    /// Check the path has the expected number of matches.
-    CountIs { expected: usize },
-
-    /// `//@ set <name> = <path>`
-    Set { variable: String },
-}
-
-impl CommandKind {
-    /// Returns both the kind and the path.
-    ///
-    /// Returns `None` if the command isn't from jsondocck (e.g. from compiletest).
-    fn parse<'a>(command_name: &str, negated: bool, args: &'a [String]) -> Option<(Self, &'a str)> {
-        let kind = match (command_name, negated) {
-            ("count", false) => {
-                assert_eq!(args.len(), 2);
-                let expected = args[1].parse().expect("invalid number for `count`");
-                Self::CountIs { expected }
-            }
-
-            ("ismany", false) => {
-                // FIXME: Make this >= 3, and migrate len(values)==1 cases to @is
-                assert!(args.len() >= 2, "Not enough args to `ismany`");
-                let values = args[1..].to_owned();
-                Self::IsMany { values }
-            }
-
-            ("is", false) => {
-                assert_eq!(args.len(), 2);
-                Self::Is { value: args[1].clone() }
-            }
-            ("is", true) => {
-                assert_eq!(args.len(), 2);
-                Self::IsNot { value: args[1].clone() }
-            }
-
-            ("set", false) => {
-                assert_eq!(args.len(), 3);
-                assert_eq!(args[1], "=");
-                return Some((Self::Set { variable: args[0].clone() }, &args[2]));
-            }
-
-            ("has", false) => match args {
-                [_path] => Self::HasPath,
-                [_path, value] => Self::HasValue { value: value.clone() },
-                _ => panic!("`//@ has` must have 2 or 3 arguments, but got {args:?}"),
-            },
-            ("has", true) => match args {
-                [_path] => Self::HasNotPath,
-                [_path, value] => Self::HasNotValue { value: value.clone() },
-                _ => panic!("`//@ !has` must have 2 or 3 arguments, but got {args:?}"),
-            },
-
-            (_, false) if KNOWN_DIRECTIVE_NAMES.contains(&command_name) => {
-                return None;
-            }
-            _ => {
-                panic!("Invalid command `//@ {}{command_name}`", if negated { "!" } else { "" })
-            }
-        };
-
-        Some((kind, &args[0]))
-    }
-}
-
 static LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
     RegexBuilder::new(
         r#"
         ^\s*
         //@\s+
         (?P<negated>!?)
-        (?P<cmd>[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)
+        (?P<directive>[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)
         (?P<args>.*)$
     "#,
     )
@@ -180,16 +70,12 @@ static DEPRECATED_LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
 });
 
 fn print_err(msg: &str, lineno: usize) {
-    eprintln!("Invalid command: {} on line {}", msg, lineno)
+    eprintln!("Invalid directive: {} on line {}", msg, lineno)
 }
 
-// FIXME: This setup is temporary until we figure out how to improve this situation.
-//        See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
-include!(concat!(env!("CARGO_MANIFEST_DIR"), "/../compiletest/src/directive-list.rs"));
-
-/// Get a list of commands from a file.
-fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
-    let mut commands = Vec::new();
+/// Get a list of directives from a file.
+fn get_directives(template: &str) -> Result<Vec<Directive>, ()> {
+    let mut directives = Vec::new();
     let mut errors = false;
     let file = fs::read_to_string(template).unwrap();
 
@@ -197,7 +83,7 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
         let lineno = lineno + 1;
 
         if DEPRECATED_LINE_PATTERN.is_match(line) {
-            print_err("Deprecated command syntax, replace `// @` with `//@ `", lineno);
+            print_err("Deprecated directive syntax, replace `// @` with `//@ `", lineno);
             errors = true;
             continue;
         }
@@ -215,115 +101,10 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
             continue;
         };
 
-        if let Some((kind, path)) = CommandKind::parse(&cap["cmd"], negated, &args) {
-            commands.push(Command { kind, lineno, path: path.to_owned() })
+        if let Some((kind, path)) = DirectiveKind::parse(&cap["directive"], negated, &args) {
+            directives.push(Directive { kind, lineno, path: path.to_owned() })
         }
     }
 
-    if !errors { Ok(commands) } else { Err(()) }
-}
-
-/// Performs the actual work of ensuring a command passes.
-fn check_command(command: &Command, cache: &mut Cache) -> Result<(), String> {
-    let matches = cache.select(&command.path);
-    match &command.kind {
-        CommandKind::HasPath => {
-            if matches.is_empty() {
-                return Err("matched to no values".to_owned());
-            }
-        }
-        CommandKind::HasNotPath => {
-            if !matches.is_empty() {
-                return Err(format!("matched to {matches:?}, but wanted no matches"));
-            }
-        }
-        CommandKind::HasValue { value } => {
-            let want_value = string_to_value(value, cache);
-            if !matches.contains(&want_value.as_ref()) {
-                return Err(format!("matched to {matches:?}, which didn't contain {want_value:?}"));
-            }
-        }
-        CommandKind::HasNotValue { value } => {
-            let wantnt_value = string_to_value(value, cache);
-            if matches.contains(&wantnt_value.as_ref()) {
-                return Err(format!(
-                    "matched to {matches:?}, which contains unwanted {wantnt_value:?}"
-                ));
-            } else if matches.is_empty() {
-                return Err(format!(
-                    "got no matches, but expected some matched (not containing {wantnt_value:?}"
-                ));
-            }
-        }
-
-        CommandKind::Is { value } => {
-            let want_value = string_to_value(value, cache);
-            let matched = get_one(&matches)?;
-            if matched != want_value.as_ref() {
-                return Err(format!("matched to {matched:?} but want {want_value:?}"));
-            }
-        }
-        CommandKind::IsNot { value } => {
-            let wantnt_value = string_to_value(value, cache);
-            let matched = get_one(&matches)?;
-            if matched == wantnt_value.as_ref() {
-                return Err(format!("got value {wantnt_value:?}, but want anything else"));
-            }
-        }
-
-        CommandKind::IsMany { values } => {
-            // Serde json doesn't implement Ord or Hash for Value, so we must
-            // use a Vec here. While in theory that makes setwize equality
-            // O(n^2), in practice n will never be large enough to matter.
-            let expected_values =
-                values.iter().map(|v| string_to_value(v, cache)).collect::<Vec<_>>();
-            if expected_values.len() != matches.len() {
-                return Err(format!(
-                    "Expected {} values, but matched to {} values ({:?})",
-                    expected_values.len(),
-                    matches.len(),
-                    matches
-                ));
-            };
-            for got_value in matches {
-                if !expected_values.iter().any(|exp| &**exp == got_value) {
-                    return Err(format!("has match {got_value:?}, which was not expected",));
-                }
-            }
-        }
-        CommandKind::CountIs { expected } => {
-            if *expected != matches.len() {
-                return Err(format!(
-                    "matched to `{matches:?}` with length {}, but expected length {expected}",
-                    matches.len(),
-                ));
-            }
-        }
-        CommandKind::Set { variable } => {
-            let value = get_one(&matches)?;
-            let r = cache.variables.insert(variable.to_owned(), value.clone());
-            assert!(r.is_none(), "name collision: {variable:?} is duplicated");
-        }
-    }
-
-    Ok(())
-}
-
-fn get_one<'a>(matches: &[&'a Value]) -> Result<&'a Value, String> {
-    match matches {
-        [] => Err("matched to no values".to_owned()),
-        [matched] => Ok(matched),
-        _ => Err(format!("matched to multiple values {matches:?}, but want exactly 1")),
-    }
-}
-
-fn string_to_value<'a>(s: &str, cache: &'a Cache) -> Cow<'a, Value> {
-    if s.starts_with("$") {
-        Cow::Borrowed(&cache.variables.get(&s[1..]).unwrap_or_else(|| {
-            // FIXME(adotinthevoid): Show line number
-            panic!("No variable: `{}`. Current state: `{:?}`", &s[1..], cache.variables)
-        }))
-    } else {
-        Cow::Owned(serde_json::from_str(s).expect(&format!("Cannot convert `{}` to json", s)))
-    }
+    if !errors { Ok(directives) } else { Err(()) }
 }
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 6f4bd3eab51..192d4f444c2 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -555,7 +555,6 @@ dependencies = [
  "tempfile",
  "tikv-jemalloc-sys",
  "ui_test",
- "windows-sys",
 ]
 
 [[package]]
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index e4d7abdb0f7..a314488bb25 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -40,13 +40,6 @@ libc = "0.2"
 libffi = "4.0.0"
 libloading = "0.8"
 
-[target.'cfg(target_family = "windows")'.dependencies]
-windows-sys = { version = "0.59", features = [
-    "Win32_Foundation",
-    "Win32_System_IO",
-    "Win32_Storage_FileSystem",
-] }
-
 [dev-dependencies]
 ui_test = "0.29.1"
 colored = "2"
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index de521393cd0..fc7942a49c0 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -396,18 +396,22 @@ to Miri failing to detect cases of undefined behavior in a program.
 * `-Zmiri-force-intrinsic-fallback` forces the use of the "fallback" body for all intrinsics that
   have one. This is useful to test the fallback bodies, but should not be used otherwise. It is
   **unsound** since the fallback body might not be checking for all UB.
-* `-Zmiri-native-lib=<path to a shared object file>` is an experimental flag for providing support
-  for calling native functions from inside the interpreter via FFI. The flag is supported only on
-  Unix systems. Functions not provided by that file are still executed via the usual Miri shims.
+* `-Zmiri-native-lib=<path to a shared object file or folder>` is an experimental flag for providing
+  support for calling native functions from inside the interpreter via FFI. The flag is supported
+  only on Unix systems. Functions not provided by that file are still executed via the usual Miri
+  shims. If a path to a directory is specified, all files in that directory are included
+  non-recursively. This flag can be passed multiple times to specify multiple files and/or
+  directories.
   **WARNING**: If an invalid/incorrect `.so` file is specified, this can cause Undefined Behavior in
-  Miri itself! And of course, Miri cannot do any checks on the actions taken by the native code.
+  Miri itself! And of course, Miri often cannot do any checks on the actions taken by the native code.
   Note that Miri has its own handling of file descriptors, so if you want to replace *some*
   functions working on file descriptors, you will have to replace *all* of them, or the two kinds of
-  file descriptors will be mixed up. This is **work in progress**; currently, only integer and
-  pointers arguments and return values are supported and memory allocated by the native code cannot
-  be accessed from Rust (only the other way around). Native code must not spawn threads that keep
-  running in the background after the call has returned to Rust and that access Rust-allocated
-  memory. Finally, the flag is **unsound** in the sense that Miri stops tracking details such as
+  file descriptors will be mixed up.
+  This is **work in progress**; currently, only integer and pointers arguments and return values are
+  supported and memory allocated by the native code cannot be accessed from Rust (only the other way
+  around). Native code must not spawn threads that keep running in the background after the call has
+  returned to Rust and that access Rust-allocated memory.
+  Finally, the flag is **unsound** in the sense that Miri stops tracking details such as
   initialization and provenance on memory shared with native code, so it is easily possible to write
   code that has UB which is missed by Miri.
 * `-Zmiri-measureme=<name>` enables `measureme` profiling for the interpreted program.
@@ -458,6 +462,10 @@ to Miri failing to detect cases of undefined behavior in a program.
   This is much less likely with Stacked Borrows.
   Using Tree Borrows currently implies `-Zmiri-strict-provenance` because integer-to-pointer
   casts are not supported in this mode, but that may change in the future.
+* `-Zmiri-tree-borrows-no-precise-interior-mut` makes Tree Borrows
+  track interior mutable data on the level of references instead of on the
+  byte-level as is done by default.  Therefore, with this flag, Tree
+  Borrows will be more permissive.
 * `-Zmiri-force-page-size=<num>` overrides the default page size for an architecture, in multiples of 1k.
   `4` is default for most targets. This value should always be a power of 2 and nonzero.
 
diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock
index c1915ae617e..d37f8750bde 100644
--- a/src/tools/miri/cargo-miri/Cargo.lock
+++ b/src/tools/miri/cargo-miri/Cargo.lock
@@ -3,6 +3,15 @@
 version = 4
 
 [[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
 name = "anyhow"
 version = "1.0.97"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -207,12 +216,42 @@ dependencies = [
 ]
 
 [[package]]
+name = "regex"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
+[[package]]
 name = "rustc-build-sysroot"
-version = "0.5.7"
+version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10edc2e4393515193bd766e2f6c050b0536a68e56f2b6d56c07ababfdc114ff0"
+checksum = "16d115ad7e26e0d1337f64ae6598f758194696afc2e9f34c8a6f24582529c3dc"
 dependencies = [
  "anyhow",
+ "regex",
  "rustc_version",
  "tempfile",
  "walkdir",
diff --git a/src/tools/miri/cargo-miri/Cargo.toml b/src/tools/miri/cargo-miri/Cargo.toml
index 5c579b2a77d..e08733959cc 100644
--- a/src/tools/miri/cargo-miri/Cargo.toml
+++ b/src/tools/miri/cargo-miri/Cargo.toml
@@ -18,7 +18,7 @@ directories = "6"
 rustc_version = "0.4"
 serde_json = "1.0.40"
 cargo_metadata = "0.19"
-rustc-build-sysroot = "0.5.7"
+rustc-build-sysroot = "0.5.8"
 
 # Enable some feature flags that dev-dependencies need but dependencies
 # do not.  This makes `./miri install` after `./miri build` faster.
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 553d410b2bc..43632bf86a7 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-337c11e5932275e7d450c1f2e26f289f0ddfa717
+c6768de2d63de7a41124a0fb8fc78f9e26111c01
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index 12a320b9676..4a038fe6487 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -132,7 +132,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
         assert!(!matches!(info.kind, AllocKind::Dead));
 
         // This allocation does not have a base address yet, pick or reuse one.
-        if this.machine.native_lib.is_some() {
+        if !this.machine.native_lib.is_empty() {
             // In native lib mode, we use the "real" address of the bytes for this allocation.
             // This ensures the interpreted program and native code have the same view of memory.
             let params = this.machine.get_default_alloc_params();
@@ -413,7 +413,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     ) -> InterpResult<'tcx, MiriAllocBytes> {
         let this = self.eval_context_ref();
         assert!(this.tcx.try_get_global_alloc(id).is_some());
-        if this.machine.native_lib.is_some() {
+        if !this.machine.native_lib.is_empty() {
             // In native lib mode, MiriAllocBytes for global allocations are handled via `prepared_alloc_bytes`.
             // This additional call ensures that some `MiriAllocBytes` are always prepared, just in case
             // this function gets called before the first time `addr_from_alloc_id` gets called.
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 0121472d330..2faaec5a174 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -35,7 +35,7 @@ use std::sync::{Arc, Once};
 
 use miri::{
     BacktraceStyle, BorrowTrackerMethod, GenmcConfig, GenmcCtx, MiriConfig, MiriEntryFnType,
-    ProvenanceMode, RetagFields, ValidationMode,
+    ProvenanceMode, RetagFields, TreeBorrowsParams, ValidationMode,
 };
 use rustc_abi::ExternAbi;
 use rustc_data_structures::sync;
@@ -554,8 +554,21 @@ fn main() {
         } else if arg == "-Zmiri-disable-stacked-borrows" {
             miri_config.borrow_tracker = None;
         } else if arg == "-Zmiri-tree-borrows" {
-            miri_config.borrow_tracker = Some(BorrowTrackerMethod::TreeBorrows);
+            miri_config.borrow_tracker =
+                Some(BorrowTrackerMethod::TreeBorrows(TreeBorrowsParams {
+                    precise_interior_mut: true,
+                }));
             miri_config.provenance_mode = ProvenanceMode::Strict;
+        } else if arg == "-Zmiri-tree-borrows-no-precise-interior-mut" {
+            match &mut miri_config.borrow_tracker {
+                Some(BorrowTrackerMethod::TreeBorrows(params)) => {
+                    params.precise_interior_mut = false;
+                }
+                _ =>
+                    show_error!(
+                        "`-Zmiri-tree-borrows` is required before `-Zmiri-tree-borrows-no-precise-interior-mut`"
+                    ),
+            };
         } else if arg == "-Zmiri-disable-data-race-detector" {
             miri_config.data_race_detector = false;
             miri_config.weak_memory_emulation = false;
@@ -692,11 +705,18 @@ fn main() {
             };
         } else if let Some(param) = arg.strip_prefix("-Zmiri-native-lib=") {
             let filename = param.to_string();
-            if std::path::Path::new(&filename).exists() {
-                if let Some(other_filename) = miri_config.native_lib {
-                    show_error!("-Zmiri-native-lib is already set to {}", other_filename.display());
+            let file_path = std::path::Path::new(&filename);
+            if file_path.exists() {
+                // For directories, nonrecursively add all normal files inside
+                if let Ok(dir) = file_path.read_dir() {
+                    for lib in dir.filter_map(|res| res.ok()) {
+                        if lib.file_type().unwrap().is_file() {
+                            miri_config.native_lib.push(lib.path().to_owned());
+                        }
+                    }
+                } else {
+                    miri_config.native_lib.push(filename.into());
                 }
-                miri_config.native_lib = Some(filename.into());
             } else {
                 show_error!("-Zmiri-native-lib `{}` does not exist", filename);
             }
@@ -725,18 +745,19 @@ fn main() {
         }
     }
     // Tree Borrows implies strict provenance, and is not compatible with native calls.
-    if matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows)) {
+    if matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows { .. })) {
         if miri_config.provenance_mode != ProvenanceMode::Strict {
             show_error!(
                 "Tree Borrows does not support integer-to-pointer casts, and hence requires strict provenance"
             );
         }
-        if miri_config.native_lib.is_some() {
+        if !miri_config.native_lib.is_empty() {
             show_error!("Tree Borrows is not compatible with calling native functions");
         }
     }
+
     // Native calls and strict provenance are not compatible.
-    if miri_config.native_lib.is_some() && miri_config.provenance_mode == ProvenanceMode::Strict {
+    if !miri_config.native_lib.is_empty() && miri_config.provenance_mode == ProvenanceMode::Strict {
         show_error!("strict provenance is not compatible with calling native functions");
     }
     // You can set either one seed or many.
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index b66c561d2b8..36c61053a32 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -226,7 +226,13 @@ pub enum BorrowTrackerMethod {
     /// Stacked Borrows, as implemented in borrow_tracker/stacked_borrows
     StackedBorrows,
     /// Tree borrows, as implemented in borrow_tracker/tree_borrows
-    TreeBorrows,
+    TreeBorrows(TreeBorrowsParams),
+}
+
+/// Parameters that Tree Borrows can take.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct TreeBorrowsParams {
+    pub precise_interior_mut: bool,
 }
 
 impl BorrowTrackerMethod {
@@ -237,6 +243,13 @@ impl BorrowTrackerMethod {
             config.retag_fields,
         ))
     }
+
+    pub fn get_tree_borrows_params(self) -> TreeBorrowsParams {
+        match self {
+            BorrowTrackerMethod::TreeBorrows(params) => params,
+            _ => panic!("can only be called when `BorrowTrackerMethod` is `TreeBorrows`"),
+        }
+    }
 }
 
 impl GlobalStateInner {
@@ -252,7 +265,7 @@ impl GlobalStateInner {
                 AllocState::StackedBorrows(Box::new(RefCell::new(Stacks::new_allocation(
                     id, alloc_size, self, kind, machine,
                 )))),
-            BorrowTrackerMethod::TreeBorrows =>
+            BorrowTrackerMethod::TreeBorrows { .. } =>
                 AllocState::TreeBorrows(Box::new(RefCell::new(Tree::new_allocation(
                     id, alloc_size, self, kind, machine,
                 )))),
@@ -271,7 +284,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
         match method {
             BorrowTrackerMethod::StackedBorrows => this.sb_retag_ptr_value(kind, val),
-            BorrowTrackerMethod::TreeBorrows => this.tb_retag_ptr_value(kind, val),
+            BorrowTrackerMethod::TreeBorrows { .. } => this.tb_retag_ptr_value(kind, val),
         }
     }
 
@@ -284,7 +297,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
         match method {
             BorrowTrackerMethod::StackedBorrows => this.sb_retag_place_contents(kind, place),
-            BorrowTrackerMethod::TreeBorrows => this.tb_retag_place_contents(kind, place),
+            BorrowTrackerMethod::TreeBorrows { .. } => this.tb_retag_place_contents(kind, place),
         }
     }
 
@@ -293,7 +306,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
         match method {
             BorrowTrackerMethod::StackedBorrows => this.sb_protect_place(place),
-            BorrowTrackerMethod::TreeBorrows => this.tb_protect_place(place),
+            BorrowTrackerMethod::TreeBorrows { .. } => this.tb_protect_place(place),
         }
     }
 
@@ -302,7 +315,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
         match method {
             BorrowTrackerMethod::StackedBorrows => this.sb_expose_tag(alloc_id, tag),
-            BorrowTrackerMethod::TreeBorrows => this.tb_expose_tag(alloc_id, tag),
+            BorrowTrackerMethod::TreeBorrows { .. } => this.tb_expose_tag(alloc_id, tag),
         }
     }
 
@@ -319,7 +332,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.tcx.tcx.dcx().warn("Stacked Borrows does not support named pointers; `miri_pointer_name` is a no-op");
                 interp_ok(())
             }
-            BorrowTrackerMethod::TreeBorrows =>
+            BorrowTrackerMethod::TreeBorrows { .. } =>
                 this.tb_give_pointer_debug_name(ptr, nth_parent, name),
         }
     }
@@ -333,7 +346,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let method = borrow_tracker.borrow().borrow_tracker_method;
         match method {
             BorrowTrackerMethod::StackedBorrows => this.print_stacks(alloc_id),
-            BorrowTrackerMethod::TreeBorrows => this.print_tree(alloc_id, show_unnamed),
+            BorrowTrackerMethod::TreeBorrows { .. } => this.print_tree(alloc_id, show_unnamed),
         }
     }
 
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index 411ae89da90..ce8fe03ee47 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -312,8 +312,6 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         }
 
         let span = this.machine.current_span();
-        let alloc_extra = this.get_alloc_extra(alloc_id)?;
-        let mut tree_borrows = alloc_extra.borrow_tracker_tb().borrow_mut();
 
         // Store initial permissions and their corresponding range.
         let mut perms_map: RangeMap<LocationState> = RangeMap::new(
@@ -342,36 +340,83 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         assert!(new_perm.freeze_access);
 
         let protected = new_perm.protector.is_some();
-        this.visit_freeze_sensitive(place, ptr_size, |range, frozen| {
-            has_unsafe_cell = has_unsafe_cell || !frozen;
-
-            // We are only ever `Frozen` inside the frozen bits.
-            let (perm, access) = if frozen {
+        let precise_interior_mut = this
+            .machine
+            .borrow_tracker
+            .as_mut()
+            .unwrap()
+            .get_mut()
+            .borrow_tracker_method
+            .get_tree_borrows_params()
+            .precise_interior_mut;
+
+        let default_perm = if !precise_interior_mut {
+            // NOTE: Using `ty_is_freeze` doesn't give the same result as going through the range
+            // and computing `has_unsafe_cell`.  This is because of zero-sized `UnsafeCell`, for which
+            // `has_unsafe_cell` is false, but `!ty_is_freeze` is true.
+            let ty_is_freeze = place.layout.ty.is_freeze(*this.tcx, this.typing_env());
+            let (perm, access) = if ty_is_freeze {
                 (new_perm.freeze_perm, new_perm.freeze_access)
             } else {
                 (new_perm.nonfreeze_perm, new_perm.nonfreeze_access)
             };
+            let sifa = perm.strongest_idempotent_foreign_access(protected);
+            let new_loc = if access {
+                LocationState::new_accessed(perm, sifa)
+            } else {
+                LocationState::new_non_accessed(perm, sifa)
+            };
+
+            for (_loc_range, loc) in perms_map.iter_mut_all() {
+                *loc = new_loc;
+            }
+
+            perm
+        } else {
+            this.visit_freeze_sensitive(place, ptr_size, |range, frozen| {
+                has_unsafe_cell = has_unsafe_cell || !frozen;
 
-            // Store initial permissions.
-            for (_loc_range, loc) in perms_map.iter_mut(range.start, range.size) {
+                // We are only ever `Frozen` inside the frozen bits.
+                let (perm, access) = if frozen {
+                    (new_perm.freeze_perm, new_perm.freeze_access)
+                } else {
+                    (new_perm.nonfreeze_perm, new_perm.nonfreeze_access)
+                };
                 let sifa = perm.strongest_idempotent_foreign_access(protected);
                 // NOTE: Currently, `access` is false if and only if `perm` is Cell, so this `if`
                 // doesn't not change whether any code is UB or not. We could just always use
                 // `new_accessed` and everything would stay the same. But that seems conceptually
                 // odd, so we keep the initial "accessed" bit of the `LocationState` in sync with whether
                 // a read access is performed below.
-                if access {
-                    *loc = LocationState::new_accessed(perm, sifa);
+                let new_loc = if access {
+                    LocationState::new_accessed(perm, sifa)
                 } else {
-                    *loc = LocationState::new_non_accessed(perm, sifa);
+                    LocationState::new_non_accessed(perm, sifa)
+                };
+
+                // Store initial permissions.
+                for (_loc_range, loc) in perms_map.iter_mut(range.start, range.size) {
+                    *loc = new_loc;
                 }
-            }
 
-            // Some reborrows incur a read access to the parent.
-            if access {
+                interp_ok(())
+            })?;
+
+            // Allow lazily writing to surrounding data if we found an `UnsafeCell`.
+            if has_unsafe_cell { new_perm.nonfreeze_perm } else { new_perm.freeze_perm }
+        };
+
+        let alloc_extra = this.get_alloc_extra(alloc_id)?;
+        let mut tree_borrows = alloc_extra.borrow_tracker_tb().borrow_mut();
+
+        for (perm_range, perm) in perms_map.iter_mut_all() {
+            if perm.is_accessed() {
+                // Some reborrows incur a read access to the parent.
                 // Adjust range to be relative to allocation start (rather than to `place`).
-                let mut range_in_alloc = range;
-                range_in_alloc.start += base_offset;
+                let range_in_alloc = AllocRange {
+                    start: Size::from_bytes(perm_range.start) + base_offset,
+                    size: Size::from_bytes(perm_range.end - perm_range.start),
+                };
 
                 tree_borrows.perform_access(
                     orig_tag,
@@ -382,7 +427,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 )?;
 
                 // Also inform the data race model (but only if any bytes are actually affected).
-                if range.size.bytes() > 0 {
+                if range_in_alloc.size.bytes() > 0 {
                     if let Some(data_race) = alloc_extra.data_race.as_vclocks_ref() {
                         data_race.read(
                             alloc_id,
@@ -394,8 +439,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     }
                 }
             }
-            interp_ok(())
-        })?;
+        }
 
         // Record the parent-child pair in the tree.
         tree_borrows.new_child(
@@ -403,8 +447,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             orig_tag,
             new_tag,
             perms_map,
-            // Allow lazily writing to surrounding data if we found an `UnsafeCell`.
-            if has_unsafe_cell { new_perm.nonfreeze_perm } else { new_perm.freeze_perm },
+            default_perm,
             protected,
             span,
         )?;
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index 1728a9cfd6d..58bf163bfad 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -682,7 +682,10 @@ impl<'tcx> MiriMachine<'tcx> {
                     ),
                 ];
                 if self.borrow_tracker.as_ref().is_some_and(|b| {
-                    matches!(b.borrow().borrow_tracker_method(), BorrowTrackerMethod::TreeBorrows)
+                    matches!(
+                        b.borrow().borrow_tracker_method(),
+                        BorrowTrackerMethod::TreeBorrows { .. }
+                    )
                 }) {
                     v.push(
                         note!("Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used")
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index 8fe034d2582..6f5f756e144 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -148,9 +148,8 @@ pub struct MiriConfig {
     pub report_progress: Option<u32>,
     /// Whether Stacked Borrows and Tree Borrows retagging should recurse into fields of datatypes.
     pub retag_fields: RetagFields,
-    /// The location of a shared object file to load when calling external functions
-    /// FIXME! consider allowing users to specify paths to multiple files, or to a directory
-    pub native_lib: Option<PathBuf>,
+    /// The location of the shared object files to load when calling external functions
+    pub native_lib: Vec<PathBuf>,
     /// Run a garbage collector for BorTags every N basic blocks.
     pub gc_interval: u32,
     /// The number of CPUs to be reported by miri.
@@ -197,7 +196,7 @@ impl Default for MiriConfig {
             preemption_rate: 0.01, // 1%
             report_progress: None,
             retag_fields: RetagFields::Yes,
-            native_lib: None,
+            native_lib: vec![],
             gc_interval: 10_000,
             num_cpus: 1,
             page_size: None,
@@ -359,8 +358,8 @@ pub fn create_ecx<'tcx>(
         let argvs_layout =
             ecx.layout_of(Ty::new_array(tcx, u8_ptr_type, u64::try_from(argvs.len()).unwrap()))?;
         let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Machine.into())?;
-        for (idx, arg) in argvs.into_iter().enumerate() {
-            let place = ecx.project_field(&argvs_place, idx)?;
+        for (arg, idx) in argvs.into_iter().zip(0..) {
+            let place = ecx.project_index(&argvs_place, idx)?;
             ecx.write_immediate(arg, &place)?;
         }
         ecx.mark_immutable(&argvs_place);
@@ -389,8 +388,8 @@ pub fn create_ecx<'tcx>(
                 ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into())?;
             ecx.machine.cmd_line = Some(cmd_place.ptr());
             // Store the UTF-16 string. We just allocated so we know the bounds are fine.
-            for (idx, &c) in cmd_utf16.iter().enumerate() {
-                let place = ecx.project_field(&cmd_place, idx)?;
+            for (&c, idx) in cmd_utf16.iter().zip(0..) {
+                let place = ecx.project_index(&cmd_place, idx)?;
                 ecx.write_scalar(Scalar::from_u16(c), &place)?;
             }
             ecx.mark_immutable(&cmd_place);
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 20ea239b7e5..4edecc864dd 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -326,7 +326,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     ) -> InterpResult<'tcx, Option<P>> {
         let this = self.eval_context_ref();
         let adt = base.layout().ty.ty_adt_def().unwrap();
-        for (idx, field) in adt.non_enum_variant().fields.iter().enumerate() {
+        for (idx, field) in adt.non_enum_variant().fields.iter_enumerated() {
             if field.name.as_str() == name {
                 return interp_ok(Some(this.project_field(base, idx)?));
             }
@@ -376,6 +376,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
         for (idx, &val) in values.iter().enumerate() {
+            let idx = FieldIdx::from_usize(idx);
             let field = this.project_field(dest, idx)?;
             this.write_int(val, &field)?;
         }
@@ -763,10 +764,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     /// `EINVAL` in this case.
     fn read_timespec(&mut self, tp: &MPlaceTy<'tcx>) -> InterpResult<'tcx, Option<Duration>> {
         let this = self.eval_context_mut();
-        let seconds_place = this.project_field(tp, 0)?;
+        let seconds_place = this.project_field(tp, FieldIdx::ZERO)?;
         let seconds_scalar = this.read_scalar(&seconds_place)?;
         let seconds = seconds_scalar.to_target_isize(this)?;
-        let nanoseconds_place = this.project_field(tp, 1)?;
+        let nanoseconds_place = this.project_field(tp, FieldIdx::ONE)?;
         let nanoseconds_scalar = this.read_scalar(&nanoseconds_place)?;
         let nanoseconds = nanoseconds_scalar.to_target_isize(this)?;
 
diff --git a/src/tools/miri/src/intrinsics/atomic.rs b/src/tools/miri/src/intrinsics/atomic.rs
index a61226eeed9..0a59a707a10 100644
--- a/src/tools/miri/src/intrinsics/atomic.rs
+++ b/src/tools/miri/src/intrinsics/atomic.rs
@@ -26,108 +26,131 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     ) -> InterpResult<'tcx, EmulateItemResult> {
         let this = self.eval_context_mut();
 
-        let intrinsic_structure: Vec<_> = intrinsic_name.split('_').collect();
+        let get_ord_at = |i: usize| {
+            let ordering = generic_args.const_at(i).to_value();
+            ordering.valtree.unwrap_branch()[0].unwrap_leaf().to_atomic_ordering()
+        };
 
-        fn read_ord(ord: &str) -> AtomicReadOrd {
+        fn read_ord(ord: AtomicOrdering) -> AtomicReadOrd {
             match ord {
-                "seqcst" => AtomicReadOrd::SeqCst,
-                "acquire" => AtomicReadOrd::Acquire,
-                "relaxed" => AtomicReadOrd::Relaxed,
-                _ => panic!("invalid read ordering `{ord}`"),
-            }
-        }
-
-        fn read_ord_const_generic(o: AtomicOrdering) -> AtomicReadOrd {
-            match o {
                 AtomicOrdering::SeqCst => AtomicReadOrd::SeqCst,
                 AtomicOrdering::Acquire => AtomicReadOrd::Acquire,
                 AtomicOrdering::Relaxed => AtomicReadOrd::Relaxed,
-                _ => panic!("invalid read ordering `{o:?}`"),
+                _ => panic!("invalid read ordering `{ord:?}`"),
             }
         }
 
-        fn write_ord(ord: &str) -> AtomicWriteOrd {
+        fn write_ord(ord: AtomicOrdering) -> AtomicWriteOrd {
             match ord {
-                "seqcst" => AtomicWriteOrd::SeqCst,
-                "release" => AtomicWriteOrd::Release,
-                "relaxed" => AtomicWriteOrd::Relaxed,
-                _ => panic!("invalid write ordering `{ord}`"),
+                AtomicOrdering::SeqCst => AtomicWriteOrd::SeqCst,
+                AtomicOrdering::Release => AtomicWriteOrd::Release,
+                AtomicOrdering::Relaxed => AtomicWriteOrd::Relaxed,
+                _ => panic!("invalid write ordering `{ord:?}`"),
             }
         }
 
-        fn rw_ord(ord: &str) -> AtomicRwOrd {
+        fn rw_ord(ord: AtomicOrdering) -> AtomicRwOrd {
             match ord {
-                "seqcst" => AtomicRwOrd::SeqCst,
-                "acqrel" => AtomicRwOrd::AcqRel,
-                "acquire" => AtomicRwOrd::Acquire,
-                "release" => AtomicRwOrd::Release,
-                "relaxed" => AtomicRwOrd::Relaxed,
-                _ => panic!("invalid read-write ordering `{ord}`"),
+                AtomicOrdering::SeqCst => AtomicRwOrd::SeqCst,
+                AtomicOrdering::AcqRel => AtomicRwOrd::AcqRel,
+                AtomicOrdering::Acquire => AtomicRwOrd::Acquire,
+                AtomicOrdering::Release => AtomicRwOrd::Release,
+                AtomicOrdering::Relaxed => AtomicRwOrd::Relaxed,
             }
         }
 
-        fn fence_ord(ord: &str) -> AtomicFenceOrd {
+        fn fence_ord(ord: AtomicOrdering) -> AtomicFenceOrd {
             match ord {
-                "seqcst" => AtomicFenceOrd::SeqCst,
-                "acqrel" => AtomicFenceOrd::AcqRel,
-                "acquire" => AtomicFenceOrd::Acquire,
-                "release" => AtomicFenceOrd::Release,
-                _ => panic!("invalid fence ordering `{ord}`"),
+                AtomicOrdering::SeqCst => AtomicFenceOrd::SeqCst,
+                AtomicOrdering::AcqRel => AtomicFenceOrd::AcqRel,
+                AtomicOrdering::Acquire => AtomicFenceOrd::Acquire,
+                AtomicOrdering::Release => AtomicFenceOrd::Release,
+                _ => panic!("invalid fence ordering `{ord:?}`"),
             }
         }
 
-        match &*intrinsic_structure {
-            // New-style intrinsics that use const generics
-            ["load"] => {
-                let ordering = generic_args.const_at(1).to_value();
-                let ordering =
-                    ordering.valtree.unwrap_branch()[0].unwrap_leaf().to_atomic_ordering();
-                this.atomic_load(args, dest, read_ord_const_generic(ordering))?;
+        match intrinsic_name {
+            "load" => {
+                let ord = get_ord_at(1);
+                this.atomic_load(args, dest, read_ord(ord))?;
+            }
+
+            "store" => {
+                let ord = get_ord_at(1);
+                this.atomic_store(args, write_ord(ord))?
             }
 
-            // Old-style intrinsics that have the ordering in the intrinsic name
-            ["store", ord] => this.atomic_store(args, write_ord(ord))?,
-
-            ["fence", ord] => this.atomic_fence_intrinsic(args, fence_ord(ord))?,
-            ["singlethreadfence", ord] => this.compiler_fence_intrinsic(args, fence_ord(ord))?,
-
-            ["xchg", ord] => this.atomic_exchange(args, dest, rw_ord(ord))?,
-            ["cxchg", ord1, ord2] =>
-                this.atomic_compare_exchange(args, dest, rw_ord(ord1), read_ord(ord2))?,
-            ["cxchgweak", ord1, ord2] =>
-                this.atomic_compare_exchange_weak(args, dest, rw_ord(ord1), read_ord(ord2))?,
-
-            ["or", ord] =>
-                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitOr, false), rw_ord(ord))?,
-            ["xor", ord] =>
-                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitXor, false), rw_ord(ord))?,
-            ["and", ord] =>
-                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, false), rw_ord(ord))?,
-            ["nand", ord] =>
-                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, true), rw_ord(ord))?,
-            ["xadd", ord] =>
-                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Add, false), rw_ord(ord))?,
-            ["xsub", ord] =>
-                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Sub, false), rw_ord(ord))?,
-            ["min", ord] => {
+            "fence" => {
+                let ord = get_ord_at(0);
+                this.atomic_fence_intrinsic(args, fence_ord(ord))?
+            }
+            "singlethreadfence" => {
+                let ord = get_ord_at(0);
+                this.compiler_fence_intrinsic(args, fence_ord(ord))?;
+            }
+
+            "xchg" => {
+                let ord = get_ord_at(1);
+                this.atomic_exchange(args, dest, rw_ord(ord))?;
+            }
+            "cxchg" => {
+                let ord1 = get_ord_at(1);
+                let ord2 = get_ord_at(2);
+                this.atomic_compare_exchange(args, dest, rw_ord(ord1), read_ord(ord2))?;
+            }
+            "cxchgweak" => {
+                let ord1 = get_ord_at(1);
+                let ord2 = get_ord_at(2);
+                this.atomic_compare_exchange_weak(args, dest, rw_ord(ord1), read_ord(ord2))?;
+            }
+
+            "or" => {
+                let ord = get_ord_at(1);
+                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitOr, false), rw_ord(ord))?;
+            }
+            "xor" => {
+                let ord = get_ord_at(1);
+                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitXor, false), rw_ord(ord))?;
+            }
+            "and" => {
+                let ord = get_ord_at(1);
+                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, false), rw_ord(ord))?;
+            }
+            "nand" => {
+                let ord = get_ord_at(1);
+                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, true), rw_ord(ord))?;
+            }
+            "xadd" => {
+                let ord = get_ord_at(1);
+                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Add, false), rw_ord(ord))?;
+            }
+            "xsub" => {
+                let ord = get_ord_at(1);
+                this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Sub, false), rw_ord(ord))?;
+            }
+            "min" => {
+                let ord = get_ord_at(1);
                 // Later we will use the type to indicate signed vs unsigned,
                 // so make sure it matches the intrinsic name.
                 assert!(matches!(args[1].layout.ty.kind(), ty::Int(_)));
                 this.atomic_rmw_op(args, dest, AtomicOp::Min, rw_ord(ord))?;
             }
-            ["umin", ord] => {
+            "umin" => {
+                let ord = get_ord_at(1);
                 // Later we will use the type to indicate signed vs unsigned,
                 // so make sure it matches the intrinsic name.
                 assert!(matches!(args[1].layout.ty.kind(), ty::Uint(_)));
                 this.atomic_rmw_op(args, dest, AtomicOp::Min, rw_ord(ord))?;
             }
-            ["max", ord] => {
+            "max" => {
+                let ord = get_ord_at(1);
                 // Later we will use the type to indicate signed vs unsigned,
                 // so make sure it matches the intrinsic name.
                 assert!(matches!(args[1].layout.ty.kind(), ty::Int(_)));
                 this.atomic_rmw_op(args, dest, AtomicOp::Max, rw_ord(ord))?;
             }
-            ["umax", ord] => {
+            "umax" => {
+                let ord = get_ord_at(1);
                 // Later we will use the type to indicate signed vs unsigned,
                 // so make sure it matches the intrinsic name.
                 assert!(matches!(args[1].layout.ty.kind(), ty::Uint(_)));
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index a4882a20148..9957e351ff1 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -3,17 +3,20 @@
 mod atomic;
 mod simd;
 
+use std::ops::Neg;
+
 use rand::Rng;
 use rustc_abi::Size;
-use rustc_apfloat::{Float, Round};
+use rustc_apfloat::ieee::{IeeeFloat, Semantics};
+use rustc_apfloat::{self, Float, Round};
 use rustc_middle::mir;
-use rustc_middle::ty::{self, FloatTy};
+use rustc_middle::ty::{self, FloatTy, ScalarInt};
 use rustc_span::{Symbol, sym};
 
 use self::atomic::EvalContextExt as _;
 use self::helpers::{ToHost, ToSoft, check_intrinsic_arg_count};
 use self::simd::EvalContextExt as _;
-use crate::math::apply_random_float_error_to_imm;
+use crate::math::{IeeeExt, apply_random_float_error_ulp};
 use crate::*;
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
@@ -187,31 +190,39 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             => {
                 let [f] = check_intrinsic_arg_count(args)?;
                 let f = this.read_scalar(f)?.to_f32()?;
-                // Using host floats (but it's fine, these operations do not have
-                // guaranteed precision).
-                let host = f.to_host();
-                let res = match intrinsic_name {
-                    "sinf32" => host.sin(),
-                    "cosf32" => host.cos(),
-                    "expf32" => host.exp(),
-                    "exp2f32" => host.exp2(),
-                    "logf32" => host.ln(),
-                    "log10f32" => host.log10(),
-                    "log2f32" => host.log2(),
-                    _ => bug!(),
-                };
-                let res = res.to_soft();
-                // Apply a relative error of 16ULP to introduce some non-determinism
-                // simulating imprecise implementations and optimizations.
-                // FIXME: temporarily disabled as it breaks std tests.
-                // let res = apply_random_float_error_ulp(
-                //     this,
-                //     res,
-                //     4, // log2(16)
-                // );
+
+                let res = fixed_float_value(intrinsic_name, &[f]).unwrap_or_else(||{
+                    // Using host floats (but it's fine, these operations do not have
+                    // guaranteed precision).
+                    let host = f.to_host();
+                    let res = match intrinsic_name {
+                        "sinf32" => host.sin(),
+                        "cosf32" => host.cos(),
+                        "expf32" => host.exp(),
+                        "exp2f32" => host.exp2(),
+                        "logf32" => host.ln(),
+                        "log10f32" => host.log10(),
+                        "log2f32" => host.log2(),
+                        _ => bug!(),
+                    };
+                    let res = res.to_soft();
+
+                    // Apply a relative error of 4ULP to introduce some non-determinism
+                    // simulating imprecise implementations and optimizations.
+                    let res = apply_random_float_error_ulp(
+                        this,
+                        res,
+                        2, // log2(4)
+                    );
+
+                    // Clamp the result to the guaranteed range of this function according to the C standard,
+                    // if any.
+                    clamp_float_value(intrinsic_name, res)
+                });
                 let res = this.adjust_nan(res, &[f]);
                 this.write_scalar(res, dest)?;
             }
+
             #[rustfmt::skip]
             | "sinf64"
             | "cosf64"
@@ -223,28 +234,35 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             => {
                 let [f] = check_intrinsic_arg_count(args)?;
                 let f = this.read_scalar(f)?.to_f64()?;
-                // Using host floats (but it's fine, these operations do not have
-                // guaranteed precision).
-                let host = f.to_host();
-                let res = match intrinsic_name {
-                    "sinf64" => host.sin(),
-                    "cosf64" => host.cos(),
-                    "expf64" => host.exp(),
-                    "exp2f64" => host.exp2(),
-                    "logf64" => host.ln(),
-                    "log10f64" => host.log10(),
-                    "log2f64" => host.log2(),
-                    _ => bug!(),
-                };
-                let res = res.to_soft();
-                // Apply a relative error of 16ULP to introduce some non-determinism
-                // simulating imprecise implementations and optimizations.
-                // FIXME: temporarily disabled as it breaks std tests.
-                // let res = apply_random_float_error_ulp(
-                //     this,
-                //     res,
-                //     4, // log2(16)
-                // );
+
+                let res = fixed_float_value(intrinsic_name, &[f]).unwrap_or_else(||{
+                    // Using host floats (but it's fine, these operations do not have
+                    // guaranteed precision).
+                    let host = f.to_host();
+                    let res = match intrinsic_name {
+                        "sinf64" => host.sin(),
+                        "cosf64" => host.cos(),
+                        "expf64" => host.exp(),
+                        "exp2f64" => host.exp2(),
+                        "logf64" => host.ln(),
+                        "log10f64" => host.log10(),
+                        "log2f64" => host.log2(),
+                        _ => bug!(),
+                    };
+                    let res = res.to_soft();
+
+                    // Apply a relative error of 4ULP to introduce some non-determinism
+                    // simulating imprecise implementations and optimizations.
+                    let res = apply_random_float_error_ulp(
+                        this,
+                        res,
+                        2, // log2(4)
+                    );
+
+                    // Clamp the result to the guaranteed range of this function according to the C standard,
+                    // if any.
+                    clamp_float_value(intrinsic_name, res)
+                });
                 let res = this.adjust_nan(res, &[f]);
                 this.write_scalar(res, dest)?;
             }
@@ -302,43 +320,75 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
 
             "powf32" => {
-                // FIXME: apply random relative error but without altering behaviour of powf
                 let [f1, f2] = check_intrinsic_arg_count(args)?;
                 let f1 = this.read_scalar(f1)?.to_f32()?;
                 let f2 = this.read_scalar(f2)?.to_f32()?;
-                // Using host floats (but it's fine, this operation does not have guaranteed precision).
-                let res = f1.to_host().powf(f2.to_host()).to_soft();
+
+                let res = fixed_float_value(intrinsic_name, &[f1, f2]).unwrap_or_else(|| {
+                    // Using host floats (but it's fine, this operation does not have guaranteed precision).
+                    let res = f1.to_host().powf(f2.to_host()).to_soft();
+
+                    // Apply a relative error of 4ULP to introduce some non-determinism
+                    // simulating imprecise implementations and optimizations.
+                    apply_random_float_error_ulp(
+                        this, res, 2, // log2(4)
+                    )
+                });
                 let res = this.adjust_nan(res, &[f1, f2]);
                 this.write_scalar(res, dest)?;
             }
             "powf64" => {
-                // FIXME: apply random relative error but without altering behaviour of powf
                 let [f1, f2] = check_intrinsic_arg_count(args)?;
                 let f1 = this.read_scalar(f1)?.to_f64()?;
                 let f2 = this.read_scalar(f2)?.to_f64()?;
-                // Using host floats (but it's fine, this operation does not have guaranteed precision).
-                let res = f1.to_host().powf(f2.to_host()).to_soft();
+
+                let res = fixed_float_value(intrinsic_name, &[f1, f2]).unwrap_or_else(|| {
+                    // Using host floats (but it's fine, this operation does not have guaranteed precision).
+                    let res = f1.to_host().powf(f2.to_host()).to_soft();
+
+                    // Apply a relative error of 4ULP to introduce some non-determinism
+                    // simulating imprecise implementations and optimizations.
+                    apply_random_float_error_ulp(
+                        this, res, 2, // log2(4)
+                    )
+                });
                 let res = this.adjust_nan(res, &[f1, f2]);
                 this.write_scalar(res, dest)?;
             }
 
             "powif32" => {
-                // FIXME: apply random relative error but without altering behaviour of powi
                 let [f, i] = check_intrinsic_arg_count(args)?;
                 let f = this.read_scalar(f)?.to_f32()?;
                 let i = this.read_scalar(i)?.to_i32()?;
-                // Using host floats (but it's fine, this operation does not have guaranteed precision).
-                let res = f.to_host().powi(i).to_soft();
+
+                let res = fixed_powi_float_value(f, i).unwrap_or_else(|| {
+                    // Using host floats (but it's fine, this operation does not have guaranteed precision).
+                    let res = f.to_host().powi(i).to_soft();
+
+                    // Apply a relative error of 4ULP to introduce some non-determinism
+                    // simulating imprecise implementations and optimizations.
+                    apply_random_float_error_ulp(
+                        this, res, 2, // log2(4)
+                    )
+                });
                 let res = this.adjust_nan(res, &[f]);
                 this.write_scalar(res, dest)?;
             }
             "powif64" => {
-                // FIXME: apply random relative error but without altering behaviour of powi
                 let [f, i] = check_intrinsic_arg_count(args)?;
                 let f = this.read_scalar(f)?.to_f64()?;
                 let i = this.read_scalar(i)?.to_i32()?;
-                // Using host floats (but it's fine, this operation does not have guaranteed precision).
-                let res = f.to_host().powi(i).to_soft();
+
+                let res = fixed_powi_float_value(f, i).unwrap_or_else(|| {
+                    // Using host floats (but it's fine, this operation does not have guaranteed precision).
+                    let res = f.to_host().powi(i).to_soft();
+
+                    // Apply a relative error of 4ULP to introduce some non-determinism
+                    // simulating imprecise implementations and optimizations.
+                    apply_random_float_error_ulp(
+                        this, res, 2, // log2(4)
+                    )
+                });
                 let res = this.adjust_nan(res, &[f]);
                 this.write_scalar(res, dest)?;
             }
@@ -425,3 +475,97 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         interp_ok(EmulateItemResult::NeedsReturn)
     }
 }
+
+/// Applies a random ULP floating point error to `val` and returns the new value.
+/// So if you want an X ULP error, `ulp_exponent` should be log2(X).
+///
+/// Will fail if `val` is not a floating point number.
+fn apply_random_float_error_to_imm<'tcx>(
+    ecx: &mut MiriInterpCx<'tcx>,
+    val: ImmTy<'tcx>,
+    ulp_exponent: u32,
+) -> InterpResult<'tcx, ImmTy<'tcx>> {
+    let scalar = val.to_scalar_int()?;
+    let res: ScalarInt = match val.layout.ty.kind() {
+        ty::Float(FloatTy::F16) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f16(), ulp_exponent).into(),
+        ty::Float(FloatTy::F32) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f32(), ulp_exponent).into(),
+        ty::Float(FloatTy::F64) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f64(), ulp_exponent).into(),
+        ty::Float(FloatTy::F128) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f128(), ulp_exponent).into(),
+        _ => bug!("intrinsic called with non-float input type"),
+    };
+
+    interp_ok(ImmTy::from_scalar_int(res, val.layout))
+}
+
+/// For the intrinsics:
+/// - sinf32, sinf64
+/// - cosf32, cosf64
+/// - expf32, expf64, exp2f32, exp2f64
+/// - logf32, logf64, log2f32, log2f64, log10f32, log10f64
+/// - powf32, powf64
+///
+/// Returns `Some(output)` if the `intrinsic` results in a defined fixed `output` specified in the C standard
+/// (specifically, C23 annex F.10)  when given `args` as arguments. Outputs that are unaffected by a relative error
+/// (such as INF and zero) are not handled here, they are assumed to be handled by the underlying
+/// implementation. Returns `None` if no specific value is guaranteed.
+fn fixed_float_value<S: Semantics>(
+    intrinsic_name: &str,
+    args: &[IeeeFloat<S>],
+) -> Option<IeeeFloat<S>> {
+    let one = IeeeFloat::<S>::one();
+    match (intrinsic_name, args) {
+        // cos(+- 0) = 1
+        ("cosf32" | "cosf64", [input]) if input.is_zero() => Some(one),
+
+        // e^0 = 1
+        ("expf32" | "expf64" | "exp2f32" | "exp2f64", [input]) if input.is_zero() => Some(one),
+
+        // 1^y = 1 for any y, even a NaN.
+        ("powf32" | "powf64", [base, _]) if *base == one => Some(one),
+
+        // (-1)^(±INF) = 1
+        ("powf32" | "powf64", [base, exp]) if *base == -one && exp.is_infinite() => Some(one),
+
+        // FIXME(#4286): The C ecosystem is inconsistent with handling sNaN's, some return 1 others propogate
+        // the NaN. We should return either 1 or the NaN non-deterministically here.
+        // But for now, just handle them all the same.
+        // x^(±0) = 1 for any x, even a NaN
+        ("powf32" | "powf64", [_, exp]) if exp.is_zero() => Some(one),
+
+        // There are a lot of cases for fixed outputs according to the C Standard, but these are mainly INF or zero
+        // which are not affected by the applied error.
+        _ => None,
+    }
+}
+
+/// Returns `Some(output)` if `powi` (called `pown` in C) results in a fixed value specified in the C standard
+/// (specifically, C23 annex F.10.4.6) when doing `base^exp`. Otherwise, returns `None`.
+fn fixed_powi_float_value<S: Semantics>(base: IeeeFloat<S>, exp: i32) -> Option<IeeeFloat<S>> {
+    match (base.category(), exp) {
+        // x^0 = 1, if x is not a Signaling NaN
+        // FIXME(#4286): The C ecosystem is inconsistent with handling sNaN's, some return 1 others propogate
+        // the NaN. We should return either 1 or the NaN non-deterministically here.
+        // But for now, just handle them all the same.
+        (_, 0) => Some(IeeeFloat::<S>::one()),
+
+        _ => None,
+    }
+}
+
+/// Given an floating-point operation and a floating-point value, clamps the result to the output
+/// range of the given operation.
+fn clamp_float_value<S: Semantics>(intrinsic_name: &str, val: IeeeFloat<S>) -> IeeeFloat<S> {
+    match intrinsic_name {
+        // sin and cos: [-1, 1]
+        "sinf32" | "cosf32" | "sinf64" | "cosf64" =>
+            val.clamp(IeeeFloat::<S>::one().neg(), IeeeFloat::<S>::one()),
+        // exp: [0, +INF]
+        "expf32" | "exp2f32" | "expf64" | "exp2f64" =>
+            IeeeFloat::<S>::maximum(val, IeeeFloat::<S>::ZERO),
+        _ => val,
+    }
+}
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 51ec19af52a..344e12e9fa3 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -16,6 +16,7 @@
 #![feature(unqualified_local_imports)]
 #![feature(derive_coerce_pointee)]
 #![feature(arbitrary_self_types)]
+#![feature(file_lock)]
 // Configure clippy and other lints
 #![allow(
     clippy::collapsible_else_if,
@@ -113,7 +114,9 @@ pub use crate::borrow_tracker::stacked_borrows::{
     EvalContextExt as _, Item, Permission, Stack, Stacks,
 };
 pub use crate::borrow_tracker::tree_borrows::{EvalContextExt as _, Tree};
-pub use crate::borrow_tracker::{BorTag, BorrowTrackerMethod, EvalContextExt as _, RetagFields};
+pub use crate::borrow_tracker::{
+    BorTag, BorrowTrackerMethod, EvalContextExt as _, RetagFields, TreeBorrowsParams,
+};
 pub use crate::clock::{Instant, MonotonicClock};
 pub use crate::concurrency::cpu_affinity::MAX_CPUS;
 pub use crate::concurrency::data_race::{
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 15b3653d7ae..b221dd85092 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -558,9 +558,9 @@ pub struct MiriMachine<'tcx> {
 
     /// Handle of the optional shared object file for native functions.
     #[cfg(unix)]
-    pub native_lib: Option<(libloading::Library, std::path::PathBuf)>,
+    pub native_lib: Vec<(libloading::Library, std::path::PathBuf)>,
     #[cfg(not(unix))]
-    pub native_lib: Option<!>,
+    pub native_lib: Vec<!>,
 
     /// Run a garbage collector for BorTags every N basic blocks.
     pub(crate) gc_interval: u32,
@@ -720,7 +720,7 @@ impl<'tcx> MiriMachine<'tcx> {
             extern_statics: FxHashMap::default(),
             rng: RefCell::new(rng),
             #[cfg(target_os = "linux")]
-            allocator: if config.native_lib.is_some() {
+            allocator: if !config.native_lib.is_empty() {
                 Some(Rc::new(RefCell::new(crate::alloc::isolated_alloc::IsolatedAlloc::new())))
             } else { None },
             tracked_alloc_ids: config.tracked_alloc_ids.clone(),
@@ -732,7 +732,7 @@ impl<'tcx> MiriMachine<'tcx> {
             basic_block_count: 0,
             monotonic_clock: MonotonicClock::new(config.isolated_op == IsolatedOp::Allow),
             #[cfg(unix)]
-            native_lib: config.native_lib.as_ref().map(|lib_file_path| {
+            native_lib: config.native_lib.iter().map(|lib_file_path| {
                 let host_triple = rustc_session::config::host_tuple();
                 let target_triple = tcx.sess.opts.target_triple.tuple();
                 // Check if host target == the session target.
@@ -752,11 +752,11 @@ impl<'tcx> MiriMachine<'tcx> {
                     },
                     lib_file_path.clone(),
                 )
-            }),
+            }).collect(),
             #[cfg(not(unix))]
-            native_lib: config.native_lib.as_ref().map(|_| {
+            native_lib: config.native_lib.iter().map(|_| {
                 panic!("calling functions from native libraries via FFI is only supported on Unix")
-            }),
+            }).collect(),
             gc_interval: config.gc_interval,
             since_gc: 0,
             num_cpus: config.num_cpus,
diff --git a/src/tools/miri/src/math.rs b/src/tools/miri/src/math.rs
index 2ff29c7ac1a..d1355a21684 100644
--- a/src/tools/miri/src/math.rs
+++ b/src/tools/miri/src/math.rs
@@ -151,6 +151,20 @@ pub(crate) fn sqrt<S: rustc_apfloat::ieee::Semantics>(x: IeeeFloat<S>) -> IeeeFl
     }
 }
 
+/// Extend functionality of rustc_apfloat softfloats
+pub trait IeeeExt: rustc_apfloat::Float {
+    #[inline]
+    fn one() -> Self {
+        Self::from_u128(1).value
+    }
+
+    #[inline]
+    fn clamp(self, min: Self, max: Self) -> Self {
+        self.maximum(min).minimum(max)
+    }
+}
+impl<S: rustc_apfloat::ieee::Semantics> IeeeExt for IeeeFloat<S> {}
+
 #[cfg(test)]
 mod tests {
     use rustc_apfloat::ieee::{DoubleS, HalfS, IeeeFloat, QuadS, SingleS};
diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs
index 323b95d5f5f..f05c5fbbe1d 100644
--- a/src/tools/miri/src/shims/alloc.rs
+++ b/src/tools/miri/src/shims/alloc.rs
@@ -13,12 +13,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         // alignment requirement and size less than or equal to the size requested."
         // So first we need to figure out what the limits are for "fundamental alignment".
         // This is given by `alignof(max_align_t)`. The following list is taken from
-        // `library/std/src/sys/pal/common/alloc.rs` (where this is called `MIN_ALIGN`) and should
+        // `library/std/src/sys/alloc/mod.rs` (where this is called `MIN_ALIGN`) and should
         // be kept in sync.
+        let os = this.tcx.sess.target.os.as_ref();
         let max_fundamental_align = match this.tcx.sess.target.arch.as_ref() {
-            "x86" | "arm" | "mips" | "mips32r6" | "powerpc" | "powerpc64" | "wasm32" => 8,
-            "x86_64" | "aarch64" | "mips64" | "mips64r6" | "s390x" | "sparc64" | "loongarch64" =>
-                16,
+            "riscv32" if matches!(os, "espidf" | "zkvm") => 4,
+            "xtensa" if matches!(os, "espidf") => 4,
+            "x86" | "arm" | "m68k" | "csky" | "loongarch32" | "mips" | "mips32r6" | "powerpc"
+            | "powerpc64" | "sparc" | "wasm32" | "hexagon" | "riscv32" | "xtensa" => 8,
+            "x86_64" | "aarch64" | "arm64ec" | "loongarch64" | "mips64" | "mips64r6" | "s390x"
+            | "sparc64" | "riscv64" | "wasm64" => 16,
             arch => bug!("unsupported target architecture for malloc: `{}`", arch),
         };
         // The C standard only requires sufficient alignment for any *type* with size less than or
diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs
index ab11553df63..feb83ca8829 100644
--- a/src/tools/miri/src/shims/backtrace.rs
+++ b/src/tools/miri/src/shims/backtrace.rs
@@ -1,4 +1,4 @@
-use rustc_abi::{CanonAbi, Size};
+use rustc_abi::{CanonAbi, FieldIdx, Size};
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_span::{BytePos, Loc, Symbol, hygiene};
@@ -159,23 +159,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             1 => {
                 this.write_scalar(
                     Scalar::from_target_usize(name.len().to_u64(), this),
-                    &this.project_field(dest, 0)?,
+                    &this.project_field(dest, FieldIdx::from_u32(0))?,
                 )?;
                 this.write_scalar(
                     Scalar::from_target_usize(filename.len().to_u64(), this),
-                    &this.project_field(dest, 1)?,
+                    &this.project_field(dest, FieldIdx::from_u32(1))?,
                 )?;
             }
             _ => throw_unsup_format!("unknown `miri_resolve_frame` flags {}", flags),
         }
 
-        this.write_scalar(Scalar::from_u32(lineno), &this.project_field(dest, 2)?)?;
-        this.write_scalar(Scalar::from_u32(colno), &this.project_field(dest, 3)?)?;
+        this.write_scalar(
+            Scalar::from_u32(lineno),
+            &this.project_field(dest, FieldIdx::from_u32(2))?,
+        )?;
+        this.write_scalar(
+            Scalar::from_u32(colno),
+            &this.project_field(dest, FieldIdx::from_u32(3))?,
+        )?;
 
         // Support a 4-field struct for now - this is deprecated
         // and slated for removal.
         if num_fields == 5 {
-            this.write_pointer(fn_ptr, &this.project_field(dest, 4)?)?;
+            this.write_pointer(fn_ptr, &this.project_field(dest, FieldIdx::from_u32(4))?)?;
         }
 
         interp_ok(())
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index ae04ca018ab..39b930fdeb9 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -238,7 +238,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         // First deal with any external C functions in linked .so file.
         #[cfg(unix)]
-        if this.machine.native_lib.as_ref().is_some() {
+        if !this.machine.native_lib.is_empty() {
             use crate::shims::native_lib::EvalContextExt as _;
             // An Ok(false) here means that the function being called was not exported
             // by the specified `.so` file; we should continue and check if it corresponds to
diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs
index 1e6c93333c1..acf258f4eed 100644
--- a/src/tools/miri/src/shims/native_lib.rs
+++ b/src/tools/miri/src/shims/native_lib.rs
@@ -87,31 +87,35 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
     }
 
     /// Get the pointer to the function of the specified name in the shared object file,
-    /// if it exists. The function must be in the shared object file specified: we do *not*
-    /// return pointers to functions in dependencies of the library.  
+    /// if it exists. The function must be in one of the shared object files specified:
+    /// we do *not* return pointers to functions in dependencies of libraries.
     fn get_func_ptr_explicitly_from_lib(&mut self, link_name: Symbol) -> Option<CodePtr> {
         let this = self.eval_context_mut();
-        // Try getting the function from the shared library.
-        let (lib, lib_path) = this.machine.native_lib.as_ref().unwrap();
-        let func: libloading::Symbol<'_, unsafe extern "C" fn()> =
-            unsafe { lib.get(link_name.as_str().as_bytes()).ok()? };
-        #[expect(clippy::as_conversions)] // fn-ptr to raw-ptr cast needs `as`.
-        let fn_ptr = *func.deref() as *mut std::ffi::c_void;
+        // Try getting the function from one of the shared libraries.
+        for (lib, lib_path) in &this.machine.native_lib {
+            let Ok(func): Result<libloading::Symbol<'_, unsafe extern "C" fn()>, _> =
+                (unsafe { lib.get(link_name.as_str().as_bytes()) })
+            else {
+                continue;
+            };
+            #[expect(clippy::as_conversions)] // fn-ptr to raw-ptr cast needs `as`.
+            let fn_ptr = *func.deref() as *mut std::ffi::c_void;
 
-        // FIXME: this is a hack!
-        // The `libloading` crate will automatically load system libraries like `libc`.
-        // On linux `libloading` is based on `dlsym`: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#202
-        // and `dlsym`(https://linux.die.net/man/3/dlsym) looks through the dependency tree of the
-        // library if it can't find the symbol in the library itself.
-        // So, in order to check if the function was actually found in the specified
-        // `machine.external_so_lib` we need to check its `dli_fname` and compare it to
-        // the specified SO file path.
-        // This code is a reimplementation of the mechanism for getting `dli_fname` in `libloading`,
-        // from: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#411
-        // using the `libc` crate where this interface is public.
-        let mut info = std::mem::MaybeUninit::<libc::Dl_info>::zeroed();
-        unsafe {
-            if libc::dladdr(fn_ptr, info.as_mut_ptr()) != 0 {
+            // FIXME: this is a hack!
+            // The `libloading` crate will automatically load system libraries like `libc`.
+            // On linux `libloading` is based on `dlsym`: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#202
+            // and `dlsym`(https://linux.die.net/man/3/dlsym) looks through the dependency tree of the
+            // library if it can't find the symbol in the library itself.
+            // So, in order to check if the function was actually found in the specified
+            // `machine.external_so_lib` we need to check its `dli_fname` and compare it to
+            // the specified SO file path.
+            // This code is a reimplementation of the mechanism for getting `dli_fname` in `libloading`,
+            // from: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#411
+            // using the `libc` crate where this interface is public.
+            let mut info = std::mem::MaybeUninit::<libc::Dl_info>::zeroed();
+            unsafe {
+                let res = libc::dladdr(fn_ptr, info.as_mut_ptr());
+                assert!(res != 0, "failed to load info about function we already loaded");
                 let info = info.assume_init();
                 #[cfg(target_os = "cygwin")]
                 let fname_ptr = info.dli_fname.as_ptr();
@@ -121,13 +125,15 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 if std::ffi::CStr::from_ptr(fname_ptr).to_str().unwrap()
                     != lib_path.to_str().unwrap()
                 {
-                    return None;
+                    // The function is not actually in this .so, check the next one.
+                    continue;
                 }
             }
-        }
 
-        // Return a pointer to the function.
-        Some(CodePtr(fn_ptr))
+            // Return a pointer to the function.
+            return Some(CodePtr(fn_ptr));
+        }
+        None
     }
 }
 
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index 549d859a6e1..a6bce830149 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -247,7 +247,7 @@ 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 fn_item = this.tcx.require_lang_item(msg.panic_function(), this.tcx.span);
                 let instance = ty::Instance::mono(this.tcx.tcx, fn_item);
                 this.call_function(
                     instance,
diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs
index aebb5757aec..62ac7ee3806 100644
--- a/src/tools/miri/src/shims/unix/env.rs
+++ b/src/tools/miri/src/shims/unix/env.rs
@@ -2,8 +2,9 @@ use std::ffi::{OsStr, OsString};
 use std::io::ErrorKind;
 use std::{env, mem};
 
-use rustc_abi::Size;
+use rustc_abi::{FieldIdx, Size};
 use rustc_data_structures::fx::FxHashMap;
+use rustc_index::IndexVec;
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf;
 
@@ -118,7 +119,7 @@ fn alloc_env_var<'tcx>(
 /// Allocates an `environ` block with the given list of pointers.
 fn alloc_environ_block<'tcx>(
     ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>,
-    mut vars: Vec<Pointer>,
+    mut vars: IndexVec<FieldIdx, Pointer>,
 ) -> InterpResult<'tcx, Pointer> {
     // Add trailing null.
     vars.push(Pointer::null());
@@ -129,7 +130,7 @@ fn alloc_environ_block<'tcx>(
         u64::try_from(vars.len()).unwrap(),
     ))?;
     let vars_place = ecx.allocate(vars_layout, MiriMemoryKind::Runtime.into())?;
-    for (idx, var) in vars.into_iter().enumerate() {
+    for (idx, var) in vars.into_iter_enumerated() {
         let place = ecx.project_field(&vars_place, idx)?;
         ecx.write_pointer(var, &place)?;
     }
diff --git a/src/tools/miri/src/shims/unix/freebsd/sync.rs b/src/tools/miri/src/shims/unix/freebsd/sync.rs
index 54650f35b2c..f4e7d9e58f9 100644
--- a/src/tools/miri/src/shims/unix/freebsd/sync.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/sync.rs
@@ -2,6 +2,8 @@
 
 use core::time::Duration;
 
+use rustc_abi::FieldIdx;
+
 use crate::concurrency::sync::FutexRef;
 use crate::*;
 
@@ -214,18 +216,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         // Only flag allowed is UMTX_ABSTIME.
         let abs_time = this.eval_libc_u32("UMTX_ABSTIME");
 
-        let timespec_place = this.project_field(ut, 0)?;
+        let timespec_place = this.project_field(ut, FieldIdx::from_u32(0))?;
         // Inner `timespec` must still be valid.
         let duration = match this.read_timespec(&timespec_place)? {
             Some(dur) => dur,
             None => return interp_ok(None),
         };
 
-        let flags_place = this.project_field(ut, 1)?;
+        let flags_place = this.project_field(ut, FieldIdx::from_u32(1))?;
         let flags = this.read_scalar(&flags_place)?.to_u32()?;
         let abs_time_flag = flags == abs_time;
 
-        let clock_id_place = this.project_field(ut, 2)?;
+        let clock_id_place = this.project_field(ut, FieldIdx::from_u32(2))?;
         let clock_id = this.read_scalar(&clock_id_place)?.to_i32()?;
         let timeout_clock = this.translate_umtx_time_clock_id(clock_id)?;
 
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index 31cb269059c..0f7d453b296 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -2,7 +2,8 @@
 
 use std::borrow::Cow;
 use std::fs::{
-    DirBuilder, File, FileType, OpenOptions, ReadDir, read_dir, remove_dir, remove_file, rename,
+    DirBuilder, File, FileType, OpenOptions, ReadDir, TryLockError, read_dir, remove_dir,
+    remove_file, rename,
 };
 use std::io::{self, ErrorKind, Read, Seek, SeekFrom, Write};
 use std::path::{Path, PathBuf};
@@ -89,103 +90,27 @@ impl UnixFileDescription for FileHandle {
         communicate_allowed: bool,
         op: FlockOp,
     ) -> InterpResult<'tcx, io::Result<()>> {
-        // cfg(bootstrap)
-        macro_rules! cfg_select_dispatch {
-            ($($tokens:tt)*) => {
-                #[cfg(bootstrap)]
-                cfg_match! { $($tokens)* }
-
-                #[cfg(not(bootstrap))]
-                cfg_select! { $($tokens)* }
-            };
-        }
-
         assert!(communicate_allowed, "isolation should have prevented even opening a file");
-        cfg_select_dispatch! {
-            all(target_family = "unix", not(target_os = "solaris")) => {
-                use std::os::fd::AsRawFd;
-
-                use FlockOp::*;
-                // We always use non-blocking call to prevent interpreter from being blocked
-                let (host_op, lock_nb) = match op {
-                    SharedLock { nonblocking } => (libc::LOCK_SH | libc::LOCK_NB, nonblocking),
-                    ExclusiveLock { nonblocking } => (libc::LOCK_EX | libc::LOCK_NB, nonblocking),
-                    Unlock => (libc::LOCK_UN, false),
-                };
 
-                let fd = self.file.as_raw_fd();
-                let ret = unsafe { libc::flock(fd, host_op) };
-                let res = match ret {
-                    0 => Ok(()),
-                    -1 => {
-                        let err = io::Error::last_os_error();
-                        if !lock_nb && err.kind() == io::ErrorKind::WouldBlock {
-                            throw_unsup_format!("blocking `flock` is not currently supported");
-                        }
-                        Err(err)
-                    }
-                    ret => panic!("Unexpected return value from flock: {ret}"),
-                };
-                interp_ok(res)
+        use FlockOp::*;
+        // We must not block the interpreter loop, so we always `try_lock`.
+        let (res, nonblocking) = match op {
+            SharedLock { nonblocking } => (self.file.try_lock_shared(), nonblocking),
+            ExclusiveLock { nonblocking } => (self.file.try_lock(), nonblocking),
+            Unlock => {
+                return interp_ok(self.file.unlock());
             }
-            target_family = "windows" => {
-                use std::os::windows::io::AsRawHandle;
-
-                use windows_sys::Win32::Foundation::{
-                    ERROR_IO_PENDING, ERROR_LOCK_VIOLATION, FALSE, TRUE,
-                };
-                use windows_sys::Win32::Storage::FileSystem::{
-                    LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, LockFileEx, UnlockFile,
-                };
-
-                let fh = self.file.as_raw_handle();
-
-                use FlockOp::*;
-                let (ret, lock_nb) = match op {
-                    SharedLock { nonblocking } | ExclusiveLock { nonblocking } => {
-                        // We always use non-blocking call to prevent interpreter from being blocked
-                        let mut flags = LOCKFILE_FAIL_IMMEDIATELY;
-                        if matches!(op, ExclusiveLock { .. }) {
-                            flags |= LOCKFILE_EXCLUSIVE_LOCK;
-                        }
-                        let ret = unsafe { LockFileEx(fh, flags, 0, !0, !0, &mut std::mem::zeroed()) };
-                        (ret, nonblocking)
-                    }
-                    Unlock => {
-                        let ret = unsafe { UnlockFile(fh, 0, 0, !0, !0) };
-                        (ret, false)
-                    }
-                };
+        };
 
-                let res = match ret {
-                    TRUE => Ok(()),
-                    FALSE => {
-                        let mut err = io::Error::last_os_error();
-                        // This only runs on Windows hosts so we can use `raw_os_error`.
-                        // We have to be careful not to forward that error code to target code.
-                        let code: u32 = err.raw_os_error().unwrap().try_into().unwrap();
-                        if matches!(code, ERROR_IO_PENDING | ERROR_LOCK_VIOLATION) {
-                            if lock_nb {
-                                // The io error mapping does not know about these error codes,
-                                // so we translate it to `WouldBlock` manually.
-                                let desc = format!("LockFileEx wouldblock error: {err}");
-                                err = io::Error::new(io::ErrorKind::WouldBlock, desc);
-                            } else {
-                                throw_unsup_format!("blocking `flock` is not currently supported");
-                            }
-                        }
-                        Err(err)
-                    }
-                    _ => panic!("Unexpected return value: {ret}"),
-                };
-                interp_ok(res)
-            }
-            _ => {
-                let _ = op;
-                throw_unsup_format!(
-                    "flock is supported only on UNIX (except Solaris) and Windows hosts"
-                );
-            }
+        match res {
+            Ok(()) => interp_ok(Ok(())),
+            Err(TryLockError::Error(err)) => interp_ok(Err(err)),
+            Err(TryLockError::WouldBlock) =>
+                if nonblocking {
+                    interp_ok(Err(ErrorKind::WouldBlock.into()))
+                } else {
+                    throw_unsup_format!("blocking `flock` is not currently supported");
+                },
         }
     }
 }
diff --git a/src/tools/miri/src/shims/unix/linux_like/epoll.rs b/src/tools/miri/src/shims/unix/linux_like/epoll.rs
index b489595b4cd..d460abc783d 100644
--- a/src/tools/miri/src/shims/unix/linux_like/epoll.rs
+++ b/src/tools/miri/src/shims/unix/linux_like/epoll.rs
@@ -4,6 +4,8 @@ use std::io;
 use std::rc::{Rc, Weak};
 use std::time::Duration;
 
+use rustc_abi::FieldIdx;
+
 use crate::concurrency::VClock;
 use crate::shims::files::{
     DynFileDescriptionRef, FdId, FileDescription, FileDescriptionRef, WeakFileDescriptionRef,
@@ -284,8 +286,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         if op == epoll_ctl_add || op == epoll_ctl_mod {
             // Read event bitmask and data from epoll_event passed by caller.
-            let mut events = this.read_scalar(&this.project_field(&event, 0)?)?.to_u32()?;
-            let data = this.read_scalar(&this.project_field(&event, 1)?)?.to_u64()?;
+            let mut events =
+                this.read_scalar(&this.project_field(&event, FieldIdx::ZERO)?)?.to_u32()?;
+            let data = this.read_scalar(&this.project_field(&event, FieldIdx::ONE)?)?.to_u64()?;
 
             // Unset the flag we support to discover if any unsupported flags are used.
             let mut flags = events;
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index 7dee8ddd23c..1e82f521249 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -1,4 +1,4 @@
-use rustc_abi::{CanonAbi, Size};
+use rustc_abi::{CanonAbi, FieldIdx, Size};
 use rustc_apfloat::Float;
 use rustc_apfloat::ieee::Single;
 use rustc_middle::ty::Ty;
@@ -54,8 +54,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 };
 
                 let (sum, cb_out) = carrying_add(this, cb_in, a, b, op)?;
-                this.write_scalar(cb_out, &this.project_field(dest, 0)?)?;
-                this.write_immediate(*sum, &this.project_field(dest, 1)?)?;
+                this.write_scalar(cb_out, &this.project_field(dest, FieldIdx::ZERO)?)?;
+                this.write_immediate(*sum, &this.project_field(dest, FieldIdx::ONE)?)?;
             }
 
             // Used to implement the `_addcarryx_u{32, 64}` functions. They are semantically identical with the `_addcarry_u{32, 64}` functions,
diff --git a/src/tools/miri/tests/fail/async-shared-mutable.rs b/src/tools/miri/tests/fail/async-shared-mutable.rs
new file mode 100644
index 00000000000..62780e7a11c
--- /dev/null
+++ b/src/tools/miri/tests/fail/async-shared-mutable.rs
@@ -0,0 +1,25 @@
+//! FIXME: This test should pass! However, `async fn` does not yet use `UnsafePinned`.
+//! This is a regression test for <https://github.com/rust-lang/rust/issues/137750>:
+//! `UnsafePinned` must include the effects of `UnsafeCell`.
+//@revisions: stack tree
+//@[tree]compile-flags: -Zmiri-tree-borrows
+//@normalize-stderr-test: "\[0x[a-fx\d.]+\]" -> "[OFFSET]"
+
+use core::future::Future;
+use core::pin::{Pin, pin};
+use core::task::{Context, Poll, Waker};
+
+fn main() {
+    let mut f = pin!(async move {
+        let x = &mut 0u8;
+        core::future::poll_fn(move |_| {
+            *x = 1; //~ERROR: write access
+            Poll::<()>::Pending
+        })
+        .await
+    });
+    let mut cx = Context::from_waker(&Waker::noop());
+    assert_eq!(f.as_mut().poll(&mut cx), Poll::Pending);
+    let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`.
+    assert_eq!(f.as_mut().poll(&mut cx), Poll::Pending);
+}
diff --git a/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr b/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr
new file mode 100644
index 00000000000..8f53a55cc3e
--- /dev/null
+++ b/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr
@@ -0,0 +1,43 @@
+error: Undefined Behavior: attempting a write access using <TAG> at ALLOC[OFFSET], but that tag does not exist in the borrow stack for this location
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL |             *x = 1;
+   |             ^^^^^^
+   |             |
+   |             attempting a write access using <TAG> at ALLOC[OFFSET], but that tag does not exist in the borrow stack for this location
+   |             this error occurs as part of an access at ALLOC[OFFSET]
+   |
+   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
+   = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
+help: <TAG> was created by a Unique retag at offsets [OFFSET]
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL | /         core::future::poll_fn(move |_| {
+LL | |             *x = 1;
+LL | |             Poll::<()>::Pending
+LL | |         })
+LL | |         .await
+   | |______________^
+help: <TAG> was later invalidated at offsets [OFFSET] by a SharedReadOnly retag
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL |     let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`.
+   |                      ^^^^^^^^^^
+   = note: BACKTRACE (of the first span):
+   = note: inside closure at tests/fail/async-shared-mutable.rs:LL:CC
+   = note: inside `<std::future::PollFn<{closure@tests/fail/async-shared-mutable.rs:LL:CC}> as std::future::Future>::poll` at RUSTLIB/core/src/future/poll_fn.rs:LL:CC
+note: inside closure
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL |         .await
+   |          ^^^^^
+note: inside `main`
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL |     assert_eq!(f.as_mut().poll(&mut cx), Poll::Pending);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^
+
+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/async-shared-mutable.tree.stderr b/src/tools/miri/tests/fail/async-shared-mutable.tree.stderr
new file mode 100644
index 00000000000..d1e66a0d043
--- /dev/null
+++ b/src/tools/miri/tests/fail/async-shared-mutable.tree.stderr
@@ -0,0 +1,47 @@
+error: Undefined Behavior: write access through <TAG> at ALLOC[OFFSET] is forbidden
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL |             *x = 1;
+   |             ^^^^^^ write access through <TAG> at ALLOC[OFFSET] is forbidden
+   |
+   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
+   = help: the accessed tag <TAG> has state Frozen which forbids this child write access
+help: the accessed tag <TAG> was created here, in the initial state Reserved
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL | /         core::future::poll_fn(move |_| {
+LL | |             *x = 1;
+LL | |             Poll::<()>::Pending
+LL | |         })
+LL | |         .await
+   | |______________^
+help: the accessed tag <TAG> later transitioned to Active due to a child write access at offsets [OFFSET]
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL |             *x = 1;
+   |             ^^^^^^
+   = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference
+help: the accessed tag <TAG> later transitioned to Frozen due to a reborrow (acting as a foreign read access) at offsets [OFFSET]
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL |     let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`.
+   |                      ^^^^^^^^^^
+   = help: this transition corresponds to a loss of write permissions
+   = note: BACKTRACE (of the first span):
+   = note: inside closure at tests/fail/async-shared-mutable.rs:LL:CC
+   = note: inside `<std::future::PollFn<{closure@tests/fail/async-shared-mutable.rs:LL:CC}> as std::future::Future>::poll` at RUSTLIB/core/src/future/poll_fn.rs:LL:CC
+note: inside closure
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL |         .await
+   |          ^^^^^
+note: inside `main`
+  --> tests/fail/async-shared-mutable.rs:LL:CC
+   |
+LL |     assert_eq!(f.as_mut().poll(&mut cx), Poll::Pending);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^
+
+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/const-ub-checks.stderr b/src/tools/miri/tests/fail/const-ub-checks.stderr
index 9bac524bd45..df2d5653d2d 100644
--- a/src/tools/miri/tests/fail/const-ub-checks.stderr
+++ b/src/tools/miri/tests/fail/const-ub-checks.stderr
@@ -2,7 +2,7 @@ error[E0080]: accessing memory based on pointer with alignment ALIGN, but alignm
   --> tests/fail/const-ub-checks.rs:LL:CC
    |
 LL |     ptr.read();
-   |     ^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^ evaluation of `UNALIGNED_READ` failed here
 
 note: erroneous constant encountered
   --> tests/fail/const-ub-checks.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/erroneous_const2.stderr b/src/tools/miri/tests/fail/erroneous_const2.stderr
index 9d3f1b13bee..08d2cc124f1 100644
--- a/src/tools/miri/tests/fail/erroneous_const2.stderr
+++ b/src/tools/miri/tests/fail/erroneous_const2.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `5_u32 - 6_u32`, which would overflow
   --> tests/fail/erroneous_const2.rs:LL:CC
    |
 LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
-   |                   ^^^^^ evaluation of constant value failed here
+   |                   ^^^^^ evaluation of `FOO` failed here
 
 note: erroneous constant encountered
   --> tests/fail/erroneous_const2.rs:LL:CC
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs
index 129b18d8e59..0ff48c389e8 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs
@@ -88,16 +88,17 @@ fn test_dup() {
     let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>();
     unsafe {
         let fd = libc::open(name_ptr, libc::O_RDONLY);
+        let new_fd = libc::dup(fd);
+        let new_fd2 = libc::dup2(fd, 8);
+
         let mut first_buf = [0u8; 4];
         libc::read(fd, first_buf.as_mut_ptr() as *mut libc::c_void, 4);
         assert_eq!(&first_buf, b"dup ");
 
-        let new_fd = libc::dup(fd);
         let mut second_buf = [0u8; 4];
         libc::read(new_fd, second_buf.as_mut_ptr() as *mut libc::c_void, 4);
         assert_eq!(&second_buf, b"and ");
 
-        let new_fd2 = libc::dup2(fd, 8);
         let mut third_buf = [0u8; 4];
         libc::read(new_fd2, third_buf.as_mut_ptr() as *mut libc::c_void, 4);
         assert_eq!(&third_buf, b"dup2");
diff --git a/src/tools/miri/tests/pass/both_borrows/smallvec.rs b/src/tools/miri/tests/pass/both_borrows/smallvec.rs
new file mode 100644
index 00000000000..f48815e37be
--- /dev/null
+++ b/src/tools/miri/tests/pass/both_borrows/smallvec.rs
@@ -0,0 +1,99 @@
+//! This test represents a core part of `SmallVec`'s `extend_impl`.
+//! What makes it interesting as a test is that it relies on Stacked Borrow's "quirk"
+//! in a fundamental, hard-to-fix-without-full-trees way.
+
+//@revisions: stack tree
+//@[tree]compile-flags: -Zmiri-tree-borrows
+
+use std::marker::PhantomData;
+use std::mem::{ManuallyDrop, MaybeUninit};
+use std::ptr::NonNull;
+
+#[repr(C)]
+pub union RawSmallVec<T, const N: usize> {
+    inline: ManuallyDrop<MaybeUninit<[T; N]>>,
+    heap: (NonNull<T>, usize),
+}
+
+impl<T, const N: usize> RawSmallVec<T, N> {
+    const fn new() -> Self {
+        Self::new_inline(MaybeUninit::uninit())
+    }
+
+    const fn new_inline(inline: MaybeUninit<[T; N]>) -> Self {
+        Self { inline: ManuallyDrop::new(inline) }
+    }
+
+    const fn as_mut_ptr_inline(&mut self) -> *mut T {
+        (unsafe { &raw mut self.inline }) as *mut T
+    }
+
+    const unsafe fn as_mut_ptr_heap(&mut self) -> *mut T {
+        self.heap.0.as_ptr()
+    }
+}
+
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+struct TaggedLen(usize);
+
+impl TaggedLen {
+    pub const fn new(len: usize, on_heap: bool, is_zst: bool) -> Self {
+        if is_zst {
+            debug_assert!(!on_heap);
+            TaggedLen(len)
+        } else {
+            debug_assert!(len < isize::MAX as usize);
+            TaggedLen((len << 1) | on_heap as usize)
+        }
+    }
+
+    pub const fn on_heap(self, is_zst: bool) -> bool {
+        if is_zst { false } else { (self.0 & 1_usize) == 1 }
+    }
+
+    pub const fn value(self, is_zst: bool) -> usize {
+        if is_zst { self.0 } else { self.0 >> 1 }
+    }
+}
+
+#[repr(C)]
+pub struct SmallVec<T, const N: usize> {
+    len: TaggedLen,
+    raw: RawSmallVec<T, N>,
+    _marker: PhantomData<T>,
+}
+
+impl<T, const N: usize> SmallVec<T, N> {
+    pub const fn new() -> SmallVec<T, N> {
+        Self {
+            len: TaggedLen::new(0, false, Self::is_zst()),
+            raw: RawSmallVec::new(),
+            _marker: PhantomData,
+        }
+    }
+
+    const fn is_zst() -> bool {
+        size_of::<T>() == 0
+    }
+
+    pub const fn as_mut_ptr(&mut self) -> *mut T {
+        if self.len.on_heap(Self::is_zst()) {
+            // SAFETY: see above
+            unsafe { self.raw.as_mut_ptr_heap() }
+        } else {
+            self.raw.as_mut_ptr_inline()
+        }
+    }
+
+    pub const fn len(&self) -> usize {
+        self.len.value(Self::is_zst())
+    }
+}
+
+fn main() {
+    let mut v = SmallVec::<i32, 4>::new();
+    let ptr = v.as_mut_ptr();
+    let _len = v.len(); // this call incurs a reborrow which just barely does not invalidate `ptr`
+    unsafe { ptr.write(0) };
+}
diff --git a/src/tools/miri/tests/pass/both_borrows/unsafe_pinned.rs b/src/tools/miri/tests/pass/both_borrows/unsafe_pinned.rs
new file mode 100644
index 00000000000..0c75a07bfa2
--- /dev/null
+++ b/src/tools/miri/tests/pass/both_borrows/unsafe_pinned.rs
@@ -0,0 +1,16 @@
+//@revisions: stack tree
+//@[tree]compile-flags: -Zmiri-tree-borrows
+#![feature(unsafe_pinned)]
+
+use std::pin::UnsafePinned;
+
+fn mutate(x: &UnsafePinned<i32>) {
+    let ptr = x as *const _ as *mut i32;
+    unsafe { ptr.write(42) };
+}
+
+fn main() {
+    let x = UnsafePinned::new(0);
+    mutate(&x);
+    assert_eq!(x.into_inner(), 42);
+}
diff --git a/src/tools/miri/tests/pass/fat_ptr.rs b/src/tools/miri/tests/pass/fat_ptr.rs
index c5603d2cf80..13608b8f898 100644
--- a/src/tools/miri/tests/pass/fat_ptr.rs
+++ b/src/tools/miri/tests/pass/fat_ptr.rs
@@ -19,11 +19,11 @@ fn fat_ptr_via_local(a: &[u8]) -> &[u8] {
     x
 }
 
-fn fat_ptr_from_struct(s: FatPtrContainer) -> &[u8] {
+fn fat_ptr_from_struct(s: FatPtrContainer<'_>) -> &[u8] {
     s.ptr
 }
 
-fn fat_ptr_to_struct(a: &[u8]) -> FatPtrContainer {
+fn fat_ptr_to_struct(a: &[u8]) -> FatPtrContainer<'_> {
     FatPtrContainer { ptr: a }
 }
 
diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs
index 98a88cfd62d..383579198bb 100644
--- a/src/tools/miri/tests/pass/float.rs
+++ b/src/tools/miri/tests/pass/float.rs
@@ -45,6 +45,30 @@ macro_rules! assert_approx_eq {
     };
 }
 
+/// From IEEE 754 a Signaling NaN for single precision has the following representation:
+/// ```
+/// s | 1111 1111 | 0x..x
+/// ````
+/// Were at least one `x` is a 1.
+///
+/// This sNaN has the following representation and is used for testing purposes.:
+/// ```
+/// 0 | 1111111 | 01..0
+/// ```
+const SNAN_F32: f32 = f32::from_bits(0x7fa00000);
+
+/// From IEEE 754 a Signaling NaN for double precision has the following representation:
+/// ```
+/// s | 1111 1111 111 | 0x..x
+/// ````
+/// Were at least one `x` is a 1.
+///
+/// This sNaN has the following representation and is used for testing purposes.:
+/// ```
+/// 0 | 1111 1111 111 | 01..0
+/// ```
+const SNAN_F64: f64 = f64::from_bits(0x7ff4000000000000);
+
 fn main() {
     basic();
     casts();
@@ -1008,17 +1032,84 @@ pub fn libm() {
     assert_approx_eq!(25f32.powf(-2f32), 0.0016f32);
     assert_approx_eq!(400f64.powf(0.5f64), 20f64);
 
+    // Some inputs to powf and powi result in fixed outputs
+    // and thus must be exactly equal to that value.
+    // C standard says:
+    // 1^y = 1 for any y, even a NaN.
+    assert_eq!(1f32.powf(10.0), 1.0);
+    assert_eq!(1f64.powf(100.0), 1.0);
+    assert_eq!(1f32.powf(f32::INFINITY), 1.0);
+    assert_eq!(1f64.powf(f64::INFINITY), 1.0);
+    assert_eq!(1f32.powf(f32::NAN), 1.0);
+    assert_eq!(1f64.powf(f64::NAN), 1.0);
+
+    // f*::NAN is a quiet NAN and should return 1 as well.
+    assert_eq!(f32::NAN.powf(0.0), 1.0);
+    assert_eq!(f64::NAN.powf(0.0), 1.0);
+
+    assert_eq!(42f32.powf(0.0), 1.0);
+    assert_eq!(42f64.powf(0.0), 1.0);
+    assert_eq!(f32::INFINITY.powf(0.0), 1.0);
+    assert_eq!(f64::INFINITY.powf(0.0), 1.0);
+
+    // f*::NAN is a quiet NAN and should return 1 as well.
+    assert_eq!(f32::NAN.powi(0), 1.0);
+    assert_eq!(f64::NAN.powi(0), 1.0);
+
+    assert_eq!(10.0f32.powi(0), 1.0);
+    assert_eq!(10.0f64.powi(0), 1.0);
+    assert_eq!(f32::INFINITY.powi(0), 1.0);
+    assert_eq!(f64::INFINITY.powi(0), 1.0);
+
+    assert_eq!((-1f32).powf(f32::INFINITY), 1.0);
+    assert_eq!((-1f64).powf(f64::INFINITY), 1.0);
+    assert_eq!((-1f32).powf(f32::NEG_INFINITY), 1.0);
+    assert_eq!((-1f64).powf(f64::NEG_INFINITY), 1.0);
+
+    // For pow (powf in rust) the C standard says:
+    // x^0 = 1 for all x even a sNaN
+    // FIXME(#4286): this does not match the behavior of all implementations.
+    assert_eq!(SNAN_F32.powf(0.0), 1.0);
+    assert_eq!(SNAN_F64.powf(0.0), 1.0);
+
+    // For pown (powi in rust) the C standard says:
+    // x^0 = 1 for all x even a sNaN
+    // FIXME(#4286): this does not match the behavior of all implementations.
+    assert_eq!(SNAN_F32.powi(0), 1.0);
+    assert_eq!(SNAN_F64.powi(0), 1.0);
+
+    assert_eq!(0f32.powi(10), 0.0);
+    assert_eq!(0f64.powi(100), 0.0);
+    assert_eq!(0f32.powi(9), 0.0);
+    assert_eq!(0f64.powi(99), 0.0);
+
+    assert_biteq((-0f32).powf(10.0), 0.0, "-0^x = +0 where x is positive");
+    assert_biteq((-0f64).powf(100.0), 0.0, "-0^x = +0 where x is positive");
+    assert_biteq((-0f32).powf(9.0), -0.0, "-0^x = -0 where x is negative");
+    assert_biteq((-0f64).powf(99.0), -0.0, "-0^x = -0 where x is negative");
+
+    assert_biteq((-0f32).powi(10), 0.0, "-0^x = +0 where x is positive");
+    assert_biteq((-0f64).powi(100), 0.0, "-0^x = +0 where x is positive");
+    assert_biteq((-0f32).powi(9), -0.0, "-0^x = -0 where x is negative");
+    assert_biteq((-0f64).powi(99), -0.0, "-0^x = -0 where x is negative");
+
     assert_approx_eq!(1f32.exp(), f32::consts::E);
     assert_approx_eq!(1f64.exp(), f64::consts::E);
+    assert_eq!(0f32.exp(), 1.0);
+    assert_eq!(0f64.exp(), 1.0);
 
     assert_approx_eq!(1f32.exp_m1(), f32::consts::E - 1.0);
     assert_approx_eq!(1f64.exp_m1(), f64::consts::E - 1.0);
 
     assert_approx_eq!(10f32.exp2(), 1024f32);
     assert_approx_eq!(50f64.exp2(), 1125899906842624f64);
+    assert_eq!(0f32.exp2(), 1.0);
+    assert_eq!(0f64.exp2(), 1.0);
 
     assert_approx_eq!(f32::consts::E.ln(), 1f32);
-    assert_approx_eq!(1f64.ln(), 0f64);
+    assert_approx_eq!(f64::consts::E.ln(), 1f64);
+    assert_eq!(1f32.ln(), 0.0);
+    assert_eq!(1f64.ln(), 0.0);
 
     assert_approx_eq!(0f32.ln_1p(), 0f32);
     assert_approx_eq!(0f64.ln_1p(), 0f64);
@@ -1047,7 +1138,8 @@ pub fn libm() {
 
     // Trigonometric functions.
 
-    assert_approx_eq!(0f32.sin(), 0f32);
+    assert_eq!(0f32.sin(), 0f32);
+    assert_eq!(0f64.sin(), 0f64);
     assert_approx_eq!((f64::consts::PI / 2f64).sin(), 1f64);
     assert_approx_eq!(f32::consts::FRAC_PI_6.sin(), 0.5);
     assert_approx_eq!(f64::consts::FRAC_PI_6.sin(), 0.5);
@@ -1059,7 +1151,23 @@ pub fn libm() {
     assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
     assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
 
-    assert_approx_eq!(0f32.cos(), 1f32);
+    // Ensure `sin` always returns something that is a valid input for `asin`, and same for
+    // `cos` and `acos`.
+    let halve_pi_f32 = std::f32::consts::FRAC_PI_2;
+    let halve_pi_f64 = std::f64::consts::FRAC_PI_2;
+    let pi_f32 = std::f32::consts::PI;
+    let pi_f64 = std::f64::consts::PI;
+    for _ in 0..64 {
+        // sin() should be clamped to [-1, 1] so asin() can never return NaN
+        assert!(!halve_pi_f32.sin().asin().is_nan());
+        assert!(!halve_pi_f64.sin().asin().is_nan());
+        // cos() should be clamped to [-1, 1] so acos() can never return NaN
+        assert!(!pi_f32.cos().acos().is_nan());
+        assert!(!pi_f64.cos().acos().is_nan());
+    }
+
+    assert_eq!(0f32.cos(), 1f32);
+    assert_eq!(0f64.cos(), 1f64);
     assert_approx_eq!((f64::consts::PI * 2f64).cos(), 1f64);
     assert_approx_eq!(f32::consts::FRAC_PI_3.cos(), 0.5);
     assert_approx_eq!(f64::consts::FRAC_PI_3.cos(), 0.5);
@@ -1278,7 +1386,6 @@ fn test_non_determinism() {
         frem_algebraic, frem_fast, fsub_algebraic, fsub_fast,
     };
     use std::{f32, f64};
-    // TODO: Also test powi and powf when the non-determinism is implemented for them
 
     /// Ensure that the operation is non-deterministic
     #[track_caller]
@@ -1318,21 +1425,23 @@ fn test_non_determinism() {
     }
     pub fn test_operations_f32(a: f32, b: f32) {
         test_operations_f!(a, b);
-        // FIXME: temporarily disabled as it breaks std tests.
-        // ensure_nondet(|| a.log(b));
-        // ensure_nondet(|| a.exp());
-        // ensure_nondet(|| 10f32.exp2());
-        // ensure_nondet(|| f32::consts::E.ln());
+        // FIXME: some are temporarily disabled as it breaks std tests.
+        ensure_nondet(|| a.powf(b));
+        ensure_nondet(|| a.powi(2));
+        ensure_nondet(|| a.log(b));
+        ensure_nondet(|| a.exp());
+        ensure_nondet(|| 10f32.exp2());
+        ensure_nondet(|| f32::consts::E.ln());
+        ensure_nondet(|| 10f32.log10());
+        ensure_nondet(|| 8f32.log2());
         // ensure_nondet(|| 1f32.ln_1p());
-        // ensure_nondet(|| 10f32.log10());
-        // ensure_nondet(|| 8f32.log2());
         // ensure_nondet(|| 27.0f32.cbrt());
         // ensure_nondet(|| 3.0f32.hypot(4.0f32));
-        // ensure_nondet(|| 1f32.sin());
-        // ensure_nondet(|| 0f32.cos());
-        // // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version,
-        // // which means the little rounding errors Miri introduces are discard by the cast down to `f32`.
-        // // Just skip the test for them.
+        ensure_nondet(|| 1f32.sin());
+        ensure_nondet(|| 1f32.cos());
+        // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version,
+        // which means the little rounding errors Miri introduces are discarded by the cast down to
+        // `f32`. Just skip the test for them.
         // if !cfg!(all(target_os = "windows", target_env = "msvc", target_arch = "x86")) {
         //     ensure_nondet(|| 1.0f32.tan());
         //     ensure_nondet(|| 1.0f32.asin());
@@ -1353,18 +1462,20 @@ fn test_non_determinism() {
     }
     pub fn test_operations_f64(a: f64, b: f64) {
         test_operations_f!(a, b);
-        // FIXME: temporarily disabled as it breaks std tests.
-        // ensure_nondet(|| a.log(b));
-        // ensure_nondet(|| a.exp());
-        // ensure_nondet(|| 50f64.exp2());
-        // ensure_nondet(|| 3f64.ln());
+        // FIXME: some are temporarily disabled as it breaks std tests.
+        ensure_nondet(|| a.powf(b));
+        ensure_nondet(|| a.powi(2));
+        ensure_nondet(|| a.log(b));
+        ensure_nondet(|| a.exp());
+        ensure_nondet(|| 50f64.exp2());
+        ensure_nondet(|| 3f64.ln());
+        ensure_nondet(|| f64::consts::E.log10());
+        ensure_nondet(|| f64::consts::E.log2());
         // ensure_nondet(|| 1f64.ln_1p());
-        // ensure_nondet(|| f64::consts::E.log10());
-        // ensure_nondet(|| f64::consts::E.log2());
         // ensure_nondet(|| 27.0f64.cbrt());
         // ensure_nondet(|| 3.0f64.hypot(4.0f64));
-        // ensure_nondet(|| 1f64.sin());
-        // ensure_nondet(|| 0f64.cos());
+        ensure_nondet(|| 1f64.sin());
+        ensure_nondet(|| 1f64.cos());
         // ensure_nondet(|| 1.0f64.tan());
         // ensure_nondet(|| 1.0f64.asin());
         // ensure_nondet(|| 5.0f64.acos());
diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs
index 87df43ca7e5..2f30827c933 100644
--- a/src/tools/miri/tests/pass/shims/fs.rs
+++ b/src/tools/miri/tests/pass/shims/fs.rs
@@ -2,12 +2,12 @@
 
 #![feature(io_error_more)]
 #![feature(io_error_uncategorized)]
+#![feature(file_lock)]
 
 use std::collections::BTreeMap;
 use std::ffi::OsString;
 use std::fs::{
-    File, OpenOptions, canonicalize, create_dir, read_dir, remove_dir, remove_dir_all, remove_file,
-    rename,
+    self, File, OpenOptions, create_dir, read_dir, remove_dir, remove_dir_all, remove_file, rename,
 };
 use std::io::{Error, ErrorKind, IsTerminal, Read, Result, Seek, SeekFrom, Write};
 use std::path::Path;
@@ -33,6 +33,8 @@ fn main() {
         test_canonicalize();
         #[cfg(unix)]
         test_pread_pwrite();
+        #[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
+        test_flock();
     }
 }
 
@@ -240,7 +242,7 @@ fn test_canonicalize() {
     let path = dir_path.join("test_file");
     drop(File::create(&path).unwrap());
 
-    let p = canonicalize(format!("{}/./test_file", dir_path.to_string_lossy())).unwrap();
+    let p = fs::canonicalize(format!("{}/./test_file", dir_path.to_string_lossy())).unwrap();
     assert_eq!(p.to_string_lossy().find("/./"), None);
 
     remove_dir_all(&dir_path).unwrap();
@@ -351,3 +353,28 @@ fn test_pread_pwrite() {
     f.read_exact(&mut buf1).unwrap();
     assert_eq!(&buf1, b"  m");
 }
+
+// This function does seem to exist on Illumos but std does not expose it there.
+#[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
+fn test_flock() {
+    let bytes = b"Hello, World!\n";
+    let path = utils::prepare_with_content("miri_test_fs_flock.txt", bytes);
+    let file1 = OpenOptions::new().read(true).write(true).open(&path).unwrap();
+    let file2 = OpenOptions::new().read(true).write(true).open(&path).unwrap();
+
+    // Test that we can apply many shared locks
+    file1.lock_shared().unwrap();
+    file2.lock_shared().unwrap();
+    // Test that shared lock prevents exclusive lock
+    assert!(matches!(file1.try_lock().unwrap_err(), fs::TryLockError::WouldBlock));
+    // Unlock shared lock
+    file1.unlock().unwrap();
+    file2.unlock().unwrap();
+    // Take exclusive lock
+    file1.lock().unwrap();
+    // Test that shared lock prevents exclusive and shared locks
+    assert!(matches!(file2.try_lock().unwrap_err(), fs::TryLockError::WouldBlock));
+    assert!(matches!(file2.try_lock_shared().unwrap_err(), fs::TryLockError::WouldBlock));
+    // Unlock exclusive lock
+    file1.unlock().unwrap();
+}
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs
index 48633c0a7fe..8936ae8e912 100644
--- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs
+++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs
@@ -2,8 +2,6 @@
 //@only-target: x86_64 i686
 //@compile-flags: -C target-feature=+aes,+vaes,+avx512f
 
-#![feature(stdarch_x86_avx512)]
-
 use core::mem::transmute;
 #[cfg(target_arch = "x86")]
 use std::arch::x86::*;
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs
index 0ec2f679d80..65d7b57d1ce 100644
--- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs
+++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs
@@ -2,8 +2,6 @@
 //@only-target: x86_64 i686
 //@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bitalg,+avx512vpopcntdq
 
-#![feature(stdarch_x86_avx512)]
-
 #[cfg(target_arch = "x86")]
 use std::arch::x86::*;
 #[cfg(target_arch = "x86_64")]
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs
index b58d68e2ef9..48958ef5810 100644
--- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs
+++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs
@@ -6,7 +6,6 @@
 // be interpreted as integers; signedness does not make sense for them, but
 // __mXXXi happens to be defined in terms of signed integers.
 #![allow(overflowing_literals)]
-#![feature(stdarch_x86_avx512)]
 
 #[cfg(target_arch = "x86")]
 use std::arch::x86::*;
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-vpclmulqdq.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-vpclmulqdq.rs
index c7c9eb5e395..e2a045bf81f 100644
--- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-vpclmulqdq.rs
+++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-vpclmulqdq.rs
@@ -8,7 +8,6 @@
 // be interpreted as integers; signedness does not make sense for them, but
 // __mXXXi happens to be defined in terms of signed integers.
 #![allow(overflowing_literals)]
-#![feature(stdarch_x86_avx512)]
 
 #[cfg(target_arch = "x86")]
 use std::arch::x86::*;
diff --git a/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.rs b/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.rs
new file mode 100644
index 00000000000..fd68685a2f4
--- /dev/null
+++ b/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.rs
@@ -0,0 +1,34 @@
+//! The same as `tests/fail/tree-borrows/cell-inside-struct` but with
+//! precise tracking of interior mutability disabled.
+//@compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-no-precise-interior-mut
+#[path = "../../utils/mod.rs"]
+#[macro_use]
+mod utils;
+
+use std::cell::Cell;
+
+struct Foo {
+    field1: u32,
+    field2: Cell<u32>,
+}
+
+pub fn main() {
+    let root = Foo { field1: 42, field2: Cell::new(88) };
+    unsafe {
+        let a = &root;
+
+        name!(a as *const Foo, "a");
+
+        let a: *const Foo = a as *const Foo;
+        let a: *mut Foo = a as *mut Foo;
+
+        let alloc_id = alloc_id!(a);
+        print_state!(alloc_id);
+
+        // Writing to `field2`, which is interior mutable, should be allowed.
+        (*a).field2.set(10);
+
+        // Writing to `field1` should be allowed because it also has the `Cell` permission.
+        (*a).field1 = 88;
+    }
+}
diff --git a/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.stderr b/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.stderr
new file mode 100644
index 00000000000..1d939329040
--- /dev/null
+++ b/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.stderr
@@ -0,0 +1,6 @@
+──────────────────────────────────────────────────
+Warning: this tree is indicative only. Some tags may have been hidden.
+0..   8
+| Act |    └─┬──<TAG=root of the allocation>
+|?Cel |      └────<TAG=a>
+──────────────────────────────────────────────────
diff --git a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
index d3f0499e434..6e2be7fd3da 100644
--- a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
@@ -28,7 +28,7 @@ jobs:
         run: rustup update --no-self-update stable
 
       - name: Install cargo-workspaces
-        run: cargo install cargo-workspaces
+        run: cargo install cargo-workspaces --version "0.3.6"
 
       - name: Publish Crates
         env:
@@ -54,8 +54,8 @@ jobs:
           cargo workspaces rename --from project-model project_model
           cargo workspaces rename --from test-fixture test_fixture
           cargo workspaces rename --from test-utils test_utils
-          # Remove library crates from the workspaces so we don't auto-publish them as well
-          sed -i 's/ "lib\/\*",//' ./Cargo.toml
+          # Remove library crates and xtask from the workspaces so we don't auto-publish them as well
+          sed -i 's|^members = .*$|members = ["crates/*"]|' Cargo.toml
           cargo workspaces rename ra_ap_%n
           find crates/rust-analyzer -type f -name '*.rs' -exec sed -i 's/rust_analyzer/ra_ap_rust_analyzer/g' {} +
           cargo workspaces publish --yes --force '*' --exact --no-git-commit --allow-dirty --skip-published custom 0.0.$(($RUN_NUMBER + 133))
diff --git a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
index 93ae5675a71..f2c8b6365b6 100644
--- a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
@@ -22,7 +22,7 @@ jobs:
         run: rustup update --no-self-update stable
 
       - name: Install cargo-workspaces
-        run: cargo install cargo-workspaces
+        run: cargo install cargo-workspaces --version "0.3.6"
 
       - name: Publish Crates
         env:
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index 8c507189846..975fe277b22 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -21,6 +21,8 @@ smol_str.opt-level = 3
 text-size.opt-level = 3
 serde.opt-level = 3
 salsa.opt-level = 3
+dissimilar.opt-level = 3
+
 # This speeds up `cargo xtask dist`.
 miniz_oxide.opt-level = 3
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs
index eed1490a7af..20018b61e5c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs
@@ -67,8 +67,14 @@ pub mod keys {
     pub const PROC_MACRO: Key<ast::Fn, ProcMacroId> = Key::new();
     pub const MACRO_CALL: Key<ast::MacroCall, MacroCallId> = Key::new();
     pub const ATTR_MACRO_CALL: Key<ast::Item, MacroCallId> = Key::new();
-    pub const DERIVE_MACRO_CALL: Key<ast::Attr, (AttrId, MacroCallId, Box<[Option<MacroCallId>]>)> =
-        Key::new();
+    pub const DERIVE_MACRO_CALL: Key<
+        ast::Attr,
+        (
+            AttrId,
+            /* derive() */ MacroCallId,
+            /* actual derive macros */ Box<[Option<MacroCallId>]>,
+        ),
+    > = Key::new();
 
     /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are
     /// equal if they point to exactly the same object.
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
index cb4fcd887d8..2cc3ca8c752 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
@@ -931,11 +931,12 @@ pub fn new() {
 //                             PATH_TYPE@23..26
 //                               PATH@23..26
 //                                 PATH_SEGMENT@23..26
-//                                   L_ANGLE@23..24 "<"
-//                                   PAREN_TYPE@24..26
-//                                     L_PAREN@24..25 "("
-//                                     ERROR@25..26
-//                                       INT_NUMBER@25..26 "8"
+//                                   TYPE_ANCHOR@23..26
+//                                     L_ANGLE@23..24 "<"
+//                                     PAREN_TYPE@24..26
+//                                       L_PAREN@24..25 "("
+//                                       ERROR@25..26
+//                                         INT_NUMBER@25..26 "8"
 //                           PLUS@26..27 "+"
 //                     CONST_ARG@27..28
 //                       LITERAL@27..28
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs
index 980ee264b02..1e985dc604e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs
@@ -31,6 +31,7 @@ use crate::{
 #[query_group::query_group]
 pub trait HirDatabase: DefDatabase + std::fmt::Debug {
     #[salsa::invoke(crate::infer::infer_query)]
+    #[salsa::cycle(cycle_result = crate::infer::infer_cycle_result)]
     fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
 
     // region:mir
@@ -132,6 +133,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
 
     // FIXME: Make this a non-interned query.
     #[salsa::invoke_interned(crate::lower::const_param_ty_with_diagnostics_query)]
+    #[salsa::cycle(cycle_result = crate::lower::const_param_ty_with_diagnostics_cycle_result)]
     fn const_param_ty_with_diagnostics(&self, def: ConstParamId) -> (Ty, Diagnostics);
 
     #[salsa::invoke(crate::lower::const_param_ty_query)]
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index e698fb201cb..14eb7160753 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -35,7 +35,8 @@ use chalk_ir::{
 use either::Either;
 use hir_def::{
     AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId,
-    ImplId, ItemContainerId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId,
+    ImplId, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId,
+    VariantId,
     builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
     expr_store::{Body, ExpressionStore, HygieneId, path::Path},
     hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
@@ -135,6 +136,10 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
     Arc::new(ctx.resolve_all())
 }
 
+pub(crate) fn infer_cycle_result(_: &dyn HirDatabase, _: DefWithBodyId) -> Arc<InferenceResult> {
+    Arc::new(InferenceResult { has_errors: true, ..Default::default() })
+}
+
 /// Fully normalize all the types found within `ty` in context of `owner` body definition.
 ///
 /// This is appropriate to use only after type-check: it assumes
@@ -203,7 +208,7 @@ pub(crate) type InferResult<T> = Result<InferOk<T>, TypeError>;
 pub enum InferenceDiagnostic {
     NoSuchField {
         field: ExprOrPatId,
-        private: bool,
+        private: Option<LocalFieldId>,
         variant: VariantId,
     },
     PrivateField {
@@ -558,6 +563,9 @@ impl InferenceResult {
             ExprOrPatId::PatId(id) => self.type_of_pat.get(id),
         }
     }
+    pub fn is_erroneous(&self) -> bool {
+        self.has_errors && self.type_of_expr.iter().count() == 0
+    }
 }
 
 impl Index<ExprId> for InferenceResult {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index 87b7f3406ff..64031279296 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -554,7 +554,7 @@ impl InferenceContext<'_> {
                                             self.push_diagnostic(
                                                 InferenceDiagnostic::NoSuchField {
                                                     field: field.expr.into(),
-                                                    private: true,
+                                                    private: Some(local_id),
                                                     variant: def,
                                                 },
                                             );
@@ -564,7 +564,7 @@ impl InferenceContext<'_> {
                                     None => {
                                         self.push_diagnostic(InferenceDiagnostic::NoSuchField {
                                             field: field.expr.into(),
-                                            private: false,
+                                            private: None,
                                             variant: def,
                                         });
                                         None
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
index a9a3265858e..4bc3e167ebf 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
@@ -143,7 +143,7 @@ impl InferenceContext<'_> {
                                 {
                                     self.push_diagnostic(InferenceDiagnostic::NoSuchField {
                                         field: inner.into(),
-                                        private: true,
+                                        private: Some(local_id),
                                         variant: def,
                                     });
                                 }
@@ -157,7 +157,7 @@ impl InferenceContext<'_> {
                             None => {
                                 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
                                     field: inner.into(),
-                                    private: false,
+                                    private: None,
                                     variant: def,
                                 });
                                 self.err_ty()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index ea8e7cc2be9..0a546768dab 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -1604,6 +1604,14 @@ pub(crate) fn impl_self_ty_with_diagnostics_query(
     )
 }
 
+pub(crate) fn impl_self_ty_with_diagnostics_cycle_result(
+    db: &dyn HirDatabase,
+    impl_id: ImplId,
+) -> (Binders<Ty>, Diagnostics) {
+    let generics = generics(db, impl_id.into());
+    (make_binders(db, &generics, TyKind::Error.intern(Interner)), None)
+}
+
 pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
     db.const_param_ty_with_diagnostics(def).0
 }
@@ -1633,12 +1641,12 @@ pub(crate) fn const_param_ty_with_diagnostics_query(
     (ty, create_diagnostics(ctx.diagnostics))
 }
 
-pub(crate) fn impl_self_ty_with_diagnostics_cycle_result(
-    db: &dyn HirDatabase,
-    impl_id: ImplId,
-) -> (Binders<Ty>, Diagnostics) {
-    let generics = generics(db, impl_id.into());
-    (make_binders(db, &generics, TyKind::Error.intern(Interner)), None)
+pub(crate) fn const_param_ty_with_diagnostics_cycle_result(
+    _: &dyn HirDatabase,
+    _: crate::db::HirDatabaseData,
+    _: ConstParamId,
+) -> (Ty, Diagnostics) {
+    (TyKind::Error.intern(Interner), None)
 }
 
 pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index e6caf2d8d97..99d93515303 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -2182,7 +2182,7 @@ pub fn lower_to_mir(
     // need to take this input explicitly.
     root_expr: ExprId,
 ) -> Result<MirBody> {
-    if infer.type_mismatches().next().is_some() {
+    if infer.type_mismatches().next().is_some() || infer.is_erroneous() {
         return Err(MirLowerError::HasErrors);
     }
     let mut ctx = MirLowerCtx::new(db, owner, body, infer);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs
index 48474d2d26d..e8e3812c69d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs
@@ -106,3 +106,256 @@ fn baz() -> i32 {
         assert_eq!(format!("{events:?}").matches("infer_shim").count(), 1, "{events:#?}")
     }
 }
+
+#[test]
+fn adding_struct_invalidates_infer() {
+    let (mut db, pos) = TestDB::with_position(
+        "
+//- /lib.rs
+fn foo() -> i32 {
+    1 + 1
+}
+
+fn bar() -> f32 {
+    2.0 * 3.0
+}
+$0",
+    );
+    {
+        let events = db.log_executed(|| {
+            let module = db.module_for_file(pos.file_id.file_id(&db));
+            let _crate_def_map = module.def_map(&db);
+            db.trait_impls_in_crate(module.krate());
+        });
+        assert!(format!("{events:?}").contains("trait_impls_in_crate_shim"))
+    }
+
+    let new_text = "
+fn foo() -> i32 {
+    1 + 1
+}
+
+fn bar() -> f32 {
+    2.0 * 3.0
+}
+
+pub struct NewStruct {
+    field: i32,
+}
+";
+
+    db.set_file_text(pos.file_id.file_id(&db), new_text);
+
+    {
+        let actual = db.log_executed(|| {
+            let module = db.module_for_file(pos.file_id.file_id(&db));
+            let _crate_def_map = module.def_map(&db);
+            db.trait_impls_in_crate(module.krate());
+        });
+
+        let expected = vec![
+            "parse_shim".to_owned(),
+            "ast_id_map_shim".to_owned(),
+            "file_item_tree_shim".to_owned(),
+            "real_span_map_shim".to_owned(),
+            "crate_local_def_map".to_owned(),
+            "trait_impls_in_crate_shim".to_owned(),
+        ];
+
+        assert_eq!(expected, actual);
+    }
+}
+
+#[test]
+fn adding_enum_query_log() {
+    let (mut db, pos) = TestDB::with_position(
+        "
+//- /lib.rs
+fn foo() -> i32 {
+    1 + 1
+}
+
+fn bar() -> f32 {
+    2.0 * 3.0
+}
+$0",
+    );
+    {
+        let events = db.log_executed(|| {
+            let module = db.module_for_file(pos.file_id.file_id(&db));
+            let _crate_def_map = module.def_map(&db);
+            db.trait_impls_in_crate(module.krate());
+        });
+        assert!(format!("{events:?}").contains("trait_impls_in_crate_shim"))
+    }
+
+    let new_text = "
+fn foo() -> i32 {
+    1 + 1
+}
+
+fn bar() -> f32 {
+    2.0 * 3.0
+}
+
+pub enum SomeEnum {
+    A,
+    B
+}
+";
+
+    db.set_file_text(pos.file_id.file_id(&db), new_text);
+
+    {
+        let actual = db.log_executed(|| {
+            let module = db.module_for_file(pos.file_id.file_id(&db));
+            let _crate_def_map = module.def_map(&db);
+            db.trait_impls_in_crate(module.krate());
+        });
+
+        let expected = vec![
+            "parse_shim".to_owned(),
+            "ast_id_map_shim".to_owned(),
+            "file_item_tree_shim".to_owned(),
+            "real_span_map_shim".to_owned(),
+            "crate_local_def_map".to_owned(),
+            "trait_impls_in_crate_shim".to_owned(),
+        ];
+
+        assert_eq!(expected, actual);
+    }
+}
+
+#[test]
+fn adding_use_query_log() {
+    let (mut db, pos) = TestDB::with_position(
+        "
+//- /lib.rs
+fn foo() -> i32 {
+    1 + 1
+}
+
+fn bar() -> f32 {
+    2.0 * 3.0
+}
+$0",
+    );
+    {
+        let events = db.log_executed(|| {
+            let module = db.module_for_file(pos.file_id.file_id(&db));
+            let _crate_def_map = module.def_map(&db);
+            db.trait_impls_in_crate(module.krate());
+        });
+        assert!(format!("{events:?}").contains("trait_impls_in_crate_shim"))
+    }
+
+    let new_text = "
+use std::collections::HashMap;
+
+fn foo() -> i32 {
+    1 + 1
+}
+
+fn bar() -> f32 {
+    2.0 * 3.0
+}
+";
+
+    db.set_file_text(pos.file_id.file_id(&db), new_text);
+
+    {
+        let actual = db.log_executed(|| {
+            let module = db.module_for_file(pos.file_id.file_id(&db));
+            let _crate_def_map = module.def_map(&db);
+            db.trait_impls_in_crate(module.krate());
+        });
+
+        let expected = vec![
+            "parse_shim".to_owned(),
+            "ast_id_map_shim".to_owned(),
+            "file_item_tree_shim".to_owned(),
+            "real_span_map_shim".to_owned(),
+            "crate_local_def_map".to_owned(),
+            "trait_impls_in_crate_shim".to_owned(),
+        ];
+
+        assert_eq!(expected, actual);
+    }
+}
+
+#[test]
+fn adding_impl_query_log() {
+    let (mut db, pos) = TestDB::with_position(
+        "
+//- /lib.rs
+fn foo() -> i32 {
+    1 + 1
+}
+
+fn bar() -> f32 {
+    2.0 * 3.0
+}
+
+pub struct SomeStruct {
+    field: i32,
+}
+$0",
+    );
+    {
+        let events = db.log_executed(|| {
+            let module = db.module_for_file(pos.file_id.file_id(&db));
+            let _crate_def_map = module.def_map(&db);
+            db.trait_impls_in_crate(module.krate());
+        });
+        assert!(format!("{events:?}").contains("trait_impls_in_crate_shim"))
+    }
+
+    let new_text = "
+fn foo() -> i32 {
+    1 + 1
+}
+
+fn bar() -> f32 {
+    2.0 * 3.0
+}
+
+pub struct SomeStruct {
+    field: i32,
+}
+
+impl SomeStruct {
+    pub fn new(value: i32) -> Self {
+        Self { field: value }
+    }
+}
+";
+
+    db.set_file_text(pos.file_id.file_id(&db), new_text);
+
+    {
+        let actual = db.log_executed(|| {
+            let module = db.module_for_file(pos.file_id.file_id(&db));
+            let _crate_def_map = module.def_map(&db);
+            db.trait_impls_in_crate(module.krate());
+        });
+
+        let expected = vec![
+            "parse_shim".to_owned(),
+            "ast_id_map_shim".to_owned(),
+            "file_item_tree_shim".to_owned(),
+            "real_span_map_shim".to_owned(),
+            "crate_local_def_map".to_owned(),
+            "trait_impls_in_crate_shim".to_owned(),
+            "attrs_shim".to_owned(),
+            "impl_trait_with_diagnostics_shim".to_owned(),
+            "impl_signature_shim".to_owned(),
+            "impl_signature_with_source_map_shim".to_owned(),
+            "impl_self_ty_with_diagnostics_shim".to_owned(),
+            "struct_signature_shim".to_owned(),
+            "struct_signature_with_source_map_shim".to_owned(),
+            "type_for_adt_tracked".to_owned(),
+        ];
+
+        assert_eq!(expected, actual);
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
index 47c695c6974..ff8adeef1db 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
@@ -2301,3 +2301,51 @@ trait Foo {
         "#]],
     );
 }
+
+#[test]
+fn no_panic_on_recursive_const() {
+    check_infer(
+        r#"
+struct Foo<const N: usize> {}
+impl<const N: Foo<N>> Foo<N> {
+    fn foo(self) {}
+}
+
+fn test() {
+    let _ = N;
+}
+"#,
+        expect![[r#"
+            72..76 'self': Foo<N>
+            78..80 '{}': ()
+            94..112 '{     ...= N; }': ()
+            104..105 '_': {unknown}
+            108..109 'N': {unknown}
+        "#]],
+    );
+
+    check_infer(
+        r#"
+struct Foo<const N: usize>;
+const N: Foo<N> = Foo;
+
+impl<const N: usize> Foo<N> {
+    fn foo(self) -> usize {
+        N
+    }
+}
+
+fn test() {
+    let _ = N;
+}
+"#,
+        expect![[r#"
+            93..97 'self': Foo<N>
+            108..125 '{     ...     }': usize
+            118..119 'N': usize
+            139..157 '{     ...= N; }': ()
+            149..150 '_': Foo<_>
+            153..154 'N': Foo<_>
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
index b6e3002ed5d..f7b140e03d4 100644
--- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
@@ -224,7 +224,7 @@ pub struct MalformedDerive {
 #[derive(Debug)]
 pub struct NoSuchField {
     pub field: InFile<AstPtr<Either<ast::RecordExprField, ast::RecordPatField>>>,
-    pub private: bool,
+    pub private: Option<Field>,
     pub variant: VariantId,
 }
 
@@ -648,6 +648,7 @@ impl AnyDiagnostic {
                     }
                     ExprOrPatId::PatId(pat) => source_map.pat_field_syntax(pat),
                 };
+                let private = private.map(|id| Field { id, parent: variant.into() });
                 NoSuchField { field: expr_or_pat, private, variant }.into()
             }
             &InferenceDiagnostic::MismatchedArgCount { call_expr, expected, found } => {
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index e01774650b1..4a2e8e379fb 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -222,6 +222,21 @@ impl<DB: HirDatabase> Semantics<'_, DB> {
         self.imp.descend_node_at_offset(node, offset).filter_map(|mut it| it.find_map(N::cast))
     }
 
+    // FIXME: Rethink this API
+    pub fn find_namelike_at_offset_with_descend<'slf>(
+        &'slf self,
+        node: &SyntaxNode,
+        offset: TextSize,
+    ) -> impl Iterator<Item = ast::NameLike> + 'slf {
+        node.token_at_offset(offset)
+            .map(move |token| self.descend_into_macros_no_opaque(token))
+            .map(|descendants| descendants.into_iter().filter_map(move |it| it.value.parent()))
+            // re-order the tokens from token_at_offset by returning the ancestors with the smaller first nodes first
+            // See algo::ancestors_at_offset, which uses the same approach
+            .kmerge_by(|left, right| left.text_range().len().lt(&right.text_range().len()))
+            .filter_map(ast::NameLike::cast)
+    }
+
     pub fn resolve_range_pat(&self, range_pat: &ast::RangePat) -> Option<Struct> {
         self.imp.resolve_range_pat(range_pat).map(Struct::from)
     }
@@ -535,7 +550,7 @@ impl<'db> SemanticsImpl<'db> {
     }
 
     pub fn is_derive_annotated(&self, adt: InFile<&ast::Adt>) -> bool {
-        self.with_ctx(|ctx| ctx.has_derives(adt))
+        self.with_ctx(|ctx| ctx.file_of_adt_has_derives(adt))
     }
 
     pub fn derive_helpers_in_scope(&self, adt: &ast::Adt) -> Option<Vec<(Symbol, Symbol)>> {
@@ -644,7 +659,7 @@ impl<'db> SemanticsImpl<'db> {
 
     /// Checks if renaming `renamed` to `new_name` may introduce conflicts with other locals,
     /// and returns the conflicting locals.
-    pub fn rename_conflicts(&self, to_be_renamed: &Local, new_name: &str) -> Vec<Local> {
+    pub fn rename_conflicts(&self, to_be_renamed: &Local, new_name: &Name) -> Vec<Local> {
         let body = self.db.body(to_be_renamed.parent);
         let resolver = to_be_renamed.parent.resolver(self.db);
         let starting_expr =
@@ -653,7 +668,7 @@ impl<'db> SemanticsImpl<'db> {
             body: &body,
             conflicts: FxHashSet::default(),
             db: self.db,
-            new_name: Symbol::intern(new_name),
+            new_name: new_name.symbol().clone(),
             old_name: to_be_renamed.name(self.db).symbol().clone(),
             owner: to_be_renamed.parent,
             to_be_renamed: to_be_renamed.binding_id,
@@ -877,8 +892,9 @@ impl<'db> SemanticsImpl<'db> {
 
         if first == last {
             // node is just the token, so descend the token
-            self.descend_into_macros_impl(
+            self.descend_into_macros_all(
                 InFile::new(file.file_id, first),
+                false,
                 &mut |InFile { value, .. }, _ctx| {
                     if let Some(node) = value
                         .parent_ancestors()
@@ -887,20 +903,21 @@ impl<'db> SemanticsImpl<'db> {
                     {
                         res.push(node)
                     }
-                    CONTINUE_NO_BREAKS
                 },
             );
         } else {
             // Descend first and last token, then zip them to look for the node they belong to
             let mut scratch: SmallVec<[_; 1]> = smallvec![];
-            self.descend_into_macros_impl(InFile::new(file.file_id, first), &mut |token, _ctx| {
-                scratch.push(token);
-                CONTINUE_NO_BREAKS
-            });
+            self.descend_into_macros_all(
+                InFile::new(file.file_id, first),
+                false,
+                &mut |token, _ctx| scratch.push(token),
+            );
 
             let mut scratch = scratch.into_iter();
-            self.descend_into_macros_impl(
+            self.descend_into_macros_all(
                 InFile::new(file.file_id, last),
+                false,
                 &mut |InFile { value: last, file_id: last_fid }, _ctx| {
                     if let Some(InFile { value: first, file_id: first_fid }) = scratch.next() {
                         if first_fid == last_fid {
@@ -917,17 +934,18 @@ impl<'db> SemanticsImpl<'db> {
                             }
                         }
                     }
-                    CONTINUE_NO_BREAKS
                 },
             );
         }
         res
     }
 
-    pub fn is_inside_macro_call(&self, token: InFile<&SyntaxToken>) -> bool {
-        // FIXME: Maybe `ancestors_with_macros()` is more suitable here? Currently
-        // this is only used on real (not macro) files so this is not a problem.
-        token.value.parent_ancestors().any(|ancestor| {
+    /// Returns true if the given input is within a macro call.
+    ///
+    /// Note that if this token itself is within the context of a macro expansion does not matter.
+    /// That is, we strictly check if it lies inside the input of a macro call.
+    pub fn is_inside_macro_call(&self, token @ InFile { value, .. }: InFile<&SyntaxToken>) -> bool {
+        value.parent_ancestors().any(|ancestor| {
             if ast::MacroCall::can_cast(ancestor.kind()) {
                 return true;
             }
@@ -952,7 +970,7 @@ impl<'db> SemanticsImpl<'db> {
                     ast::Item::Union(it) => it.into(),
                     _ => return false,
                 };
-                ctx.has_derives(token.with_value(&adt))
+                ctx.file_of_adt_has_derives(token.with_value(&adt))
             })
         })
     }
@@ -962,18 +980,18 @@ impl<'db> SemanticsImpl<'db> {
         token: SyntaxToken,
         mut cb: impl FnMut(InFile<SyntaxToken>, SyntaxContext),
     ) {
-        self.descend_into_macros_impl(self.wrap_token_infile(token), &mut |t, ctx| {
-            cb(t, ctx);
-            CONTINUE_NO_BREAKS
+        self.descend_into_macros_all(self.wrap_token_infile(token), false, &mut |t, ctx| {
+            cb(t, ctx)
         });
     }
 
     pub fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
         let mut res = smallvec![];
-        self.descend_into_macros_impl(self.wrap_token_infile(token.clone()), &mut |t, _ctx| {
-            res.push(t.value);
-            CONTINUE_NO_BREAKS
-        });
+        self.descend_into_macros_all(
+            self.wrap_token_infile(token.clone()),
+            false,
+            &mut |t, _ctx| res.push(t.value),
+        );
         if res.is_empty() {
             res.push(token);
         }
@@ -986,12 +1004,11 @@ impl<'db> SemanticsImpl<'db> {
     ) -> SmallVec<[InFile<SyntaxToken>; 1]> {
         let mut res = smallvec![];
         let token = self.wrap_token_infile(token);
-        self.descend_into_macros_impl(token.clone(), &mut |t, ctx| {
+        self.descend_into_macros_all(token.clone(), true, &mut |t, ctx| {
             if !ctx.is_opaque(self.db) {
                 // Don't descend into opaque contexts
                 res.push(t);
             }
-            CONTINUE_NO_BREAKS
         });
         if res.is_empty() {
             res.push(token);
@@ -1004,7 +1021,7 @@ impl<'db> SemanticsImpl<'db> {
         token: InFile<SyntaxToken>,
         mut cb: impl FnMut(InFile<SyntaxToken>, SyntaxContext) -> ControlFlow<T>,
     ) -> Option<T> {
-        self.descend_into_macros_impl(token, &mut cb)
+        self.descend_into_macros_impl(token, false, &mut cb)
     }
 
     /// Descends the token into expansions, returning the tokens that matches the input
@@ -1074,44 +1091,56 @@ impl<'db> SemanticsImpl<'db> {
         .unwrap_or(token)
     }
 
+    fn descend_into_macros_all(
+        &self,
+        token: InFile<SyntaxToken>,
+        always_descend_into_derives: bool,
+        f: &mut dyn FnMut(InFile<SyntaxToken>, SyntaxContext),
+    ) {
+        self.descend_into_macros_impl(token, always_descend_into_derives, &mut |tok, ctx| {
+            f(tok, ctx);
+            CONTINUE_NO_BREAKS
+        });
+    }
+
     fn descend_into_macros_impl<T>(
         &self,
         InFile { value: token, file_id }: InFile<SyntaxToken>,
+        always_descend_into_derives: bool,
         f: &mut dyn FnMut(InFile<SyntaxToken>, SyntaxContext) -> ControlFlow<T>,
     ) -> Option<T> {
         let _p = tracing::info_span!("descend_into_macros_impl").entered();
 
-        let span = self.db.span_map(file_id).span_for_range(token.text_range());
+        let db = self.db;
+        let span = db.span_map(file_id).span_for_range(token.text_range());
 
         // Process the expansion of a call, pushing all tokens with our span in the expansion back onto our stack
-        let process_expansion_for_token = |stack: &mut Vec<_>, macro_file| {
-            let InMacroFile { file_id, value: mapped_tokens } = self.with_ctx(|ctx| {
-                Some(
-                    ctx.cache
-                        .get_or_insert_expansion(ctx.db, macro_file)
-                        .map_range_down(span)?
-                        .map(SmallVec::<[_; 2]>::from_iter),
-                )
-            })?;
-            // we have found a mapping for the token if the vec is non-empty
-            let res = mapped_tokens.is_empty().not().then_some(());
-            // requeue the tokens we got from mapping our current token down
-            stack.push((HirFileId::from(file_id), mapped_tokens));
-            res
-        };
+        let process_expansion_for_token =
+            |ctx: &mut SourceToDefCtx<'_, '_>, stack: &mut Vec<_>, macro_file| {
+                let InMacroFile { file_id, value: mapped_tokens } = ctx
+                    .cache
+                    .get_or_insert_expansion(ctx.db, macro_file)
+                    .map_range_down(span)?
+                    .map(SmallVec::<[_; 2]>::from_iter);
+                // we have found a mapping for the token if the vec is non-empty
+                let res = mapped_tokens.is_empty().not().then_some(());
+                // requeue the tokens we got from mapping our current token down
+                stack.push((HirFileId::from(file_id), mapped_tokens));
+                res
+            };
 
         // A stack of tokens to process, along with the file they came from
         // These are tracked to know which macro calls we still have to look into
         // the tokens themselves aren't that interesting as the span that is being used to map
         // things down never changes.
         let mut stack: Vec<(_, SmallVec<[_; 2]>)> = vec![];
-        let include = file_id.file_id().and_then(|file_id| {
-            self.s2d_cache.borrow_mut().get_or_insert_include_for(self.db, file_id)
-        });
+        let include = file_id
+            .file_id()
+            .and_then(|file_id| self.s2d_cache.borrow_mut().get_or_insert_include_for(db, file_id));
         match include {
             Some(include) => {
                 // include! inputs are always from real files, so they only need to be handled once upfront
-                process_expansion_for_token(&mut stack, include)?;
+                self.with_ctx(|ctx| process_expansion_for_token(ctx, &mut stack, include))?;
             }
             None => {
                 stack.push((file_id, smallvec![(token, span.ctx)]));
@@ -1133,62 +1162,120 @@ impl<'db> SemanticsImpl<'db> {
             tokens.reverse();
             while let Some((token, ctx)) = tokens.pop() {
                 let was_not_remapped = (|| {
-                    // First expand into attribute invocations
-                    let containing_attribute_macro_call = self.with_ctx(|ctx| {
-                        token.parent_ancestors().filter_map(ast::Item::cast).find_map(|item| {
-                            // Don't force populate the dyn cache for items that don't have an attribute anyways
-                            item.attrs().next()?;
-                            Some((ctx.item_to_macro_call(InFile::new(expansion, &item))?, item))
-                        })
-                    });
-                    if let Some((call_id, item)) = containing_attribute_macro_call {
-                        let attr_id = match self.db.lookup_intern_macro_call(call_id).kind {
-                            hir_expand::MacroCallKind::Attr { invoc_attr_index, .. } => {
-                                invoc_attr_index.ast_index()
-                            }
-                            _ => 0,
-                        };
-                        // FIXME: here, the attribute's text range is used to strip away all
-                        // entries from the start of the attribute "list" up the invoking
-                        // attribute. But in
-                        // ```
-                        // mod foo {
-                        //     #![inner]
-                        // }
-                        // ```
-                        // we don't wanna strip away stuff in the `mod foo {` range, that is
-                        // here if the id corresponds to an inner attribute we got strip all
-                        // text ranges of the outer ones, and then all of the inner ones up
-                        // to the invoking attribute so that the inbetween is ignored.
-                        let text_range = item.syntax().text_range();
-                        let start = collect_attrs(&item)
-                            .nth(attr_id)
-                            .map(|attr| match attr.1 {
-                                Either::Left(it) => it.syntax().text_range().start(),
-                                Either::Right(it) => it.syntax().text_range().start(),
+                    // First expand into attribute invocations, this is required to be handled
+                    // upfront as any other macro call within will not semantically resolve unless
+                    // also descended.
+                    let res = self.with_ctx(|ctx| {
+                        token
+                            .parent_ancestors()
+                            .filter_map(ast::Item::cast)
+                            // FIXME: This might work incorrectly when we have a derive, followed by
+                            // an attribute on an item, like:
+                            // ```
+                            // #[derive(Debug$0)]
+                            // #[my_attr]
+                            // struct MyStruct;
+                            // ```
+                            // here we should not consider the attribute at all, as our cursor
+                            // technically lies outside of its expansion
+                            .find_map(|item| {
+                                // Don't force populate the dyn cache for items that don't have an attribute anyways
+                                item.attrs().next()?;
+                                ctx.item_to_macro_call(InFile::new(expansion, &item))
+                                    .zip(Some(item))
                             })
-                            .unwrap_or_else(|| text_range.start());
-                        let text_range = TextRange::new(start, text_range.end());
-                        filter_duplicates(tokens, text_range);
-                        return process_expansion_for_token(&mut stack, call_id);
+                            .map(|(call_id, item)| {
+                                let attr_id = match db.lookup_intern_macro_call(call_id).kind {
+                                    hir_expand::MacroCallKind::Attr {
+                                        invoc_attr_index, ..
+                                    } => invoc_attr_index.ast_index(),
+                                    _ => 0,
+                                };
+                                // FIXME: here, the attribute's text range is used to strip away all
+                                // entries from the start of the attribute "list" up the invoking
+                                // attribute. But in
+                                // ```
+                                // mod foo {
+                                //     #![inner]
+                                // }
+                                // ```
+                                // we don't wanna strip away stuff in the `mod foo {` range, that is
+                                // here if the id corresponds to an inner attribute we got strip all
+                                // text ranges of the outer ones, and then all of the inner ones up
+                                // to the invoking attribute so that the inbetween is ignored.
+                                let text_range = item.syntax().text_range();
+                                let start = collect_attrs(&item)
+                                    .nth(attr_id)
+                                    .map(|attr| match attr.1 {
+                                        Either::Left(it) => it.syntax().text_range().start(),
+                                        Either::Right(it) => it.syntax().text_range().start(),
+                                    })
+                                    .unwrap_or_else(|| text_range.start());
+                                let text_range = TextRange::new(start, text_range.end());
+                                filter_duplicates(tokens, text_range);
+                                process_expansion_for_token(ctx, &mut stack, call_id)
+                            })
+                    });
+
+                    if let Some(res) = res {
+                        return res;
                     }
 
+                    if always_descend_into_derives {
+                        let res = self.with_ctx(|ctx| {
+                            let (derives, adt) = token
+                                .parent_ancestors()
+                                .filter_map(ast::Adt::cast)
+                                .find_map(|adt| {
+                                    Some((
+                                        ctx.derive_macro_calls(InFile::new(expansion, &adt))?
+                                            .map(|(a, b, c)| (a, b, c.to_owned()))
+                                            .collect::<SmallVec<[_; 2]>>(),
+                                        adt,
+                                    ))
+                                })?;
+                            let mut res = None;
+                            for (_, derive_attr, derives) in derives {
+                                // as there may be multiple derives registering the same helper
+                                // name, we gotta make sure to call this for all of them!
+                                // FIXME: We need to call `f` for all of them as well though!
+                                res = res.or(process_expansion_for_token(
+                                    ctx,
+                                    &mut stack,
+                                    derive_attr,
+                                ));
+                                for derive in derives.into_iter().flatten() {
+                                    res = res
+                                        .or(process_expansion_for_token(ctx, &mut stack, derive));
+                                }
+                            }
+                            // remove all tokens that are within the derives expansion
+                            filter_duplicates(tokens, adt.syntax().text_range());
+                            Some(res)
+                        });
+                        // if we found derives, we can early exit. There is no way we can be in any
+                        // macro call at this point given we are not in a token tree
+                        if let Some(res) = res {
+                            return res;
+                        }
+                    }
                     // Then check for token trees, that means we are either in a function-like macro or
                     // secondary attribute inputs
                     let tt = token
                         .parent_ancestors()
                         .map_while(Either::<ast::TokenTree, ast::Meta>::cast)
                         .last()?;
+
                     match tt {
                         // function-like macro call
                         Either::Left(tt) => {
+                            let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?;
                             if tt.left_delimiter_token().map_or(false, |it| it == token) {
                                 return None;
                             }
                             if tt.right_delimiter_token().map_or(false, |it| it == token) {
                                 return None;
                             }
-                            let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?;
                             let mcall = InFile::new(expansion, macro_call);
                             let file_id = match m_cache.get(&mcall) {
                                 Some(&it) => it,
@@ -1201,13 +1288,16 @@ impl<'db> SemanticsImpl<'db> {
                             let text_range = tt.syntax().text_range();
                             filter_duplicates(tokens, text_range);
 
-                            process_expansion_for_token(&mut stack, file_id).or(file_id
-                                .eager_arg(self.db)
-                                .and_then(|arg| {
-                                    // also descend into eager expansions
-                                    process_expansion_for_token(&mut stack, arg)
-                                }))
+                            self.with_ctx(|ctx| {
+                                process_expansion_for_token(ctx, &mut stack, file_id).or(file_id
+                                    .eager_arg(db)
+                                    .and_then(|arg| {
+                                        // also descend into eager expansions
+                                        process_expansion_for_token(ctx, &mut stack, arg)
+                                    }))
+                            })
                         }
+                        Either::Right(_) if always_descend_into_derives => None,
                         // derive or derive helper
                         Either::Right(meta) => {
                             // attribute we failed expansion for earlier, this might be a derive invocation
@@ -1216,31 +1306,33 @@ impl<'db> SemanticsImpl<'db> {
                             let adt = match attr.syntax().parent().and_then(ast::Adt::cast) {
                                 Some(adt) => {
                                     // this might be a derive on an ADT
-                                    let derive_call = self.with_ctx(|ctx| {
+                                    let res = self.with_ctx(|ctx| {
                                         // so try downmapping the token into the pseudo derive expansion
                                         // see [hir_expand::builtin_attr_macro] for how the pseudo derive expansion works
-                                        ctx.attr_to_derive_macro_call(
-                                            InFile::new(expansion, &adt),
-                                            InFile::new(expansion, attr.clone()),
-                                        )
-                                        .map(|(_, call_id, _)| call_id)
+                                        let derive_call = ctx
+                                            .attr_to_derive_macro_call(
+                                                InFile::new(expansion, &adt),
+                                                InFile::new(expansion, attr.clone()),
+                                            )?
+                                            .1;
+
+                                        // resolved to a derive
+                                        let text_range = attr.syntax().text_range();
+                                        // remove any other token in this macro input, all their mappings are the
+                                        // same as this
+                                        tokens.retain(|(t, _)| {
+                                            !text_range.contains_range(t.text_range())
+                                        });
+                                        Some(process_expansion_for_token(
+                                            ctx,
+                                            &mut stack,
+                                            derive_call,
+                                        ))
                                     });
-
-                                    match derive_call {
-                                        Some(call_id) => {
-                                            // resolved to a derive
-                                            let text_range = attr.syntax().text_range();
-                                            // remove any other token in this macro input, all their mappings are the
-                                            // same as this
-                                            tokens.retain(|(t, _)| {
-                                                !text_range.contains_range(t.text_range())
-                                            });
-                                            return process_expansion_for_token(
-                                                &mut stack, call_id,
-                                            );
-                                        }
-                                        None => Some(adt),
+                                    if let Some(res) = res {
+                                        return res;
                                     }
+                                    Some(adt)
                                 }
                                 None => {
                                     // Otherwise this could be a derive helper on a variant or field
@@ -1254,12 +1346,9 @@ impl<'db> SemanticsImpl<'db> {
                                     )
                                 }
                             }?;
-                            if !self.with_ctx(|ctx| ctx.has_derives(InFile::new(expansion, &adt))) {
-                                return None;
-                            }
                             let attr_name =
                                 attr.path().and_then(|it| it.as_single_name_ref())?.as_name();
-                            // Not an attribute, nor a derive, so it's either an intert attribute or a derive helper
+                            // Not an attribute, nor a derive, so it's either an inert attribute or a derive helper
                             // Try to resolve to a derive helper and downmap
                             let resolver = &token
                                 .parent()
@@ -1267,7 +1356,7 @@ impl<'db> SemanticsImpl<'db> {
                                     self.analyze_impl(InFile::new(expansion, &parent), None, false)
                                 })?
                                 .resolver;
-                            let id = self.db.ast_id_map(expansion).ast_id(&adt);
+                            let id = db.ast_id_map(expansion).ast_id(&adt);
                             let helpers = resolver
                                 .def_map()
                                 .derive_helpers_in_scope(InFile::new(expansion, id))?;
@@ -1278,20 +1367,22 @@ impl<'db> SemanticsImpl<'db> {
                             }
 
                             let mut res = None;
-                            for (.., derive) in
-                                helpers.iter().filter(|(helper, ..)| *helper == attr_name)
-                            {
-                                // as there may be multiple derives registering the same helper
-                                // name, we gotta make sure to call this for all of them!
-                                // FIXME: We need to call `f` for all of them as well though!
-                                res = res.or(process_expansion_for_token(&mut stack, *derive));
-                            }
-                            res
+                            self.with_ctx(|ctx| {
+                                for (.., derive) in
+                                    helpers.iter().filter(|(helper, ..)| *helper == attr_name)
+                                {
+                                    // as there may be multiple derives registering the same helper
+                                    // name, we gotta make sure to call this for all of them!
+                                    // FIXME: We need to call `f` for all of them as well though!
+                                    res = res
+                                        .or(process_expansion_for_token(ctx, &mut stack, *derive));
+                                }
+                                res
+                            })
                         }
                     }
                 })()
                 .is_none();
-
                 if was_not_remapped {
                     if let ControlFlow::Break(b) = f(InFile::new(expansion, token), ctx) {
                         return Some(b);
@@ -1380,25 +1471,31 @@ impl<'db> SemanticsImpl<'db> {
     }
 
     /// Iterates the ancestors of the given node, climbing up macro expansions while doing so.
+    // FIXME: Replace with `ancestors_with_macros_file` when all usages are updated.
     pub fn ancestors_with_macros(
         &self,
         node: SyntaxNode,
     ) -> impl Iterator<Item = SyntaxNode> + Clone + '_ {
         let node = self.find_file(&node);
-        iter::successors(Some(node.cloned()), move |&InFile { file_id, ref value }| {
-            match value.parent() {
-                Some(parent) => Some(InFile::new(file_id, parent)),
-                None => {
-                    let macro_file = file_id.macro_file()?;
-
-                    self.with_ctx(|ctx| {
-                        let expansion_info = ctx.cache.get_or_insert_expansion(ctx.db, macro_file);
-                        expansion_info.arg().map(|node| node?.parent()).transpose()
-                    })
-                }
+        self.ancestors_with_macros_file(node.cloned()).map(|it| it.value)
+    }
+
+    /// Iterates the ancestors of the given node, climbing up macro expansions while doing so.
+    pub fn ancestors_with_macros_file(
+        &self,
+        node: InFile<SyntaxNode>,
+    ) -> impl Iterator<Item = InFile<SyntaxNode>> + Clone + '_ {
+        iter::successors(Some(node), move |&InFile { file_id, ref value }| match value.parent() {
+            Some(parent) => Some(InFile::new(file_id, parent)),
+            None => {
+                let macro_file = file_id.macro_file()?;
+
+                self.with_ctx(|ctx| {
+                    let expansion_info = ctx.cache.get_or_insert_expansion(ctx.db, macro_file);
+                    expansion_info.arg().map(|node| node?.parent()).transpose()
+                })
             }
         })
-        .map(|it| it.value)
     }
 
     pub fn ancestors_at_offset_with_macros(
@@ -1851,18 +1948,12 @@ impl<'db> SemanticsImpl<'db> {
             ChildContainer::TraitId(it) => {
                 return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
             }
-            ChildContainer::TraitAliasId(it) => {
-                return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
-            }
             ChildContainer::ImplId(it) => {
                 return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
             }
             ChildContainer::EnumId(it) => {
                 return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
             }
-            ChildContainer::TypeAliasId(it) => {
-                return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
-            }
             ChildContainer::GenericDefId(it) => {
                 return Some(SourceAnalyzer::new_generic_def(self.db, it, node, offset));
             }
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs
index 6accf9b2e9c..1a6d63c88c6 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs
@@ -17,6 +17,7 @@ use hir_def::{
         DynMap,
         keys::{self, Key},
     },
+    hir::generics::GenericParams,
     item_scope::ItemScope,
     item_tree::ItemTreeNode,
     nameres::DefMap,
@@ -49,6 +50,12 @@ impl ChildBySource for TraitId {
         data.items.iter().for_each(|&(_, item)| {
             add_assoc_item(db, res, file_id, item);
         });
+        let (_, source_map) = db.trait_signature_with_source_map(*self);
+        source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each(
+            |(ast, &exp_id)| {
+                res[keys::MACRO_CALL].insert(ast.value, exp_id);
+            },
+        );
     }
 }
 
@@ -68,6 +75,12 @@ impl ChildBySource for ImplId {
         data.items.iter().for_each(|&(_, item)| {
             add_assoc_item(db, res, file_id, item);
         });
+        let (_, source_map) = db.impl_signature_with_source_map(*self);
+        source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each(
+            |(ast, &exp_id)| {
+                res[keys::MACRO_CALL].insert(ast.value, exp_id);
+            },
+        );
     }
 }
 
@@ -178,6 +191,8 @@ impl ChildBySource for VariantId {
                 Either::Right(source) => res[keys::RECORD_FIELD].insert(AstPtr::new(&source), id),
             }
         }
+        let (_, sm) = db.variant_fields_with_source_map(*self);
+        sm.expansions().for_each(|(ast, &exp_id)| res[keys::MACRO_CALL].insert(ast.value, exp_id));
     }
 }
 
@@ -195,6 +210,11 @@ impl ChildBySource for EnumId {
             res[keys::ENUM_VARIANT]
                 .insert(ast_id_map.get(tree[variant.lookup(db).id.value].ast_id), variant);
         });
+        let (_, source_map) = db.enum_signature_with_source_map(*self);
+        source_map
+            .expansions()
+            .filter(|(ast, _)| ast.file_id == file_id)
+            .for_each(|(ast, &exp_id)| res[keys::MACRO_CALL].insert(ast.value, exp_id));
     }
 }
 
@@ -225,7 +245,8 @@ impl ChildBySource for GenericDefId {
             return;
         }
 
-        let generic_params = db.generic_params(*self);
+        let (generic_params, _, source_map) =
+            GenericParams::generic_params_and_store_and_source_map(db, *self);
         let mut toc_idx_iter = generic_params.iter_type_or_consts().map(|(idx, _)| idx);
         let lts_idx_iter = generic_params.iter_lt().map(|(idx, _)| idx);
 
@@ -253,6 +274,11 @@ impl ChildBySource for GenericDefId {
                 res[keys::LIFETIME_PARAM].insert(AstPtr::new(&ast_param), id);
             }
         }
+
+        source_map
+            .expansions()
+            .filter(|(ast, _)| ast.file_id == file_id)
+            .for_each(|(ast, &exp_id)| res[keys::MACRO_CALL].insert(ast.value, exp_id));
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
index 7f6c9af4740..71ee0f69389 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
@@ -108,7 +108,7 @@ use span::FileId;
 use stdx::impl_from;
 use syntax::{
     AstNode, AstPtr, SyntaxNode,
-    ast::{self, HasName},
+    ast::{self, HasAttrs, HasName},
 };
 use tt::TextRange;
 
@@ -411,10 +411,25 @@ impl SourceToDefCtx<'_, '_> {
             .map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids))
     }
 
-    pub(super) fn has_derives(&mut self, adt: InFile<&ast::Adt>) -> bool {
+    // FIXME: Make this more fine grained! This should be a `adt_has_derives`!
+    pub(super) fn file_of_adt_has_derives(&mut self, adt: InFile<&ast::Adt>) -> bool {
         self.dyn_map(adt).as_ref().is_some_and(|map| !map[keys::DERIVE_MACRO_CALL].is_empty())
     }
 
+    pub(super) fn derive_macro_calls<'slf>(
+        &'slf mut self,
+        adt: InFile<&ast::Adt>,
+    ) -> Option<impl Iterator<Item = (AttrId, MacroCallId, &'slf [Option<MacroCallId>])> + use<'slf>>
+    {
+        self.dyn_map(adt).as_ref().map(|&map| {
+            let dyn_map = &map[keys::DERIVE_MACRO_CALL];
+            adt.value
+                .attrs()
+                .filter_map(move |attr| dyn_map.get(&AstPtr::new(&attr)))
+                .map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids))
+        })
+    }
+
     fn to_def<Ast: AstNode + 'static, ID: Copy + 'static>(
         &mut self,
         src: InFile<&Ast>,
@@ -616,14 +631,14 @@ impl SourceToDefCtx<'_, '_> {
             match &item {
                 ast::Item::Module(it) => self.module_to_def(container.with_value(it))?.into(),
                 ast::Item::Trait(it) => self.trait_to_def(container.with_value(it))?.into(),
-                ast::Item::TraitAlias(it) => {
-                    self.trait_alias_to_def(container.with_value(it))?.into()
-                }
                 ast::Item::Impl(it) => self.impl_to_def(container.with_value(it))?.into(),
                 ast::Item::Enum(it) => self.enum_to_def(container.with_value(it))?.into(),
-                ast::Item::TypeAlias(it) => {
-                    self.type_alias_to_def(container.with_value(it))?.into()
-                }
+                ast::Item::TypeAlias(it) => ChildContainer::GenericDefId(
+                    self.type_alias_to_def(container.with_value(it))?.into(),
+                ),
+                ast::Item::TraitAlias(it) => ChildContainer::GenericDefId(
+                    self.trait_alias_to_def(container.with_value(it))?.into(),
+                ),
                 ast::Item::Struct(it) => {
                     let def = self.struct_to_def(container.with_value(it))?;
                     let is_in_body = it.field_list().is_some_and(|it| {
@@ -723,11 +738,9 @@ pub(crate) enum ChildContainer {
     DefWithBodyId(DefWithBodyId),
     ModuleId(ModuleId),
     TraitId(TraitId),
-    TraitAliasId(TraitAliasId),
     ImplId(ImplId),
     EnumId(EnumId),
     VariantId(VariantId),
-    TypeAliasId(TypeAliasId),
     /// XXX: this might be the same def as, for example an `EnumId`. However,
     /// here the children are generic parameters, and not, eg enum variants.
     GenericDefId(GenericDefId),
@@ -736,11 +749,9 @@ impl_from! {
     DefWithBodyId,
     ModuleId,
     TraitId,
-    TraitAliasId,
     ImplId,
     EnumId,
     VariantId,
-    TypeAliasId,
     GenericDefId
     for ChildContainer
 }
@@ -752,11 +763,9 @@ impl ChildContainer {
             ChildContainer::DefWithBodyId(it) => it.child_by_source(db, file_id),
             ChildContainer::ModuleId(it) => it.child_by_source(db, file_id),
             ChildContainer::TraitId(it) => it.child_by_source(db, file_id),
-            ChildContainer::TraitAliasId(_) => DynMap::default(),
             ChildContainer::ImplId(it) => it.child_by_source(db, file_id),
             ChildContainer::EnumId(it) => it.child_by_source(db, file_id),
             ChildContainer::VariantId(it) => it.child_by_source(db, file_id),
-            ChildContainer::TypeAliasId(_) => DynMap::default(),
             ChildContainer::GenericDefId(it) => it.child_by_source(db, file_id),
         }
     }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
index 5d75e445861..32c4ae2e869 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
@@ -56,14 +56,22 @@ pub(crate) fn convert_named_struct_to_tuple_struct(
     // XXX: We don't currently provide this assist for struct definitions inside macros, but if we
     // are to lift this limitation, don't forget to make `edit_struct_def()` consider macro files
     // too.
-    let name = ctx.find_node_at_offset::<ast::Name>()?;
-    let strukt = name.syntax().parent().and_then(<Either<ast::Struct, ast::Variant>>::cast)?;
-    let field_list = strukt.as_ref().either(|s| s.field_list(), |v| v.field_list())?;
+    let strukt_or_variant = ctx
+        .find_node_at_offset::<ast::Struct>()
+        .map(Either::Left)
+        .or_else(|| ctx.find_node_at_offset::<ast::Variant>().map(Either::Right))?;
+    let field_list = strukt_or_variant.as_ref().either(|s| s.field_list(), |v| v.field_list())?;
+
+    if ctx.offset() > field_list.syntax().text_range().start() {
+        // Assist could be distracting after the braces
+        return None;
+    }
+
     let record_fields = match field_list {
         ast::FieldList::RecordFieldList(it) => it,
         ast::FieldList::TupleFieldList(_) => return None,
     };
-    let strukt_def = match &strukt {
+    let strukt_def = match &strukt_or_variant {
         Either::Left(s) => Either::Left(ctx.sema.to_def(s)?),
         Either::Right(v) => Either::Right(ctx.sema.to_def(v)?),
     };
@@ -71,11 +79,11 @@ pub(crate) fn convert_named_struct_to_tuple_struct(
     acc.add(
         AssistId::refactor_rewrite("convert_named_struct_to_tuple_struct"),
         "Convert to tuple struct",
-        strukt.syntax().text_range(),
+        strukt_or_variant.syntax().text_range(),
         |edit| {
             edit_field_references(ctx, edit, record_fields.fields());
             edit_struct_references(ctx, edit, strukt_def);
-            edit_struct_def(ctx, edit, &strukt, record_fields);
+            edit_struct_def(ctx, edit, &strukt_or_variant, record_fields);
         },
     )
 }
@@ -294,6 +302,88 @@ impl A {
     }
 
     #[test]
+    fn convert_simple_struct_cursor_on_struct_keyword() {
+        check_assist(
+            convert_named_struct_to_tuple_struct,
+            r#"
+struct Inner;
+struct$0 A { inner: Inner }
+
+impl A {
+    fn new(inner: Inner) -> A {
+        A { inner }
+    }
+
+    fn new_with_default() -> A {
+        A::new(Inner)
+    }
+
+    fn into_inner(self) -> Inner {
+        self.inner
+    }
+}"#,
+            r#"
+struct Inner;
+struct A(Inner);
+
+impl A {
+    fn new(inner: Inner) -> A {
+        A(inner)
+    }
+
+    fn new_with_default() -> A {
+        A::new(Inner)
+    }
+
+    fn into_inner(self) -> Inner {
+        self.0
+    }
+}"#,
+        );
+    }
+
+    #[test]
+    fn convert_simple_struct_cursor_on_visibility_keyword() {
+        check_assist(
+            convert_named_struct_to_tuple_struct,
+            r#"
+struct Inner;
+pub$0 struct A { inner: Inner }
+
+impl A {
+    fn new(inner: Inner) -> A {
+        A { inner }
+    }
+
+    fn new_with_default() -> A {
+        A::new(Inner)
+    }
+
+    fn into_inner(self) -> Inner {
+        self.inner
+    }
+}"#,
+            r#"
+struct Inner;
+pub struct A(Inner);
+
+impl A {
+    fn new(inner: Inner) -> A {
+        A(inner)
+    }
+
+    fn new_with_default() -> A {
+        A::new(Inner)
+    }
+
+    fn into_inner(self) -> Inner {
+        self.0
+    }
+}"#,
+        );
+    }
+
+    #[test]
     fn convert_struct_referenced_via_self_kw() {
         check_assist(
             convert_named_struct_to_tuple_struct,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
index 0c0b93bcfbc..80756197fb7 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
@@ -51,18 +51,26 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
     acc: &mut Assists,
     ctx: &AssistContext<'_>,
 ) -> Option<()> {
-    let name = ctx.find_node_at_offset::<ast::Name>()?;
-    let strukt = name.syntax().parent().and_then(<Either<ast::Struct, ast::Variant>>::cast)?;
-    let field_list = strukt.as_ref().either(|s| s.field_list(), |v| v.field_list())?;
+    let strukt_or_variant = ctx
+        .find_node_at_offset::<ast::Struct>()
+        .map(Either::Left)
+        .or_else(|| ctx.find_node_at_offset::<ast::Variant>().map(Either::Right))?;
+    let field_list = strukt_or_variant.as_ref().either(|s| s.field_list(), |v| v.field_list())?;
+
+    if ctx.offset() > field_list.syntax().text_range().start() {
+        // Assist could be distracting after the braces
+        return None;
+    }
+
     let tuple_fields = match field_list {
         ast::FieldList::TupleFieldList(it) => it,
         ast::FieldList::RecordFieldList(_) => return None,
     };
-    let strukt_def = match &strukt {
+    let strukt_def = match &strukt_or_variant {
         Either::Left(s) => Either::Left(ctx.sema.to_def(s)?),
         Either::Right(v) => Either::Right(ctx.sema.to_def(v)?),
     };
-    let target = strukt.as_ref().either(|s| s.syntax(), |v| v.syntax()).text_range();
+    let target = strukt_or_variant.as_ref().either(|s| s.syntax(), |v| v.syntax()).text_range();
 
     acc.add(
         AssistId::refactor_rewrite("convert_tuple_struct_to_named_struct"),
@@ -72,7 +80,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
             let names = generate_names(tuple_fields.fields());
             edit_field_references(ctx, edit, tuple_fields.fields(), &names);
             edit_struct_references(ctx, edit, strukt_def, &names);
-            edit_struct_def(ctx, edit, &strukt, tuple_fields, names);
+            edit_struct_def(ctx, edit, &strukt_or_variant, tuple_fields, names);
         },
     )
 }
@@ -317,6 +325,88 @@ impl A {
     }
 
     #[test]
+    fn convert_simple_struct_cursor_on_struct_keyword() {
+        check_assist(
+            convert_tuple_struct_to_named_struct,
+            r#"
+struct Inner;
+struct$0 A(Inner);
+
+impl A {
+    fn new(inner: Inner) -> A {
+        A(inner)
+    }
+
+    fn new_with_default() -> A {
+        A::new(Inner)
+    }
+
+    fn into_inner(self) -> Inner {
+        self.0
+    }
+}"#,
+            r#"
+struct Inner;
+struct A { field1: Inner }
+
+impl A {
+    fn new(inner: Inner) -> A {
+        A { field1: inner }
+    }
+
+    fn new_with_default() -> A {
+        A::new(Inner)
+    }
+
+    fn into_inner(self) -> Inner {
+        self.field1
+    }
+}"#,
+        );
+    }
+
+    #[test]
+    fn convert_simple_struct_cursor_on_visibility_keyword() {
+        check_assist(
+            convert_tuple_struct_to_named_struct,
+            r#"
+struct Inner;
+pub$0 struct A(Inner);
+
+impl A {
+    fn new(inner: Inner) -> A {
+        A(inner)
+    }
+
+    fn new_with_default() -> A {
+        A::new(Inner)
+    }
+
+    fn into_inner(self) -> Inner {
+        self.0
+    }
+}"#,
+            r#"
+struct Inner;
+pub struct A { field1: Inner }
+
+impl A {
+    fn new(inner: Inner) -> A {
+        A { field1: inner }
+    }
+
+    fn new_with_default() -> A {
+        A::new(Inner)
+    }
+
+    fn into_inner(self) -> Inner {
+        self.field1
+    }
+}"#,
+        );
+    }
+
+    #[test]
     fn convert_struct_referenced_via_self_kw() {
         check_assist(
             convert_tuple_struct_to_named_struct,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs
index 19e0a73f333..3badc17d01a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs
@@ -7,10 +7,10 @@ use syntax::{
 
 use crate::{AssistContext, AssistId, Assists};
 
-// FIXME: this really should be a fix for diagnostic, rather than an assist.
-
 // Assist: fix_visibility
 //
+// Note that there is some duplication between this and the no_such_field diagnostic.
+//
 // Makes inaccessible item public.
 //
 // ```
@@ -32,7 +32,6 @@ use crate::{AssistContext, AssistId, Assists};
 // ```
 pub(crate) fn fix_visibility(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     add_vis_to_referenced_module_def(acc, ctx)
-        .or_else(|| add_vis_to_referenced_record_field(acc, ctx))
 }
 
 fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
@@ -88,59 +87,6 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
     })
 }
 
-fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    let record_field: ast::RecordExprField = ctx.find_node_at_offset()?;
-    let (record_field_def, _, _) = ctx.sema.resolve_record_field(&record_field)?;
-
-    let current_module = ctx.sema.scope(record_field.syntax())?.module();
-    let current_edition = current_module.krate().edition(ctx.db());
-    let visibility = record_field_def.visibility(ctx.db());
-    if visibility.is_visible_from(ctx.db(), current_module.into()) {
-        return None;
-    }
-
-    let parent = record_field_def.parent_def(ctx.db());
-    let parent_name = parent.name(ctx.db());
-    let target_module = parent.module(ctx.db());
-
-    let in_file_source = record_field_def.source(ctx.db())?;
-    let (vis_owner, target) = match in_file_source.value {
-        hir::FieldSource::Named(it) => {
-            let range = it.syntax().text_range();
-            (ast::AnyHasVisibility::new(it), range)
-        }
-        hir::FieldSource::Pos(it) => {
-            let range = it.syntax().text_range();
-            (ast::AnyHasVisibility::new(it), range)
-        }
-    };
-
-    let missing_visibility = if current_module.krate() == target_module.krate() {
-        make::visibility_pub_crate()
-    } else {
-        make::visibility_pub()
-    };
-    let target_file = in_file_source.file_id.original_file(ctx.db());
-
-    let target_name = record_field_def.name(ctx.db());
-    let assist_label = format!(
-        "Change visibility of {}.{} to {missing_visibility}",
-        parent_name.display(ctx.db(), current_edition),
-        target_name.display(ctx.db(), current_edition)
-    );
-
-    acc.add(AssistId::quick_fix("fix_visibility"), assist_label, target, |edit| {
-        edit.edit_file(target_file.file_id(ctx.db()));
-
-        let vis_owner = edit.make_mut(vis_owner);
-        vis_owner.set_visibility(Some(missing_visibility.clone_for_update()));
-
-        if let Some((cap, vis)) = ctx.config.snippet_cap.zip(vis_owner.visibility()) {
-            edit.add_tabstop_before(cap, vis);
-        }
-    })
-}
-
 fn target_data_for_def(
     db: &dyn HirDatabase,
     def: hir::ModuleDef,
@@ -294,44 +240,6 @@ struct Foo;
     }
 
     #[test]
-    fn fix_visibility_of_struct_field() {
-        check_assist(
-            fix_visibility,
-            r"mod foo { pub struct Foo { bar: (), } }
-              fn main() { foo::Foo { $0bar: () }; } ",
-            r"mod foo { pub struct Foo { $0pub(crate) bar: (), } }
-              fn main() { foo::Foo { bar: () }; } ",
-        );
-        check_assist(
-            fix_visibility,
-            r"
-//- /lib.rs
-mod foo;
-fn main() { foo::Foo { $0bar: () }; }
-//- /foo.rs
-pub struct Foo { bar: () }
-",
-            r"pub struct Foo { $0pub(crate) bar: () }
-",
-        );
-        check_assist_not_applicable(
-            fix_visibility,
-            r"mod foo { pub struct Foo { pub bar: (), } }
-              fn main() { foo::Foo { $0bar: () }; } ",
-        );
-        check_assist_not_applicable(
-            fix_visibility,
-            r"
-//- /lib.rs
-mod foo;
-fn main() { foo::Foo { $0bar: () }; }
-//- /foo.rs
-pub struct Foo { pub bar: () }
-",
-        );
-    }
-
-    #[test]
     fn fix_visibility_of_enum_variant_field() {
         // Enum variants, as well as their fields, always get the enum's visibility. In fact, rustc
         // rejects any visibility specifiers on them, so this assist should never fire on them.
@@ -368,44 +276,6 @@ pub struct Foo { pub bar: () }
     }
 
     #[test]
-    fn fix_visibility_of_union_field() {
-        check_assist(
-            fix_visibility,
-            r"mod foo { pub union Foo { bar: (), } }
-              fn main() { foo::Foo { $0bar: () }; } ",
-            r"mod foo { pub union Foo { $0pub(crate) bar: (), } }
-              fn main() { foo::Foo { bar: () }; } ",
-        );
-        check_assist(
-            fix_visibility,
-            r"
-//- /lib.rs
-mod foo;
-fn main() { foo::Foo { $0bar: () }; }
-//- /foo.rs
-pub union Foo { bar: () }
-",
-            r"pub union Foo { $0pub(crate) bar: () }
-",
-        );
-        check_assist_not_applicable(
-            fix_visibility,
-            r"mod foo { pub union Foo { pub bar: (), } }
-              fn main() { foo::Foo { $0bar: () }; } ",
-        );
-        check_assist_not_applicable(
-            fix_visibility,
-            r"
-//- /lib.rs
-mod foo;
-fn main() { foo::Foo { $0bar: () }; }
-//- /foo.rs
-pub union Foo { pub bar: () }
-",
-        );
-    }
-
-    #[test]
     fn fix_visibility_of_const() {
         check_assist(
             fix_visibility,
@@ -572,19 +442,6 @@ pub(crate) struct Bar;
             r"$0pub struct Bar;
 ",
         );
-        check_assist(
-            fix_visibility,
-            r"
-//- /main.rs crate:a deps:foo
-fn main() {
-    foo::Foo { $0bar: () };
-}
-//- /lib.rs crate:foo
-pub struct Foo { pub(crate) bar: () }
-",
-            r"pub struct Foo { $0pub bar: () }
-",
-        );
     }
 
     #[test]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs
index 912e1936b59..a8e27416d5c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs
@@ -1,6 +1,7 @@
 use ide_db::{
     assists::AssistId,
     defs::{Definition, NameClass, NameRefClass},
+    rename::RenameDefinition,
 };
 use syntax::{AstNode, ast};
 
@@ -61,7 +62,7 @@ pub(crate) fn remove_underscore(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
         "Remove underscore from a used variable",
         text_range,
         |builder| {
-            let changes = def.rename(&ctx.sema, new_name).unwrap();
+            let changes = def.rename(&ctx.sema, new_name, RenameDefinition::Yes).unwrap();
             builder.source_change = changes;
         },
     )
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs
index 3c195f80fea..705402c785a 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs
@@ -25,6 +25,7 @@ use crate::{
 
 mod cfg;
 mod derive;
+mod diagnostic;
 mod lint;
 mod macro_use;
 mod repr;
@@ -40,23 +41,22 @@ pub(crate) fn complete_known_attribute_input(
     extern_crate: Option<&ast::ExternCrate>,
 ) -> Option<()> {
     let attribute = fake_attribute_under_caret;
-    let name_ref = match attribute.path() {
-        Some(p) => Some(p.as_single_name_ref()?),
-        None => None,
-    };
-    let (path, tt) = name_ref.zip(attribute.token_tree())?;
-    tt.l_paren_token()?;
+    let path = attribute.path()?;
+    let segments = path.segments().map(|s| s.name_ref()).collect::<Option<Vec<_>>>()?;
+    let segments = segments.iter().map(|n| n.text()).collect::<Vec<_>>();
+    let segments = segments.iter().map(|t| t.as_str()).collect::<Vec<_>>();
+    let tt = attribute.token_tree()?;
 
-    match path.text().as_str() {
-        "repr" => repr::complete_repr(acc, ctx, tt),
-        "feature" => lint::complete_lint(
+    match segments.as_slice() {
+        ["repr"] => repr::complete_repr(acc, ctx, tt),
+        ["feature"] => lint::complete_lint(
             acc,
             ctx,
             colon_prefix,
             &parse_tt_as_comma_sep_paths(tt, ctx.edition)?,
             FEATURES,
         ),
-        "allow" | "expect" | "deny" | "forbid" | "warn" => {
+        ["allow"] | ["expect"] | ["deny"] | ["forbid"] | ["warn"] => {
             let existing_lints = parse_tt_as_comma_sep_paths(tt, ctx.edition)?;
 
             let lints: Vec<Lint> = CLIPPY_LINT_GROUPS
@@ -70,13 +70,14 @@ pub(crate) fn complete_known_attribute_input(
 
             lint::complete_lint(acc, ctx, colon_prefix, &existing_lints, &lints);
         }
-        "cfg" => cfg::complete_cfg(acc, ctx),
-        "macro_use" => macro_use::complete_macro_use(
+        ["cfg"] => cfg::complete_cfg(acc, ctx),
+        ["macro_use"] => macro_use::complete_macro_use(
             acc,
             ctx,
             extern_crate,
             &parse_tt_as_comma_sep_paths(tt, ctx.edition)?,
         ),
+        ["diagnostic", "on_unimplemented"] => diagnostic::complete_on_unimplemented(acc, ctx, tt),
         _ => (),
     }
     Some(())
@@ -139,6 +140,8 @@ pub(crate) fn complete_attribute_path(
         }
         Qualified::TypeAnchor { .. } | Qualified::With { .. } => {}
     }
+    let qualifier_path =
+        if let Qualified::With { path, .. } = qualified { Some(path) } else { None };
 
     let attributes = annotated_item_kind.and_then(|kind| {
         if ast::Expr::can_cast(kind) {
@@ -149,18 +152,33 @@ pub(crate) fn complete_attribute_path(
     });
 
     let add_completion = |attr_completion: &AttrCompletion| {
-        let mut item = CompletionItem::new(
-            SymbolKind::Attribute,
-            ctx.source_range(),
-            attr_completion.label,
-            ctx.edition,
-        );
+        // if we don't already have the qualifiers of the completion, then
+        // add the missing parts to the label and snippet
+        let mut label = attr_completion.label.to_owned();
+        let mut snippet = attr_completion.snippet.map(|s| s.to_owned());
+        let segments = qualifier_path.iter().flat_map(|q| q.segments()).collect::<Vec<_>>();
+        let qualifiers = attr_completion.qualifiers;
+        let matching_qualifiers = segments
+            .iter()
+            .zip(qualifiers)
+            .take_while(|(s, q)| s.name_ref().is_some_and(|t| t.text() == **q))
+            .count();
+        if matching_qualifiers != qualifiers.len() {
+            let prefix = qualifiers[matching_qualifiers..].join("::");
+            label = format!("{prefix}::{label}");
+            if let Some(s) = snippet.as_mut() {
+                *s = format!("{prefix}::{s}");
+            }
+        }
+
+        let mut item =
+            CompletionItem::new(SymbolKind::Attribute, ctx.source_range(), label, ctx.edition);
 
         if let Some(lookup) = attr_completion.lookup {
             item.lookup_by(lookup);
         }
 
-        if let Some((snippet, cap)) = attr_completion.snippet.zip(ctx.config.snippet_cap) {
+        if let Some((snippet, cap)) = snippet.zip(ctx.config.snippet_cap) {
             item.insert_snippet(cap, snippet);
         }
 
@@ -184,6 +202,7 @@ struct AttrCompletion {
     label: &'static str,
     lookup: Option<&'static str>,
     snippet: Option<&'static str>,
+    qualifiers: &'static [&'static str],
     prefer_inner: bool,
 }
 
@@ -192,6 +211,10 @@ impl AttrCompletion {
         self.lookup.unwrap_or(self.label)
     }
 
+    const fn qualifiers(self, qualifiers: &'static [&'static str]) -> AttrCompletion {
+        AttrCompletion { qualifiers, ..self }
+    }
+
     const fn prefer_inner(self) -> AttrCompletion {
         AttrCompletion { prefer_inner: true, ..self }
     }
@@ -202,7 +225,7 @@ const fn attr(
     lookup: Option<&'static str>,
     snippet: Option<&'static str>,
 ) -> AttrCompletion {
-    AttrCompletion { label, lookup, snippet, prefer_inner: false }
+    AttrCompletion { label, lookup, snippet, qualifiers: &[], prefer_inner: false }
 }
 
 macro_rules! attrs {
@@ -264,14 +287,14 @@ static KIND_TO_ATTRIBUTES: LazyLock<FxHashMap<SyntaxKind, &[&str]>> = LazyLock::
             FN,
             attrs!(
                 item, linkable,
-                "cold", "ignore", "inline", "must_use", "panic_handler", "proc_macro",
+                "cold", "ignore", "inline", "panic_handler", "proc_macro",
                 "proc_macro_derive", "proc_macro_attribute", "should_panic", "target_feature",
                 "test", "track_caller"
             ),
         ),
         (STATIC, attrs!(item, linkable, "global_allocator", "used")),
-        (TRAIT, attrs!(item, "must_use")),
-        (IMPL, attrs!(item, "automatically_derived")),
+        (TRAIT, attrs!(item, "diagnostic::on_unimplemented")),
+        (IMPL, attrs!(item, "automatically_derived", "diagnostic::do_not_recommend")),
         (ASSOC_ITEM_LIST, attrs!(item)),
         (EXTERN_BLOCK, attrs!(item, "link")),
         (EXTERN_ITEM_LIST, attrs!(item, "link")),
@@ -311,6 +334,14 @@ const ATTRIBUTES: &[AttrCompletion] = &[
     attr("deny(…)", Some("deny"), Some("deny(${0:lint})")),
     attr(r#"deprecated"#, Some("deprecated"), Some(r#"deprecated"#)),
     attr("derive(…)", Some("derive"), Some(r#"derive(${0:Debug})"#)),
+    attr("do_not_recommend", Some("diagnostic::do_not_recommend"), None)
+        .qualifiers(&["diagnostic"]),
+    attr(
+        "on_unimplemented",
+        Some("diagnostic::on_unimplemented"),
+        Some(r#"on_unimplemented(${0:keys})"#),
+    )
+    .qualifiers(&["diagnostic"]),
     attr(r#"doc = "…""#, Some("doc"), Some(r#"doc = "${0:docs}""#)),
     attr(r#"doc(alias = "…")"#, Some("docalias"), Some(r#"doc(alias = "${0:docs}")"#)),
     attr(r#"doc(hidden)"#, Some("dochidden"), Some(r#"doc(hidden)"#)),
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs
new file mode 100644
index 00000000000..8adc9742390
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs
@@ -0,0 +1,60 @@
+//! Completion for diagnostic attributes.
+
+use ide_db::SymbolKind;
+use syntax::ast;
+
+use crate::{CompletionItem, Completions, context::CompletionContext};
+
+use super::AttrCompletion;
+
+pub(super) fn complete_on_unimplemented(
+    acc: &mut Completions,
+    ctx: &CompletionContext<'_>,
+    input: ast::TokenTree,
+) {
+    if let Some(existing_keys) = super::parse_comma_sep_expr(input) {
+        for attr in ATTRIBUTE_ARGS {
+            let already_annotated = existing_keys
+                .iter()
+                .filter_map(|expr| match expr {
+                    ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
+                    ast::Expr::BinExpr(bin)
+                        if bin.op_kind() == Some(ast::BinaryOp::Assignment { op: None }) =>
+                    {
+                        match bin.lhs()? {
+                            ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
+                            _ => None,
+                        }
+                    }
+                    _ => None,
+                })
+                .any(|it| {
+                    let text = it.text();
+                    attr.key() == text && text != "note"
+                });
+            if already_annotated {
+                continue;
+            }
+
+            let mut item = CompletionItem::new(
+                SymbolKind::BuiltinAttr,
+                ctx.source_range(),
+                attr.label,
+                ctx.edition,
+            );
+            if let Some(lookup) = attr.lookup {
+                item.lookup_by(lookup);
+            }
+            if let Some((snippet, cap)) = attr.snippet.zip(ctx.config.snippet_cap) {
+                item.insert_snippet(cap, snippet);
+            }
+            item.add_to(acc, ctx.db);
+        }
+    }
+}
+
+const ATTRIBUTE_ARGS: &[AttrCompletion] = &[
+    super::attr(r#"label = "…""#, Some("label"), Some(r#"label = "${0:label}""#)),
+    super::attr(r#"message = "…""#, Some("message"), Some(r#"message = "${0:message}""#)),
+    super::attr(r#"note = "…""#, Some("note"), Some(r#"note = "${0:note}""#)),
+];
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs
index 32d3b50f237..411902f1117 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs
@@ -30,6 +30,8 @@ pub struct Foo(#[m$0] i32);
             at deprecated
             at derive                                  macro derive
             at derive(…)
+            at diagnostic::do_not_recommend
+            at diagnostic::on_unimplemented
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
@@ -472,13 +474,13 @@ fn attr_on_trait() {
             at cfg_attr(…)
             at deny(…)
             at deprecated
+            at diagnostic::on_unimplemented
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
             at expect(…)
             at forbid(…)
             at must_use
-            at must_use
             at no_mangle
             at warn(…)
             kw crate::
@@ -498,6 +500,7 @@ fn attr_on_impl() {
             at cfg_attr(…)
             at deny(…)
             at deprecated
+            at diagnostic::do_not_recommend
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
@@ -533,6 +536,76 @@ fn attr_on_impl() {
 }
 
 #[test]
+fn attr_with_qualifier() {
+    check(
+        r#"#[diagnostic::$0] impl () {}"#,
+        expect![[r#"
+            at allow(…)
+            at automatically_derived
+            at cfg(…)
+            at cfg_attr(…)
+            at deny(…)
+            at deprecated
+            at do_not_recommend
+            at doc = "…"
+            at doc(alias = "…")
+            at doc(hidden)
+            at expect(…)
+            at forbid(…)
+            at must_use
+            at no_mangle
+            at warn(…)
+        "#]],
+    );
+    check(
+        r#"#[diagnostic::$0] trait Foo {}"#,
+        expect![[r#"
+            at allow(…)
+            at cfg(…)
+            at cfg_attr(…)
+            at deny(…)
+            at deprecated
+            at doc = "…"
+            at doc(alias = "…")
+            at doc(hidden)
+            at expect(…)
+            at forbid(…)
+            at must_use
+            at no_mangle
+            at on_unimplemented
+            at warn(…)
+        "#]],
+    );
+}
+
+#[test]
+fn attr_diagnostic_on_unimplemented() {
+    check(
+        r#"#[diagnostic::on_unimplemented($0)] trait Foo {}"#,
+        expect![[r#"
+            ba label = "…"
+            ba message = "…"
+            ba note = "…"
+        "#]],
+    );
+    check(
+        r#"#[diagnostic::on_unimplemented(message = "foo", $0)] trait Foo {}"#,
+        expect![[r#"
+            ba label = "…"
+            ba note = "…"
+        "#]],
+    );
+    check(
+        r#"#[diagnostic::on_unimplemented(note = "foo", $0)] trait Foo {}"#,
+        expect![[r#"
+            ba label = "…"
+            ba message = "…"
+            ba note = "…"
+        "#]],
+    );
+}
+
+#[test]
 fn attr_on_extern_block() {
     check(
         r#"#[$0] extern {}"#,
@@ -619,7 +692,6 @@ fn attr_on_fn() {
             at link_name = "…"
             at link_section = "…"
             at must_use
-            at must_use
             at no_mangle
             at panic_handler
             at proc_macro
@@ -649,6 +721,8 @@ fn attr_in_source_file_end() {
             at deny(…)
             at deprecated
             at derive(…)
+            at diagnostic::do_not_recommend
+            at diagnostic::on_unimplemented
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
index f9ff3921266..de8a42979bb 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
@@ -4458,20 +4458,6 @@ The tracking issue for this feature is: [#133214]
         deny_since: None,
     },
     Lint {
-        label: "const_eq_ignore_ascii_case",
-        description: r##"# `const_eq_ignore_ascii_case`
-
-The tracking issue for this feature is: [#131719]
-
-[#131719]: https://github.com/rust-lang/rust/issues/131719
-
-------------------------
-"##,
-        default_severity: Severity::Allow,
-        warn_since: None,
-        deny_since: None,
-    },
-    Lint {
         label: "const_eval_select",
         description: r##"# `const_eval_select`
 
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
index fa2a46a0f7c..4e737e27f05 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
@@ -20,7 +20,7 @@
 //!
 //! The correct behavior in such cases is probably to show a dialog to the user.
 //! Our current behavior is ¯\_(ツ)_/¯.
-use std::fmt;
+use std::fmt::{self, Display};
 
 use crate::{
     source_change::ChangeAnnotation,
@@ -28,13 +28,12 @@ use crate::{
 };
 use base_db::AnchoredPathBuf;
 use either::Either;
-use hir::{EditionedFileId, FieldSource, FileRange, InFile, ModuleSource, Semantics};
+use hir::{FieldSource, FileRange, InFile, ModuleSource, Name, Semantics, sym};
 use span::{Edition, FileId, SyntaxContext};
 use stdx::{TupleExt, never};
 use syntax::{
     AstNode, SyntaxKind, T, TextRange,
     ast::{self, HasName},
-    utils::is_raw_identifier,
 };
 
 use crate::{
@@ -70,26 +69,33 @@ macro_rules! _bail {
 }
 pub use _bail as bail;
 
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum RenameDefinition {
+    Yes,
+    No,
+}
+
 impl Definition {
     pub fn rename(
         &self,
         sema: &Semantics<'_, RootDatabase>,
         new_name: &str,
+        rename_definition: RenameDefinition,
     ) -> Result<SourceChange> {
-        // We append `r#` if needed.
-        let new_name = new_name.trim_start_matches("r#");
-
         // self.krate() returns None if
         // self is a built-in attr, built-in type or tool module.
         // it is not allowed for these defs to be renamed.
         // cases where self.krate() is None is handled below.
-        if let Some(krate) = self.krate(sema.db) {
+        let edition = if let Some(krate) = self.krate(sema.db) {
             // Can we not rename non-local items?
             // Then bail if non-local
             if !krate.origin(sema.db).is_local() {
                 bail!("Cannot rename a non-local definition")
             }
-        }
+            krate.edition(sema.db)
+        } else {
+            Edition::LATEST
+        };
 
         match *self {
             Definition::Module(module) => rename_mod(sema, module, new_name),
@@ -103,8 +109,10 @@ impl Definition {
                 bail!("Cannot rename a builtin attr.")
             }
             Definition::SelfType(_) => bail!("Cannot rename `Self`"),
-            Definition::Macro(mac) => rename_reference(sema, Definition::Macro(mac), new_name),
-            def => rename_reference(sema, def, new_name),
+            Definition::Macro(mac) => {
+                rename_reference(sema, Definition::Macro(mac), new_name, rename_definition, edition)
+            }
+            def => rename_reference(sema, def, new_name, rename_definition, edition),
         }
     }
 
@@ -237,10 +245,6 @@ fn rename_mod(
     module: hir::Module,
     new_name: &str,
 ) -> Result<SourceChange> {
-    if IdentifierKind::classify(new_name)? != IdentifierKind::Ident {
-        bail!("Invalid name `{0}`: cannot rename module to {0}", new_name);
-    }
-
     let mut source_change = SourceChange::default();
 
     if module.is_crate_root() {
@@ -248,6 +252,14 @@ fn rename_mod(
     }
 
     let InFile { file_id, value: def_source } = module.definition_source(sema.db);
+    let edition = file_id.edition(sema.db);
+    let (new_name, kind) = IdentifierKind::classify(edition, new_name)?;
+    if kind != IdentifierKind::Ident {
+        bail!(
+            "Invalid name `{0}`: cannot rename module to {0}",
+            new_name.display(sema.db, edition)
+        );
+    }
     if let ModuleSource::SourceFile(..) = def_source {
         let anchor = file_id.original_file(sema.db).file_id(sema.db);
 
@@ -256,7 +268,7 @@ fn rename_mod(
 
         // Module exists in a named file
         if !is_mod_rs {
-            let path = format!("{new_name}.rs");
+            let path = format!("{}.rs", new_name.as_str());
             let dst = AnchoredPathBuf { anchor, path };
             source_change.push_file_system_edit(FileSystemEdit::MoveFile { src: anchor, dst })
         }
@@ -267,11 +279,11 @@ fn rename_mod(
         let dir_paths = match (is_mod_rs, has_detached_child, module.name(sema.db)) {
             // Go up one level since the anchor is inside the dir we're trying to rename
             (true, _, Some(mod_name)) => {
-                Some((format!("../{}", mod_name.as_str()), format!("../{new_name}")))
+                Some((format!("../{}", mod_name.as_str()), format!("../{}", new_name.as_str())))
             }
             // The anchor is on the same level as target dir
             (false, true, Some(mod_name)) => {
-                Some((mod_name.as_str().to_owned(), new_name.to_owned()))
+                Some((mod_name.as_str().to_owned(), new_name.as_str().to_owned()))
             }
             _ => None,
         };
@@ -296,11 +308,7 @@ fn rename_mod(
                     .original_file_range_opt(sema.db)
                     .map(TupleExt::head)
                 {
-                    let new_name = if is_raw_identifier(new_name, file_id.edition(sema.db)) {
-                        format!("r#{new_name}")
-                    } else {
-                        new_name.to_owned()
-                    };
+                    let new_name = new_name.display(sema.db, edition).to_string();
                     source_change.insert_source_edit(
                         file_id.file_id(sema.db),
                         TextEdit::replace(file_range.range, new_name),
@@ -314,9 +322,10 @@ fn rename_mod(
     let def = Definition::Module(module);
     let usages = def.usages(sema).all();
     let ref_edits = usages.iter().map(|(file_id, references)| {
+        let edition = file_id.edition(sema.db);
         (
             file_id.file_id(sema.db),
-            source_edit_from_references(references, def, new_name, file_id.edition(sema.db)),
+            source_edit_from_references(sema.db, references, def, &new_name, edition),
         )
     });
     source_change.extend(ref_edits);
@@ -328,8 +337,10 @@ fn rename_reference(
     sema: &Semantics<'_, RootDatabase>,
     def: Definition,
     new_name: &str,
+    rename_definition: RenameDefinition,
+    edition: Edition,
 ) -> Result<SourceChange> {
-    let ident_kind = IdentifierKind::classify(new_name)?;
+    let (mut new_name, ident_kind) = IdentifierKind::classify(edition, new_name)?;
 
     if matches!(
         def,
@@ -337,18 +348,34 @@ fn rename_reference(
     ) {
         match ident_kind {
             IdentifierKind::Underscore => {
-                bail!("Invalid name `{}`: not a lifetime identifier", new_name);
+                bail!(
+                    "Invalid name `{}`: not a lifetime identifier",
+                    new_name.display(sema.db, edition)
+                );
+            }
+            IdentifierKind::Ident => {
+                new_name = Name::new_lifetime(&format!("'{}", new_name.as_str()))
             }
-            _ => cov_mark::hit!(rename_lifetime),
+            IdentifierKind::Lifetime => (),
+            IdentifierKind::LowercaseSelf => bail!(
+                "Invalid name `{}`: not a lifetime identifier",
+                new_name.display(sema.db, edition)
+            ),
         }
     } else {
         match ident_kind {
             IdentifierKind::Lifetime => {
                 cov_mark::hit!(rename_not_an_ident_ref);
-                bail!("Invalid name `{}`: not an identifier", new_name);
+                bail!("Invalid name `{}`: not an identifier", new_name.display(sema.db, edition));
             }
             IdentifierKind::Ident => cov_mark::hit!(rename_non_local),
             IdentifierKind::Underscore => (),
+            IdentifierKind::LowercaseSelf => {
+                bail!(
+                    "Invalid name `{}`: cannot rename to `self`",
+                    new_name.display(sema.db, edition)
+                );
+            }
         }
     }
 
@@ -361,30 +388,29 @@ fn rename_reference(
     }
     let mut source_change = SourceChange::default();
     source_change.extend(usages.iter().map(|(file_id, references)| {
+        let edition = file_id.edition(sema.db);
         (
             file_id.file_id(sema.db),
-            source_edit_from_references(references, def, new_name, file_id.edition(sema.db)),
+            source_edit_from_references(sema.db, references, def, &new_name, edition),
         )
     }));
-
-    // This needs to come after the references edits, because we change the annotation of existing edits
-    // if a conflict is detected.
-    let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?;
-    source_change.insert_source_edit(file_id, edit);
+    if rename_definition == RenameDefinition::Yes {
+        // This needs to come after the references edits, because we change the annotation of existing edits
+        // if a conflict is detected.
+        let (file_id, edit) = source_edit_from_def(sema, def, &new_name, &mut source_change)?;
+        source_change.insert_source_edit(file_id, edit);
+    }
     Ok(source_change)
 }
 
 pub fn source_edit_from_references(
+    db: &RootDatabase,
     references: &[FileReference],
     def: Definition,
-    new_name: &str,
+    new_name: &Name,
     edition: Edition,
 ) -> TextEdit {
-    let new_name = if is_raw_identifier(new_name, edition) {
-        format!("r#{new_name}")
-    } else {
-        new_name.to_owned()
-    };
+    let name_display = new_name.display(db, edition);
     let mut edit = TextEdit::builder();
     // macros can cause multiple refs to occur for the same text range, so keep track of what we have edited so far
     let mut edited_ranges = Vec::new();
@@ -395,23 +421,15 @@ pub fn source_edit_from_references(
             // to make special rewrites like shorthand syntax and such, so just rename the node in
             // the macro input
             FileReferenceNode::NameRef(name_ref) if name_range == range => {
-                source_edit_from_name_ref(&mut edit, name_ref, &new_name, def)
+                source_edit_from_name_ref(&mut edit, name_ref, &name_display, def)
             }
             FileReferenceNode::Name(name) if name_range == range => {
-                source_edit_from_name(&mut edit, name, &new_name)
+                source_edit_from_name(&mut edit, name, &name_display)
             }
             _ => false,
         };
         if !has_emitted_edit && !edited_ranges.contains(&range.start()) {
-            let (range, new_name) = match name {
-                FileReferenceNode::Lifetime(_) => (
-                    TextRange::new(range.start() + syntax::TextSize::from(1), range.end()),
-                    new_name.strip_prefix('\'').unwrap_or(&new_name).to_owned(),
-                ),
-                _ => (range, new_name.to_owned()),
-            };
-
-            edit.replace(range, new_name);
+            edit.replace(range, name_display.to_string());
             edited_ranges.push(range.start());
         }
     }
@@ -419,7 +437,11 @@ pub fn source_edit_from_references(
     edit.finish()
 }
 
-fn source_edit_from_name(edit: &mut TextEditBuilder, name: &ast::Name, new_name: &str) -> bool {
+fn source_edit_from_name(
+    edit: &mut TextEditBuilder,
+    name: &ast::Name,
+    new_name: &dyn Display,
+) -> bool {
     if ast::RecordPatField::for_field_name(name).is_some() {
         if let Some(ident_pat) = name.syntax().parent().and_then(ast::IdentPat::cast) {
             cov_mark::hit!(rename_record_pat_field_name_split);
@@ -439,7 +461,7 @@ fn source_edit_from_name(edit: &mut TextEditBuilder, name: &ast::Name, new_name:
 fn source_edit_from_name_ref(
     edit: &mut TextEditBuilder,
     name_ref: &ast::NameRef,
-    new_name: &str,
+    new_name: &dyn Display,
     def: Definition,
 ) -> bool {
     if name_ref.super_token().is_some() {
@@ -452,6 +474,7 @@ fn source_edit_from_name_ref(
         match &(rcf_name_ref, rcf_expr.and_then(|it| expr_as_name_ref(&it))) {
             // field: init-expr, check if we can use a field init shorthand
             (Some(field_name), Some(init)) => {
+                let new_name = new_name.to_string();
                 if field_name == name_ref {
                     if init.text() == new_name {
                         cov_mark::hit!(test_rename_field_put_init_shorthand);
@@ -507,6 +530,7 @@ fn source_edit_from_name_ref(
             {
                 // field name is being renamed
                 if let Some(name) = pat.name() {
+                    let new_name = new_name.to_string();
                     if name.text() == new_name {
                         cov_mark::hit!(test_rename_field_put_init_shorthand_pat);
                         // Foo { field: ref mut local } -> Foo { ref mut field }
@@ -518,7 +542,7 @@ fn source_edit_from_name_ref(
                         let s = field_name.syntax().text_range().start();
                         let e = pat.syntax().text_range().start();
                         edit.delete(TextRange::new(s, e));
-                        edit.replace(name.syntax().text_range(), new_name.to_owned());
+                        edit.replace(name.syntax().text_range(), new_name);
                         return true;
                     }
                 }
@@ -532,16 +556,9 @@ fn source_edit_from_name_ref(
 fn source_edit_from_def(
     sema: &Semantics<'_, RootDatabase>,
     def: Definition,
-    new_name: &str,
+    new_name: &Name,
     source_change: &mut SourceChange,
 ) -> Result<(FileId, TextEdit)> {
-    let new_name_edition_aware = |new_name: &str, file_id: EditionedFileId| {
-        if is_raw_identifier(new_name, file_id.edition(sema.db)) {
-            format!("r#{new_name}")
-        } else {
-            new_name.to_owned()
-        }
-    };
     let mut edit = TextEdit::builder();
     if let Definition::Local(local) = def {
         let mut file_id = None;
@@ -573,7 +590,10 @@ fn source_edit_from_def(
                 {
                     Some(FileRange { file_id: file_id2, range }) => {
                         file_id = Some(file_id2);
-                        edit.replace(range, new_name_edition_aware(new_name, file_id2));
+                        edit.replace(
+                            range,
+                            new_name.display(sema.db, file_id2.edition(sema.db)).to_string(),
+                        );
                         continue;
                     }
                     None => {
@@ -587,7 +607,7 @@ fn source_edit_from_def(
                 // special cases required for renaming fields/locals in Record patterns
                 if let Some(pat_field) = pat.syntax().parent().and_then(ast::RecordPatField::cast) {
                     if let Some(name_ref) = pat_field.name_ref() {
-                        if new_name == name_ref.text().as_str().trim_start_matches("r#")
+                        if new_name.as_str() == name_ref.text().as_str().trim_start_matches("r#")
                             && pat.at_token().is_none()
                         {
                             // Foo { field: ref mut local } -> Foo { ref mut field }
@@ -607,7 +627,9 @@ fn source_edit_from_def(
                             //                      ^^^^^ replace this with `new_name`
                             edit.replace(
                                 name_range,
-                                new_name_edition_aware(new_name, source.file_id),
+                                new_name
+                                    .display(sema.db, source.file_id.edition(sema.db))
+                                    .to_string(),
                             );
                         }
                     } else {
@@ -618,10 +640,16 @@ fn source_edit_from_def(
                             pat.syntax().text_range().start(),
                             format!("{}: ", pat_field.field_name().unwrap()),
                         );
-                        edit.replace(name_range, new_name_edition_aware(new_name, source.file_id));
+                        edit.replace(
+                            name_range,
+                            new_name.display(sema.db, source.file_id.edition(sema.db)).to_string(),
+                        );
                     }
                 } else {
-                    edit.replace(name_range, new_name_edition_aware(new_name, source.file_id));
+                    edit.replace(
+                        name_range,
+                        new_name.display(sema.db, source.file_id.edition(sema.db)).to_string(),
+                    );
                 }
             }
         }
@@ -639,16 +667,13 @@ fn source_edit_from_def(
         .range_for_rename(sema)
         .ok_or_else(|| format_err!("No identifier available to rename"))?;
     let (range, new_name) = match def {
-        Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) | Definition::Label(_) => (
-            TextRange::new(range.start() + syntax::TextSize::from(1), range.end()),
-            new_name.strip_prefix('\'').unwrap_or(new_name).to_owned(),
+        Definition::ExternCrateDecl(decl) if decl.alias(sema.db).is_none() => (
+            TextRange::empty(range.end()),
+            format!(" as {}", new_name.display(sema.db, file_id.edition(sema.db)),),
         ),
-        Definition::ExternCrateDecl(decl) if decl.alias(sema.db).is_none() => {
-            (TextRange::empty(range.end()), format!(" as {new_name}"))
-        }
-        _ => (range, new_name.to_owned()),
+        _ => (range, new_name.display(sema.db, file_id.edition(sema.db)).to_string()),
     };
-    edit.replace(range, new_name_edition_aware(&new_name, file_id));
+    edit.replace(range, new_name);
     Ok((file_id.file_id(sema.db), edit.finish()))
 }
 
@@ -657,26 +682,27 @@ pub enum IdentifierKind {
     Ident,
     Lifetime,
     Underscore,
+    LowercaseSelf,
 }
 
 impl IdentifierKind {
-    pub fn classify(new_name: &str) -> Result<IdentifierKind> {
-        let new_name = new_name.trim_start_matches("r#");
-        match parser::LexedStr::single_token(Edition::LATEST, new_name) {
+    pub fn classify(edition: Edition, new_name: &str) -> Result<(Name, IdentifierKind)> {
+        match parser::LexedStr::single_token(edition, new_name) {
             Some(res) => match res {
-                (SyntaxKind::IDENT, _) => {
-                    if let Some(inner) = new_name.strip_prefix("r#") {
-                        if matches!(inner, "self" | "crate" | "super" | "Self") {
-                            bail!("Invalid name: `{}` cannot be a raw identifier", inner);
-                        }
-                    }
-                    Ok(IdentifierKind::Ident)
+                (SyntaxKind::IDENT, _) => Ok((Name::new_root(new_name), IdentifierKind::Ident)),
+                (T![_], _) => {
+                    Ok((Name::new_symbol_root(sym::underscore), IdentifierKind::Underscore))
                 }
-                (T![_], _) => Ok(IdentifierKind::Underscore),
                 (SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => {
-                    Ok(IdentifierKind::Lifetime)
+                    Ok((Name::new_lifetime(new_name), IdentifierKind::Lifetime))
                 }
-                _ if is_raw_identifier(new_name, Edition::LATEST) => Ok(IdentifierKind::Ident),
+                _ if SyntaxKind::from_keyword(new_name, edition).is_some() => match new_name {
+                    "self" => Ok((Name::new_root(new_name), IdentifierKind::LowercaseSelf)),
+                    "crate" | "super" | "Self" => {
+                        bail!("Invalid name `{}`: cannot rename to a keyword", new_name)
+                    }
+                    _ => Ok((Name::new_root(new_name), IdentifierKind::Ident)),
+                },
                 (_, Some(syntax_error)) => bail!("Invalid name `{}`: {}", new_name, syntax_error),
                 (_, None) => bail!("Invalid name `{}`: not an identifier", new_name),
             },
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs
index 38f10c778d6..519ff192799 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs
@@ -1,5 +1,5 @@
 use hir::{CaseType, InFile, db::ExpandDatabase};
-use ide_db::{assists::Assist, defs::NameClass};
+use ide_db::{assists::Assist, defs::NameClass, rename::RenameDefinition};
 use syntax::AstNode;
 
 use crate::{
@@ -44,7 +44,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Option<Vec<Ass
     let label = format!("Rename to {}", d.suggested_text);
     let mut res = unresolved_fix("change_case", &label, frange.range);
     if ctx.resolve.should_resolve(&res.id) {
-        let source_change = def.rename(&ctx.sema, &d.suggested_text);
+        let source_change = def.rename(&ctx.sema, &d.suggested_text, RenameDefinition::Yes);
         res.source_change = Some(source_change.ok().unwrap_or_default());
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
index 87c9397fb77..bf7dddacd8c 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
@@ -135,6 +135,7 @@ pub(crate) fn json_in_items(
                         "JSON syntax is not valid as a Rust item",
                         FileRange { file_id: vfs_file_id, range },
                     )
+                    .stable()
                     .with_fixes(Some(vec![{
                         let mut scb = SourceChangeBuilder::new(vfs_file_id);
                         let scope = scb.make_import_scope_mut(import_scope);
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
index 84fb467a5ce..ef42f2dc744 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
@@ -1,4 +1,5 @@
 use either::Either;
+use hir::{Field, HasCrate};
 use hir::{HasSource, HirDisplay, Semantics, VariantId, db::ExpandDatabase};
 use ide_db::text_edit::TextEdit;
 use ide_db::{EditionedFileId, RootDatabase, source_change::SourceChange};
@@ -13,44 +14,69 @@ use crate::{Assist, Diagnostic, DiagnosticCode, DiagnosticsContext, fix};
 //
 // This diagnostic is triggered if created structure does not have field provided in record.
 pub(crate) fn no_such_field(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Diagnostic {
-    let node = d.field.map(Into::into);
-    if d.private {
-        // FIXME: quickfix to add required visibility
-        Diagnostic::new_with_syntax_node_ptr(
-            ctx,
-            DiagnosticCode::RustcHardError("E0451"),
-            "field is private",
-            node,
-        )
-        .stable()
+    let (code, message) = if d.private.is_some() {
+        ("E0451", "field is private")
+    } else if let VariantId::EnumVariantId(_) = d.variant {
+        ("E0559", "no such field")
     } else {
-        Diagnostic::new_with_syntax_node_ptr(
-            ctx,
-            match d.variant {
-                VariantId::EnumVariantId(_) => DiagnosticCode::RustcHardError("E0559"),
-                _ => DiagnosticCode::RustcHardError("E0560"),
-            },
-            "no such field",
-            node,
-        )
+        ("E0560", "no such field")
+    };
+
+    let node = d.field.map(Into::into);
+    Diagnostic::new_with_syntax_node_ptr(ctx, DiagnosticCode::RustcHardError(code), message, node)
         .stable()
         .with_fixes(fixes(ctx, d))
-    }
 }
 
 fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Option<Vec<Assist>> {
     // FIXME: quickfix for pattern
     let root = ctx.sema.db.parse_or_expand(d.field.file_id);
     match &d.field.value.to_node(&root) {
-        Either::Left(node) => missing_record_expr_field_fixes(
-            &ctx.sema,
-            d.field.file_id.original_file(ctx.sema.db),
-            node,
-        ),
+        Either::Left(node) => {
+            if let Some(private_field) = d.private {
+                field_is_private_fixes(
+                    &ctx.sema,
+                    d.field.file_id.original_file(ctx.sema.db),
+                    node,
+                    private_field,
+                )
+            } else {
+                missing_record_expr_field_fixes(
+                    &ctx.sema,
+                    d.field.file_id.original_file(ctx.sema.db),
+                    node,
+                )
+            }
+        }
         _ => None,
     }
 }
 
+fn field_is_private_fixes(
+    sema: &Semantics<'_, RootDatabase>,
+    usage_file_id: EditionedFileId,
+    record_expr_field: &ast::RecordExprField,
+    private_field: Field,
+) -> Option<Vec<Assist>> {
+    let def_crate = private_field.krate(sema.db);
+    let usage_crate = sema.file_to_module_def(usage_file_id.file_id(sema.db))?.krate();
+    let visibility = if usage_crate == def_crate { "pub(crate) " } else { "pub " };
+
+    let source = private_field.source(sema.db)?;
+    let (range, _) = source.syntax().original_file_range_opt(sema.db)?;
+    let source_change = SourceChange::from_text_edit(
+        range.file_id.file_id(sema.db),
+        TextEdit::insert(range.range.start(), visibility.into()),
+    );
+
+    Some(vec![fix(
+        "increase_field_visibility",
+        "Increase field visibility",
+        source_change,
+        sema.original_range(record_expr_field.syntax()).range,
+    )])
+}
+
 fn missing_record_expr_field_fixes(
     sema: &Semantics<'_, RootDatabase>,
     usage_file_id: EditionedFileId,
@@ -118,7 +144,7 @@ fn missing_record_expr_field_fixes(
         "create_field",
         "Create field",
         source_change,
-        record_expr_field.syntax().text_range(),
+        sema.original_range(record_expr_field.syntax()).range,
     )]);
 
     fn record_field_list(field_def_list: ast::FieldList) -> Option<ast::RecordFieldList> {
@@ -387,15 +413,15 @@ fn f(s@m::Struct {
     // assignee expression
     m::Struct {
         field: 0,
-      //^^^^^^^^ error: field is private
+      //^^^^^^^^ 💡 error: field is private
         field2
-      //^^^^^^ error: field is private
+      //^^^^^^ 💡 error: field is private
     } = s;
     m::Struct {
         field: 0,
-      //^^^^^^^^ error: field is private
+      //^^^^^^^^ 💡 error: field is private
         field2
-      //^^^^^^ error: field is private
+      //^^^^^^ 💡 error: field is private
     };
 }
 "#,
@@ -403,6 +429,77 @@ fn f(s@m::Struct {
     }
 
     #[test]
+    fn test_struct_field_private_same_crate_fix() {
+        check_diagnostics(
+            r#"
+mod m {
+    pub struct Struct {
+        field: u32,
+    }
+}
+fn f() {
+    let _ = m::Struct {
+        field: 0,
+      //^^^^^^^^ 💡 error: field is private
+    };
+}
+"#,
+        );
+
+        check_fix(
+            r#"
+mod m {
+    pub struct Struct {
+        field: u32,
+    }
+}
+fn f() {
+    let _ = m::Struct {
+        field$0: 0,
+    };
+}
+"#,
+            r#"
+mod m {
+    pub struct Struct {
+        pub(crate) field: u32,
+    }
+}
+fn f() {
+    let _ = m::Struct {
+        field: 0,
+    };
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn test_struct_field_private_other_crate_fix() {
+        check_fix(
+            r#"
+//- /lib.rs crate:another_crate
+pub struct Struct {
+    field: u32,
+}
+//- /lib.rs crate:this_crate deps:another_crate
+use another_crate;
+
+fn f() {
+    let _ = another_crate::Struct {
+        field$0: 0,
+    };
+}
+"#,
+            r#"
+pub struct Struct {
+    pub field: u32,
+}
+"#,
+        );
+    }
+
+    #[test]
     fn editions_between_macros() {
         check_diagnostics(
             r#"
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs
index af9126c8933..d96c658d7b0 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs
@@ -69,6 +69,7 @@ pub(crate) fn unlinked_file(
             FileRange { file_id, range },
         )
         .with_unused(unused)
+        .stable()
         .with_fixes(fixes),
     );
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
index 7c396339c14..f31886b9697 100644
--- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
@@ -800,4 +800,65 @@ foo();
                 foo();"#]],
         );
     }
+
+    #[test]
+    fn works_in_sig() {
+        check(
+            r#"
+macro_rules! foo {
+    () => { u32 };
+}
+fn foo() -> foo$0!() {
+    42
+}
+"#,
+            expect![[r#"
+                foo!
+                u32"#]],
+        );
+        check(
+            r#"
+macro_rules! foo {
+    () => { u32 };
+}
+fn foo(_: foo$0!() ) {}
+"#,
+            expect![[r#"
+                foo!
+                u32"#]],
+        );
+    }
+
+    #[test]
+    fn works_in_generics() {
+        check(
+            r#"
+trait Trait {}
+macro_rules! foo {
+    () => { Trait };
+}
+impl<const C: foo$0!()> Trait for () {}
+"#,
+            expect![[r#"
+                foo!
+                Trait"#]],
+        );
+    }
+
+    #[test]
+    fn works_in_fields() {
+        check(
+            r#"
+macro_rules! foo {
+    () => { u32 };
+}
+struct S {
+    field: foo$0!(),
+}
+"#,
+            expect![[r#"
+                foo!
+                u32"#]],
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
index 82704af647d..b094b098462 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
@@ -6,7 +6,7 @@ use std::{
 use either::Either;
 use hir::{
     ClosureStyle, DisplayTarget, EditionedFileId, HasVisibility, HirDisplay, HirDisplayError,
-    HirWrite, ModuleDef, ModuleDefId, Semantics, sym,
+    HirWrite, InRealFile, ModuleDef, ModuleDefId, Semantics, sym,
 };
 use ide_db::{FileRange, RootDatabase, famous_defs::FamousDefs, text_edit::TextEditBuilder};
 use ide_db::{FxHashSet, text_edit::TextEdit};
@@ -34,6 +34,7 @@ mod extern_block;
 mod generic_param;
 mod implicit_drop;
 mod implicit_static;
+mod implied_dyn_trait;
 mod lifetime;
 mod param_name;
 mod range_exclusive;
@@ -95,16 +96,16 @@ pub(crate) fn inlay_hints(
         return acc;
     };
     let famous_defs = FamousDefs(&sema, scope.krate());
+    let display_target = famous_defs.1.to_display_target(sema.db);
 
     let ctx = &mut InlayHintCtx::default();
     let mut hints = |event| {
         if let Some(node) = handle_event(ctx, event) {
-            hints(&mut acc, ctx, &famous_defs, config, file_id, node);
+            hints(&mut acc, ctx, &famous_defs, config, file_id, display_target, node);
         }
     };
     let mut preorder = file.preorder();
     while let Some(event) = preorder.next() {
-        // FIXME: This can miss some hints that require the parent of the range to calculate
         if matches!((&event, range_limit), (WalkEvent::Enter(node), Some(range)) if range.intersect(node.text_range()).is_none())
         {
             preorder.skip_subtree();
@@ -144,10 +145,12 @@ pub(crate) fn inlay_hints_resolve(
     let famous_defs = FamousDefs(&sema, scope.krate());
     let mut acc = Vec::new();
 
+    let display_target = famous_defs.1.to_display_target(sema.db);
+
     let ctx = &mut InlayHintCtx::default();
     let mut hints = |event| {
         if let Some(node) = handle_event(ctx, event) {
-            hints(&mut acc, ctx, &famous_defs, config, file_id, node);
+            hints(&mut acc, ctx, &famous_defs, config, file_id, display_target, node);
         }
     };
 
@@ -202,17 +205,19 @@ fn handle_event(ctx: &mut InlayHintCtx, node: WalkEvent<SyntaxNode>) -> Option<S
 fn hints(
     hints: &mut Vec<InlayHint>,
     ctx: &mut InlayHintCtx,
-    famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>,
+    famous_defs @ FamousDefs(sema, _krate): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
     file_id: EditionedFileId,
+    display_target: DisplayTarget,
     node: SyntaxNode,
 ) {
-    let file_id = file_id.editioned_file_id(sema.db);
-    let Some(krate) = sema.first_crate(file_id.file_id()) else {
-        return;
-    };
-    let display_target = krate.to_display_target(sema.db);
-    closing_brace::hints(hints, sema, config, file_id, display_target, node.clone());
+    closing_brace::hints(
+        hints,
+        sema,
+        config,
+        display_target,
+        InRealFile { file_id, value: node.clone() },
+    );
     if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) {
         generic_param::hints(hints, famous_defs, config, any_has_generic_args);
     }
@@ -231,18 +236,18 @@ fn hints(
                         closure_captures::hints(hints, famous_defs, config, it.clone());
                         closure_ret::hints(hints, famous_defs, config, display_target, it)
                     },
-                    ast::Expr::RangeExpr(it) => range_exclusive::hints(hints, famous_defs, config, file_id,  it),
+                    ast::Expr::RangeExpr(it) => range_exclusive::hints(hints, famous_defs, config, it),
                     _ => Some(()),
                 }
             },
             ast::Pat(it) => {
-                binding_mode::hints(hints, famous_defs, config, file_id,  &it);
+                binding_mode::hints(hints, famous_defs, config, &it);
                 match it {
                     ast::Pat::IdentPat(it) => {
                         bind_pat::hints(hints, famous_defs, config, display_target, &it);
                     }
                     ast::Pat::RangePat(it) => {
-                        range_exclusive::hints(hints, famous_defs, config, file_id, it);
+                        range_exclusive::hints(hints, famous_defs, config, it);
                     }
                     _ => {}
                 }
@@ -250,30 +255,38 @@ fn hints(
             },
             ast::Item(it) => match it {
                 ast::Item::Fn(it) => {
-                    implicit_drop::hints(hints, famous_defs, config, file_id, &it);
+                    implicit_drop::hints(hints, famous_defs, config, display_target, &it);
                     if let Some(extern_block) = &ctx.extern_block_parent {
-                        extern_block::fn_hints(hints, famous_defs, config, file_id, &it, extern_block);
+                        extern_block::fn_hints(hints, famous_defs, config, &it, extern_block);
                     }
-                    lifetime::fn_hints(hints, ctx, famous_defs, config, file_id, it)
+                    lifetime::fn_hints(hints, ctx, famous_defs, config,  it)
                 },
                 ast::Item::Static(it) => {
                     if let Some(extern_block) = &ctx.extern_block_parent {
-                        extern_block::static_hints(hints, famous_defs, config, file_id, &it, extern_block);
+                        extern_block::static_hints(hints, famous_defs, config, &it, extern_block);
                     }
-                    implicit_static::hints(hints, famous_defs, config, file_id, Either::Left(it))
+                    implicit_static::hints(hints, famous_defs, config,  Either::Left(it))
                 },
-                ast::Item::Const(it) => implicit_static::hints(hints, famous_defs, config, file_id, Either::Right(it)),
-                ast::Item::Enum(it) => discriminant::enum_hints(hints, famous_defs, config, file_id, it),
-                ast::Item::ExternBlock(it) => extern_block::extern_block_hints(hints, famous_defs, config, file_id, it),
+                ast::Item::Const(it) => implicit_static::hints(hints, famous_defs, config, Either::Right(it)),
+                ast::Item::Enum(it) => discriminant::enum_hints(hints, famous_defs, config, it),
+                ast::Item::ExternBlock(it) => extern_block::extern_block_hints(hints, famous_defs, config, it),
                 _ => None,
             },
             // FIXME: trait object type elisions
             ast::Type(ty) => match ty {
-                ast::Type::FnPtrType(ptr) => lifetime::fn_ptr_hints(hints, ctx, famous_defs, config, file_id, ptr),
-                ast::Type::PathType(path) => lifetime::fn_path_hints(hints, ctx, famous_defs, config, file_id, path),
+                ast::Type::FnPtrType(ptr) => lifetime::fn_ptr_hints(hints, ctx, famous_defs, config,  ptr),
+                ast::Type::PathType(path) => {
+                    lifetime::fn_path_hints(hints, ctx, famous_defs, config, &path);
+                    implied_dyn_trait::hints(hints, famous_defs, config, Either::Left(path));
+                    Some(())
+                },
+                ast::Type::DynTraitType(dyn_) => {
+                    implied_dyn_trait::hints(hints, famous_defs, config, Either::Right(dyn_));
+                    Some(())
+                },
                 _ => Some(()),
             },
-            ast::GenericParamList(it) => bounds::hints(hints, famous_defs, config, file_id, it),
+            ast::GenericParamList(it) => bounds::hints(hints, famous_defs, config,  it),
             _ => Some(()),
         }
     };
@@ -438,6 +451,7 @@ pub enum InlayKind {
     Parameter,
     GenericParameter,
     Type,
+    Dyn,
     Drop,
     RangeExclusive,
     ExternUnsafety,
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs
index d2917320688..169ab92342b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs
@@ -8,7 +8,6 @@ use hir::Mutability;
 use ide_db::famous_defs::FamousDefs;
 
 use ide_db::text_edit::TextEditBuilder;
-use span::EditionedFileId;
 use syntax::ast::{self, AstNode};
 
 use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind};
@@ -17,7 +16,6 @@ pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
     FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    _file_id: EditionedFileId,
     pat: &ast::Pat,
 ) -> Option<()> {
     if !config.binding_mode_hints {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs
index 8ddbfaeffe8..b9a98f88be7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs
@@ -3,7 +3,6 @@
 //! Currently this renders the implied `Sized` bound.
 use ide_db::{FileRange, famous_defs::FamousDefs};
 
-use span::EditionedFileId;
 use syntax::ast::{self, AstNode, HasTypeBounds};
 
 use crate::{
@@ -15,7 +14,6 @@ pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
     famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    _file_id: EditionedFileId,
     params: ast::GenericParamList,
 ) -> Option<()> {
     if !config.sized_bound {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
index 2ec85da4a42..ca3a982760f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
@@ -3,9 +3,8 @@
 //! fn g() {
 //! } /* fn g */
 //! ```
-use hir::{DisplayTarget, HirDisplay, Semantics};
+use hir::{DisplayTarget, HirDisplay, InRealFile, Semantics};
 use ide_db::{FileRange, RootDatabase};
-use span::EditionedFileId;
 use syntax::{
     SyntaxKind, SyntaxNode, T,
     ast::{self, AstNode, HasLoopBody, HasName},
@@ -21,15 +20,14 @@ pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
     sema: &Semantics<'_, RootDatabase>,
     config: &InlayHintsConfig,
-    file_id: EditionedFileId,
     display_target: DisplayTarget,
-    original_node: SyntaxNode,
+    InRealFile { file_id, value: node }: InRealFile<SyntaxNode>,
 ) -> Option<()> {
     let min_lines = config.closing_brace_hints_min_lines?;
 
     let name = |it: ast::Name| it.syntax().text_range();
 
-    let mut node = original_node.clone();
+    let mut node = node.clone();
     let mut closing_token;
     let (label, name_range) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) {
         closing_token = item_list.r_curly_token()?;
@@ -44,7 +42,7 @@ pub(super) fn hints(
                     let hint_text = match trait_ {
                         Some(tr) => format!(
                             "impl {} for {}",
-                            tr.name(sema.db).display(sema.db, file_id.edition()),
+                            tr.name(sema.db).display(sema.db, display_target.edition),
                             ty.display_truncated(sema.db, config.max_length, display_target,
                         )),
                         None => format!("impl {}", ty.display_truncated(sema.db, config.max_length, display_target)),
@@ -142,7 +140,8 @@ pub(super) fn hints(
         return None;
     }
 
-    let linked_location = name_range.map(|range| FileRange { file_id: file_id.into(), range });
+    let linked_location =
+        name_range.map(|range| FileRange { file_id: file_id.file_id(sema.db), range });
     acc.push(InlayHint {
         range: closing_token.text_range(),
         kind: InlayKind::ClosingBrace,
@@ -151,7 +150,7 @@ pub(super) fn hints(
         position: InlayHintPosition::After,
         pad_left: true,
         pad_right: false,
-        resolve_parent: Some(original_node.text_range()),
+        resolve_parent: Some(node.text_range()),
     });
 
     None
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs
index 827a0438dd0..a2a702835a7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs
@@ -7,7 +7,6 @@
 use hir::Semantics;
 use ide_db::text_edit::TextEdit;
 use ide_db::{RootDatabase, famous_defs::FamousDefs};
-use span::EditionedFileId;
 use syntax::ast::{self, AstNode, HasName};
 
 use crate::{
@@ -19,7 +18,6 @@ pub(super) fn enum_hints(
     acc: &mut Vec<InlayHint>,
     FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    _: EditionedFileId,
     enum_: ast::Enum,
 ) -> Option<()> {
     if let DiscriminantHints::Never = config.discriminant_hints {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs
index 20f54b2cd19..88152bf3e38 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs
@@ -1,6 +1,5 @@
 //! Extern block hints
 use ide_db::{famous_defs::FamousDefs, text_edit::TextEdit};
-use span::EditionedFileId;
 use syntax::{AstNode, SyntaxToken, ast};
 
 use crate::{InlayHint, InlayHintsConfig};
@@ -9,7 +8,6 @@ pub(super) fn extern_block_hints(
     acc: &mut Vec<InlayHint>,
     FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    _file_id: EditionedFileId,
     extern_block: ast::ExternBlock,
 ) -> Option<()> {
     if extern_block.unsafe_token().is_some() {
@@ -36,7 +34,6 @@ pub(super) fn fn_hints(
     acc: &mut Vec<InlayHint>,
     FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    _file_id: EditionedFileId,
     fn_: &ast::Fn,
     extern_block: &ast::ExternBlock,
 ) -> Option<()> {
@@ -55,7 +52,6 @@ pub(super) fn static_hints(
     acc: &mut Vec<InlayHint>,
     FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    _file_id: EditionedFileId,
     static_: &ast::Static,
     extern_block: &ast::ExternBlock,
 ) -> Option<()> {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs
index f52e27946ff..bf4688e9d82 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs
@@ -12,7 +12,6 @@ use hir::{
 };
 use ide_db::{FileRange, famous_defs::FamousDefs};
 
-use span::EditionedFileId;
 use syntax::{
     ToSmolStr,
     ast::{self, AstNode},
@@ -25,7 +24,7 @@ pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
     FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    file_id: EditionedFileId,
+    display_target: hir::DisplayTarget,
     node: &ast::Fn,
 ) -> Option<()> {
     if !config.implicit_drop_hints {
@@ -94,7 +93,7 @@ pub(super) fn hints(
                 MirSpan::Unknown => continue,
             };
             let binding = &hir.bindings[binding_idx];
-            let name = binding.name.display_no_db(file_id.edition()).to_smolstr();
+            let name = binding.name.display_no_db(display_target.edition).to_smolstr();
             if name.starts_with("<ra@") {
                 continue; // Ignore desugared variables
             }
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
index f3be09f30a1..7212efd954e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
@@ -5,7 +5,6 @@
 use either::Either;
 use ide_db::famous_defs::FamousDefs;
 use ide_db::text_edit::TextEdit;
-use span::EditionedFileId;
 use syntax::{
     SyntaxKind,
     ast::{self, AstNode},
@@ -17,7 +16,6 @@ pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
     FamousDefs(_sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    _file_id: EditionedFileId,
     statik_or_const: Either<ast::Static, ast::Const>,
 ) -> Option<()> {
     if config.lifetime_elision_hints != LifetimeElisionHints::Always {
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs
new file mode 100644
index 00000000000..32d130503a4
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs
@@ -0,0 +1,133 @@
+//! Implementation of trait bound hints.
+//!
+//! Currently this renders the implied `Sized` bound.
+use either::Either;
+use ide_db::{famous_defs::FamousDefs, text_edit::TextEdit};
+
+use syntax::ast::{self, AstNode};
+
+use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind};
+
+pub(super) fn hints(
+    acc: &mut Vec<InlayHint>,
+    FamousDefs(sema, _): &FamousDefs<'_, '_>,
+    config: &InlayHintsConfig,
+    path: Either<ast::PathType, ast::DynTraitType>,
+) -> Option<()> {
+    let parent = path.syntax().parent()?;
+    let range = match path {
+        Either::Left(path) => {
+            let paren =
+                parent.ancestors().take_while(|it| ast::ParenType::can_cast(it.kind())).last();
+            let parent = paren.as_ref().and_then(|it| it.parent()).unwrap_or(parent);
+            if ast::TypeBound::can_cast(parent.kind())
+                || ast::TypeAnchor::can_cast(parent.kind())
+                || ast::Impl::cast(parent)
+                    .and_then(|it| it.trait_())
+                    .is_some_and(|it| it.syntax() == path.syntax())
+            {
+                return None;
+            }
+            sema.resolve_trait(&path.path()?)?;
+            paren.map_or_else(|| path.syntax().text_range(), |it| it.text_range())
+        }
+        Either::Right(dyn_) => {
+            if dyn_.dyn_token().is_some() {
+                return None;
+            }
+
+            dyn_.syntax().text_range()
+        }
+    };
+
+    acc.push(InlayHint {
+        range,
+        kind: InlayKind::Dyn,
+        label: InlayHintLabel::simple("dyn", None, None),
+        text_edit: Some(
+            config.lazy_text_edit(|| TextEdit::insert(range.start(), "dyn ".to_owned())),
+        ),
+        position: InlayHintPosition::Before,
+        pad_left: false,
+        pad_right: true,
+        resolve_parent: Some(range),
+    });
+
+    Some(())
+}
+
+#[cfg(test)]
+mod tests {
+
+    use expect_test::expect;
+
+    use crate::inlay_hints::InlayHintsConfig;
+
+    use crate::inlay_hints::tests::{DISABLED_CONFIG, check_edit, check_with_config};
+
+    #[track_caller]
+    fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
+        check_with_config(InlayHintsConfig { sized_bound: true, ..DISABLED_CONFIG }, ra_fixture);
+    }
+
+    #[test]
+    fn path_works() {
+        check(
+            r#"
+struct S {}
+trait T {}
+fn foo(_: T,  _: dyn T, _: S) {}
+       // ^ dyn
+fn foo(_: &T,  _: for<'a> T) {}
+        // ^ dyn
+                       // ^ dyn
+impl T {}
+  // ^ dyn
+impl T for (T) {}
+        // ^^^ dyn
+"#,
+        );
+    }
+
+    #[test]
+    fn missing_dyn_bounds() {
+        check(
+            r#"
+trait T {}
+fn foo(
+    _: T + T,
+    // ^^^^^ dyn
+    _: T + 'a,
+    // ^^^^^^ dyn
+    _: 'a + T,
+    // ^^^^^^ dyn
+    _: &(T + T)
+    //   ^^^^^ dyn
+    _: &mut (T + T)
+    //       ^^^^^ dyn
+    _: *mut (T),
+    //      ^^^ dyn
+) {}
+"#,
+        );
+    }
+
+    #[test]
+    fn edit() {
+        check_edit(
+            DISABLED_CONFIG,
+            r#"
+trait T {}
+fn foo(
+    _: &mut T
+) {}
+"#,
+            expect![[r#"
+                trait T {}
+                fn foo(
+                    _: &mut dyn T
+                ) {}
+            "#]],
+        );
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs
index baba49a427d..0069452e7b9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs
@@ -6,7 +6,6 @@ use std::iter;
 
 use ide_db::{FxHashMap, famous_defs::FamousDefs, syntax_helpers::node_ext::walk_ty};
 use itertools::Itertools;
-use span::EditionedFileId;
 use syntax::{SmolStr, format_smolstr};
 use syntax::{
     SyntaxKind, SyntaxToken,
@@ -23,7 +22,6 @@ pub(super) fn fn_hints(
     ctx: &mut InlayHintCtx,
     fd: &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    file_id: EditionedFileId,
     func: ast::Fn,
 ) -> Option<()> {
     if config.lifetime_elision_hints == LifetimeElisionHints::Never {
@@ -40,7 +38,6 @@ pub(super) fn fn_hints(
         ctx,
         fd,
         config,
-        file_id,
         param_list.params().filter_map(|it| {
             Some((
                 it.pat().and_then(|it| match it {
@@ -74,7 +71,6 @@ pub(super) fn fn_ptr_hints(
     ctx: &mut InlayHintCtx,
     fd: &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    file_id: EditionedFileId,
     func: ast::FnPtrType,
 ) -> Option<()> {
     if config.lifetime_elision_hints == LifetimeElisionHints::Never {
@@ -97,7 +93,6 @@ pub(super) fn fn_ptr_hints(
         ctx,
         fd,
         config,
-        file_id,
         param_list.params().filter_map(|it| {
             Some((
                 it.pat().and_then(|it| match it {
@@ -140,8 +135,7 @@ pub(super) fn fn_path_hints(
     ctx: &mut InlayHintCtx,
     fd: &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    file_id: EditionedFileId,
-    func: ast::PathType,
+    func: &ast::PathType,
 ) -> Option<()> {
     if config.lifetime_elision_hints == LifetimeElisionHints::Never {
         return None;
@@ -163,7 +157,6 @@ pub(super) fn fn_path_hints(
         ctx,
         fd,
         config,
-        file_id,
         param_list.type_args().filter_map(|it| Some((None, it.ty()?))),
         generic_param_list,
         ret_type,
@@ -202,7 +195,6 @@ fn hints_(
     ctx: &mut InlayHintCtx,
     FamousDefs(_, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    _file_id: EditionedFileId,
     params: impl Iterator<Item = (Option<ast::Name>, ast::Type)>,
     generic_param_list: Option<ast::GenericParamList>,
     ret_type: Option<ast::RetType>,
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs
index d67d8458840..47bd6d737f8 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs
@@ -4,7 +4,6 @@
 //! if let ../* < */100 = 50 {}
 //! ```
 use ide_db::famous_defs::FamousDefs;
-use span::EditionedFileId;
 use syntax::{SyntaxToken, T, ast};
 
 use crate::{InlayHint, InlayHintsConfig};
@@ -13,7 +12,6 @@ pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
     FamousDefs(_sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
-    _file_id: EditionedFileId,
     range: impl ast::RangeItem,
 ) -> Option<()> {
     (config.range_exclusive_hints && range.end().is_some())
diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs
index 0423e3da2c8..fb84e8e6b47 100644
--- a/src/tools/rust-analyzer/crates/ide/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs
@@ -4,11 +4,11 @@
 //! tests. This module also implements a couple of magic tricks, like renaming
 //! `self` and to `self` (to switch between associated function and method).
 
-use hir::{AsAssocItem, InFile, Semantics};
+use hir::{AsAssocItem, InFile, Name, Semantics, sym};
 use ide_db::{
     FileId, FileRange, RootDatabase,
     defs::{Definition, NameClass, NameRefClass},
-    rename::{IdentifierKind, bail, format_err, source_edit_from_references},
+    rename::{IdentifierKind, RenameDefinition, bail, format_err, source_edit_from_references},
     source_change::SourceChangeBuilder,
 };
 use itertools::Itertools;
@@ -33,8 +33,8 @@ pub(crate) fn prepare_rename(
     let source_file = sema.parse_guess_edition(position.file_id);
     let syntax = source_file.syntax();
 
-    let res = find_definitions(&sema, syntax, position)?
-        .map(|(frange, kind, def)| {
+    let res = find_definitions(&sema, syntax, position, &Name::new_symbol_root(sym::underscore))?
+        .map(|(frange, kind, def, _, _)| {
             // ensure all ranges are valid
 
             if def.range_for_rename(&sema).is_none() {
@@ -88,22 +88,28 @@ pub(crate) fn rename(
     let source_file = sema.parse(file_id);
     let syntax = source_file.syntax();
 
-    let defs = find_definitions(&sema, syntax, position)?;
-    let alias_fallback = alias_fallback(syntax, position, new_name);
+    let edition = file_id.edition(db);
+    let (new_name, kind) = IdentifierKind::classify(edition, new_name)?;
+
+    let defs = find_definitions(&sema, syntax, position, &new_name)?;
+    let alias_fallback =
+        alias_fallback(syntax, position, &new_name.display(db, edition).to_string());
 
     let ops: RenameResult<Vec<SourceChange>> = match alias_fallback {
         Some(_) => defs
             // FIXME: This can use the `ide_db::rename_reference` (or def.rename) method once we can
             // properly find "direct" usages/references.
-            .map(|(.., def)| {
-                match IdentifierKind::classify(new_name)? {
+            .map(|(.., def, new_name, _)| {
+                match kind {
                     IdentifierKind::Ident => (),
                     IdentifierKind::Lifetime => {
                         bail!("Cannot alias reference to a lifetime identifier")
                     }
                     IdentifierKind::Underscore => bail!("Cannot alias reference to `_`"),
+                    IdentifierKind::LowercaseSelf => {
+                        bail!("Cannot rename alias reference to `self`")
+                    }
                 };
-
                 let mut usages = def.usages(&sema).all();
 
                 // FIXME: hack - removes the usage that triggered this rename operation.
@@ -120,7 +126,7 @@ pub(crate) fn rename(
                 source_change.extend(usages.references.get_mut(&file_id).iter().map(|refs| {
                     (
                         position.file_id,
-                        source_edit_from_references(refs, def, new_name, file_id.edition(db)),
+                        source_edit_from_references(db, refs, def, &new_name, edition),
                     )
                 }));
 
@@ -128,18 +134,18 @@ pub(crate) fn rename(
             })
             .collect(),
         None => defs
-            .map(|(.., def)| {
+            .map(|(.., def, new_name, rename_def)| {
                 if let Definition::Local(local) = def {
                     if let Some(self_param) = local.as_self_param(sema.db) {
                         cov_mark::hit!(rename_self_to_param);
-                        return rename_self_to_param(&sema, local, self_param, new_name);
+                        return rename_self_to_param(&sema, local, self_param, &new_name, kind);
                     }
-                    if new_name == "self" {
+                    if kind == IdentifierKind::LowercaseSelf {
                         cov_mark::hit!(rename_to_self);
                         return rename_to_self(&sema, local);
                     }
                 }
-                def.rename(&sema, new_name)
+                def.rename(&sema, new_name.as_str(), rename_def)
             })
             .collect(),
     };
@@ -159,7 +165,7 @@ pub(crate) fn will_rename_file(
     let sema = Semantics::new(db);
     let module = sema.file_to_module_def(file_id)?;
     let def = Definition::Module(module);
-    let mut change = def.rename(&sema, new_name_stem).ok()?;
+    let mut change = def.rename(&sema, new_name_stem, RenameDefinition::Yes).ok()?;
     change.file_system_edits.clear();
     Some(change)
 }
@@ -200,22 +206,40 @@ fn find_definitions(
     sema: &Semantics<'_, RootDatabase>,
     syntax: &SyntaxNode,
     FilePosition { file_id, offset }: FilePosition,
-) -> RenameResult<impl Iterator<Item = (FileRange, SyntaxKind, Definition)>> {
-    let token = syntax.token_at_offset(offset).find(|t| matches!(t.kind(), SyntaxKind::STRING));
+    new_name: &Name,
+) -> RenameResult<impl Iterator<Item = (FileRange, SyntaxKind, Definition, Name, RenameDefinition)>>
+{
+    let maybe_format_args =
+        syntax.token_at_offset(offset).find(|t| matches!(t.kind(), SyntaxKind::STRING));
 
     if let Some((range, _, _, Some(resolution))) =
-        token.and_then(|token| sema.check_for_format_args_template(token, offset))
+        maybe_format_args.and_then(|token| sema.check_for_format_args_template(token, offset))
     {
         return Ok(vec![(
             FileRange { file_id, range },
             SyntaxKind::STRING,
             Definition::from(resolution),
+            new_name.clone(),
+            RenameDefinition::Yes,
         )]
         .into_iter());
     }
 
+    let original_ident = syntax
+        .token_at_offset(offset)
+        .max_by_key(|t| {
+            t.kind().is_any_identifier() || matches!(t.kind(), SyntaxKind::LIFETIME_IDENT)
+        })
+        .map(|t| {
+            if t.kind() == SyntaxKind::LIFETIME_IDENT {
+                Name::new_lifetime(t.text())
+            } else {
+                Name::new_root(t.text())
+            }
+        })
+        .ok_or_else(|| format_err!("No references found at position"))?;
     let symbols =
-        sema.find_nodes_at_offset_with_descend::<ast::NameLike>(syntax, offset).map(|name_like| {
+        sema.find_namelike_at_offset_with_descend(syntax, offset).map(|name_like| {
             let kind = name_like.syntax().kind();
             let range = sema
                 .original_range_opt(name_like.syntax())
@@ -284,23 +308,28 @@ fn find_definitions(
                         .ok_or_else(|| format_err!("No references found at position"))
                 }
             };
-            res.map(|def| (range, kind, def))
+            res.map(|def| {
+                let n = def.name(sema.db)?;
+                if n == original_ident {
+                    Some((range, kind, def, new_name.clone(), RenameDefinition::Yes))
+                } else if let Some(suffix) =  n.as_str().strip_prefix(original_ident.as_str()) {
+                    Some((range, kind, def, Name::new_root(&format!("{}{suffix}", new_name.as_str())), RenameDefinition::No))
+                } else {
+                     n.as_str().strip_suffix(original_ident.as_str().trim_start_matches('\''))
+                        .map(|prefix| (range, kind, def, Name::new_root(&format!("{prefix}{}", new_name.as_str())), RenameDefinition::No))
+                }
+            })
         });
 
-    let res: RenameResult<Vec<_>> = symbols.collect();
+    let res: RenameResult<Vec<_>> = symbols.filter_map(Result::transpose).collect();
     match res {
         Ok(v) => {
-            if v.is_empty() {
-                // FIXME: some semantic duplication between "empty vec" and "Err()"
-                Err(format_err!("No references found at position"))
-            } else {
-                // remove duplicates, comparing `Definition`s
-                Ok(v.into_iter()
-                    .unique_by(|&(.., def)| def)
-                    .map(|(a, b, c)| (a.into_file_id(sema.db), b, c))
-                    .collect::<Vec<_>>()
-                    .into_iter())
-            }
+            // remove duplicates, comparing `Definition`s
+            Ok(v.into_iter()
+                .unique_by(|&(.., def, _, _)| def)
+                .map(|(a, b, c, d, e)| (a.into_file_id(sema.db), b, c, d, e))
+                .collect::<Vec<_>>()
+                .into_iter())
         }
         Err(e) => Err(e),
     }
@@ -370,7 +399,13 @@ fn rename_to_self(
     source_change.extend(usages.iter().map(|(file_id, references)| {
         (
             file_id.file_id(sema.db),
-            source_edit_from_references(references, def, "self", file_id.edition(sema.db)),
+            source_edit_from_references(
+                sema.db,
+                references,
+                def,
+                &Name::new_symbol_root(sym::self_),
+                file_id.edition(sema.db),
+            ),
         )
     }));
     source_change.insert_source_edit(
@@ -384,23 +419,25 @@ fn rename_self_to_param(
     sema: &Semantics<'_, RootDatabase>,
     local: hir::Local,
     self_param: hir::SelfParam,
-    new_name: &str,
+    new_name: &Name,
+    identifier_kind: IdentifierKind,
 ) -> RenameResult<SourceChange> {
-    if new_name == "self" {
+    if identifier_kind == IdentifierKind::LowercaseSelf {
         // Let's do nothing rather than complain.
         cov_mark::hit!(rename_self_to_self);
         return Ok(SourceChange::default());
     }
 
-    let identifier_kind = IdentifierKind::classify(new_name)?;
-
     let InFile { file_id, value: self_param } =
         sema.source(self_param).ok_or_else(|| format_err!("cannot find function source"))?;
 
     let def = Definition::Local(local);
     let usages = def.usages(sema).all();
-    let edit = text_edit_from_self_param(&self_param, new_name)
-        .ok_or_else(|| format_err!("No target type found"))?;
+    let edit = text_edit_from_self_param(
+        &self_param,
+        new_name.display(sema.db, file_id.edition(sema.db)).to_string(),
+    )
+    .ok_or_else(|| format_err!("No target type found"))?;
     if usages.len() > 1 && identifier_kind == IdentifierKind::Underscore {
         bail!("Cannot rename reference to `_` as it is being referenced multiple times");
     }
@@ -409,13 +446,19 @@ fn rename_self_to_param(
     source_change.extend(usages.iter().map(|(file_id, references)| {
         (
             file_id.file_id(sema.db),
-            source_edit_from_references(references, def, new_name, file_id.edition(sema.db)),
+            source_edit_from_references(
+                sema.db,
+                references,
+                def,
+                new_name,
+                file_id.edition(sema.db),
+            ),
         )
     }));
     Ok(source_change)
 }
 
-fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: &str) -> Option<TextEdit> {
+fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: String) -> Option<TextEdit> {
     fn target_type_name(impl_def: &ast::Impl) -> Option<String> {
         if let Some(ast::Type::PathType(p)) = impl_def.self_ty() {
             return Some(p.path()?.segment()?.name_ref()?.text().to_string());
@@ -427,7 +470,7 @@ fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: &str) -> Opt
         Some(impl_def) => {
             let type_name = target_type_name(&impl_def)?;
 
-            let mut replacement_text = String::from(new_name);
+            let mut replacement_text = new_name;
             replacement_text.push_str(": ");
             match (self_param.amp_token(), self_param.mut_token()) {
                 (Some(_), None) => replacement_text.push('&'),
@@ -440,7 +483,7 @@ fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: &str) -> Opt
         }
         None => {
             cov_mark::hit!(rename_self_outside_of_methods);
-            let mut replacement_text = String::from(new_name);
+            let mut replacement_text = new_name;
             replacement_text.push_str(": _");
             Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text))
         }
@@ -710,7 +753,7 @@ impl Foo {
         check(
             "super",
             r#"fn main() { let i$0 = 1; }"#,
-            "error: Invalid name `super`: not an identifier",
+            "error: Invalid name `super`: cannot rename to a keyword",
         );
     }
 
@@ -759,7 +802,11 @@ impl Foo {
 
     #[test]
     fn test_rename_mod_invalid_raw_ident() {
-        check("r#self", r#"mod foo$0 {}"#, "error: Invalid name `self`: not an identifier");
+        check(
+            "r#self",
+            r#"mod foo$0 {}"#,
+            "error: Invalid name `self`: cannot rename module to self",
+        );
     }
 
     #[test]
@@ -2359,7 +2406,6 @@ fn foo(foo: Foo) {
 
     #[test]
     fn test_rename_lifetimes() {
-        cov_mark::check!(rename_lifetime);
         check(
             "'yeeee",
             r#"
@@ -2536,7 +2582,7 @@ fn baz() {
     x.0$0 = 5;
 }
 "#,
-            "error: No identifier available to rename",
+            "error: No references found at position",
         );
     }
 
@@ -2566,7 +2612,7 @@ impl Foo {
     }
 }
 "#,
-            "error: Cannot rename `Self`",
+            "error: No references found at position",
         );
     }
 
@@ -3262,4 +3308,100 @@ trait Trait<U> {
 "#,
         );
     }
+
+    #[test]
+    fn rename_macro_generated_type_from_type_with_a_suffix() {
+        check(
+            "Bar",
+            r#"
+//- proc_macros: generate_suffixed_type
+#[proc_macros::generate_suffixed_type]
+struct Foo$0;
+fn usage(_: FooSuffix) {}
+usage(FooSuffix);
+"#,
+            r#"
+#[proc_macros::generate_suffixed_type]
+struct Bar;
+fn usage(_: BarSuffix) {}
+usage(BarSuffix);
+"#,
+        );
+    }
+
+    #[test]
+    // FIXME
+    #[should_panic]
+    fn rename_macro_generated_type_from_type_usage_with_a_suffix() {
+        check(
+            "Bar",
+            r#"
+//- proc_macros: generate_suffixed_type
+#[proc_macros::generate_suffixed_type]
+struct Foo;
+fn usage(_: FooSuffix) {}
+usage(FooSuffix);
+fn other_place() { Foo$0; }
+"#,
+            r#"
+#[proc_macros::generate_suffixed_type]
+struct Bar;
+fn usage(_: BarSuffix) {}
+usage(BarSuffix);
+fn other_place() { Bar; }
+"#,
+        );
+    }
+
+    #[test]
+    fn rename_macro_generated_type_from_variant_with_a_suffix() {
+        check(
+            "Bar",
+            r#"
+//- proc_macros: generate_suffixed_type
+#[proc_macros::generate_suffixed_type]
+enum Quux {
+    Foo$0,
+}
+fn usage(_: FooSuffix) {}
+usage(FooSuffix);
+"#,
+            r#"
+#[proc_macros::generate_suffixed_type]
+enum Quux {
+    Bar,
+}
+fn usage(_: BarSuffix) {}
+usage(BarSuffix);
+"#,
+        );
+    }
+
+    #[test]
+    // FIXME
+    #[should_panic]
+    fn rename_macro_generated_type_from_variant_usage_with_a_suffix() {
+        check(
+            "Bar",
+            r#"
+//- proc_macros: generate_suffixed_type
+#[proc_macros::generate_suffixed_type]
+enum Quux {
+    Foo,
+}
+fn usage(_: FooSuffix) {}
+usage(FooSuffix);
+fn other_place() { Quux::Foo$0; }
+"#,
+            r#"
+#[proc_macros::generate_suffixed_type]
+enum Quux {
+    Bar,
+}
+fn usage(_: BarSuffix) {}
+usage(BartSuffix);
+fn other_place() { Quux::Bar$0; }
+"#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
index 8cc332d4633..8ed0fc6729f 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
@@ -562,8 +562,12 @@ fn closure_expr(p: &mut Parser<'_>) -> CompletedMarker {
 
     let m = p.start();
 
+    // test closure_binder
+    // fn main() { for<'a> || (); }
     if p.at(T![for]) {
+        let b = p.start();
         types::for_binder(p);
+        b.complete(p, CLOSURE_BINDER);
     }
     // test const_closure
     // fn main() { let cl = const || _ = 0; }
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
index 9d4fdbfaf2e..ea5a3bc8593 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
@@ -201,6 +201,17 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
             }
             if paths::is_use_path_start(p) {
                 types::path_type_bounds(p, false);
+                // test_err type_bounds_macro_call_recovery
+                // fn foo<T: T![], T: T!, T: T!{}>() -> Box<T! + T!{}> {}
+                if p.at(T![!]) {
+                    let m = p.start();
+                    p.bump(T![!]);
+                    p.error("unexpected `!` in type path, macro calls are not allowed here");
+                    if p.at_ts(TokenSet::new(&[T!['{'], T!['['], T!['(']])) {
+                        items::token_tree(p);
+                    }
+                    m.complete(p, ERROR);
+                }
             } else {
                 m.abandon(p);
                 return false;
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
index 770827c6b0d..dfe7cb57d24 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
@@ -89,19 +89,22 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option<Completed
     // test qual_paths
     // type X = <A as B>::Output;
     // fn foo() { <usize as Default>::default(); }
-    if first && p.eat(T![<]) {
+    if first && p.at(T![<]) {
+        let m = p.start();
+        p.bump(T![<]);
         // test_err angled_path_without_qual
         // type X = <()>;
         // type Y = <A as B>;
         types::type_(p);
         if p.eat(T![as]) {
             if is_use_path_start(p) {
-                types::path_type(p);
+                types::path_type_bounds(p, true);
             } else {
                 p.error("expected a trait");
             }
         }
         p.expect(T![>]);
+        m.complete(p, TYPE_ANCHOR);
         if !p.at(T![::]) {
             p.error("expected `::`");
         }
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs
index 9d31e435cf9..908440b5d05 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs
@@ -330,15 +330,6 @@ fn bare_dyn_trait_type(p: &mut Parser<'_>) {
     m.complete(p, DYN_TRAIT_TYPE);
 }
 
-// test path_type
-// type A = Foo;
-// type B = ::Foo;
-// type C = self::Foo;
-// type D = super::Foo;
-pub(super) fn path_type(p: &mut Parser<'_>) {
-    path_type_bounds(p, true);
-}
-
 // test macro_call_type
 // type A = foo!();
 // type B = crate::foo!();
@@ -365,6 +356,11 @@ fn path_or_macro_type(p: &mut Parser<'_>, allow_bounds: bool) {
     }
 }
 
+// test path_type
+// type A = Foo;
+// type B = ::Foo;
+// type C = self::Foo;
+// type D = super::Foo;
 pub(super) fn path_type_bounds(p: &mut Parser<'_>, allow_bounds: bool) {
     assert!(paths::is_path_start(p));
     let m = p.start();
diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
index b1727509b13..f534546ea07 100644
--- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
@@ -291,6 +291,7 @@ pub enum SyntaxKind {
     TUPLE_STRUCT_PAT,
     TUPLE_TYPE,
     TYPE_ALIAS,
+    TYPE_ANCHOR,
     TYPE_ARG,
     TYPE_BOUND,
     TYPE_BOUND_LIST,
@@ -463,6 +464,7 @@ impl SyntaxKind {
             | TUPLE_STRUCT_PAT
             | TUPLE_TYPE
             | TYPE_ALIAS
+            | TYPE_ANCHOR
             | TYPE_ARG
             | TYPE_BOUND
             | TYPE_BOUND_LIST
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
index 030d8e0f04d..6ec4192830b 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
@@ -83,6 +83,10 @@ mod ok {
     #[test]
     fn cast_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/cast_expr.rs"); }
     #[test]
+    fn closure_binder() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/closure_binder.rs");
+    }
+    #[test]
     fn closure_body_underscore_assignment() {
         run_and_expect_no_errors(
             "test_data/parser/inline/ok/closure_body_underscore_assignment.rs",
@@ -872,6 +876,10 @@ mod err {
         run_and_expect_errors("test_data/parser/inline/err/tuple_pat_leading_comma.rs");
     }
     #[test]
+    fn type_bounds_macro_call_recovery() {
+        run_and_expect_errors("test_data/parser/inline/err/type_bounds_macro_call_recovery.rs");
+    }
+    #[test]
     fn type_in_array_recover() {
         run_and_expect_errors("test_data/parser/inline/err/type_in_array_recover.rs");
     }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0024_many_type_parens.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0024_many_type_parens.rast
index f0dbc9b1027..025c12e4c2a 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0024_many_type_parens.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0024_many_type_parens.rast
@@ -186,13 +186,14 @@ SOURCE_FILE
               TUPLE_EXPR
                 L_PAREN "("
                 CLOSURE_EXPR
-                  FOR_KW "for"
-                  GENERIC_PARAM_LIST
-                    L_ANGLE "<"
-                    LIFETIME_PARAM
-                      LIFETIME
-                        LIFETIME_IDENT "'a"
-                    R_ANGLE ">"
+                  CLOSURE_BINDER
+                    FOR_KW "for"
+                    GENERIC_PARAM_LIST
+                      L_ANGLE "<"
+                      LIFETIME_PARAM
+                        LIFETIME
+                          LIFETIME_IDENT "'a"
+                      R_ANGLE ">"
                 WHITESPACE " "
                 BIN_EXPR
                   BIN_EXPR
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast
index 0529e9750e7..53fbe0b615e 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast
@@ -10,11 +10,12 @@ SOURCE_FILE
     PATH_TYPE
       PATH
         PATH_SEGMENT
-          L_ANGLE "<"
-          TUPLE_TYPE
-            L_PAREN "("
-            R_PAREN ")"
-          R_ANGLE ">"
+          TYPE_ANCHOR
+            L_ANGLE "<"
+            TUPLE_TYPE
+              L_PAREN "("
+              R_PAREN ")"
+            R_ANGLE ">"
     SEMICOLON ";"
   WHITESPACE "\n"
   TYPE_ALIAS
@@ -28,21 +29,22 @@ SOURCE_FILE
     PATH_TYPE
       PATH
         PATH_SEGMENT
-          L_ANGLE "<"
-          PATH_TYPE
-            PATH
-              PATH_SEGMENT
-                NAME_REF
-                  IDENT "A"
-          WHITESPACE " "
-          AS_KW "as"
-          WHITESPACE " "
-          PATH_TYPE
-            PATH
-              PATH_SEGMENT
-                NAME_REF
-                  IDENT "B"
-          R_ANGLE ">"
+          TYPE_ANCHOR
+            L_ANGLE "<"
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "A"
+            WHITESPACE " "
+            AS_KW "as"
+            WHITESPACE " "
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "B"
+            R_ANGLE ">"
     SEMICOLON ";"
   WHITESPACE "\n"
 error 13: expected `::`
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast
new file mode 100644
index 00000000000..4722beb6192
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast
@@ -0,0 +1,112 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    GENERIC_PARAM_LIST
+      L_ANGLE "<"
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "T"
+            ERROR
+              BANG "!"
+              TOKEN_TREE
+                L_BRACK "["
+                R_BRACK "]"
+      COMMA ","
+      WHITESPACE " "
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "T"
+            ERROR
+              BANG "!"
+      COMMA ","
+      WHITESPACE " "
+      TYPE_PARAM
+        NAME
+          IDENT "T"
+        COLON ":"
+        WHITESPACE " "
+        TYPE_BOUND_LIST
+          TYPE_BOUND
+            PATH_TYPE
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "T"
+            ERROR
+              BANG "!"
+              TOKEN_TREE
+                L_CURLY "{"
+                R_CURLY "}"
+      R_ANGLE ">"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    RET_TYPE
+      THIN_ARROW "->"
+      WHITESPACE " "
+      PATH_TYPE
+        PATH
+          PATH_SEGMENT
+            NAME_REF
+              IDENT "Box"
+            GENERIC_ARG_LIST
+              L_ANGLE "<"
+              TYPE_ARG
+                DYN_TRAIT_TYPE
+                  TYPE_BOUND_LIST
+                    TYPE_BOUND
+                      MACRO_TYPE
+                        MACRO_CALL
+                          PATH
+                            PATH_SEGMENT
+                              NAME_REF
+                                IDENT "T"
+                          BANG "!"
+                    WHITESPACE " "
+                    PLUS "+"
+                    WHITESPACE " "
+                    TYPE_BOUND
+                      PATH_TYPE
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "T"
+                      ERROR
+                        BANG "!"
+                        TOKEN_TREE
+                          L_CURLY "{"
+                          R_CURLY "}"
+              R_ANGLE ">"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 12: unexpected `!` in type path, macro calls are not allowed here
+error 21: unexpected `!` in type path, macro calls are not allowed here
+error 28: unexpected `!` in type path, macro calls are not allowed here
+error 43: expected `{`, `[`, `(`
+error 48: unexpected `!` in type path, macro calls are not allowed here
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rs
new file mode 100644
index 00000000000..517404fdb0e
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rs
@@ -0,0 +1 @@
+fn foo<T: T![], T: T!, T: T!{}>() -> Box<T! + T!{}> {}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast
index 19cc8d5ac7c..7c1d894f7e4 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast
@@ -88,13 +88,14 @@ SOURCE_FILE
                   PATH
                     PATH
                       PATH_SEGMENT
-                        L_ANGLE "<"
-                        PATH_TYPE
-                          PATH
-                            PATH_SEGMENT
-                              NAME_REF
-                                IDENT "Foo"
-                        R_ANGLE ">"
+                        TYPE_ANCHOR
+                          L_ANGLE "<"
+                          PATH_TYPE
+                            PATH
+                              PATH_SEGMENT
+                                NAME_REF
+                                  IDENT "Foo"
+                          R_ANGLE ">"
                     COLON2 "::"
                     PATH_SEGMENT
                       NAME_REF
@@ -119,21 +120,22 @@ SOURCE_FILE
                   PATH
                     PATH
                       PATH_SEGMENT
-                        L_ANGLE "<"
-                        PATH_TYPE
-                          PATH
-                            PATH_SEGMENT
-                              NAME_REF
-                                IDENT "Foo"
-                        WHITESPACE " "
-                        AS_KW "as"
-                        WHITESPACE " "
-                        PATH_TYPE
-                          PATH
-                            PATH_SEGMENT
-                              NAME_REF
-                                IDENT "Trait"
-                        R_ANGLE ">"
+                        TYPE_ANCHOR
+                          L_ANGLE "<"
+                          PATH_TYPE
+                            PATH
+                              PATH_SEGMENT
+                                NAME_REF
+                                  IDENT "Foo"
+                          WHITESPACE " "
+                          AS_KW "as"
+                          WHITESPACE " "
+                          PATH_TYPE
+                            PATH
+                              PATH_SEGMENT
+                                NAME_REF
+                                  IDENT "Trait"
+                          R_ANGLE ">"
                     COLON2 "::"
                     PATH_SEGMENT
                       NAME_REF
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rast
new file mode 100644
index 00000000000..c04dbe1ea0a
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rast
@@ -0,0 +1,36 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE " "
+        EXPR_STMT
+          CLOSURE_EXPR
+            CLOSURE_BINDER
+              FOR_KW "for"
+              GENERIC_PARAM_LIST
+                L_ANGLE "<"
+                LIFETIME_PARAM
+                  LIFETIME
+                    LIFETIME_IDENT "'a"
+                R_ANGLE ">"
+            WHITESPACE " "
+            PARAM_LIST
+              PIPE "|"
+              PIPE "|"
+            WHITESPACE " "
+            TUPLE_EXPR
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE " "
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rs
new file mode 100644
index 00000000000..a6d8aafb08a
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rs
@@ -0,0 +1 @@
+fn main() { for<'a> || (); }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast
index c25ad8430d0..ea401d224e6 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast
@@ -202,13 +202,14 @@ SOURCE_FILE
         WHITESPACE "\n    "
         EXPR_STMT
           CLOSURE_EXPR
-            FOR_KW "for"
-            GENERIC_PARAM_LIST
-              L_ANGLE "<"
-              LIFETIME_PARAM
-                LIFETIME
-                  LIFETIME_IDENT "'a"
-              R_ANGLE ">"
+            CLOSURE_BINDER
+              FOR_KW "for"
+              GENERIC_PARAM_LIST
+                L_ANGLE "<"
+                LIFETIME_PARAM
+                  LIFETIME
+                    LIFETIME_IDENT "'a"
+                R_ANGLE ">"
             WHITESPACE " "
             PARAM_LIST
               PIPE "|"
@@ -222,13 +223,14 @@ SOURCE_FILE
         WHITESPACE "\n    "
         EXPR_STMT
           CLOSURE_EXPR
-            FOR_KW "for"
-            GENERIC_PARAM_LIST
-              L_ANGLE "<"
-              LIFETIME_PARAM
-                LIFETIME
-                  LIFETIME_IDENT "'a"
-              R_ANGLE ">"
+            CLOSURE_BINDER
+              FOR_KW "for"
+              GENERIC_PARAM_LIST
+                L_ANGLE "<"
+                LIFETIME_PARAM
+                  LIFETIME
+                    LIFETIME_IDENT "'a"
+                R_ANGLE ">"
             WHITESPACE " "
             MOVE_KW "move"
             WHITESPACE " "
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast
index 8c66cfe599f..10f8a6a7516 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast
@@ -11,21 +11,22 @@ SOURCE_FILE
       PATH
         PATH
           PATH_SEGMENT
-            L_ANGLE "<"
-            PATH_TYPE
-              PATH
-                PATH_SEGMENT
-                  NAME_REF
-                    IDENT "A"
-            WHITESPACE " "
-            AS_KW "as"
-            WHITESPACE " "
-            PATH_TYPE
-              PATH
-                PATH_SEGMENT
-                  NAME_REF
-                    IDENT "B"
-            R_ANGLE ">"
+            TYPE_ANCHOR
+              L_ANGLE "<"
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "A"
+              WHITESPACE " "
+              AS_KW "as"
+              WHITESPACE " "
+              PATH_TYPE
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "B"
+              R_ANGLE ">"
         COLON2 "::"
         PATH_SEGMENT
           NAME_REF
@@ -51,21 +52,22 @@ SOURCE_FILE
               PATH
                 PATH
                   PATH_SEGMENT
-                    L_ANGLE "<"
-                    PATH_TYPE
-                      PATH
-                        PATH_SEGMENT
-                          NAME_REF
-                            IDENT "usize"
-                    WHITESPACE " "
-                    AS_KW "as"
-                    WHITESPACE " "
-                    PATH_TYPE
-                      PATH
-                        PATH_SEGMENT
-                          NAME_REF
-                            IDENT "Default"
-                    R_ANGLE ">"
+                    TYPE_ANCHOR
+                      L_ANGLE "<"
+                      PATH_TYPE
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "usize"
+                      WHITESPACE " "
+                      AS_KW "as"
+                      WHITESPACE " "
+                      PATH_TYPE
+                        PATH
+                          PATH_SEGMENT
+                            NAME_REF
+                              IDENT "Default"
+                      R_ANGLE ">"
                 COLON2 "::"
                 PATH_SEGMENT
                   NAME_REF
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast
index 297f7575ca6..3d27afa5ecd 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast
@@ -19,10 +19,11 @@ SOURCE_FILE
             PATH
               PATH
                 PATH_SEGMENT
-                  L_ANGLE "<"
-                  INFER_TYPE
-                    UNDERSCORE "_"
-                  R_ANGLE ">"
+                  TYPE_ANCHOR
+                    L_ANGLE "<"
+                    INFER_TYPE
+                      UNDERSCORE "_"
+                    R_ANGLE ">"
               COLON2 "::"
               PATH_SEGMENT
                 NAME_REF
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast
index a3cbe457e1a..9adfe2caa73 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast
@@ -84,21 +84,22 @@ SOURCE_FILE
           PATH
             PATH
               PATH_SEGMENT
-                L_ANGLE "<"
-                PATH_TYPE
-                  PATH
-                    PATH_SEGMENT
-                      NAME_REF
-                        IDENT "T"
-                WHITESPACE " "
-                AS_KW "as"
-                WHITESPACE " "
-                PATH_TYPE
-                  PATH
-                    PATH_SEGMENT
-                      NAME_REF
-                        IDENT "Iterator"
-                R_ANGLE ">"
+                TYPE_ANCHOR
+                  L_ANGLE "<"
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "T"
+                  WHITESPACE " "
+                  AS_KW "as"
+                  WHITESPACE " "
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "Iterator"
+                  R_ANGLE ">"
             COLON2 "::"
             PATH_SEGMENT
               NAME_REF
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0036_fully_qualified.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0036_fully_qualified.rast
index 9382020e2f6..2fecb1cc47d 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0036_fully_qualified.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0036_fully_qualified.rast
@@ -45,21 +45,22 @@ SOURCE_FILE
           PATH
             PATH
               PATH_SEGMENT
-                L_ANGLE "<"
-                PATH_TYPE
-                  PATH
-                    PATH_SEGMENT
-                      NAME_REF
-                        IDENT "S"
-                WHITESPACE " "
-                AS_KW "as"
-                WHITESPACE " "
-                PATH_TYPE
-                  PATH
-                    PATH_SEGMENT
-                      NAME_REF
-                        IDENT "Iterator"
-                R_ANGLE ">"
+                TYPE_ANCHOR
+                  L_ANGLE "<"
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "S"
+                  WHITESPACE " "
+                  AS_KW "as"
+                  WHITESPACE " "
+                  PATH_TYPE
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "Iterator"
+                  R_ANGLE ">"
             COLON2 "::"
             PATH_SEGMENT
               NAME_REF
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast
index a536b0e881f..d1d1ffacf0d 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast
@@ -107,13 +107,14 @@ SOURCE_FILE
                 PATH
                   PATH
                     PATH_SEGMENT
-                      L_ANGLE "<"
-                      PATH_TYPE
-                        PATH
-                          PATH_SEGMENT
-                            NAME_REF
-                              IDENT "Foo"
-                      R_ANGLE ">"
+                      TYPE_ANCHOR
+                        L_ANGLE "<"
+                        PATH_TYPE
+                          PATH
+                            PATH_SEGMENT
+                              NAME_REF
+                                IDENT "Foo"
+                        R_ANGLE ">"
                   COLON2 "::"
                   PATH_SEGMENT
                     NAME_REF
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0067_where_for_pred.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0067_where_for_pred.rast
index cd3b21ae94f..8bf1090f9cf 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0067_where_for_pred.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0067_where_for_pred.rast
@@ -288,26 +288,27 @@ SOURCE_FILE
           PATH
             PATH
               PATH_SEGMENT
-                L_ANGLE "<"
-                REF_TYPE
-                  AMP "&"
-                  LIFETIME
-                    LIFETIME_IDENT "'a"
+                TYPE_ANCHOR
+                  L_ANGLE "<"
+                  REF_TYPE
+                    AMP "&"
+                    LIFETIME
+                      LIFETIME_IDENT "'a"
+                    WHITESPACE " "
+                    PATH_TYPE
+                      PATH
+                        PATH_SEGMENT
+                          NAME_REF
+                            IDENT "T"
+                  WHITESPACE " "
+                  AS_KW "as"
                   WHITESPACE " "
                   PATH_TYPE
                     PATH
                       PATH_SEGMENT
                         NAME_REF
-                          IDENT "T"
-                WHITESPACE " "
-                AS_KW "as"
-                WHITESPACE " "
-                PATH_TYPE
-                  PATH
-                    PATH_SEGMENT
-                      NAME_REF
-                        IDENT "Baz"
-                R_ANGLE ">"
+                          IDENT "Baz"
+                  R_ANGLE ">"
             COLON2 "::"
             PATH_SEGMENT
               NAME_REF
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs
index 11dbd920091..ad285990334 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs
@@ -10,6 +10,7 @@
 
 use std::fmt;
 
+use intern::Symbol;
 use proc_macro::bridge;
 
 mod token_stream;
@@ -112,3 +113,135 @@ fn literal_kind_to_internal(kind: bridge::LitKind) -> tt::LitKind {
         bridge::LitKind::ErrWithGuar => tt::LitKind::Err(()),
     }
 }
+
+pub(super) fn literal_from_str<Span: Copy>(
+    s: &str,
+    span: Span,
+) -> Result<bridge::Literal<Span, Symbol>, ()> {
+    use proc_macro::bridge::LitKind;
+    use rustc_lexer::{LiteralKind, Token, TokenKind};
+
+    let mut tokens = rustc_lexer::tokenize(s);
+    let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
+
+    let lit = if minus_or_lit.kind == TokenKind::Minus {
+        let lit = tokens.next().ok_or(())?;
+        if !matches!(
+            lit.kind,
+            TokenKind::Literal { kind: LiteralKind::Int { .. } | LiteralKind::Float { .. }, .. }
+        ) {
+            return Err(());
+        }
+        lit
+    } else {
+        minus_or_lit
+    };
+
+    if tokens.next().is_some() {
+        return Err(());
+    }
+
+    let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
+    let (kind, start_offset, end_offset) = match kind {
+        LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
+        LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
+        LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
+        LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
+        LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
+        LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
+        LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
+        LiteralKind::RawStr { n_hashes } => (
+            LitKind::StrRaw(n_hashes.unwrap_or_default()),
+            2 + n_hashes.unwrap_or_default() as usize,
+            1 + n_hashes.unwrap_or_default() as usize,
+        ),
+        LiteralKind::RawByteStr { n_hashes } => (
+            LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
+            3 + n_hashes.unwrap_or_default() as usize,
+            1 + n_hashes.unwrap_or_default() as usize,
+        ),
+        LiteralKind::RawCStr { n_hashes } => (
+            LitKind::CStrRaw(n_hashes.unwrap_or_default()),
+            3 + n_hashes.unwrap_or_default() as usize,
+            1 + n_hashes.unwrap_or_default() as usize,
+        ),
+    };
+
+    let (lit, suffix) = s.split_at(suffix_start as usize);
+    let lit = &lit[start_offset..lit.len() - end_offset];
+    let suffix = match suffix {
+        "" | "_" => None,
+        suffix => Some(Symbol::intern(suffix)),
+    };
+
+    Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span })
+}
+
+pub(super) fn from_token_tree<Span: Copy>(
+    tree: bridge::TokenTree<TokenStream<Span>, Span, Symbol>,
+) -> TokenStream<Span> {
+    match tree {
+        bridge::TokenTree::Group(group) => {
+            let group = TopSubtree::from_bridge(group);
+            TokenStream { token_trees: group.0 }
+        }
+
+        bridge::TokenTree::Ident(ident) => {
+            let text = ident.sym;
+            let ident: tt::Ident<Span> = tt::Ident {
+                sym: text,
+                span: ident.span,
+                is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
+            };
+            let leaf = tt::Leaf::from(ident);
+            let tree = tt::TokenTree::from(leaf);
+            TokenStream { token_trees: vec![tree] }
+        }
+
+        bridge::TokenTree::Literal(literal) => {
+            let token_trees =
+                if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
+                    let punct = tt::Punct {
+                        spacing: tt::Spacing::Alone,
+                        span: literal.span,
+                        char: '-' as char,
+                    };
+                    let leaf: tt::Leaf<Span> = tt::Leaf::from(punct);
+                    let minus_tree = tt::TokenTree::from(leaf);
+
+                    let literal = tt::Literal {
+                        symbol: Symbol::intern(symbol),
+                        suffix: literal.suffix,
+                        span: literal.span,
+                        kind: literal_kind_to_internal(literal.kind),
+                    };
+                    let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
+                    let tree = tt::TokenTree::from(leaf);
+                    vec![minus_tree, tree]
+                } else {
+                    let literal = tt::Literal {
+                        symbol: literal.symbol,
+                        suffix: literal.suffix,
+                        span: literal.span,
+                        kind: literal_kind_to_internal(literal.kind),
+                    };
+
+                    let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
+                    let tree = tt::TokenTree::from(leaf);
+                    vec![tree]
+                };
+            TokenStream { token_trees }
+        }
+
+        bridge::TokenTree::Punct(p) => {
+            let punct = tt::Punct {
+                char: p.ch as char,
+                spacing: if p.joint { tt::Spacing::Joint } else { tt::Spacing::Alone },
+                span: p.span,
+            };
+            let leaf = tt::Leaf::from(punct);
+            let tree = tt::TokenTree::from(leaf);
+            TokenStream { token_trees: vec![tree] }
+        }
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
index e0c6e68f803..5d1271ba81e 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
@@ -14,16 +14,7 @@ use proc_macro::bridge::{self, server};
 use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
 use tt::{TextRange, TextSize};
 
-use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder};
-mod tt {
-    pub use tt::*;
-
-    pub type TokenTree = ::tt::TokenTree<super::Span>;
-    pub type Leaf = ::tt::Leaf<super::Span>;
-    pub type Literal = ::tt::Literal<super::Span>;
-    pub type Punct = ::tt::Punct<super::Span>;
-    pub type Ident = ::tt::Ident<super::Span>;
-}
+use crate::server_impl::{from_token_tree, literal_from_str, token_stream::TokenStreamBuilder};
 
 type TokenStream = crate::server_impl::TokenStream<Span>;
 
@@ -62,66 +53,7 @@ impl server::FreeFunctions for RaSpanServer {
         &mut self,
         s: &str,
     ) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
-        use proc_macro::bridge::LitKind;
-        use rustc_lexer::{LiteralKind, Token, TokenKind};
-
-        let mut tokens = rustc_lexer::tokenize(s);
-        let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
-
-        let lit = if minus_or_lit.kind == TokenKind::Minus {
-            let lit = tokens.next().ok_or(())?;
-            if !matches!(
-                lit.kind,
-                TokenKind::Literal {
-                    kind: LiteralKind::Int { .. } | LiteralKind::Float { .. },
-                    ..
-                }
-            ) {
-                return Err(());
-            }
-            lit
-        } else {
-            minus_or_lit
-        };
-
-        if tokens.next().is_some() {
-            return Err(());
-        }
-
-        let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
-        let (kind, start_offset, end_offset) = match kind {
-            LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
-            LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
-            LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
-            LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
-            LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
-            LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
-            LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
-            LiteralKind::RawStr { n_hashes } => (
-                LitKind::StrRaw(n_hashes.unwrap_or_default()),
-                2 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-            LiteralKind::RawByteStr { n_hashes } => (
-                LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
-                3 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-            LiteralKind::RawCStr { n_hashes } => (
-                LitKind::CStrRaw(n_hashes.unwrap_or_default()),
-                3 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-        };
-
-        let (lit, suffix) = s.split_at(suffix_start as usize);
-        let lit = &lit[start_offset..lit.len() - end_offset];
-        let suffix = match suffix {
-            "" | "_" => None,
-            suffix => Some(Symbol::intern(suffix)),
-        };
-
-        Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site })
+        literal_from_str(s, self.call_site)
     }
 
     fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {
@@ -149,70 +81,7 @@ impl server::TokenStream for RaSpanServer {
         &mut self,
         tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
     ) -> Self::TokenStream {
-        match tree {
-            bridge::TokenTree::Group(group) => {
-                let group = TopSubtree::from_bridge(group);
-                TokenStream { token_trees: group.0 }
-            }
-
-            bridge::TokenTree::Ident(ident) => {
-                let text = ident.sym;
-                let ident: tt::Ident = tt::Ident {
-                    sym: text,
-                    span: ident.span,
-                    is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
-                };
-                let leaf = tt::Leaf::from(ident);
-                let tree = tt::TokenTree::from(leaf);
-                TokenStream { token_trees: vec![tree] }
-            }
-
-            bridge::TokenTree::Literal(literal) => {
-                let token_trees =
-                    if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
-                        let punct = tt::Punct {
-                            spacing: tt::Spacing::Alone,
-                            span: literal.span,
-                            char: '-' as char,
-                        };
-                        let leaf: tt::Leaf = tt::Leaf::from(punct);
-                        let minus_tree = tt::TokenTree::from(leaf);
-
-                        let literal = tt::Literal {
-                            symbol: Symbol::intern(symbol),
-                            suffix: literal.suffix,
-                            span: literal.span,
-                            kind: literal_kind_to_internal(literal.kind),
-                        };
-                        let leaf: tt::Leaf = tt::Leaf::from(literal);
-                        let tree = tt::TokenTree::from(leaf);
-                        vec![minus_tree, tree]
-                    } else {
-                        let literal = tt::Literal {
-                            symbol: literal.symbol,
-                            suffix: literal.suffix,
-                            span: literal.span,
-                            kind: literal_kind_to_internal(literal.kind),
-                        };
-
-                        let leaf: tt::Leaf = tt::Leaf::from(literal);
-                        let tree = tt::TokenTree::from(leaf);
-                        vec![tree]
-                    };
-                TokenStream { token_trees }
-            }
-
-            bridge::TokenTree::Punct(p) => {
-                let punct = tt::Punct {
-                    char: p.ch as char,
-                    spacing: if p.joint { tt::Spacing::Joint } else { tt::Spacing::Alone },
-                    span: p.span,
-                };
-                let leaf = tt::Leaf::from(punct);
-                let tree = tt::TokenTree::from(leaf);
-                TokenStream { token_trees: vec![tree] }
-            }
-        }
+        from_token_tree(tree)
     }
 
     fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs
index d55b269f868..b493b325e83 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs
@@ -5,23 +5,9 @@ use std::ops::{Bound, Range};
 use intern::Symbol;
 use proc_macro::bridge::{self, server};
 
-use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder};
-mod tt {
-    pub use span::TokenId;
+use crate::server_impl::{from_token_tree, literal_from_str, token_stream::TokenStreamBuilder};
 
-    pub use tt::*;
-
-    pub type TokenTree = ::tt::TokenTree<TokenId>;
-    pub type Leaf = ::tt::Leaf<TokenId>;
-    pub type Literal = ::tt::Literal<TokenId>;
-    pub type Punct = ::tt::Punct<TokenId>;
-    pub type Ident = ::tt::Ident<TokenId>;
-}
-type TokenTree = tt::TokenTree;
-type Punct = tt::Punct;
-type Spacing = tt::Spacing;
-type Literal = tt::Literal;
-type Span = tt::TokenId;
+type Span = span::TokenId;
 type TokenStream = crate::server_impl::TokenStream<Span>;
 
 pub struct FreeFunctions;
@@ -49,67 +35,7 @@ impl server::FreeFunctions for TokenIdServer {
         &mut self,
         s: &str,
     ) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
-        use proc_macro::bridge::LitKind;
-        use rustc_lexer::{LiteralKind, Token, TokenKind};
-
-        let mut tokens = rustc_lexer::tokenize(s);
-        let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
-
-        let lit = if minus_or_lit.kind == TokenKind::Minus {
-            let lit = tokens.next().ok_or(())?;
-            if !matches!(
-                lit.kind,
-                TokenKind::Literal {
-                    kind: LiteralKind::Int { .. } | LiteralKind::Float { .. },
-                    ..
-                }
-            ) {
-                return Err(());
-            }
-            lit
-        } else {
-            minus_or_lit
-        };
-
-        if tokens.next().is_some() {
-            return Err(());
-        }
-
-        let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
-
-        let (kind, start_offset, end_offset) = match kind {
-            LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
-            LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
-            LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
-            LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
-            LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
-            LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
-            LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
-            LiteralKind::RawStr { n_hashes } => (
-                LitKind::StrRaw(n_hashes.unwrap_or_default()),
-                2 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-            LiteralKind::RawByteStr { n_hashes } => (
-                LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
-                3 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-            LiteralKind::RawCStr { n_hashes } => (
-                LitKind::CStrRaw(n_hashes.unwrap_or_default()),
-                3 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-        };
-
-        let (lit, suffix) = s.split_at(suffix_start as usize);
-        let lit = &lit[start_offset..lit.len() - end_offset];
-        let suffix = match suffix {
-            "" | "_" => None,
-            suffix => Some(Symbol::intern(suffix)),
-        };
-
-        Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site })
+        literal_from_str(s, self.call_site)
     }
 
     fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {}
@@ -135,69 +61,7 @@ impl server::TokenStream for TokenIdServer {
         &mut self,
         tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
     ) -> Self::TokenStream {
-        match tree {
-            bridge::TokenTree::Group(group) => {
-                let group = TopSubtree::from_bridge(group);
-                TokenStream { token_trees: group.0 }
-            }
-
-            bridge::TokenTree::Ident(ident) => {
-                let ident: tt::Ident = tt::Ident {
-                    sym: ident.sym,
-                    span: ident.span,
-                    is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
-                };
-                let leaf = tt::Leaf::from(ident);
-                let tree = TokenTree::from(leaf);
-                TokenStream { token_trees: vec![tree] }
-            }
-
-            bridge::TokenTree::Literal(literal) => {
-                let token_trees =
-                    if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
-                        let punct = tt::Punct {
-                            spacing: tt::Spacing::Alone,
-                            span: literal.span,
-                            char: '-' as char,
-                        };
-                        let leaf: tt::Leaf = tt::Leaf::from(punct);
-                        let minus_tree = tt::TokenTree::from(leaf);
-
-                        let literal = Literal {
-                            symbol: Symbol::intern(symbol),
-                            suffix: literal.suffix,
-                            span: literal.span,
-                            kind: literal_kind_to_internal(literal.kind),
-                        };
-                        let leaf: tt::Leaf = tt::Leaf::from(literal);
-                        let tree = tt::TokenTree::from(leaf);
-                        vec![minus_tree, tree]
-                    } else {
-                        let literal = Literal {
-                            symbol: literal.symbol,
-                            suffix: literal.suffix,
-                            span: literal.span,
-                            kind: literal_kind_to_internal(literal.kind),
-                        };
-
-                        let leaf: tt::Leaf = tt::Leaf::from(literal);
-                        let tree = tt::TokenTree::from(leaf);
-                        vec![tree]
-                    };
-                TokenStream { token_trees }
-            }
-
-            bridge::TokenTree::Punct(p) => {
-                let punct = Punct {
-                    char: p.ch as char,
-                    spacing: if p.joint { Spacing::Joint } else { Spacing::Alone },
-                    span: p.span,
-                };
-                let leaf = tt::Leaf::from(punct);
-                let tree = TokenTree::from(leaf);
-                TokenStream { token_trees: vec![tree] }
-            }
-        }
+        from_token_tree(tree)
     }
 
     fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
@@ -337,6 +201,8 @@ impl server::Server for TokenIdServer {
 
 #[cfg(test)]
 mod tests {
+    use span::TokenId;
+
     use super::*;
 
     #[test]
@@ -345,18 +211,18 @@ mod tests {
             token_trees: vec![
                 tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                     sym: Symbol::intern("struct"),
-                    span: tt::TokenId(0),
+                    span: TokenId(0),
                     is_raw: tt::IdentIsRaw::No,
                 })),
                 tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                     sym: Symbol::intern("T"),
-                    span: tt::TokenId(0),
+                    span: TokenId(0),
                     is_raw: tt::IdentIsRaw::No,
                 })),
                 tt::TokenTree::Subtree(tt::Subtree {
                     delimiter: tt::Delimiter {
-                        open: tt::TokenId(0),
-                        close: tt::TokenId(0),
+                        open: TokenId(0),
+                        close: TokenId(0),
                         kind: tt::DelimiterKind::Brace,
                     },
                     len: 0,
@@ -372,8 +238,8 @@ mod tests {
         let subtree_paren_a = vec![
             tt::TokenTree::Subtree(tt::Subtree {
                 delimiter: tt::Delimiter {
-                    open: tt::TokenId(0),
-                    close: tt::TokenId(0),
+                    open: TokenId(0),
+                    close: TokenId(0),
                     kind: tt::DelimiterKind::Parenthesis,
                 },
                 len: 1,
@@ -381,24 +247,24 @@ mod tests {
             tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                 is_raw: tt::IdentIsRaw::No,
                 sym: Symbol::intern("a"),
-                span: tt::TokenId(0),
+                span: TokenId(0),
             })),
         ];
 
-        let t1 = TokenStream::from_str("(a)", tt::TokenId(0)).unwrap();
+        let t1 = TokenStream::from_str("(a)", TokenId(0)).unwrap();
         assert_eq!(t1.token_trees.len(), 2);
         assert!(t1.token_trees[0..2] == subtree_paren_a);
 
-        let t2 = TokenStream::from_str("(a);", tt::TokenId(0)).unwrap();
+        let t2 = TokenStream::from_str("(a);", TokenId(0)).unwrap();
         assert_eq!(t2.token_trees.len(), 3);
         assert!(t2.token_trees[0..2] == subtree_paren_a);
 
-        let underscore = TokenStream::from_str("_", tt::TokenId(0)).unwrap();
+        let underscore = TokenStream::from_str("_", TokenId(0)).unwrap();
         assert!(
             underscore.token_trees[0]
                 == tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                     sym: Symbol::intern("_"),
-                    span: tt::TokenId(0),
+                    span: TokenId(0),
                     is_raw: tt::IdentIsRaw::No,
                 }))
         );
diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
index 6e730b1aea2..bb02284a513 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
@@ -431,12 +431,6 @@ impl CargoWorkspace {
                 .ok_or(cargo_metadata::Error::NoJson)?;
             Ok((cargo_metadata::MetadataCommand::parse(stdout)?, None))
         })()
-        .map(|(metadata, error)| {
-            (
-                metadata,
-                error.map(|e| e.context(format!("Failed to run `{:?}`", meta.cargo_command()))),
-            )
-        })
         .with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index d1ca8c1a91a..5cbea9c2b3d 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -1192,7 +1192,7 @@ impl ConfigChange {
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum LinkedProject {
     ProjectManifest(ProjectManifest),
-    InlineJsonProject(ProjectJson),
+    InlineProjectJson(ProjectJson),
 }
 
 impl From<ProjectManifest> for LinkedProject {
@@ -1203,7 +1203,7 @@ impl From<ProjectManifest> for LinkedProject {
 
 impl From<ProjectJson> for LinkedProject {
     fn from(v: ProjectJson) -> Self {
-        LinkedProject::InlineJsonProject(v)
+        LinkedProject::InlineProjectJson(v)
     }
 }
 
@@ -1597,6 +1597,16 @@ impl Config {
             term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(),
         }
     }
+
+    pub fn diagnostic_fixes(&self, source_root: Option<SourceRootId>) -> DiagnosticsConfig {
+        // We always want to show quickfixes for diagnostics, even when diagnostics/experimental diagnostics are disabled.
+        DiagnosticsConfig {
+            enabled: true,
+            disable_experimental: false,
+            ..self.diagnostics(source_root)
+        }
+    }
+
     pub fn expand_proc_attr_macros(&self) -> bool {
         self.procMacro_enable().to_owned() && self.procMacro_attributes_enable().to_owned()
     }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
index 69983a67626..6d46ce68ed4 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
@@ -1439,7 +1439,7 @@ pub(crate) fn handle_code_action(
     };
     let assists = snap.analysis.assists_with_fixes(
         &assists_config,
-        &snap.config.diagnostics(Some(source_root)),
+        &snap.config.diagnostic_fixes(Some(source_root)),
         resolve,
         frange,
     )?;
@@ -1530,7 +1530,7 @@ pub(crate) fn handle_code_action_resolve(
 
     let assists = snap.analysis.assists_with_fixes(
         &assists_config,
-        &snap.config.diagnostics(Some(source_root)),
+        &snap.config.diagnostic_fixes(Some(source_root)),
         AssistResolveStrategy::Single(assist_resolve),
         frange,
     )?;
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
index 673eaa5952f..5bea7084fdb 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
@@ -108,8 +108,7 @@ impl GlobalState {
     /// edge users from being upset!
     pub(crate) fn poke_rust_analyzer_developer(&mut self, message: String) {
         let from_source_build = option_env!("POKE_RA_DEVS").is_some();
-        let profiling_enabled = std::env::var("RA_PROFILE").is_ok();
-        if from_source_build || profiling_enabled {
+        if from_source_build {
             self.show_and_log_error(message, None);
         }
     }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
index ae9e3e99874..4677880daaf 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -292,7 +292,7 @@ impl GlobalState {
 
                 if let (Some(_command), Some(path)) = (&discover_command, &path) {
                     let build = linked_projects.iter().find_map(|project| match project {
-                        LinkedProject::InlineJsonProject(it) => it.crate_by_buildfile(path),
+                        LinkedProject::InlineProjectJson(it) => it.crate_by_buildfile(path),
                         _ => None,
                     });
 
@@ -318,7 +318,7 @@ impl GlobalState {
                                 &progress,
                             )
                         }
-                        LinkedProject::InlineJsonProject(it) => {
+                        LinkedProject::InlineProjectJson(it) => {
                             let workspace = project_model::ProjectWorkspace::load_inline(
                                 it.clone(),
                                 &cargo_config,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
index f6bcb5642c3..59073af983b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -975,10 +975,6 @@ version = \"0.0.0\"
 }
 
 fn out_dirs_check_impl(root_contains_symlink: bool) {
-    if skip_slow_tests() {
-        return;
-    }
-
     let mut server = Project::with_fixture(
         r###"
 //- /Cargo.toml
@@ -1130,12 +1126,18 @@ fn main() {
 
 #[test]
 fn out_dirs_check() {
+    if skip_slow_tests() {
+        return;
+    }
     out_dirs_check_impl(false);
 }
 
 #[test]
 #[cfg(not(windows))] // windows requires elevated permissions to create symlinks
 fn root_contains_symlink_out_dirs_check() {
+    if skip_slow_tests() {
+        return;
+    }
     out_dirs_check_impl(true);
 }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs
index 485f32281dd..cac7efd84aa 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs
@@ -439,6 +439,7 @@ assist.emitMustUse = true"#,
 }
 
 #[test]
+#[ignore = "flaky test that tends to hang"]
 fn ratoml_inherit_config_from_ws_root() {
     if skip_slow_tests() {
         return;
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram
index 10abca7d35d..c81da06682e 100644
--- a/src/tools/rust-analyzer/crates/syntax/rust.ungram
+++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -39,7 +39,10 @@ PathSegment =
 | NameRef GenericArgList?
 | NameRef ParenthesizedArgList RetType?
 | NameRef ReturnTypeSyntax
-| '<' Type ('as' PathType)? '>'
+| TypeAnchor
+
+TypeAnchor =
+  '<' Type ('as' PathType)? '>'
 
 ReturnTypeSyntax =
   '(' '..' ')'
@@ -98,7 +101,7 @@ WhereClause =
   'where' predicates:(WherePred (',' WherePred)* ','?)
 
 WherePred =
-  ('for' GenericParamList)?  (Lifetime | Type) ':' TypeBoundList?
+  ('for' GenericParamList)? (Lifetime | Type) ':' TypeBoundList?
 
 
 //*************************//
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
index cd9f4dba890..04c7e8a578c 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
@@ -1232,21 +1232,13 @@ impl PathSegment {
         support::child(&self.syntax)
     }
     #[inline]
-    pub fn path_type(&self) -> Option<PathType> { support::child(&self.syntax) }
-    #[inline]
     pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
     #[inline]
     pub fn return_type_syntax(&self) -> Option<ReturnTypeSyntax> { support::child(&self.syntax) }
     #[inline]
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
+    pub fn type_anchor(&self) -> Option<TypeAnchor> { support::child(&self.syntax) }
     #[inline]
     pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
-    #[inline]
-    pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
-    #[inline]
-    pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
-    #[inline]
-    pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
 }
 pub struct PathType {
     pub(crate) syntax: SyntaxNode,
@@ -1739,6 +1731,21 @@ impl TypeAlias {
     #[inline]
     pub fn type_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![type]) }
 }
+pub struct TypeAnchor {
+    pub(crate) syntax: SyntaxNode,
+}
+impl TypeAnchor {
+    #[inline]
+    pub fn path_type(&self) -> Option<PathType> { support::child(&self.syntax) }
+    #[inline]
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
+    #[inline]
+    pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
+    #[inline]
+    pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
+    #[inline]
+    pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
+}
 pub struct TypeArg {
     pub(crate) syntax: SyntaxNode,
 }
@@ -7108,6 +7115,42 @@ impl fmt::Debug for TypeAlias {
         f.debug_struct("TypeAlias").field("syntax", &self.syntax).finish()
     }
 }
+impl AstNode for TypeAnchor {
+    #[inline]
+    fn kind() -> SyntaxKind
+    where
+        Self: Sized,
+    {
+        TYPE_ANCHOR
+    }
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ANCHOR }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl hash::Hash for TypeAnchor {
+    fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); }
+}
+impl Eq for TypeAnchor {}
+impl PartialEq for TypeAnchor {
+    fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax }
+}
+impl Clone for TypeAnchor {
+    fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } }
+}
+impl fmt::Debug for TypeAnchor {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("TypeAnchor").field("syntax", &self.syntax).finish()
+    }
+}
 impl AstNode for TypeArg {
     #[inline]
     fn kind() -> SyntaxKind
@@ -10624,6 +10667,11 @@ impl std::fmt::Display for TypeAlias {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for TypeAnchor {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for TypeArg {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
index b9ccd34cff0..dcf853427e5 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
@@ -276,18 +276,15 @@ impl ast::PathSegment {
                 _ => PathSegmentKind::Name(name_ref),
             }
         } else {
-            match self.syntax().first_child_or_token()?.kind() {
-                T![<] => {
-                    // <T> or <T as Trait>
-                    // T is any TypeRef, Trait has to be a PathType
-                    let mut type_refs =
-                        self.syntax().children().filter(|node| ast::Type::can_cast(node.kind()));
-                    let type_ref = type_refs.next().and_then(ast::Type::cast);
-                    let trait_ref = type_refs.next().and_then(ast::PathType::cast);
-                    PathSegmentKind::Type { type_ref, trait_ref }
-                }
-                _ => return None,
-            }
+            let anchor = self.type_anchor()?;
+            // FIXME: Move this over to `ast::TypeAnchor`
+            // <T> or <T as Trait>
+            // T is any TypeRef, Trait has to be a PathType
+            let mut type_refs =
+                anchor.syntax().children().filter(|node| ast::Type::can_cast(node.kind()));
+            let type_ref = type_refs.next().and_then(ast::Type::cast);
+            let trait_ref = type_refs.next().and_then(ast::PathType::cast);
+            PathSegmentKind::Type { type_ref, trait_ref }
         };
         Some(res)
     }
@@ -473,7 +470,7 @@ impl ast::Impl {
 // [#15778](https://github.com/rust-lang/rust-analyzer/issues/15778)
 impl ast::PathSegment {
     pub fn qualifying_trait(&self) -> Option<ast::PathType> {
-        let mut path_types = support::children(self.syntax());
+        let mut path_types = support::children(self.type_anchor()?.syntax());
         let first = path_types.next()?;
         path_types.next().or(Some(first))
     }
diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
index 96e1301f227..8eb48f8d93e 100644
--- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
@@ -538,6 +538,21 @@ pub fn disallow_cfg(_attr: TokenStream, input: TokenStream) -> TokenStream {
                 disabled: false,
             },
         ),
+        (
+            r#"
+#[proc_macro_attribute]
+pub fn generate_suffixed_type(_attr: TokenStream, input: TokenStream) -> TokenStream {
+    input
+}
+"#
+            .into(),
+            ProcMacro {
+                name: Symbol::intern("generate_suffixed_type"),
+                kind: ProcMacroKind::Attr,
+                expander: sync::Arc::new(GenerateSuffixedTypeProcMacroExpander),
+                disabled: false,
+            },
+        ),
     ])
 }
 
@@ -919,3 +934,57 @@ impl ProcMacroExpander for DisallowCfgProcMacroExpander {
         Ok(subtree.clone())
     }
 }
+
+// Generates a new type by adding a suffix to the original name
+#[derive(Debug)]
+struct GenerateSuffixedTypeProcMacroExpander;
+impl ProcMacroExpander for GenerateSuffixedTypeProcMacroExpander {
+    fn expand(
+        &self,
+        subtree: &TopSubtree,
+        _attrs: Option<&TopSubtree>,
+        _env: &Env,
+        _def_site: Span,
+        call_site: Span,
+        _mixed_site: Span,
+        _current_dir: String,
+    ) -> Result<TopSubtree, ProcMacroExpansionError> {
+        let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[1] else {
+            return Err(ProcMacroExpansionError::Panic("incorrect Input".into()));
+        };
+
+        let ident = match ident.sym.as_str() {
+            "struct" => {
+                let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[2] else {
+                    return Err(ProcMacroExpansionError::Panic("incorrect Input".into()));
+                };
+                ident
+            }
+
+            "enum" => {
+                let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[4] else {
+                    return Err(ProcMacroExpansionError::Panic("incorrect Input".into()));
+                };
+                ident
+            }
+
+            _ => {
+                return Err(ProcMacroExpansionError::Panic("incorrect Input".into()));
+            }
+        };
+
+        let generated_ident = tt::Ident {
+            sym: Symbol::intern(&format!("{}Suffix", ident.sym)),
+            span: ident.span,
+            is_raw: tt::IdentIsRaw::No,
+        };
+
+        let ret = quote! { call_site =>
+            #subtree
+
+            struct #generated_ident;
+        };
+
+        Ok(ret)
+    }
+}
diff --git a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md
index 151f8758a17..bbdb48bbbc9 100644
--- a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md
+++ b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md
@@ -5,7 +5,7 @@ build system, you’ll have to describe the structure of your project for
 rust-analyzer in the `rust-project.json` format:
 
 ```typescript
-interface JsonProject {
+interface ProjectJson {
     /// Path to the sysroot directory.
     ///
     /// The sysroot is where rustc looks for the
diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json
index 18fb097aad7..ab431140c10 100644
--- a/src/tools/rust-analyzer/editors/code/package-lock.json
+++ b/src/tools/rust-analyzer/editors/code/package-lock.json
@@ -5500,9 +5500,9 @@
             }
         },
         "node_modules/tar-fs": {
-            "version": "2.1.2",
-            "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
-            "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==",
+            "version": "2.1.3",
+            "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz",
+            "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==",
             "dev": true,
             "license": "MIT",
             "optional": true,
diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version
index 5b47d1bbaed..af0dd5c9acd 100644
--- a/src/tools/rust-analyzer/rust-version
+++ b/src/tools/rust-analyzer/rust-version
@@ -1 +1 @@
-a8e4c68dcb4dc1e48a0db294c5323cab0227fcb9
+7c10378e1fee5ddc6573b916aeb884ab10e0de17
diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs
index bc5a6d3e704..44c8123517c 100644
--- a/src/tools/rustfmt/src/modules.rs
+++ b/src/tools/rustfmt/src/modules.rs
@@ -174,7 +174,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
     ) -> Result<(), ModuleResolutionError> {
         for item in items {
             if is_cfg_if(&item) {
-                self.visit_cfg_if(Cow::Owned(item.into_inner()))?;
+                self.visit_cfg_if(Cow::Owned(*item))?;
                 continue;
             }
 
diff --git a/src/tools/rustfmt/src/parse/macros/cfg_if.rs b/src/tools/rustfmt/src/parse/macros/cfg_if.rs
index 30b83373c17..26bf6c5326f 100644
--- a/src/tools/rustfmt/src/parse/macros/cfg_if.rs
+++ b/src/tools/rustfmt/src/parse/macros/cfg_if.rs
@@ -62,7 +62,7 @@ fn parse_cfg_if_inner<'a>(
 
         while parser.token != TokenKind::CloseBrace && parser.token.kind != TokenKind::Eof {
             let item = match parser.parse_item(ForceCollect::No) {
-                Ok(Some(item_ptr)) => item_ptr.into_inner(),
+                Ok(Some(item_ptr)) => *item_ptr,
                 Ok(None) => continue,
                 Err(err) => {
                     err.cancel();
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index 32555911194..edf16548e7d 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -259,6 +259,12 @@
 //@ revisions: i686_wrs_vxworks
 //@ [i686_wrs_vxworks] compile-flags: --target i686-wrs-vxworks
 //@ [i686_wrs_vxworks] needs-llvm-components: x86
+//@ revisions: loongarch32_unknown_none
+//@ [loongarch32_unknown_none] compile-flags: --target loongarch32-unknown-none
+//@ [loongarch32_unknown_none] needs-llvm-components: loongarch
+//@ revisions: loongarch32_unknown_none_softfloat
+//@ [loongarch32_unknown_none_softfloat] compile-flags: --target loongarch32-unknown-none-softfloat
+//@ [loongarch32_unknown_none_softfloat] needs-llvm-components: loongarch
 //@ revisions: loongarch64_unknown_linux_gnu
 //@ [loongarch64_unknown_linux_gnu] compile-flags: --target loongarch64-unknown-linux-gnu
 //@ [loongarch64_unknown_linux_gnu] needs-llvm-components: loongarch
diff --git a/tests/crashes/121429.rs b/tests/crashes/121429.rs
deleted file mode 100644
index e407754db5c..00000000000
--- a/tests/crashes/121429.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ known-bug: #121429
-
-#![feature(generic_const_exprs)]
-
-struct FixedI8<const X: usize>;
-const FRAC_LHS: usize = 0;
-const FRAC_RHS: usize = 1;
-
-pub trait True {}
-
-impl<const N: usize = { const { 3 } }> PartialEq<FixedI8<FRAC_RHS>> for FixedI8<FRAC_LHS> where
-    If<{}>: True
-{
-}
diff --git a/tests/crashes/135863.rs b/tests/crashes/135863.rs
deleted file mode 100644
index a0ff5988a0d..00000000000
--- a/tests/crashes/135863.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: #135863
-struct A;
-
-impl A {
-    fn len(self: &&B) {}
-}
-
-fn main() {
-    A.len()
-}
diff --git a/tests/crashes/139825.rs b/tests/crashes/139825.rs
deleted file mode 100644
index 8c5b6b80f0b..00000000000
--- a/tests/crashes/139825.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//@ known-bug: #139825
-//@compile-flags: --check-cfg=cfg(docsrs,test) --crate-type lib
-struct a
-where
-    for<#[cfg(b)] c> u8:;
diff --git a/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff
index 7b94a4c2bf7..22ebe2f3f29 100644
--- a/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff
+++ b/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff
@@ -32,16 +32,12 @@
           StorageDead(_4);
           _9 = discriminant((_3.0: Option2<u32>));
 -         switchInt(move _9) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb9];
-+         StorageLive(_12);
 +         _12 = discriminant((_3.1: Option2<bool>));
-+         StorageLive(_13);
 +         _13 = Ne(copy _9, move _12);
-+         StorageDead(_12);
 +         switchInt(move _13) -> [0: bb7, otherwise: bb1];
       }
   
       bb1: {
-+         StorageDead(_13);
           _0 = const 1_u32;
 -         goto -> bb8;
 +         goto -> bb5;
@@ -100,7 +96,6 @@
 +     }
 + 
 +     bb7: {
-+         StorageDead(_13);
 +         switchInt(copy _9) -> [0: bb4, 1: bb3, 2: bb2, otherwise: bb6];
       }
   }
diff --git a/tests/mir-opt/early_otherwise_branch.opt4.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt4.EarlyOtherwiseBranch.diff
index f52795baef8..0da0eb3c53c 100644
--- a/tests/mir-opt/early_otherwise_branch.opt4.EarlyOtherwiseBranch.diff
+++ b/tests/mir-opt/early_otherwise_branch.opt4.EarlyOtherwiseBranch.diff
@@ -32,16 +32,12 @@
           StorageDead(_4);
           _9 = discriminant((_3.0: Option2<u32>));
 -         switchInt(move _9) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb9];
-+         StorageLive(_12);
 +         _12 = discriminant((_3.1: Option2<u32>));
-+         StorageLive(_13);
 +         _13 = Ne(copy _9, move _12);
-+         StorageDead(_12);
 +         switchInt(move _13) -> [0: bb7, otherwise: bb1];
       }
   
       bb1: {
-+         StorageDead(_13);
           _0 = const 1_u32;
 -         goto -> bb8;
 +         goto -> bb5;
@@ -100,7 +96,6 @@
 +     }
 + 
 +     bb7: {
-+         StorageDead(_13);
 +         switchInt(copy _9) -> [0: bb4, 1: bb3, 2: bb2, otherwise: bb6];
       }
   }
diff --git a/tests/mir-opt/early_otherwise_branch.opt5.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt5.EarlyOtherwiseBranch.diff
index b7447ef0c46..b13d21e2d7a 100644
--- a/tests/mir-opt/early_otherwise_branch.opt5.EarlyOtherwiseBranch.diff
+++ b/tests/mir-opt/early_otherwise_branch.opt5.EarlyOtherwiseBranch.diff
@@ -20,13 +20,11 @@
           StorageDead(_5);
           StorageDead(_4);
 -         switchInt(copy (_3.0: u32)) -> [1: bb2, 2: bb3, 3: bb4, otherwise: bb1];
-+         StorageLive(_6);
 +         _6 = Ne(copy (_3.0: u32), copy (_3.1: u32));
 +         switchInt(move _6) -> [0: bb6, otherwise: bb1];
       }
   
       bb1: {
-+         StorageDead(_6);
           _0 = const 0_u32;
 -         goto -> bb8;
 +         goto -> bb5;
@@ -70,7 +68,6 @@
 -     bb8: {
 -         StorageDead(_3);
 -         return;
-+         StorageDead(_6);
 +         switchInt(copy (_3.0: u32)) -> [1: bb4, 2: bb3, 3: bb2, otherwise: bb1];
       }
   }
diff --git a/tests/mir-opt/early_otherwise_branch.rs b/tests/mir-opt/early_otherwise_branch.rs
index 382c38ceb3a..19a5d25de2d 100644
--- a/tests/mir-opt/early_otherwise_branch.rs
+++ b/tests/mir-opt/early_otherwise_branch.rs
@@ -1,6 +1,10 @@
 //@ test-mir-pass: EarlyOtherwiseBranch
 //@ compile-flags: -Zmir-enable-passes=+UnreachableEnumBranching
 
+#![feature(custom_mir, core_intrinsics)]
+
+use std::intrinsics::mir::*;
+
 enum Option2<T> {
     Some(T),
     None,
@@ -124,6 +128,34 @@ fn opt5_failed_type(x: u32, y: u64) -> u32 {
     }
 }
 
+// EMIT_MIR early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff
+#[custom_mir(dialect = "runtime")]
+fn target_self(val: i32) {
+    // CHECK-LABEL: fn target_self(
+    // CHECK: Ne(
+    // CHECK-NEXT: switchInt
+    mir! {
+        {
+            Goto(bb1)
+        }
+        bb1 = {
+            match val {
+                0 => bb2,
+                _ => bb1,
+            }
+        }
+        bb2 = {
+            match val {
+                0 => bb3,
+                _ => bb1,
+            }
+        }
+        bb3 = {
+            Return()
+        }
+    }
+}
+
 fn main() {
     opt1(None, Some(0));
     opt2(None, Some(0));
@@ -131,4 +163,5 @@ fn main() {
     opt4(Option2::None, Option2::Some(0));
     opt5(0, 0);
     opt5_failed(0, 0);
+    target_self(1);
 }
diff --git a/tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff
new file mode 100644
index 00000000000..4f70847bcdf
--- /dev/null
+++ b/tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff
@@ -0,0 +1,28 @@
+- // MIR for `target_self` before EarlyOtherwiseBranch
++ // MIR for `target_self` after EarlyOtherwiseBranch
+  
+  fn target_self(_1: i32) -> () {
+      let mut _0: ();
++     let mut _2: bool;
+  
+      bb0: {
+          goto -> bb1;
+      }
+  
+      bb1: {
+-         switchInt(copy _1) -> [0: bb2, otherwise: bb1];
++         _2 = Ne(copy _1, copy _1);
++         switchInt(move _2) -> [0: bb3, otherwise: bb1];
+      }
+  
+      bb2: {
+-         switchInt(copy _1) -> [0: bb3, otherwise: bb1];
++         return;
+      }
+  
+      bb3: {
+-         return;
++         switchInt(copy _1) -> [0: bb2, otherwise: bb1];
+      }
+  }
+  
diff --git a/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt2.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt2.EarlyOtherwiseBranch.diff
index 831d8cbb4d6..e0878167e44 100644
--- a/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt2.EarlyOtherwiseBranch.diff
+++ b/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt2.EarlyOtherwiseBranch.diff
@@ -42,16 +42,12 @@
           StorageDead(_5);
           _14 = discriminant((_4.0: Option2<u32>));
 -         switchInt(move _14) -> [0: bb2, 1: bb4, 2: bb6, otherwise: bb12];
-+         StorageLive(_18);
 +         _18 = discriminant((_4.1: Option2<u32>));
-+         StorageLive(_19);
 +         _19 = Ne(copy _14, move _18);
-+         StorageDead(_18);
 +         switchInt(move _19) -> [0: bb10, otherwise: bb1];
       }
   
       bb1: {
-+         StorageDead(_19);
           _0 = const 1_u32;
 -         goto -> bb11;
 +         goto -> bb8;
@@ -134,7 +130,6 @@
 +     }
 + 
 +     bb10: {
-+         StorageDead(_19);
 +         switchInt(copy _14) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb9];
       }
   }
diff --git a/tests/run-make/atomic-lock-free/atomic_lock_free.rs b/tests/run-make/atomic-lock-free/atomic_lock_free.rs
index b49c5044f31..e8bbd420cc4 100644
--- a/tests/run-make/atomic-lock-free/atomic_lock_free.rs
+++ b/tests/run-make/atomic-lock-free/atomic_lock_free.rs
@@ -1,9 +1,20 @@
 #![feature(no_core, intrinsics, lang_items)]
+#![feature(adt_const_params)]
 #![crate_type = "rlib"]
 #![no_core]
 
+pub enum AtomicOrdering {
+    // These values must match the compiler's `AtomicOrdering` defined in
+    // `rustc_middle/src/ty/consts/int.rs`!
+    Relaxed = 0,
+    Release = 1,
+    Acquire = 2,
+    AcqRel = 3,
+    SeqCst = 4,
+}
+
 #[rustc_intrinsic]
-unsafe fn atomic_xadd_seqcst<T>(dst: *mut T, src: T) -> T;
+unsafe fn atomic_xadd<T, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
 
 #[lang = "sized"]
 trait Sized {}
@@ -11,55 +22,58 @@ trait Sized {}
 trait Copy {}
 #[lang = "freeze"]
 trait Freeze {}
+#[lang = "const_param_ty"]
+pub trait ConstParamTy {}
 
 impl<T: ?Sized> Copy for *mut T {}
+impl ConstParamTy for AtomicOrdering {}
 
 #[cfg(target_has_atomic = "8")]
 pub unsafe fn atomic_u8(x: *mut u8) {
-    atomic_xadd_seqcst(x, 1);
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "8")]
 pub unsafe fn atomic_i8(x: *mut i8) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "16")]
 pub unsafe fn atomic_u16(x: *mut u16) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "16")]
 pub unsafe fn atomic_i16(x: *mut i16) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "32")]
 pub unsafe fn atomic_u32(x: *mut u32) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "32")]
 pub unsafe fn atomic_i32(x: *mut i32) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "64")]
 pub unsafe fn atomic_u64(x: *mut u64) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "64")]
 pub unsafe fn atomic_i64(x: *mut i64) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "128")]
 pub unsafe fn atomic_u128(x: *mut u128) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "128")]
 pub unsafe fn atomic_i128(x: *mut i128) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "ptr")]
 pub unsafe fn atomic_usize(x: *mut usize) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
 #[cfg(target_has_atomic = "ptr")]
 pub unsafe fn atomic_isize(x: *mut isize) {
-    atomic_xadd_seqcst(x, 1);
+    atomic_xadd::<_, { AtomicOrdering::SeqCst }>(x, 1);
 }
diff --git a/tests/run-make/doctests-keep-binaries-2024/rmake.rs b/tests/run-make/doctests-keep-binaries-2024/rmake.rs
index 3e8ffcbf244..97324e1dcbc 100644
--- a/tests/run-make/doctests-keep-binaries-2024/rmake.rs
+++ b/tests/run-make/doctests-keep-binaries-2024/rmake.rs
@@ -16,7 +16,22 @@ fn setup_test_env<F: FnOnce(&Path, &Path)>(callback: F) {
 }
 
 fn check_generated_binaries() {
-    run("doctests/merged_doctest_2024/rust_out");
+    let mut found_merged_doctest = false;
+    rfs::read_dir_entries("doctests/", |path| {
+        if path
+            .file_name()
+            .and_then(|name| name.to_str())
+            .is_some_and(|name| name.starts_with("merged_doctest_2024"))
+        {
+            found_merged_doctest = true;
+            let rust_out = path.join("rust_out");
+            let rust_out = rust_out.to_string_lossy();
+            run(&*rust_out);
+        }
+    });
+    if !found_merged_doctest {
+        panic!("no directory starting with `merged_doctest_2024` found under `doctests/`");
+    }
 }
 
 fn main() {
diff --git a/tests/run-make/linker-warning/short-error.txt b/tests/run-make/linker-warning/short-error.txt
index a7f48af885a..33d03832b7e 100644
--- a/tests/run-make/linker-warning/short-error.txt
+++ b/tests/run-make/linker-warning/short-error.txt
@@ -1,6 +1,6 @@
 error: linking with `./fake-linker` failed: exit status: 1
   |
-  = note:  "./fake-linker" "-m64" "/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error"
+  = note:  "./fake-linker" "-m64" "/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,librustc_std_workspace_core-*,liballoc-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error"
   = note: some arguments are omitted. use `--verbose` to show all linker arguments
   = note: error: baz
           
diff --git a/tests/rustdoc-ui/const-evalutation-ice.stderr b/tests/rustdoc-ui/const-evalutation-ice.stderr
index 2410782000d..51958319f5f 100644
--- a/tests/rustdoc-ui/const-evalutation-ice.stderr
+++ b/tests/rustdoc-ui/const-evalutation-ice.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `0_usize - 1_usize`, which would overflow
   --> $DIR/const-evalutation-ice.rs:10:22
    |
 LL | pub const N: usize = 0 - (mem::size_of::<S>() != 400) as usize;
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `N` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/rustdoc-ui/doctest/dead-code-items.rs b/tests/rustdoc-ui/doctest/dead-code-items.rs
new file mode 100644
index 00000000000..015504cbced
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/dead-code-items.rs
@@ -0,0 +1,116 @@
+// Same test as dead-code-module but with 2 doc(test(attr())) at different levels.
+
+//@ edition: 2024
+//@ compile-flags:--test --test-args=--test-threads=1
+//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ failure-status: 101
+
+#![doc(test(attr(deny(warnings))))]
+
+#[doc(test(attr(allow(dead_code))))]
+/// Example
+///
+/// ```rust,no_run
+/// trait OnlyWarning { fn no_deny_warnings(); }
+/// ```
+static S: u32 = 5;
+
+#[doc(test(attr(allow(dead_code))))]
+/// Example
+///
+/// ```rust,no_run
+/// let unused_error = 5;
+///
+/// fn dead_code_but_no_error() {}
+/// ```
+const C: u32 = 5;
+
+#[doc(test(attr(allow(dead_code))))]
+/// Example
+///
+/// ```rust,no_run
+/// trait OnlyWarningAtA { fn no_deny_warnings(); }
+/// ```
+struct A {
+    #[doc(test(attr(deny(dead_code))))]
+    /// Example
+    ///
+    /// ```rust,no_run
+    /// trait DeadCodeInField {}
+    /// ```
+    field: u32
+}
+
+#[doc(test(attr(allow(dead_code))))]
+/// Example
+///
+/// ```rust,no_run
+/// trait OnlyWarningAtU { fn no_deny_warnings(); }
+/// ```
+union U {
+    #[doc(test(attr(deny(dead_code))))]
+    /// Example
+    ///
+    /// ```rust,no_run
+    /// trait DeadCodeInUnionField {}
+    /// ```
+    field: u32,
+    /// Example
+    ///
+    /// ```rust,no_run
+    /// trait NotDeadCodeInUnionField {}
+    /// ```
+    field2: u64,
+}
+
+#[doc(test(attr(deny(dead_code))))]
+/// Example
+///
+/// ```rust,no_run
+/// let not_dead_code_but_unused = 5;
+/// ```
+enum Enum {
+    #[doc(test(attr(allow(dead_code))))]
+    /// Example
+    ///
+    /// ```rust,no_run
+    /// trait NotDeadCodeInVariant {}
+    ///
+    /// fn main() { let unused_in_variant = 5; }
+    /// ```
+    Variant1,
+}
+
+#[doc(test(attr(allow(dead_code))))]
+/// Example
+///
+/// ```rust,no_run
+/// trait OnlyWarningAtImplA { fn no_deny_warnings(); }
+/// ```
+impl A {
+    /// Example
+    ///
+    /// ```rust,no_run
+    /// trait NotDeadCodeInImplMethod {}
+    /// ```
+    fn method() {}
+}
+
+#[doc(test(attr(deny(dead_code))))]
+/// Example
+///
+/// ```rust,no_run
+/// trait StillDeadCodeAtMyTrait { }
+/// ```
+trait MyTrait {
+    #[doc(test(attr(allow(dead_code))))]
+    /// Example
+    ///
+    /// ```rust,no_run
+    /// trait NotDeadCodeAtImplFn {}
+    ///
+    /// fn main() { let unused_in_impl = 5; }
+    /// ```
+    fn my_trait_fn();
+}
diff --git a/tests/rustdoc-ui/doctest/dead-code-items.stdout b/tests/rustdoc-ui/doctest/dead-code-items.stdout
new file mode 100644
index 00000000000..4b9d8be94dd
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/dead-code-items.stdout
@@ -0,0 +1,146 @@
+
+running 13 tests
+test $DIR/dead-code-items.rs - A (line 32) - compile ... ok
+test $DIR/dead-code-items.rs - A (line 88) - compile ... ok
+test $DIR/dead-code-items.rs - A::field (line 39) - compile ... FAILED
+test $DIR/dead-code-items.rs - A::method (line 94) - compile ... ok
+test $DIR/dead-code-items.rs - C (line 22) - compile ... FAILED
+test $DIR/dead-code-items.rs - Enum (line 70) - compile ... FAILED
+test $DIR/dead-code-items.rs - Enum::Variant1 (line 77) - compile ... FAILED
+test $DIR/dead-code-items.rs - MyTrait (line 103) - compile ... FAILED
+test $DIR/dead-code-items.rs - MyTrait::my_trait_fn (line 110) - compile ... FAILED
+test $DIR/dead-code-items.rs - S (line 14) - compile ... ok
+test $DIR/dead-code-items.rs - U (line 48) - compile ... ok
+test $DIR/dead-code-items.rs - U::field (line 55) - compile ... FAILED
+test $DIR/dead-code-items.rs - U::field2 (line 61) - compile ... ok
+
+failures:
+
+---- $DIR/dead-code-items.rs - A::field (line 39) stdout ----
+error: trait `DeadCodeInField` is never used
+  --> $DIR/dead-code-items.rs:40:7
+   |
+LL | trait DeadCodeInField {}
+   |       ^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/dead-code-items.rs:38:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+---- $DIR/dead-code-items.rs - C (line 22) stdout ----
+error: unused variable: `unused_error`
+  --> $DIR/dead-code-items.rs:23:5
+   |
+LL | let unused_error = 5;
+   |     ^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_error`
+   |
+note: the lint level is defined here
+  --> $DIR/dead-code-items.rs:20:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]`
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+---- $DIR/dead-code-items.rs - Enum (line 70) stdout ----
+error: unused variable: `not_dead_code_but_unused`
+  --> $DIR/dead-code-items.rs:71:5
+   |
+LL | let not_dead_code_but_unused = 5;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_not_dead_code_but_unused`
+   |
+note: the lint level is defined here
+  --> $DIR/dead-code-items.rs:68:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]`
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+---- $DIR/dead-code-items.rs - Enum::Variant1 (line 77) stdout ----
+error: unused variable: `unused_in_variant`
+  --> $DIR/dead-code-items.rs:80:17
+   |
+LL | fn main() { let unused_in_variant = 5; }
+   |                 ^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_in_variant`
+   |
+note: the lint level is defined here
+  --> $DIR/dead-code-items.rs:75:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]`
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+---- $DIR/dead-code-items.rs - MyTrait (line 103) stdout ----
+error: trait `StillDeadCodeAtMyTrait` is never used
+  --> $DIR/dead-code-items.rs:104:7
+   |
+LL | trait StillDeadCodeAtMyTrait { }
+   |       ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/dead-code-items.rs:102:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+---- $DIR/dead-code-items.rs - MyTrait::my_trait_fn (line 110) stdout ----
+error: unused variable: `unused_in_impl`
+  --> $DIR/dead-code-items.rs:113:17
+   |
+LL | fn main() { let unused_in_impl = 5; }
+   |                 ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_in_impl`
+   |
+note: the lint level is defined here
+  --> $DIR/dead-code-items.rs:108:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]`
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+---- $DIR/dead-code-items.rs - U::field (line 55) stdout ----
+error: trait `DeadCodeInUnionField` is never used
+  --> $DIR/dead-code-items.rs:56:7
+   |
+LL | trait DeadCodeInUnionField {}
+   |       ^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/dead-code-items.rs:54:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+
+failures:
+    $DIR/dead-code-items.rs - A::field (line 39)
+    $DIR/dead-code-items.rs - C (line 22)
+    $DIR/dead-code-items.rs - Enum (line 70)
+    $DIR/dead-code-items.rs - Enum::Variant1 (line 77)
+    $DIR/dead-code-items.rs - MyTrait (line 103)
+    $DIR/dead-code-items.rs - MyTrait::my_trait_fn (line 110)
+    $DIR/dead-code-items.rs - U::field (line 55)
+
+test result: FAILED. 6 passed; 7 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/doctest/dead-code-module-2.rs b/tests/rustdoc-ui/doctest/dead-code-module-2.rs
new file mode 100644
index 00000000000..de7b11b91ec
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/dead-code-module-2.rs
@@ -0,0 +1,27 @@
+// Same test as dead-code-module but with 2 doc(test(attr())) at different levels.
+
+//@ edition: 2024
+//@ compile-flags:--test
+//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ failure-status: 101
+
+#![doc(test(attr(allow(unused_variables))))]
+
+mod my_mod {
+    #![doc(test(attr(deny(warnings))))]
+
+    /// Example
+    ///
+    /// ```rust,no_run
+    /// trait T { fn f(); }
+    /// ```
+    pub fn f() {}
+}
+
+/// Example
+///
+/// ```rust,no_run
+/// trait OnlyWarning { fn no_deny_warnings(); }
+/// ```
+pub fn g() {}
diff --git a/tests/rustdoc-ui/doctest/dead-code-module-2.stdout b/tests/rustdoc-ui/doctest/dead-code-module-2.stdout
new file mode 100644
index 00000000000..d44068dcbf5
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/dead-code-module-2.stdout
@@ -0,0 +1,35 @@
+
+running 1 test
+test $DIR/dead-code-module-2.rs - g (line 24) - compile ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
+
+running 1 test
+test $DIR/dead-code-module-2.rs - my_mod::f (line 16) - compile ... FAILED
+
+failures:
+
+---- $DIR/dead-code-module-2.rs - my_mod::f (line 16) stdout ----
+error: trait `T` is never used
+  --> $DIR/dead-code-module-2.rs:17:7
+   |
+LL | trait T { fn f(); }
+   |       ^
+   |
+note: the lint level is defined here
+  --> $DIR/dead-code-module-2.rs:15:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]`
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+
+failures:
+    $DIR/dead-code-module-2.rs - my_mod::f (line 16)
+
+test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/doctest/dead-code-module.rs b/tests/rustdoc-ui/doctest/dead-code-module.rs
new file mode 100644
index 00000000000..f825749a6a2
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/dead-code-module.rs
@@ -0,0 +1,18 @@
+// Same test as dead-code but inside a module.
+
+//@ edition: 2024
+//@ compile-flags:--test
+//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ failure-status: 101
+
+mod my_mod {
+    #![doc(test(attr(allow(unused_variables), deny(warnings))))]
+
+    /// Example
+    ///
+    /// ```rust,no_run
+    /// trait T { fn f(); }
+    /// ```
+    pub fn f() {}
+}
diff --git a/tests/rustdoc-ui/doctest/dead-code-module.stdout b/tests/rustdoc-ui/doctest/dead-code-module.stdout
new file mode 100644
index 00000000000..b5ccf225d25
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/dead-code-module.stdout
@@ -0,0 +1,29 @@
+
+running 1 test
+test $DIR/dead-code-module.rs - my_mod::f (line 14) - compile ... FAILED
+
+failures:
+
+---- $DIR/dead-code-module.rs - my_mod::f (line 14) stdout ----
+error: trait `T` is never used
+  --> $DIR/dead-code-module.rs:15:7
+   |
+LL | trait T { fn f(); }
+   |       ^
+   |
+note: the lint level is defined here
+  --> $DIR/dead-code-module.rs:13:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]`
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+
+failures:
+    $DIR/dead-code-module.rs - my_mod::f (line 14)
+
+test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/doctest/doc-test-attr-pass-module.rs b/tests/rustdoc-ui/doctest/doc-test-attr-pass-module.rs
new file mode 100644
index 00000000000..e916ca41ea0
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/doc-test-attr-pass-module.rs
@@ -0,0 +1,11 @@
+//@ check-pass
+
+#![crate_type = "lib"]
+#![deny(invalid_doc_attributes)]
+#![doc(test(no_crate_inject))]
+
+mod my_mod {
+    #![doc(test(attr(deny(warnings))))]
+
+    pub fn foo() {}
+}
diff --git a/tests/rustdoc/inline_cross/assoc-const-equality.rs b/tests/rustdoc/inline_cross/assoc-const-equality.rs
index ec5c2f748ef..36ab027ef71 100644
--- a/tests/rustdoc/inline_cross/assoc-const-equality.rs
+++ b/tests/rustdoc/inline_cross/assoc-const-equality.rs
@@ -1,6 +1,5 @@
 //@ aux-crate:assoc_const_equality=assoc-const-equality.rs
 //@ edition:2021
-//@ ignore-test (FIXME: #125092)
 
 #![crate_name = "user"]
 
diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr
index 48fa2bf29bc..5e09145a271 100644
--- a/tests/ui/abi/c-zst.aarch64-darwin.stderr
+++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr
@@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        ty: (),
                        layout: Layout {
                            size: Size(0 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Memory {
                                sized: true,
@@ -34,9 +33,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr
index bfdf94c9900..b8d6c632b97 100644
--- a/tests/ui/abi/c-zst.powerpc-linux.stderr
+++ b/tests/ui/abi/c-zst.powerpc-linux.stderr
@@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        ty: (),
                        layout: Layout {
                            size: Size(0 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Memory {
                                sized: true,
@@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr
index bfdf94c9900..b8d6c632b97 100644
--- a/tests/ui/abi/c-zst.s390x-linux.stderr
+++ b/tests/ui/abi/c-zst.s390x-linux.stderr
@@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        ty: (),
                        layout: Layout {
                            size: Size(0 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Memory {
                                sized: true,
@@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr
index bfdf94c9900..b8d6c632b97 100644
--- a/tests/ui/abi/c-zst.sparc64-linux.stderr
+++ b/tests/ui/abi/c-zst.sparc64-linux.stderr
@@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        ty: (),
                        layout: Layout {
                            size: Size(0 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Memory {
                                sized: true,
@@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr
index 48fa2bf29bc..5e09145a271 100644
--- a/tests/ui/abi/c-zst.x86_64-linux.stderr
+++ b/tests/ui/abi/c-zst.x86_64-linux.stderr
@@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        ty: (),
                        layout: Layout {
                            size: Size(0 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Memory {
                                sized: true,
@@ -34,9 +33,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
index bfdf94c9900..b8d6c632b97 100644
--- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
+++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
@@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        ty: (),
                        layout: Layout {
                            size: Size(0 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Memory {
                                sized: true,
@@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr
index 480f3f04215..8ed6dedf4d5 100644
--- a/tests/ui/abi/debug.stderr
+++ b/tests/ui/abi/debug.stderr
@@ -5,9 +5,8 @@ error: fn_abi_of(test) = FnAbi {
                        ty: u8,
                        layout: Layout {
                            size: Size(1 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Scalar(
                                Initialized {
@@ -44,9 +43,8 @@ error: fn_abi_of(test) = FnAbi {
                    ty: bool,
                    layout: Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Scalar(
                            Initialized {
@@ -103,9 +101,8 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
                        ty: bool,
                        layout: Layout {
                            size: Size(1 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Scalar(
                                Initialized {
@@ -151,9 +148,8 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
                    ty: u8,
                    layout: Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Scalar(
                            Initialized {
@@ -201,9 +197,8 @@ error: fn_abi_of(test_generic) = FnAbi {
                        ty: *const T,
                        layout: Layout {
                            size: $SOME_SIZE,
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Scalar(
                                Initialized {
@@ -241,9 +236,8 @@ error: fn_abi_of(test_generic) = FnAbi {
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -288,9 +282,8 @@ error: ABIs are not compatible
                        ty: u8,
                        layout: Layout {
                            size: Size(1 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Scalar(
                                Initialized {
@@ -327,9 +320,8 @@ error: ABIs are not compatible
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -362,9 +354,8 @@ error: ABIs are not compatible
                        ty: u32,
                        layout: Layout {
                            size: $SOME_SIZE,
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Scalar(
                                Initialized {
@@ -401,9 +392,8 @@ error: ABIs are not compatible
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -442,9 +432,8 @@ error: ABIs are not compatible
                        ty: [u8; 32],
                        layout: Layout {
                            size: Size(32 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Memory {
                                sized: true,
@@ -482,9 +471,8 @@ error: ABIs are not compatible
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -517,9 +505,8 @@ error: ABIs are not compatible
                        ty: [u32; 32],
                        layout: Layout {
                            size: Size(128 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Memory {
                                sized: true,
@@ -557,9 +544,8 @@ error: ABIs are not compatible
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -598,9 +584,8 @@ error: ABIs are not compatible
                        ty: f32,
                        layout: Layout {
                            size: $SOME_SIZE,
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Scalar(
                                Initialized {
@@ -636,9 +621,8 @@ error: ABIs are not compatible
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -671,9 +655,8 @@ error: ABIs are not compatible
                        ty: u32,
                        layout: Layout {
                            size: $SOME_SIZE,
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Scalar(
                                Initialized {
@@ -710,9 +693,8 @@ error: ABIs are not compatible
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -751,9 +733,8 @@ error: ABIs are not compatible
                        ty: i32,
                        layout: Layout {
                            size: $SOME_SIZE,
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Scalar(
                                Initialized {
@@ -790,9 +771,8 @@ error: ABIs are not compatible
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -825,9 +805,8 @@ error: ABIs are not compatible
                        ty: u32,
                        layout: Layout {
                            size: $SOME_SIZE,
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Scalar(
                                Initialized {
@@ -864,9 +843,8 @@ error: ABIs are not compatible
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -925,9 +903,8 @@ error: fn_abi_of(assoc_test) = FnAbi {
                        ty: &S,
                        layout: Layout {
                            size: $SOME_SIZE,
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Scalar(
                                Initialized {
@@ -977,9 +954,8 @@ error: fn_abi_of(assoc_test) = FnAbi {
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr
index f91d1b5fa63..2233e8e4f62 100644
--- a/tests/ui/abi/sysv64-zst.stderr
+++ b/tests/ui/abi/sysv64-zst.stderr
@@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                        ty: (),
                        layout: Layout {
                            size: Size(0 bytes),
-                           align: AbiAndPrefAlign {
+                           align: AbiAlign {
                                abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
                            },
                            backend_repr: Memory {
                                sized: true,
@@ -34,9 +33,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    ty: (),
                    layout: Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr
index c11cc4e2d52..22dca00e3b2 100644
--- a/tests/ui/abi/unsupported.aarch64.stderr
+++ b/tests/ui/abi/unsupported.aarch64.stderr
@@ -1,5 +1,5 @@
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:40:1
+  --> $DIR/unsupported.rs:43:1
    |
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "aapcs" is not supported on this target
-  --> $DIR/unsupported.rs:51:17
+  --> $DIR/unsupported.rs:50:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:64:1
+  --> $DIR/unsupported.rs:55:1
    |
 LL | extern "aapcs" {}
    | ^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:78:1
+  --> $DIR/unsupported.rs:65:1
    |
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:88:1
+  --> $DIR/unsupported.rs:75:1
    |
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "riscv-interrupt-m" is not supported on this target
-  --> $DIR/unsupported.rs:96:17
+  --> $DIR/unsupported.rs:80:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:107:1
+  --> $DIR/unsupported.rs:85:1
    |
 LL | extern "riscv-interrupt-m" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "x86-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:118:15
+  --> $DIR/unsupported.rs:90:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,13 +84,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:129:1
+  --> $DIR/unsupported.rs:95:1
    |
 LL | extern "x86-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "thiscall" is not supported on this target
-  --> $DIR/unsupported.rs:141:20
+  --> $DIR/unsupported.rs:100:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -99,13 +99,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:154:1
+  --> $DIR/unsupported.rs:105:1
    |
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:167:19
+  --> $DIR/unsupported.rs:112:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -114,13 +114,69 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"stdcall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:180:1
+  --> $DIR/unsupported.rs:119:1
    |
 LL | extern "stdcall" {}
    | ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:123:1
+   |
+LL | extern "stdcall-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+
+warning: the calling convention "vectorcall" is not supported on this target
+  --> $DIR/unsupported.rs:145:22
+   |
+LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+error[E0570]: `"vectorcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:150:1
+   |
+LL | extern "vectorcall" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,7 +185,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -138,77 +194,95 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:200:1
+  --> $DIR/unsupported.rs:166:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:42:1
+  --> $DIR/unsupported.rs:45:1
    |
 LL | extern "gpu-kernel" fn gpu() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:45:1
+  --> $DIR/unsupported.rs:48:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:71:1
+  --> $DIR/unsupported.rs:58:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:81:1
+  --> $DIR/unsupported.rs:68:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:91:1
+  --> $DIR/unsupported.rs:78:1
    |
 LL | extern "riscv-interrupt-m" fn riscv() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:113:1
+  --> $DIR/unsupported.rs:88:1
    |
 LL | extern "x86-interrupt" fn x86() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:135:1
+  --> $DIR/unsupported.rs:98:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"stdcall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:161:1
+  --> $DIR/unsupported.rs:108:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+error[E0570]: `"vectorcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:143:1
+   |
+LL | extern "vectorcall" fn vectorcall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:193:1
+  --> $DIR/unsupported.rs:159:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 19 previous errors; 10 warnings emitted
+error: aborting due to 22 previous errors; 15 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
 Future incompatibility report: Future breakage diagnostic:
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -219,7 +293,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "aapcs" is not supported on this target
-  --> $DIR/unsupported.rs:51:17
+  --> $DIR/unsupported.rs:50:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -230,7 +304,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -241,7 +315,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -252,7 +326,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "riscv-interrupt-m" is not supported on this target
-  --> $DIR/unsupported.rs:96:17
+  --> $DIR/unsupported.rs:80:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -263,7 +337,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "x86-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:118:15
+  --> $DIR/unsupported.rs:90:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -274,7 +348,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "thiscall" is not supported on this target
-  --> $DIR/unsupported.rs:141:20
+  --> $DIR/unsupported.rs:100:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -285,7 +359,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:167:19
+  --> $DIR/unsupported.rs:112:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -295,8 +369,55 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "vectorcall" is not supported on this target
+  --> $DIR/unsupported.rs:145:22
+   |
+LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -307,7 +428,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -316,3 +437,15 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr
index b2f24381336..0ac6d888f8d 100644
--- a/tests/ui/abi/unsupported.arm.stderr
+++ b/tests/ui/abi/unsupported.arm.stderr
@@ -1,5 +1,5 @@
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:40:1
+  --> $DIR/unsupported.rs:43:1
    |
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,13 +24,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:78:1
+  --> $DIR/unsupported.rs:65:1
    |
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,13 +39,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:88:1
+  --> $DIR/unsupported.rs:75:1
    |
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "riscv-interrupt-m" is not supported on this target
-  --> $DIR/unsupported.rs:96:17
+  --> $DIR/unsupported.rs:80:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -54,13 +54,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:107:1
+  --> $DIR/unsupported.rs:85:1
    |
 LL | extern "riscv-interrupt-m" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "x86-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:118:15
+  --> $DIR/unsupported.rs:90:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:129:1
+  --> $DIR/unsupported.rs:95:1
    |
 LL | extern "x86-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "thiscall" is not supported on this target
-  --> $DIR/unsupported.rs:141:20
+  --> $DIR/unsupported.rs:100:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:154:1
+  --> $DIR/unsupported.rs:105:1
    |
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:167:19
+  --> $DIR/unsupported.rs:112:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -99,13 +99,69 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"stdcall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:180:1
+  --> $DIR/unsupported.rs:119:1
    |
 LL | extern "stdcall" {}
    | ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:123:1
+   |
+LL | extern "stdcall-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+
+warning: the calling convention "vectorcall" is not supported on this target
+  --> $DIR/unsupported.rs:145:22
+   |
+LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+error[E0570]: `"vectorcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:150:1
+   |
+LL | extern "vectorcall" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -114,7 +170,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -123,71 +179,89 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:200:1
+  --> $DIR/unsupported.rs:166:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:42:1
+  --> $DIR/unsupported.rs:45:1
    |
 LL | extern "gpu-kernel" fn gpu() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:71:1
+  --> $DIR/unsupported.rs:58:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:81:1
+  --> $DIR/unsupported.rs:68:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:91:1
+  --> $DIR/unsupported.rs:78:1
    |
 LL | extern "riscv-interrupt-m" fn riscv() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:113:1
+  --> $DIR/unsupported.rs:88:1
    |
 LL | extern "x86-interrupt" fn x86() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:135:1
+  --> $DIR/unsupported.rs:98:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"stdcall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:161:1
+  --> $DIR/unsupported.rs:108:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+error[E0570]: `"vectorcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:143:1
+   |
+LL | extern "vectorcall" fn vectorcall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:193:1
+  --> $DIR/unsupported.rs:159:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 17 previous errors; 9 warnings emitted
+error: aborting due to 20 previous errors; 14 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
 Future incompatibility report: Future breakage diagnostic:
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -198,7 +272,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +283,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -220,7 +294,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "riscv-interrupt-m" is not supported on this target
-  --> $DIR/unsupported.rs:96:17
+  --> $DIR/unsupported.rs:80:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -231,7 +305,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "x86-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:118:15
+  --> $DIR/unsupported.rs:90:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -242,7 +316,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "thiscall" is not supported on this target
-  --> $DIR/unsupported.rs:141:20
+  --> $DIR/unsupported.rs:100:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -253,7 +327,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:167:19
+  --> $DIR/unsupported.rs:112:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -263,8 +337,55 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "vectorcall" is not supported on this target
+  --> $DIR/unsupported.rs:145:22
+   |
+LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -275,7 +396,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -284,3 +405,15 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr
index 94bd9b8af90..4d903b435d8 100644
--- a/tests/ui/abi/unsupported.i686.stderr
+++ b/tests/ui/abi/unsupported.i686.stderr
@@ -1,5 +1,5 @@
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:40:1
+  --> $DIR/unsupported.rs:43:1
    |
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "aapcs" is not supported on this target
-  --> $DIR/unsupported.rs:51:17
+  --> $DIR/unsupported.rs:50:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:64:1
+  --> $DIR/unsupported.rs:55:1
    |
 LL | extern "aapcs" {}
    | ^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:78:1
+  --> $DIR/unsupported.rs:65:1
    |
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:88:1
+  --> $DIR/unsupported.rs:75:1
    |
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "riscv-interrupt-m" is not supported on this target
-  --> $DIR/unsupported.rs:96:17
+  --> $DIR/unsupported.rs:80:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:107:1
+  --> $DIR/unsupported.rs:85:1
    |
 LL | extern "riscv-interrupt-m" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +84,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -93,49 +93,49 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:200:1
+  --> $DIR/unsupported.rs:166:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:42:1
+  --> $DIR/unsupported.rs:45:1
    |
 LL | extern "gpu-kernel" fn gpu() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:45:1
+  --> $DIR/unsupported.rs:48:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:71:1
+  --> $DIR/unsupported.rs:58:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:81:1
+  --> $DIR/unsupported.rs:68:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:91:1
+  --> $DIR/unsupported.rs:78:1
    |
 LL | extern "riscv-interrupt-m" fn riscv() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:193:1
+  --> $DIR/unsupported.rs:159:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -145,7 +145,7 @@ error: aborting due to 13 previous errors; 7 warnings emitted
 For more information about this error, try `rustc --explain E0570`.
 Future incompatibility report: Future breakage diagnostic:
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -156,7 +156,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "aapcs" is not supported on this target
-  --> $DIR/unsupported.rs:51:17
+  --> $DIR/unsupported.rs:50:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -167,7 +167,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -178,7 +178,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -189,7 +189,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "riscv-interrupt-m" is not supported on this target
-  --> $DIR/unsupported.rs:96:17
+  --> $DIR/unsupported.rs:80:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -200,7 +200,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -211,7 +211,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr
index c6ff47283c6..ad57a89e455 100644
--- a/tests/ui/abi/unsupported.riscv32.stderr
+++ b/tests/ui/abi/unsupported.riscv32.stderr
@@ -1,5 +1,5 @@
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:40:1
+  --> $DIR/unsupported.rs:43:1
    |
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "aapcs" is not supported on this target
-  --> $DIR/unsupported.rs:51:17
+  --> $DIR/unsupported.rs:50:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:64:1
+  --> $DIR/unsupported.rs:55:1
    |
 LL | extern "aapcs" {}
    | ^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:78:1
+  --> $DIR/unsupported.rs:65:1
    |
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:88:1
+  --> $DIR/unsupported.rs:75:1
    |
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "x86-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:118:15
+  --> $DIR/unsupported.rs:90:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:129:1
+  --> $DIR/unsupported.rs:95:1
    |
 LL | extern "x86-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "thiscall" is not supported on this target
-  --> $DIR/unsupported.rs:141:20
+  --> $DIR/unsupported.rs:100:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:154:1
+  --> $DIR/unsupported.rs:105:1
    |
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:167:19
+  --> $DIR/unsupported.rs:112:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -99,13 +99,69 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"stdcall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:180:1
+  --> $DIR/unsupported.rs:119:1
    |
 LL | extern "stdcall" {}
    | ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:123:1
+   |
+LL | extern "stdcall-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+
+warning: the calling convention "vectorcall" is not supported on this target
+  --> $DIR/unsupported.rs:145:22
+   |
+LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+error[E0570]: `"vectorcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:150:1
+   |
+LL | extern "vectorcall" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -114,7 +170,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -123,71 +179,89 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:200:1
+  --> $DIR/unsupported.rs:166:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:42:1
+  --> $DIR/unsupported.rs:45:1
    |
 LL | extern "gpu-kernel" fn gpu() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:45:1
+  --> $DIR/unsupported.rs:48:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:71:1
+  --> $DIR/unsupported.rs:58:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:81:1
+  --> $DIR/unsupported.rs:68:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:113:1
+  --> $DIR/unsupported.rs:88:1
    |
 LL | extern "x86-interrupt" fn x86() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:135:1
+  --> $DIR/unsupported.rs:98:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"stdcall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:161:1
+  --> $DIR/unsupported.rs:108:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+error[E0570]: `"vectorcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:143:1
+   |
+LL | extern "vectorcall" fn vectorcall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:193:1
+  --> $DIR/unsupported.rs:159:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 17 previous errors; 9 warnings emitted
+error: aborting due to 20 previous errors; 14 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
 Future incompatibility report: Future breakage diagnostic:
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -198,7 +272,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "aapcs" is not supported on this target
-  --> $DIR/unsupported.rs:51:17
+  --> $DIR/unsupported.rs:50:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -209,7 +283,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -220,7 +294,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -231,7 +305,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "x86-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:118:15
+  --> $DIR/unsupported.rs:90:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -242,7 +316,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "thiscall" is not supported on this target
-  --> $DIR/unsupported.rs:141:20
+  --> $DIR/unsupported.rs:100:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -253,7 +327,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:167:19
+  --> $DIR/unsupported.rs:112:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -263,8 +337,55 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "vectorcall" is not supported on this target
+  --> $DIR/unsupported.rs:145:22
+   |
+LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -275,7 +396,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -284,3 +405,15 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr
index c6ff47283c6..ad57a89e455 100644
--- a/tests/ui/abi/unsupported.riscv64.stderr
+++ b/tests/ui/abi/unsupported.riscv64.stderr
@@ -1,5 +1,5 @@
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:40:1
+  --> $DIR/unsupported.rs:43:1
    |
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "aapcs" is not supported on this target
-  --> $DIR/unsupported.rs:51:17
+  --> $DIR/unsupported.rs:50:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:64:1
+  --> $DIR/unsupported.rs:55:1
    |
 LL | extern "aapcs" {}
    | ^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:78:1
+  --> $DIR/unsupported.rs:65:1
    |
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:88:1
+  --> $DIR/unsupported.rs:75:1
    |
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "x86-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:118:15
+  --> $DIR/unsupported.rs:90:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:129:1
+  --> $DIR/unsupported.rs:95:1
    |
 LL | extern "x86-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "thiscall" is not supported on this target
-  --> $DIR/unsupported.rs:141:20
+  --> $DIR/unsupported.rs:100:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:154:1
+  --> $DIR/unsupported.rs:105:1
    |
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:167:19
+  --> $DIR/unsupported.rs:112:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -99,13 +99,69 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"stdcall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:180:1
+  --> $DIR/unsupported.rs:119:1
    |
 LL | extern "stdcall" {}
    | ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:123:1
+   |
+LL | extern "stdcall-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+
+warning: the calling convention "vectorcall" is not supported on this target
+  --> $DIR/unsupported.rs:145:22
+   |
+LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+error[E0570]: `"vectorcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:150:1
+   |
+LL | extern "vectorcall" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -114,7 +170,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -123,71 +179,89 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:200:1
+  --> $DIR/unsupported.rs:166:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:42:1
+  --> $DIR/unsupported.rs:45:1
    |
 LL | extern "gpu-kernel" fn gpu() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:45:1
+  --> $DIR/unsupported.rs:48:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:71:1
+  --> $DIR/unsupported.rs:58:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:81:1
+  --> $DIR/unsupported.rs:68:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:113:1
+  --> $DIR/unsupported.rs:88:1
    |
 LL | extern "x86-interrupt" fn x86() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:135:1
+  --> $DIR/unsupported.rs:98:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"stdcall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:161:1
+  --> $DIR/unsupported.rs:108:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+error[E0570]: `"vectorcall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:143:1
+   |
+LL | extern "vectorcall" fn vectorcall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:193:1
+  --> $DIR/unsupported.rs:159:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 17 previous errors; 9 warnings emitted
+error: aborting due to 20 previous errors; 14 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
 Future incompatibility report: Future breakage diagnostic:
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -198,7 +272,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "aapcs" is not supported on this target
-  --> $DIR/unsupported.rs:51:17
+  --> $DIR/unsupported.rs:50:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -209,7 +283,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -220,7 +294,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -231,7 +305,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "x86-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:118:15
+  --> $DIR/unsupported.rs:90:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -242,7 +316,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "thiscall" is not supported on this target
-  --> $DIR/unsupported.rs:141:20
+  --> $DIR/unsupported.rs:100:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -253,7 +327,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:167:19
+  --> $DIR/unsupported.rs:112:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -263,8 +337,55 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "vectorcall" is not supported on this target
+  --> $DIR/unsupported.rs:145:22
+   |
+LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -275,7 +396,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -284,3 +405,15 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs
index 84646502f6f..43bdfe3ea24 100644
--- a/tests/ui/abi/unsupported.rs
+++ b/tests/ui/abi/unsupported.rs
@@ -1,8 +1,10 @@
 //@ add-core-stubs
-//@ revisions: x64 i686 aarch64 arm riscv32 riscv64
+//@ revisions: x64 x64_win i686 aarch64 arm riscv32 riscv64
 //
 //@ [x64] needs-llvm-components: x86
 //@ [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib
+//@ [x64_win] needs-llvm-components: x86
+//@ [x64_win] compile-flags: --target=x86_64-pc-windows-msvc --crate-type=rlib
 //@ [i686] needs-llvm-components: x86
 //@ [i686] compile-flags: --target=i686-unknown-linux-gnu --crate-type=rlib
 //@ [aarch64] needs-llvm-components: aarch64
@@ -24,6 +26,7 @@
     abi_x86_interrupt,
     abi_riscv_interrupt,
     abi_c_cmse_nonsecure_call,
+    abi_vectorcall,
     cmse_nonsecure_entry
 )]
 
@@ -43,30 +46,14 @@ extern "gpu-kernel" fn gpu() {}
 //~^ ERROR is not a supported ABI
 
 extern "aapcs" fn aapcs() {}
-//[x64]~^ ERROR is not a supported ABI
-//[i686]~^^ ERROR is not a supported ABI
-//[aarch64]~^^^ ERROR is not a supported ABI
-//[riscv32]~^^^^ ERROR is not a supported ABI
-//[riscv64]~^^^^^ ERROR is not a supported ABI
+//[x64,x64_win,i686,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI
 fn aapcs_ptr(f: extern "aapcs" fn()) {
-    //[x64]~^ WARN unsupported_fn_ptr_calling_conventions
-    //[x64]~^^ WARN this was previously accepted
-    //[i686]~^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[i686]~^^^^ WARN this was previously accepted
-    //[aarch64]~^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[aarch64]~^^^^^^ WARN this was previously accepted
-    //[riscv32]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[riscv32]~^^^^^^^^ WARN this was previously accepted
-    //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[riscv64]~^^^^^^^^^^ WARN this was previously accepted
+    //[x64,x64_win,i686,aarch64,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions
+    //[x64,x64_win,i686,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted
     f()
 }
 extern "aapcs" {}
-//[x64]~^ ERROR is not a supported ABI
-//[i686]~^^ ERROR is not a supported ABI
-//[aarch64]~^^^ ERROR is not a supported ABI
-//[riscv32]~^^^^ ERROR is not a supported ABI
-//[riscv64]~^^^^^ ERROR is not a supported ABI
+//[x64,x64_win,i686,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI
 
 extern "msp430-interrupt" fn msp430() {}
 //~^ ERROR is not a supported ABI
@@ -89,100 +76,79 @@ extern "avr-interrupt" {}
 //~^ ERROR is not a supported ABI
 
 extern "riscv-interrupt-m" fn riscv() {}
-//[arm]~^ ERROR is not a supported ABI
-//[x64]~^^ ERROR is not a supported ABI
-//[i686]~^^^ ERROR is not a supported ABI
-//[aarch64]~^^^^ ERROR is not a supported ABI
+//[x64,x64_win,i686,arm,aarch64]~^ ERROR is not a supported ABI
 fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
-    //[arm]~^ WARN unsupported_fn_ptr_calling_conventions
-    //[arm]~^^ WARN this was previously accepted
-    //[x64]~^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[x64]~^^^^ WARN this was previously accepted
-    //[i686]~^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[i686]~^^^^^^ WARN this was previously accepted
-    //[aarch64]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[aarch64]~^^^^^^^^ WARN this was previously accepted
+    //[x64,x64_win,i686,arm,aarch64]~^ WARN unsupported_fn_ptr_calling_conventions
+    //[x64,x64_win,i686,arm,aarch64]~^^ WARN this was previously accepted
     f()
 }
 extern "riscv-interrupt-m" {}
-//[arm]~^ ERROR is not a supported ABI
-//[x64]~^^ ERROR is not a supported ABI
-//[i686]~^^^ ERROR is not a supported ABI
-//[aarch64]~^^^^ ERROR is not a supported ABI
+//[x64,x64_win,i686,arm,aarch64]~^ ERROR is not a supported ABI
 
 extern "x86-interrupt" fn x86() {}
-//[aarch64]~^ ERROR is not a supported ABI
-//[arm]~^^ ERROR is not a supported ABI
-//[riscv32]~^^^ ERROR is not a supported ABI
-//[riscv64]~^^^^ ERROR is not a supported ABI
+//[aarch64,arm,riscv32,riscv64]~^ ERROR is not a supported ABI
 fn x86_ptr(f: extern "x86-interrupt" fn()) {
-    //[aarch64]~^ WARN unsupported_fn_ptr_calling_conventions
-    //[aarch64]~^^ WARN this was previously accepted
-    //[arm]~^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[arm]~^^^^ WARN this was previously accepted
-    //[riscv32]~^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[riscv32]~^^^^^^ WARN this was previously accepted
-    //[riscv64]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[riscv64]~^^^^^^^^ WARN this was previously accepted
+    //[aarch64,arm,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions
+    //[aarch64,arm,riscv32,riscv64]~^^ WARN this was previously accepted
     f()
 }
 extern "x86-interrupt" {}
-//[aarch64]~^ ERROR is not a supported ABI
-//[arm]~^^ ERROR is not a supported ABI
-//[riscv32]~^^^ ERROR is not a supported ABI
-//[riscv64]~^^^^ ERROR is not a supported ABI
+//[aarch64,arm,riscv32,riscv64]~^ ERROR is not a supported ABI
 
 extern "thiscall" fn thiscall() {}
-//[x64]~^ ERROR is not a supported ABI
-//[arm]~^^ ERROR is not a supported ABI
-//[aarch64]~^^^ ERROR is not a supported ABI
-//[riscv32]~^^^^ ERROR is not a supported ABI
-//[riscv64]~^^^^^ ERROR is not a supported ABI
+//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI
 fn thiscall_ptr(f: extern "thiscall" fn()) {
-    //[x64]~^ WARN unsupported_fn_ptr_calling_conventions
-    //[x64]~^^ WARN this was previously accepted
-    //[arm]~^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[arm]~^^^^ WARN this was previously accepted
-    //[aarch64]~^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[aarch64]~^^^^^^ WARN this was previously accepted
-    //[riscv32]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[riscv32]~^^^^^^^^ WARN this was previously accepted
-    //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[riscv64]~^^^^^^^^^^ WARN this was previously accepted
+    //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions
+    //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted
     f()
 }
 extern "thiscall" {}
-//[x64]~^ ERROR is not a supported ABI
-//[arm]~^^ ERROR is not a supported ABI
-//[aarch64]~^^^ ERROR is not a supported ABI
-//[riscv32]~^^^^ ERROR is not a supported ABI
-//[riscv64]~^^^^^ ERROR is not a supported ABI
+//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI
 
 extern "stdcall" fn stdcall() {}
-//[x64]~^ ERROR is not a supported ABI
-//[arm]~^^ ERROR is not a supported ABI
-//[aarch64]~^^^ ERROR is not a supported ABI
-//[riscv32]~^^^^ ERROR is not a supported ABI
-//[riscv64]~^^^^^ ERROR is not a supported ABI
+//[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI
+//[x64_win]~^^ WARN unsupported_calling_conventions
+//[x64_win]~^^^ WARN this was previously accepted
 fn stdcall_ptr(f: extern "stdcall" fn()) {
-    //[x64]~^ WARN unsupported_fn_ptr_calling_conventions
-    //[x64]~^^ WARN this was previously accepted
-    //[arm]~^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[arm]~^^^^ WARN this was previously accepted
-    //[aarch64]~^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[aarch64]~^^^^^^ WARN this was previously accepted
-    //[riscv32]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[riscv32]~^^^^^^^^ WARN this was previously accepted
-    //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions
-    //[riscv64]~^^^^^^^^^^ WARN this was previously accepted
+    //[x64_win]~^ WARN unsupported_calling_conventions
+    //[x64_win]~| WARN this was previously accepted
+    //[x64,arm,aarch64,riscv32,riscv64]~^^^ WARN unsupported_fn_ptr_calling_conventions
+    //[x64,arm,aarch64,riscv32,riscv64]~| WARN this was previously accepted
     f()
 }
 extern "stdcall" {}
-//[x64]~^ ERROR is not a supported ABI
-//[arm]~^^ ERROR is not a supported ABI
-//[aarch64]~^^^ ERROR is not a supported ABI
-//[riscv32]~^^^^ ERROR is not a supported ABI
-//[riscv64]~^^^^^ ERROR is not a supported ABI
+//[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI
+//[x64_win]~^^ WARN unsupported_calling_conventions
+//[x64_win]~^^^ WARN this was previously accepted
+extern "stdcall-unwind" {}
+//[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI
+//[x64_win]~^^ WARN unsupported_calling_conventions
+//[x64_win]~^^^ WARN this was previously accepted
+
+extern "cdecl" fn cdecl() {}
+//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions
+//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted
+fn cdecl_ptr(f: extern "cdecl" fn()) {
+    //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions
+    //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted
+    f()
+}
+extern "cdecl" {}
+//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions
+//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted
+extern "cdecl-unwind" {}
+//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions
+//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted
+
+extern "vectorcall" fn vectorcall() {}
+//[arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI
+fn vectorcall_ptr(f: extern "vectorcall" fn()) {
+    //[arm,aarch64,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions
+    //[arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted
+    f()
+}
+extern "vectorcall" {}
+//[arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI
 
 fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
     //~^ WARN unsupported_fn_ptr_calling_conventions
@@ -199,3 +165,9 @@ fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
 }
 extern "C-cmse-nonsecure-entry" {}
 //~^ ERROR is not a supported ABI
+
+#[cfg(windows)]
+#[link(name = "foo", kind = "raw-dylib")]
+extern "cdecl" {}
+//[x64_win]~^ WARN use of calling convention not supported on this target
+//[x64_win]~^^ WARN this was previously accepted
diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr
index 0a9f9a69123..f777fe86e24 100644
--- a/tests/ui/abi/unsupported.x64.stderr
+++ b/tests/ui/abi/unsupported.x64.stderr
@@ -1,5 +1,5 @@
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:40:1
+  --> $DIR/unsupported.rs:43:1
    |
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "aapcs" is not supported on this target
-  --> $DIR/unsupported.rs:51:17
+  --> $DIR/unsupported.rs:50:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:64:1
+  --> $DIR/unsupported.rs:55:1
    |
 LL | extern "aapcs" {}
    | ^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:78:1
+  --> $DIR/unsupported.rs:65:1
    |
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:88:1
+  --> $DIR/unsupported.rs:75:1
    |
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "riscv-interrupt-m" is not supported on this target
-  --> $DIR/unsupported.rs:96:17
+  --> $DIR/unsupported.rs:80:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:107:1
+  --> $DIR/unsupported.rs:85:1
    |
 LL | extern "riscv-interrupt-m" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "thiscall" is not supported on this target
-  --> $DIR/unsupported.rs:141:20
+  --> $DIR/unsupported.rs:100:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:154:1
+  --> $DIR/unsupported.rs:105:1
    |
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:167:19
+  --> $DIR/unsupported.rs:112:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -99,13 +99,54 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"stdcall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:180:1
+  --> $DIR/unsupported.rs:119:1
    |
 LL | extern "stdcall" {}
    | ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:123:1
+   |
+LL | extern "stdcall-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
 
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -114,7 +155,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -123,71 +164,83 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:200:1
+  --> $DIR/unsupported.rs:166:1
    |
 LL | extern "C-cmse-nonsecure-entry" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:33:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:42:1
+  --> $DIR/unsupported.rs:45:1
    |
 LL | extern "gpu-kernel" fn gpu() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:45:1
+  --> $DIR/unsupported.rs:48:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:71:1
+  --> $DIR/unsupported.rs:58:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:81:1
+  --> $DIR/unsupported.rs:68:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:91:1
+  --> $DIR/unsupported.rs:78:1
    |
 LL | extern "riscv-interrupt-m" fn riscv() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:135:1
+  --> $DIR/unsupported.rs:98:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"stdcall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:161:1
+  --> $DIR/unsupported.rs:108:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
 
 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:193:1
+  --> $DIR/unsupported.rs:159:1
    |
 LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 17 previous errors; 9 warnings emitted
+error: aborting due to 18 previous errors; 13 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
 Future incompatibility report: Future breakage diagnostic:
 warning: the calling convention "ptx-kernel" is not supported on this target
-  --> $DIR/unsupported.rs:35:15
+  --> $DIR/unsupported.rs:38:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -198,7 +251,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "aapcs" is not supported on this target
-  --> $DIR/unsupported.rs:51:17
+  --> $DIR/unsupported.rs:50:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -209,7 +262,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "msp430-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:73:18
+  --> $DIR/unsupported.rs:60:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -220,7 +273,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "avr-interrupt" is not supported on this target
-  --> $DIR/unsupported.rs:83:15
+  --> $DIR/unsupported.rs:70:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -231,7 +284,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "riscv-interrupt-m" is not supported on this target
-  --> $DIR/unsupported.rs:96:17
+  --> $DIR/unsupported.rs:80:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -242,7 +295,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "thiscall" is not supported on this target
-  --> $DIR/unsupported.rs:141:20
+  --> $DIR/unsupported.rs:100:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -253,7 +306,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "stdcall" is not supported on this target
-  --> $DIR/unsupported.rs:167:19
+  --> $DIR/unsupported.rs:112:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    |                   ^^^^^^^^^^^^^^^^^^^^^
@@ -263,8 +316,44 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
 Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
-  --> $DIR/unsupported.rs:187:21
+  --> $DIR/unsupported.rs:153:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -275,7 +364,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
 
 Future breakage diagnostic:
 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
-  --> $DIR/unsupported.rs:195:22
+  --> $DIR/unsupported.rs:161:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -284,3 +373,15 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
 
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
diff --git a/tests/ui/abi/unsupported.x64_win.stderr b/tests/ui/abi/unsupported.x64_win.stderr
new file mode 100644
index 00000000000..328f4c3b043
--- /dev/null
+++ b/tests/ui/abi/unsupported.x64_win.stderr
@@ -0,0 +1,453 @@
+warning: the calling convention "ptx-kernel" is not supported on this target
+  --> $DIR/unsupported.rs:38:15
+   |
+LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:43:1
+   |
+LL | extern "ptx-kernel" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: the calling convention "aapcs" is not supported on this target
+  --> $DIR/unsupported.rs:50:17
+   |
+LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+error[E0570]: `"aapcs"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:55:1
+   |
+LL | extern "aapcs" {}
+   | ^^^^^^^^^^^^^^^^^
+
+warning: the calling convention "msp430-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:60:18
+   |
+LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:65:1
+   |
+LL | extern "msp430-interrupt" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: the calling convention "avr-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:70:15
+   |
+LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:75:1
+   |
+LL | extern "avr-interrupt" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: the calling convention "riscv-interrupt-m" is not supported on this target
+  --> $DIR/unsupported.rs:80:17
+   |
+LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:85:1
+   |
+LL | extern "riscv-interrupt-m" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: the calling convention "thiscall" is not supported on this target
+  --> $DIR/unsupported.rs:100:20
+   |
+LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
+   |                    ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+error[E0570]: `"thiscall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:105:1
+   |
+LL | extern "thiscall" {}
+   | ^^^^^^^^^^^^^^^^^^^^
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:112:19
+   |
+LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
+   |                   ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:119:1
+   |
+LL | extern "stdcall" {}
+   | ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:123:1
+   |
+LL | extern "stdcall-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
+  --> $DIR/unsupported.rs:153:21
+   |
+LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
+  --> $DIR/unsupported.rs:161:22
+   |
+LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+
+error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:166:1
+   |
+LL | extern "C-cmse-nonsecure-entry" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:171:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:36:1
+   |
+LL | extern "ptx-kernel" fn ptx() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:45:1
+   |
+LL | extern "gpu-kernel" fn gpu() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"aapcs"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:48:1
+   |
+LL | extern "aapcs" fn aapcs() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:58:1
+   |
+LL | extern "msp430-interrupt" fn msp430() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:68:1
+   |
+LL | extern "avr-interrupt" fn avr() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:78:1
+   |
+LL | extern "riscv-interrupt-m" fn riscv() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"thiscall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:98:1
+   |
+LL | extern "thiscall" fn thiscall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:108:1
+   |
+LL | extern "stdcall" fn stdcall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+
+error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:159:1
+   |
+LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 15 previous errors; 17 warnings emitted
+
+For more information about this error, try `rustc --explain E0570`.
+Future incompatibility report: Future breakage diagnostic:
+warning: the calling convention "ptx-kernel" is not supported on this target
+  --> $DIR/unsupported.rs:38:15
+   |
+LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "aapcs" is not supported on this target
+  --> $DIR/unsupported.rs:50:17
+   |
+LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "msp430-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:60:18
+   |
+LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "avr-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:70:15
+   |
+LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "riscv-interrupt-m" is not supported on this target
+  --> $DIR/unsupported.rs:80:17
+   |
+LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "thiscall" is not supported on this target
+  --> $DIR/unsupported.rs:100:20
+   |
+LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
+   |                    ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:112:19
+   |
+LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
+   |                   ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:119:1
+   |
+LL | extern "stdcall" {}
+   | ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:123:1
+   |
+LL | extern "stdcall-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"`
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:131:17
+   |
+LL | fn cdecl_ptr(f: extern "cdecl" fn()) {
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:136:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:139:1
+   |
+LL | extern "cdecl-unwind" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C-unwind"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
+  --> $DIR/unsupported.rs:153:21
+   |
+LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
+  --> $DIR/unsupported.rs:161:22
+   |
+LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:171:1
+   |
+LL | extern "cdecl" {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:108:1
+   |
+LL | extern "stdcall" fn stdcall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:128:1
+   |
+LL | extern "cdecl" fn cdecl() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: use `extern "C"` instead
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
diff --git a/tests/ui/array-slice-vec/array_const_index-0.stderr b/tests/ui/array-slice-vec/array_const_index-0.stderr
index 1080705713b..04cb6849663 100644
--- a/tests/ui/array-slice-vec/array_const_index-0.stderr
+++ b/tests/ui/array-slice-vec/array_const_index-0.stderr
@@ -2,7 +2,7 @@ error[E0080]: index out of bounds: the length is 0 but the index is 1
   --> $DIR/array_const_index-0.rs:2:16
    |
 LL | const B: i32 = (&A)[1];
-   |                ^^^^^^^ evaluation of constant value failed here
+   |                ^^^^^^^ evaluation of `B` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/array-slice-vec/array_const_index-1.stderr b/tests/ui/array-slice-vec/array_const_index-1.stderr
index 56299848d92..68b02673b01 100644
--- a/tests/ui/array-slice-vec/array_const_index-1.stderr
+++ b/tests/ui/array-slice-vec/array_const_index-1.stderr
@@ -2,7 +2,7 @@ error[E0080]: index out of bounds: the length is 0 but the index is 1
   --> $DIR/array_const_index-1.rs:2:16
    |
 LL | const B: i32 = A[1];
-   |                ^^^^ evaluation of constant value failed here
+   |                ^^^^ evaluation of `B` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/asm/x86_64/evex512-implicit-feature.rs b/tests/ui/asm/x86_64/evex512-implicit-feature.rs
index ec5da7c7fa4..1f678b2387a 100644
--- a/tests/ui/asm/x86_64/evex512-implicit-feature.rs
+++ b/tests/ui/asm/x86_64/evex512-implicit-feature.rs
@@ -2,8 +2,6 @@
 //@ only-x86_64
 //@ compile-flags: --crate-type=lib -C target-cpu=skylake
 
-#![feature(stdarch_x86_avx512)]
-
 use std::arch::x86_64::*;
 
 #[target_feature(enable = "avx512f")]
diff --git a/tests/ui/associated-inherent-types/issue-109299-1.stderr b/tests/ui/associated-inherent-types/issue-109299-1.stderr
index 940ccd7e400..6bc7a539680 100644
--- a/tests/ui/associated-inherent-types/issue-109299-1.stderr
+++ b/tests/ui/associated-inherent-types/issue-109299-1.stderr
@@ -1,3 +1,11 @@
+error: unconstrained opaque type
+  --> $DIR/issue-109299-1.rs:10:10
+   |
+LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor;
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `X` must be used in combination with a concrete type within the same crate
+
 error[E0220]: associated type `Cursor` not found for `Lexer<T>` in the current scope
   --> $DIR/issue-109299-1.rs:10:40
    |
@@ -23,14 +31,6 @@ LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor;
            - `Lexer<i32>`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: unconstrained opaque type
-  --> $DIR/issue-109299-1.rs:10:10
-   |
-LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor;
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `X` must be used in combination with a concrete type within the same crate
-
 error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0220`.
diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr
index 1ce212a9ff3..68fbb345f6f 100644
--- a/tests/ui/associated-type-bounds/duplicate.stderr
+++ b/tests/ui/associated-type-bounds/duplicate.stderr
@@ -199,16 +199,6 @@ LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
    |                              `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:133:42
-   |
-LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
-   |                              ----------  ^^^^^^^^^^ re-bound here
-   |                              |
-   |                              `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:139:42
    |
 LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
@@ -217,32 +207,12 @@ LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
    |                              `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:139:42
-   |
-LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
-   |                              ----------  ^^^^^^^^^^ re-bound here
-   |                              |
-   |                              `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:145:45
-   |
-LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
-   |                              -------------  ^^^^^^^^^^^^^ re-bound here
-   |                              |
-   |                              `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:145:45
    |
 LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
    |                              -------------  ^^^^^^^^^^^^^ re-bound here
    |                              |
    |                              `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:151:40
@@ -341,60 +311,6 @@ LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:189:40
-   |
-LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:189:40
-   |
-LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:193:40
-   |
-LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:193:40
-   |
-LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:197:43
-   |
-LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
-   |                            -------------  ^^^^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:197:43
-   |
-LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
-   |                            -------------  ^^^^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:202:36
    |
 LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
@@ -664,6 +580,16 @@ LL |     type A: Iterator<Item: 'static, Item: 'static>;
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:133:42
+   |
+LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
+   |                              ----------  ^^^^^^^^^^ re-bound here
+   |                              |
+   |                              `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0282]: type annotations needed
   --> $DIR/duplicate.rs:136:5
    |
@@ -675,6 +601,16 @@ help: consider specifying the generic argument
 LL |     iter::empty::<T>()
    |                +++++
 
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:139:42
+   |
+LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
+   |                              ----------  ^^^^^^^^^^ re-bound here
+   |                              |
+   |                              `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0282]: type annotations needed
   --> $DIR/duplicate.rs:142:5
    |
@@ -686,6 +622,16 @@ help: consider specifying the generic argument
 LL |     iter::empty::<T>()
    |                +++++
 
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:145:45
+   |
+LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
+   |                              -------------  ^^^^^^^^^^^^^ re-bound here
+   |                              |
+   |                              `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0282]: type annotations needed
   --> $DIR/duplicate.rs:148:5
    |
@@ -729,6 +675,24 @@ LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |
    = note: `ETAI4` must be used in combination with a concrete type within the same crate
 
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:189:40
+   |
+LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
+   |                            ----------  ^^^^^^^^^^ re-bound here
+   |                            |
+   |                            `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:189:40
+   |
+LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
+   |                            ----------  ^^^^^^^^^^ re-bound here
+   |                            |
+   |                            `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error: unconstrained opaque type
   --> $DIR/duplicate.rs:193:14
    |
@@ -737,6 +701,24 @@ LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |
    = note: `ETAI5` must be used in combination with a concrete type within the same crate
 
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:193:40
+   |
+LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
+   |                            ----------  ^^^^^^^^^^ re-bound here
+   |                            |
+   |                            `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:193:40
+   |
+LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
+   |                            ----------  ^^^^^^^^^^ re-bound here
+   |                            |
+   |                            `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error: unconstrained opaque type
   --> $DIR/duplicate.rs:197:14
    |
@@ -745,6 +727,24 @@ LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |
    = note: `ETAI6` must be used in combination with a concrete type within the same crate
 
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:197:43
+   |
+LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
+   |                            -------------  ^^^^^^^^^^^^^ re-bound here
+   |                            |
+   |                            `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:197:43
+   |
+LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
+   |                            -------------  ^^^^^^^^^^^^^ re-bound here
+   |                            |
+   |                            `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error: aborting due to 87 previous errors
 
 Some errors have detailed explanations: E0282, E0719.
diff --git a/tests/ui/associated-types/associated-types-impl-redirect.rs b/tests/ui/associated-types/associated-types-impl-redirect.rs
index 65e6a094b77..2cbe0d72540 100644
--- a/tests/ui/associated-types/associated-types-impl-redirect.rs
+++ b/tests/ui/associated-types/associated-types-impl-redirect.rs
@@ -21,7 +21,7 @@ trait Iterator {
 }
 
 trait IteratorExt: Iterator + Sized {
-    fn by_ref(&mut self) -> ByRef<Self> {
+    fn by_ref(&mut self) -> ByRef<'_, Self> {
         ByRef(self)
     }
 }
diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
index f15de0d9a28..b32323181b5 100644
--- a/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
+++ b/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
@@ -21,11 +21,11 @@ trait SliceExt2 {
 impl<T> SliceExt2 for [T] {
     type Item = T;
 
-    fn split2<P>(&self, pred: P) -> Splits<T, P> where P: FnMut(&T) -> bool {
+    fn split2<P>(&self, pred: P) -> Splits<'_, T, P> where P: FnMut(&T) -> bool {
         loop {}
     }
 
-    fn splitn2<P>(&self, n: u32, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
+    fn splitn2<P>(&self, n: u32, pred: P) -> SplitsN<Splits<'_, T, P>> where P: FnMut(&T) -> bool {
         SliceExt2::split2(self, pred);
         loop {}
     }
diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds.rs
index 7e94d3a011f..6844c5f9adb 100644
--- a/tests/ui/associated-types/associated-types-normalize-in-bounds.rs
+++ b/tests/ui/associated-types/associated-types-normalize-in-bounds.rs
@@ -3,32 +3,40 @@
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-
 use std::marker::PhantomData;
 
-struct Splits<'a, T, P>(PhantomData<(&'a(),T,P)>);
+struct Splits<'a, T, P>(PhantomData<(&'a (), T, P)>);
 struct SplitsN<I>(PhantomData<I>);
 
 trait SliceExt2 {
     type Item;
 
     fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P>
-        where P: FnMut(&Self::Item) -> bool;
+    where
+        P: FnMut(&Self::Item) -> bool;
+
     fn splitn2<'a, P>(&'a self, n: usize, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
-        where P: FnMut(&Self::Item) -> bool;
+    where
+        P: FnMut(&Self::Item) -> bool;
 }
 
 impl<T> SliceExt2 for [T] {
     type Item = T;
 
-    fn split2<P>(&self, pred: P) -> Splits<T, P> where P: FnMut(&T) -> bool {
+    fn split2<P>(&self, pred: P) -> Splits<'_, T, P>
+    where
+        P: FnMut(&T) -> bool,
+    {
         loop {}
     }
 
-    fn splitn2<P>(&self, n: usize, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
+    fn splitn2<P>(&self, n: usize, pred: P) -> SplitsN<Splits<'_, T, P>>
+    where
+        P: FnMut(&T) -> bool,
+    {
         self.split2(pred);
         loop {}
     }
 }
 
-fn main() { }
+fn main() {}
diff --git a/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs b/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs
index dcfa3532cdf..34c269d4d90 100644
--- a/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs
+++ b/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs
@@ -20,7 +20,7 @@ trait Iterator {
 }
 
 trait IteratorExt: Iterator + Sized {
-    fn by_ref(&mut self) -> ByRef<Self> {
+    fn by_ref(&mut self) -> ByRef<'_, Self> {
         ByRef(self)
     }
 }
diff --git a/tests/ui/associated-types/cache/elision.rs b/tests/ui/associated-types/cache/elision.rs
index 12765fc5811..7ddb32ea874 100644
--- a/tests/ui/associated-types/cache/elision.rs
+++ b/tests/ui/associated-types/cache/elision.rs
@@ -14,7 +14,7 @@ pub trait UnicodeStr {
 
 impl UnicodeStr for str {
     #[inline]
-    fn split_whitespace(&self) -> SplitWhitespace {
+    fn split_whitespace(&self) -> SplitWhitespace<'_> {
         unimplemented!()
     }
 }
diff --git a/tests/ui/associated-types/project-defer-unification.rs b/tests/ui/associated-types/project-defer-unification.rs
index b51228ef411..a949171db12 100644
--- a/tests/ui/associated-types/project-defer-unification.rs
+++ b/tests/ui/associated-types/project-defer-unification.rs
@@ -50,7 +50,7 @@ where P: Pixel + 'static,
         loop { }
     }
 
-    pub fn pixels_mut(&mut self) -> PixelsMut<P> {
+    pub fn pixels_mut(&mut self) -> PixelsMut<'_, P> {
         loop { }
     }
 }
diff --git a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr
index 4ed15a942c6..b64690bae6c 100644
--- a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -1,19 +1,3 @@
-error[E0267]: `break` inside `async` block
-  --> $DIR/async-block-control-flow-static-semantics.rs:32:9
-   |
-LL |     async {
-   |     ----- enclosing `async` block
-LL |         break 0u8;
-   |         ^^^^^^^^^ cannot `break` inside `async` block
-
-error[E0267]: `break` inside `async` block
-  --> $DIR/async-block-control-flow-static-semantics.rs:39:13
-   |
-LL |         async {
-   |         ----- enclosing `async` block
-LL |             break 0u8;
-   |             ^^^^^^^^^ cannot `break` inside `async` block
-
 error[E0308]: mismatched types
   --> $DIR/async-block-control-flow-static-semantics.rs:21:58
    |
@@ -50,6 +34,22 @@ LL |     let _: &dyn Future<Output = ()> = &block;
    |
    = note: required for the cast from `&{async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 14:22}` to `&dyn Future<Output = ()>`
 
+error[E0267]: `break` inside `async` block
+  --> $DIR/async-block-control-flow-static-semantics.rs:32:9
+   |
+LL |     async {
+   |     ----- enclosing `async` block
+LL |         break 0u8;
+   |         ^^^^^^^^^ cannot `break` inside `async` block
+
+error[E0267]: `break` inside `async` block
+  --> $DIR/async-block-control-flow-static-semantics.rs:39:13
+   |
+LL |         async {
+   |         ----- enclosing `async` block
+LL |             break 0u8;
+   |             ^^^^^^^^^ cannot `break` inside `async` block
+
 error[E0308]: mismatched types
   --> $DIR/async-block-control-flow-static-semantics.rs:49:44
    |
diff --git a/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr b/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr
index 8c9d06c79ca..40d44db205f 100644
--- a/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr
+++ b/tests/ui/async-await/debug-ice-attempted-to-add-with-overflow.stderr
@@ -2,14 +2,16 @@ error[E0277]: `[usize; usize::MAX]` is not a future
   --> $DIR/debug-ice-attempted-to-add-with-overflow.rs:8:37
    |
 LL |     [0usize; 0xffff_ffff_ffff_ffff].await;
-   |                                    -^^^^^
-   |                                    ||
-   |                                    |`[usize; usize::MAX]` is not a future
-   |                                    help: remove the `.await`
+   |                                     ^^^^^ `[usize; usize::MAX]` is not a future
    |
    = help: the trait `Future` is not implemented for `[usize; usize::MAX]`
    = note: [usize; usize::MAX] must be a future or must implement `IntoFuture` to be awaited
    = note: required for `[usize; usize::MAX]` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -     [0usize; 0xffff_ffff_ffff_ffff].await;
+LL +     [0usize; 0xffff_ffff_ffff_ffff];
+   |
 
 error[E0752]: `main` function is not allowed to be `async`
   --> $DIR/debug-ice-attempted-to-add-with-overflow.rs:6:1
diff --git a/tests/ui/async-await/drop-track-bad-field-in-fru.stderr b/tests/ui/async-await/drop-track-bad-field-in-fru.stderr
index 721e0106293..644a7c7717c 100644
--- a/tests/ui/async-await/drop-track-bad-field-in-fru.stderr
+++ b/tests/ui/async-await/drop-track-bad-field-in-fru.stderr
@@ -10,14 +10,16 @@ error[E0277]: `Option<_>` is not a future
   --> $DIR/drop-track-bad-field-in-fru.rs:6:46
    |
 LL |     None { value: (), ..Default::default() }.await;
-   |                                             -^^^^^
-   |                                             ||
-   |                                             |`Option<_>` is not a future
-   |                                             help: remove the `.await`
+   |                                              ^^^^^ `Option<_>` is not a future
    |
    = help: the trait `Future` is not implemented for `Option<_>`
    = note: Option<_> must be a future or must implement `IntoFuture` to be awaited
    = note: required for `Option<_>` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -     None { value: (), ..Default::default() }.await;
+LL +     None { value: (), ..Default::default() };
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/async-await/issue-101715.stderr b/tests/ui/async-await/issue-101715.stderr
index f6af15c00d6..87302dce130 100644
--- a/tests/ui/async-await/issue-101715.stderr
+++ b/tests/ui/async-await/issue-101715.stderr
@@ -2,14 +2,15 @@ error[E0277]: `()` is not a future
   --> $DIR/issue-101715.rs:11:10
    |
 LL |         .await
-   |         -^^^^^
-   |         ||
-   |         |`()` is not a future
-   |         help: remove the `.await`
+   |          ^^^^^ `()` is not a future
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
    = note: required for `()` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -         .await
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/async-await/issues/issue-63388-1.rs b/tests/ui/async-await/issues/issue-63388-1.rs
index acfc64baff9..3a89f3ebfd2 100644
--- a/tests/ui/async-await/issues/issue-63388-1.rs
+++ b/tests/ui/async-await/issues/issue-63388-1.rs
@@ -9,7 +9,7 @@ trait Foo {}
 impl Xyz {
     async fn do_sth<'a>(
         &'a self, foo: &dyn Foo
-    ) -> &dyn Foo  //~ WARNING elided lifetime has a name
+    ) -> &dyn Foo
     {
         foo
         //~^ ERROR explicit lifetime required in the type of `foo` [E0621]
diff --git a/tests/ui/async-await/issues/issue-63388-1.stderr b/tests/ui/async-await/issues/issue-63388-1.stderr
index 579caa45bc9..277f7fa6f63 100644
--- a/tests/ui/async-await/issues/issue-63388-1.stderr
+++ b/tests/ui/async-await/issues/issue-63388-1.stderr
@@ -1,14 +1,3 @@
-warning: elided lifetime has a name
-  --> $DIR/issue-63388-1.rs:12:10
-   |
-LL |     async fn do_sth<'a>(
-   |                     -- lifetime `'a` declared here
-LL |         &'a self, foo: &dyn Foo
-LL |     ) -> &dyn Foo
-   |          ^ this elided lifetime gets resolved as `'a`
-   |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
-
 error[E0621]: explicit lifetime required in the type of `foo`
   --> $DIR/issue-63388-1.rs:14:9
    |
@@ -18,6 +7,6 @@ LL |         &'a self, foo: &dyn Foo
 LL |         foo
    |         ^^^ lifetime `'a` required
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/async-await/unnecessary-await.stderr b/tests/ui/async-await/unnecessary-await.stderr
index 620370a6113..f60b4ecb990 100644
--- a/tests/ui/async-await/unnecessary-await.stderr
+++ b/tests/ui/async-await/unnecessary-await.stderr
@@ -23,14 +23,16 @@ error[E0277]: `()` is not a future
   --> $DIR/unnecessary-await.rs:28:10
    |
 LL |     e!().await;
-   |         -^^^^^
-   |         ||
-   |         |`()` is not a future
-   |         help: remove the `.await`
+   |          ^^^^^ `()` is not a future
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
    = note: required for `()` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -     e!().await;
+LL +     e!();
+   |
 
 error[E0277]: `()` is not a future
   --> $DIR/unnecessary-await.rs:22:15
@@ -53,14 +55,16 @@ error[E0277]: `()` is not a future
   --> $DIR/unnecessary-await.rs:36:20
    |
 LL |     for x in [] {}.await
-   |                   -^^^^^
-   |                   ||
-   |                   |`()` is not a future
-   |                   help: remove the `.await`
+   |                    ^^^^^ `()` is not a future
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
    = note: required for `()` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -     for x in [] {}.await
+LL +     for x in [] {}
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/custom_attribute.rs b/tests/ui/attributes/attr_unknown_custom_attr.rs
index 4957184229d..cdbe48a636f 100644
--- a/tests/ui/custom_attribute.rs
+++ b/tests/ui/attributes/attr_unknown_custom_attr.rs
@@ -1,3 +1,5 @@
+//! Checks error handling for undefined custom attributes.
+
 #![feature(stmt_expr_attributes)]
 
 #[foo] //~ ERROR cannot find attribute `foo` in this scope
diff --git a/tests/ui/custom_attribute.stderr b/tests/ui/attributes/attr_unknown_custom_attr.stderr
index 4023892d294..76c3b884a5d 100644
--- a/tests/ui/custom_attribute.stderr
+++ b/tests/ui/attributes/attr_unknown_custom_attr.stderr
@@ -1,17 +1,17 @@
 error: cannot find attribute `foo` in this scope
-  --> $DIR/custom_attribute.rs:3:3
+  --> $DIR/attr_unknown_custom_attr.rs:5:3
    |
 LL | #[foo]
    |   ^^^
 
 error: cannot find attribute `foo` in this scope
-  --> $DIR/custom_attribute.rs:5:7
+  --> $DIR/attr_unknown_custom_attr.rs:7:7
    |
 LL |     #[foo]
    |       ^^^
 
 error: cannot find attribute `foo` in this scope
-  --> $DIR/custom_attribute.rs:7:7
+  --> $DIR/attr_unknown_custom_attr.rs:9:7
    |
 LL |     #[foo]
    |       ^^^
diff --git a/tests/ui/crate-name-attr-used.rs b/tests/ui/attributes/crate-name-attr-validation.rs
index 5d5a58c32c7..e27893c3d25 100644
--- a/tests/ui/crate-name-attr-used.rs
+++ b/tests/ui/attributes/crate-name-attr-validation.rs
@@ -1,3 +1,5 @@
+//! Checks proper validation of the `#![crate_name]` attribute.
+
 //@ run-pass
 //@ compile-flags:--crate-name crate_name_attr_used -F unused-attributes
 
diff --git a/tests/ui/crate-name-mismatch.rs b/tests/ui/attributes/crate-name-mismatch.rs
index 7651e0f97eb..0c343d70b9c 100644
--- a/tests/ui/crate-name-mismatch.rs
+++ b/tests/ui/attributes/crate-name-mismatch.rs
@@ -1,3 +1,5 @@
+//! Checks error handling for mismatched `--crate-name` and `#![crate_name]` values.
+
 //@ compile-flags: --crate-name foo
 
 #![crate_name = "bar"]
diff --git a/tests/ui/crate-name-mismatch.stderr b/tests/ui/attributes/crate-name-mismatch.stderr
index 511562618d5..4021fbe7c18 100644
--- a/tests/ui/crate-name-mismatch.stderr
+++ b/tests/ui/attributes/crate-name-mismatch.stderr
@@ -1,5 +1,5 @@
 error: `--crate-name` and `#[crate_name]` are required to match, but `foo` != `bar`
-  --> $DIR/crate-name-mismatch.rs:3:1
+  --> $DIR/crate-name-mismatch.rs:5:1
    |
 LL | #![crate_name = "bar"]
    | ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/custom-attribute-multisegment.rs b/tests/ui/attributes/custom_attr_multisegment_error.rs
index 24349213902..1045282c3a3 100644
--- a/tests/ui/custom-attribute-multisegment.rs
+++ b/tests/ui/attributes/custom_attr_multisegment_error.rs
@@ -1,4 +1,4 @@
-// Unresolved multi-segment attributes are not treated as custom.
+//! Unresolved multi-segment attributes are not treated as custom.
 
 mod existent {}
 
diff --git a/tests/ui/custom-attribute-multisegment.stderr b/tests/ui/attributes/custom_attr_multisegment_error.stderr
index 90ebe277939..02bed225d53 100644
--- a/tests/ui/custom-attribute-multisegment.stderr
+++ b/tests/ui/attributes/custom_attr_multisegment_error.stderr
@@ -1,5 +1,5 @@
 error[E0433]: failed to resolve: could not find `nonexistent` in `existent`
-  --> $DIR/custom-attribute-multisegment.rs:5:13
+  --> $DIR/custom_attr_multisegment_error.rs:5:13
    |
 LL | #[existent::nonexistent]
    |             ^^^^^^^^^^^ could not find `nonexistent` in `existent`
diff --git a/tests/ui/borrowck/copy-suggestion-region-vid.fixed b/tests/ui/borrowck/copy-suggestion-region-vid.fixed
index 7fe18615408..2bc8a74086e 100644
--- a/tests/ui/borrowck/copy-suggestion-region-vid.fixed
+++ b/tests/ui/borrowck/copy-suggestion-region-vid.fixed
@@ -7,7 +7,7 @@ pub struct HelperStruct<'n> {
 }
 
 impl DataStruct {
-    pub fn f(&self) -> HelperStruct {
+    pub fn f(&self) -> HelperStruct<'_> {
         let helpers = [vec![], vec![]];
 
         HelperStruct { helpers: helpers.clone(), is_empty: helpers[0].is_empty() }
diff --git a/tests/ui/borrowck/copy-suggestion-region-vid.rs b/tests/ui/borrowck/copy-suggestion-region-vid.rs
index daafba71ece..248ce80d22b 100644
--- a/tests/ui/borrowck/copy-suggestion-region-vid.rs
+++ b/tests/ui/borrowck/copy-suggestion-region-vid.rs
@@ -7,7 +7,7 @@ pub struct HelperStruct<'n> {
 }
 
 impl DataStruct {
-    pub fn f(&self) -> HelperStruct {
+    pub fn f(&self) -> HelperStruct<'_> {
         let helpers = [vec![], vec![]];
 
         HelperStruct { helpers, is_empty: helpers[0].is_empty() }
diff --git a/tests/ui/borrowck/issue-81899.stderr b/tests/ui/borrowck/issue-81899.stderr
index d236a17e0aa..96fe2ad709a 100644
--- a/tests/ui/borrowck/issue-81899.stderr
+++ b/tests/ui/borrowck/issue-81899.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/issue-81899.rs:6:24
    |
 LL | const _CONST: &[u8] = &f(&[], |_| {});
-   |                        ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^ evaluation of `_CONST` failed inside this call
    |
 note: inside `f::<{closure@$DIR/issue-81899.rs:6:31: 6:34}>`
   --> $DIR/issue-81899.rs:13:5
diff --git a/tests/ui/borrowck/issue-88434-minimal-example.stderr b/tests/ui/borrowck/issue-88434-minimal-example.stderr
index 3d9cc966047..3921c47640e 100644
--- a/tests/ui/borrowck/issue-88434-minimal-example.stderr
+++ b/tests/ui/borrowck/issue-88434-minimal-example.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/issue-88434-minimal-example.rs:5:22
    |
 LL | const _CONST: &() = &f(&|_| {});
-   |                      ^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^ evaluation of `_CONST` failed inside this call
    |
 note: inside `f::<{closure@$DIR/issue-88434-minimal-example.rs:5:25: 5:28}>`
   --> $DIR/issue-88434-minimal-example.rs:12:5
diff --git a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
index 90d7f36938e..c7f945dc6ef 100644
--- a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
+++ b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/issue-88434-removal-index-should-be-less.rs:5:24
    |
 LL | const _CONST: &[u8] = &f(&[], |_| {});
-   |                        ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^ evaluation of `_CONST` failed inside this call
    |
 note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:5:31: 5:34}>`
   --> $DIR/issue-88434-removal-index-should-be-less.rs:12:5
diff --git a/tests/ui/cleanup-rvalue-scopes-cf.rs b/tests/ui/borrowck/rvalue-borrow-scope-error.rs
index e3cecb1bffe..5bf96e800d3 100644
--- a/tests/ui/cleanup-rvalue-scopes-cf.rs
+++ b/tests/ui/borrowck/rvalue-borrow-scope-error.rs
@@ -1,15 +1,19 @@
-// Test that the borrow checker prevents pointers to temporaries
-// with statement lifetimes from escaping.
+//! Test that the borrow checker prevents pointers to temporaries
+//! with statement lifetimes from escaping.
 
 use std::ops::Drop;
 
 static mut FLAGS: u64 = 0;
 
-struct StackBox<T> { f: T }
-struct AddFlags { bits: u64 }
+struct StackBox<T> {
+    f: T,
+}
+struct AddFlags {
+    bits: u64,
+}
 
 fn AddFlags(bits: u64) -> AddFlags {
-    AddFlags { bits: bits }
+    AddFlags { bits }
 }
 
 fn arg(x: &AddFlags) -> &AddFlags {
diff --git a/tests/ui/cleanup-rvalue-scopes-cf.stderr b/tests/ui/borrowck/rvalue-borrow-scope-error.stderr
index 425cd75141c..bedcfce4541 100644
--- a/tests/ui/cleanup-rvalue-scopes-cf.stderr
+++ b/tests/ui/borrowck/rvalue-borrow-scope-error.stderr
@@ -1,5 +1,5 @@
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/cleanup-rvalue-scopes-cf.rs:26:19
+  --> $DIR/rvalue-borrow-scope-error.rs:30:19
    |
 LL |     let x1 = arg(&AddFlags(1));
    |                   ^^^^^^^^^^^ - temporary value is freed at the end of this statement
@@ -16,7 +16,7 @@ LL ~     let x1 = arg(&binding);
    |
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/cleanup-rvalue-scopes-cf.rs:27:14
+  --> $DIR/rvalue-borrow-scope-error.rs:31:14
    |
 LL |     let x2 = AddFlags(1).get();
    |              ^^^^^^^^^^^      - temporary value is freed at the end of this statement
@@ -33,7 +33,7 @@ LL ~     let x2 = binding.get();
    |
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/cleanup-rvalue-scopes-cf.rs:28:21
+  --> $DIR/rvalue-borrow-scope-error.rs:32:21
    |
 LL |     let x3 = &*arg(&AddFlags(1));
    |                     ^^^^^^^^^^^ - temporary value is freed at the end of this statement
@@ -50,7 +50,7 @@ LL ~     let x3 = &*arg(&binding);
    |
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/cleanup-rvalue-scopes-cf.rs:29:24
+  --> $DIR/rvalue-borrow-scope-error.rs:33:24
    |
 LL |     let ref x4 = *arg(&AddFlags(1));
    |                        ^^^^^^^^^^^ - temporary value is freed at the end of this statement
@@ -67,7 +67,7 @@ LL ~     let ref x4 = *arg(&binding);
    |
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/cleanup-rvalue-scopes-cf.rs:30:24
+  --> $DIR/rvalue-borrow-scope-error.rs:34:24
    |
 LL |     let &ref x5 = arg(&AddFlags(1));
    |                        ^^^^^^^^^^^ - temporary value is freed at the end of this statement
@@ -84,7 +84,7 @@ LL ~     let &ref x5 = arg(&binding);
    |
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/cleanup-rvalue-scopes-cf.rs:31:14
+  --> $DIR/rvalue-borrow-scope-error.rs:35:14
    |
 LL |     let x6 = AddFlags(1).get();
    |              ^^^^^^^^^^^      - temporary value is freed at the end of this statement
@@ -101,7 +101,7 @@ LL ~     let x6 = binding.get();
    |
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/cleanup-rvalue-scopes-cf.rs:32:44
+  --> $DIR/rvalue-borrow-scope-error.rs:36:44
    |
 LL |     let StackBox { f: x7 } = StackBox { f: AddFlags(1).get() };
    |                                            ^^^^^^^^^^^        - temporary value is freed at the end of this statement
diff --git a/tests/ui/break-diverging-value.rs b/tests/ui/break-diverging-value.rs
deleted file mode 100644
index d070fddaffc..00000000000
--- a/tests/ui/break-diverging-value.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-#![feature(never_type)]
-
-fn loop_break_return() -> i32 {
-    let loop_value = loop { break return 0 }; // ok
-}
-
-fn loop_break_loop() -> i32 {
-    let loop_value = loop { break loop {} }; // ok
-}
-
-fn loop_break_break() -> i32 { //~ ERROR mismatched types
-    let loop_value = loop { break break };
-}
-
-fn loop_break_return_2() -> i32 {
-    let loop_value = loop { break { return 0; () } }; // ok
-}
-
-enum Void {}
-
-fn get_void() -> Void {
-    panic!()
-}
-
-fn loop_break_void() -> i32 { //~ ERROR mismatched types
-    let loop_value = loop { break get_void() };
-}
-
-fn get_never() -> ! {
-    panic!()
-}
-
-fn loop_break_never() -> i32 {
-    let loop_value = loop { break get_never() }; // ok
-}
-
-fn main() {}
diff --git a/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs b/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs
deleted file mode 100644
index 12d143bd989..00000000000
--- a/tests/ui/cancel-clean-via-immediate-rvalue-ref.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ run-pass
-
-fn foo(x: &mut Box<u8>) {
-    *x = Box::new(5);
-}
-
-pub fn main() {
-    foo(&mut Box::new(4));
-}
diff --git a/tests/ui/cannot-mutate-captured-non-mut-var.rs b/tests/ui/cannot-mutate-captured-non-mut-var.rs
deleted file mode 100644
index 952dab25bf9..00000000000
--- a/tests/ui/cannot-mutate-captured-non-mut-var.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-#![feature(unboxed_closures, tuple_trait)]
-
-use std::io::Read;
-
-fn to_fn_once<A:std::marker::Tuple,F:FnOnce<A>>(f: F) -> F { f }
-
-fn main() {
-    let x = 1;
-    to_fn_once(move|| { x = 2; });
-    //~^ ERROR: cannot assign to `x`, as it is not declared as mutable
-
-    let s = std::io::stdin();
-    to_fn_once(move|| { s.read_to_end(&mut Vec::new()); });
-    //~^ ERROR: cannot borrow `s` as mutable, as it is not declared as mutable
-}
diff --git a/tests/ui/cast/cast-to-slice.stderr b/tests/ui/cast/cast-to-slice.stderr
index 8f862c00014..382ccc3d10c 100644
--- a/tests/ui/cast/cast-to-slice.stderr
+++ b/tests/ui/cast/cast-to-slice.stderr
@@ -2,17 +2,23 @@ error[E0620]: cast to unsized type: `&[u8]` as `[char]`
   --> $DIR/cast-to-slice.rs:2:5
    |
 LL |     "example".as_bytes() as [char];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^------
-   |                             |
-   |                             help: try casting to a reference instead: `&[char]`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider casting to a reference instead
+   |
+LL |     "example".as_bytes() as &[char];
+   |                             +
 
 error[E0620]: cast to unsized type: `&[u8]` as `[char]`
   --> $DIR/cast-to-slice.rs:6:5
    |
 LL |     arr as [char];
-   |     ^^^^^^^------
-   |            |
-   |            help: try casting to a reference instead: `&[char]`
+   |     ^^^^^^^^^^^^^
+   |
+help: consider casting to a reference instead
+   |
+LL |     arr as &[char];
+   |            +
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/cast/cast-to-unsized-trait-object-suggestion.stderr b/tests/ui/cast/cast-to-unsized-trait-object-suggestion.stderr
index 3b5b8ea69c1..2803c3380d7 100644
--- a/tests/ui/cast/cast-to-unsized-trait-object-suggestion.stderr
+++ b/tests/ui/cast/cast-to-unsized-trait-object-suggestion.stderr
@@ -2,17 +2,23 @@ error[E0620]: cast to unsized type: `&{integer}` as `dyn Send`
   --> $DIR/cast-to-unsized-trait-object-suggestion.rs:2:5
    |
 LL |     &1 as dyn Send;
-   |     ^^^^^^--------
-   |           |
-   |           help: try casting to a reference instead: `&dyn Send`
+   |     ^^^^^^^^^^^^^^
+   |
+help: consider casting to a reference instead
+   |
+LL |     &1 as &dyn Send;
+   |           +
 
 error[E0620]: cast to unsized type: `Box<{integer}>` as `dyn Send`
   --> $DIR/cast-to-unsized-trait-object-suggestion.rs:3:5
    |
 LL |     Box::new(1) as dyn Send;
-   |     ^^^^^^^^^^^^^^^--------
-   |                    |
-   |                    help: you can cast to a `Box` instead: `Box<dyn Send>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: you can cast to a `Box` instead
+   |
+LL |     Box::new(1) as Box<dyn Send>;
+   |                    ++++        +
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/char.rs b/tests/ui/char.rs
deleted file mode 100644
index a7842f16fa7..00000000000
--- a/tests/ui/char.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ run-pass
-
-pub fn main() {
-    let c: char = 'x';
-    let d: char = 'x';
-    assert_eq!(c, 'x');
-    assert_eq!('x', c);
-    assert_eq!(c, c);
-    assert_eq!(c, d);
-    assert_eq!(d, c);
-    assert_eq!(d, 'x');
-    assert_eq!('x', d);
-}
diff --git a/tests/ui/check-cfg/hrtb-crash.rs b/tests/ui/check-cfg/hrtb-crash.rs
new file mode 100644
index 00000000000..f2bce33f9f9
--- /dev/null
+++ b/tests/ui/check-cfg/hrtb-crash.rs
@@ -0,0 +1,7 @@
+// https://github.com/rust-lang/rust/issues/139825
+//@ compile-flags: --check-cfg=cfg(docsrs,test) --crate-type lib
+//@ check-pass
+struct A
+where
+    for<#[cfg(b)] c> u8:;
+//~^ WARN: unexpected `cfg` condition name
diff --git a/tests/ui/check-cfg/hrtb-crash.stderr b/tests/ui/check-cfg/hrtb-crash.stderr
new file mode 100644
index 00000000000..431cf9cf53e
--- /dev/null
+++ b/tests/ui/check-cfg/hrtb-crash.stderr
@@ -0,0 +1,13 @@
+warning: unexpected `cfg` condition name: `b`
+  --> $DIR/hrtb-crash.rs:6:15
+   |
+LL |     for<#[cfg(b)] c> u8:;
+   |               ^ help: found config with similar value: `target_feature = "b"`
+   |
+   = help: expected names are: `FALSE`, `docsrs`, and `test` and 31 more
+   = help: to expect this configuration use `--check-cfg=cfg(b)`
+   = 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
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index 7cda6c2eaa5..532c1ab13d1 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -138,7 +138,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_arch = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_arch` are: `aarch64`, `amdgpu`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa`
+   = note: expected values for `target_arch` are: `aarch64`, `amdgpu`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch32`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
diff --git a/tests/ui/class-cast-to-trait.rs b/tests/ui/class-cast-to-trait.rs
deleted file mode 100644
index ca98e4c9003..00000000000
--- a/tests/ui/class-cast-to-trait.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-trait Noisy {
-  fn speak(&mut self);
-}
-
-struct Cat {
-  meows : usize,
-
-  how_hungry : isize,
-  name : String,
-}
-
-impl Cat {
-  pub fn eat(&mut self) -> bool {
-    if self.how_hungry > 0 {
-        println!("OM NOM NOM");
-        self.how_hungry -= 2;
-        return true;
-    }
-    else {
-        println!("Not hungry!");
-        return false;
-    }
-  }
-}
-
-impl Noisy for Cat {
-  fn speak(&mut self) { self.meow(); }
-
-}
-
-impl Cat {
-    fn meow(&mut self) {
-      println!("Meow");
-      self.meows += 1;
-      if self.meows % 5 == 0 {
-          self.how_hungry += 1;
-      }
-    }
-}
-
-fn cat(in_x : usize, in_y : isize, in_name: String) -> Cat {
-    Cat {
-        meows: in_x,
-        how_hungry: in_y,
-        name: in_name
-    }
-}
-
-
-
-fn main() {
-  let nyan: Box<dyn Noisy> = Box::new(cat(0, 2, "nyan".to_string())) as Box<dyn Noisy>;
-  nyan.eat(); //~ ERROR no method named `eat` found
-}
diff --git a/tests/ui/class-cast-to-trait.stderr b/tests/ui/class-cast-to-trait.stderr
deleted file mode 100644
index 4ea0f41c3ed..00000000000
--- a/tests/ui/class-cast-to-trait.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0599]: no method named `eat` found for struct `Box<dyn Noisy>` in the current scope
-  --> $DIR/class-cast-to-trait.rs:53:8
-   |
-LL |   nyan.eat();
-   |        ^^^ method not found in `Box<dyn Noisy>`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/class-method-missing.rs b/tests/ui/class-method-missing.rs
deleted file mode 100644
index 5dc18328f31..00000000000
--- a/tests/ui/class-method-missing.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-trait Animal {
-  fn eat(&self);
-}
-
-struct Cat {
-  meows: usize,
-}
-
-impl Animal for Cat {
-    //~^ ERROR not all trait items implemented, missing: `eat`
-}
-
-fn cat(in_x : usize) -> Cat {
-    Cat {
-        meows: in_x
-    }
-}
-
-fn main() {
-  let nyan = cat(0);
-}
diff --git a/tests/ui/class-method-missing.stderr b/tests/ui/class-method-missing.stderr
deleted file mode 100644
index 42bd22e18a1..00000000000
--- a/tests/ui/class-method-missing.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0046]: not all trait items implemented, missing: `eat`
-  --> $DIR/class-method-missing.rs:9:1
-   |
-LL |   fn eat(&self);
-   |   -------------- `eat` from trait
-...
-LL | impl Animal for Cat {
-   | ^^^^^^^^^^^^^^^^^^^ missing `eat` in implementation
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/cleanup-rvalue-for-scope.rs b/tests/ui/cleanup-rvalue-for-scope.rs
deleted file mode 100644
index 8f5ee8723fd..00000000000
--- a/tests/ui/cleanup-rvalue-for-scope.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-//@ run-pass
-
-#![allow(non_snake_case)]
-#![allow(dead_code)]
-#![allow(unused_variables)]
-// Test that the lifetime of rvalues in for loops is extended
-// to the for loop itself.
-static mut FLAGS: u64 = 0;
-
-struct Box<T> { f: T }
-struct AddFlags { bits: u64 }
-
-fn AddFlags(bits: u64) -> AddFlags {
-    AddFlags { bits: bits }
-}
-
-fn arg(exp: u64, _x: &AddFlags) {
-    check_flags(exp);
-}
-
-fn pass<T>(v: T) -> T {
-    v
-}
-
-fn check_flags(exp: u64) {
-    unsafe {
-        let x = FLAGS;
-        FLAGS = 0;
-        println!("flags {}, expected {}", x, exp);
-        assert_eq!(x, exp);
-    }
-}
-
-impl AddFlags {
-    fn check_flags(&self, exp: u64) -> &AddFlags {
-        check_flags(exp);
-        self
-    }
-
-    fn bits(&self) -> u64 {
-        self.bits
-    }
-}
-
-impl Drop for AddFlags {
-    fn drop(&mut self) {
-        unsafe {
-            FLAGS = FLAGS + self.bits;
-        }
-    }
-}
-
-pub fn main() {
-    // The array containing [AddFlags] should not be dropped until
-    // after the for loop:
-    for x in &[AddFlags(1)] {
-        check_flags(0);
-    }
-    check_flags(1);
-}
diff --git a/tests/ui/cleanup-rvalue-scopes.rs b/tests/ui/cleanup-rvalue-scopes.rs
deleted file mode 100644
index 09ceda065b9..00000000000
--- a/tests/ui/cleanup-rvalue-scopes.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-//@ run-pass
-#![allow(unused_braces)]
-#![allow(non_snake_case)]
-#![allow(unused_variables)]
-// Test that destructors for rvalue temporaries run either at end of
-// statement or end of block, as appropriate given the temporary
-// lifetime rules.
-
-#![feature(box_patterns)]
-
-static mut FLAGS: u64 = 0;
-
-struct Box<T> { f: T }
-struct AddFlags { bits: u64 }
-
-fn AddFlags(bits: u64) -> AddFlags {
-    AddFlags { bits: bits }
-}
-
-fn arg(exp: u64, _x: &AddFlags) {
-    check_flags(exp);
-}
-
-fn pass<T>(v: T) -> T {
-    v
-}
-
-fn check_flags(exp: u64) {
-    unsafe {
-        let x = FLAGS;
-        FLAGS = 0;
-        println!("flags {}, expected {}", x, exp);
-        assert_eq!(x, exp);
-    }
-}
-
-impl AddFlags {
-    fn check_flags<'a>(&'a self, exp: u64) -> &'a AddFlags {
-        check_flags(exp);
-        self
-    }
-
-    fn bits(&self) -> u64 {
-        self.bits
-    }
-}
-
-impl Drop for AddFlags {
-    fn drop(&mut self) {
-        unsafe {
-            FLAGS = FLAGS + self.bits;
-        }
-    }
-}
-
-macro_rules! end_of_block {
-    ($pat:pat, $expr:expr) => (
-        {
-            println!("end_of_block({})", stringify!({let $pat = $expr;}));
-
-            {
-                // Destructor here does not run until exit from the block.
-                let $pat = $expr;
-                check_flags(0);
-            }
-            check_flags(1);
-        }
-    )
-}
-
-macro_rules! end_of_stmt {
-    ($pat:pat, $expr:expr) => (
-        {
-            println!("end_of_stmt({})", stringify!($expr));
-
-            {
-                // Destructor here run after `let` statement
-                // terminates.
-                let $pat = $expr;
-                check_flags(1);
-            }
-
-            check_flags(0);
-        }
-    )
-}
-
-pub fn main() {
-
-    // In all these cases, we trip over the rules designed to cover
-    // the case where we are taking addr of rvalue and storing that
-    // addr into a stack slot, either via `let ref` or via a `&` in
-    // the initializer.
-
-    end_of_block!(_x, AddFlags(1));
-    end_of_block!(_x, &AddFlags(1));
-    end_of_block!(_x, & &AddFlags(1));
-    end_of_block!(_x, Box { f: AddFlags(1) });
-    end_of_block!(_x, Box { f: &AddFlags(1) });
-    end_of_block!(_x, Box { f: &AddFlags(1) });
-    end_of_block!(_x, pass(AddFlags(1)));
-    end_of_block!(ref _x, AddFlags(1));
-    end_of_block!(AddFlags { bits: ref _x }, AddFlags(1));
-    end_of_block!(&AddFlags { bits }, &AddFlags(1));
-    end_of_block!((_, ref _y), (AddFlags(1), 22));
-    end_of_block!(box ref _x, std::boxed::Box::new(AddFlags(1)));
-    end_of_block!(box _x, std::boxed::Box::new(AddFlags(1)));
-    end_of_block!(_, { { check_flags(0); &AddFlags(1) } });
-    end_of_block!(_, &((Box { f: AddFlags(1) }).f));
-    end_of_block!(_, &(([AddFlags(1)])[0]));
-
-    // LHS does not create a ref binding, so temporary lives as long
-    // as statement, and we do not move the AddFlags out:
-    end_of_stmt!(_, AddFlags(1));
-    end_of_stmt!((_, _), (AddFlags(1), 22));
-
-    // `&` operator appears inside an arg to a function,
-    // so it is not prolonged:
-    end_of_stmt!(ref _x, arg(0, &AddFlags(1)));
-
-    // autoref occurs inside receiver, so temp lifetime is not
-    // prolonged:
-    end_of_stmt!(ref _x, AddFlags(1).check_flags(0).bits());
-
-    // No reference is created on LHS, thus RHS is moved into
-    // a temporary that lives just as long as the statement.
-    end_of_stmt!(AddFlags { bits }, AddFlags(1));
-}
diff --git a/tests/ui/close-over-big-then-small-data.rs b/tests/ui/close-over-big-then-small-data.rs
deleted file mode 100644
index d3cb1db8886..00000000000
--- a/tests/ui/close-over-big-then-small-data.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-//@ run-pass
-
-#![allow(dead_code)]
-// If we use GEPi rather than GEP_tup_like when
-// storing closure data (as we used to do), the u64 would
-// overwrite the u16.
-
-struct Pair<A,B> {
-    a: A, b: B
-}
-
-struct Invoker<A> {
-    a: A,
-    b: u16,
-}
-
-trait Invokable<A> {
-    fn f(&self) -> (A, u16);
-}
-
-impl<A:Clone> Invokable<A> for Invoker<A> {
-    fn f(&self) -> (A, u16) {
-        (self.a.clone(), self.b)
-    }
-}
-
-fn f<A:Clone + 'static>(a: A, b: u16) -> Box<dyn Invokable<A>+'static> {
-    Box::new(Invoker {
-        a: a,
-        b: b,
-    }) as Box<dyn Invokable<A>+'static>
-}
-
-pub fn main() {
-    let (a, b) = f(22_u64, 44u16).f();
-    println!("a={} b={}", a, b);
-    assert_eq!(a, 22u64);
-    assert_eq!(b, 44u16);
-}
diff --git a/tests/ui/closures/closure-immut-capture-error.rs b/tests/ui/closures/closure-immut-capture-error.rs
new file mode 100644
index 00000000000..19fe599f241
--- /dev/null
+++ b/tests/ui/closures/closure-immut-capture-error.rs
@@ -0,0 +1,23 @@
+//! Tests that mutation of captured immutable variables in closures are not permitted.
+
+#![feature(unboxed_closures, tuple_trait)]
+
+use std::io::Read;
+
+fn to_fn_once<A: std::marker::Tuple, F: FnOnce<A>>(f: F) -> F {
+    f
+}
+
+fn main() {
+    let x = 1;
+    to_fn_once(move || {
+        x = 2;
+        //~^ ERROR: cannot assign to `x`, as it is not declared as mutable
+    });
+
+    let s = std::io::stdin();
+    to_fn_once(move || {
+        s.read_to_end(&mut Vec::new());
+        //~^ ERROR: cannot borrow `s` as mutable, as it is not declared as mutable
+    });
+}
diff --git a/tests/ui/cannot-mutate-captured-non-mut-var.stderr b/tests/ui/closures/closure-immut-capture-error.stderr
index 8d794f8251f..516cf7c074e 100644
--- a/tests/ui/cannot-mutate-captured-non-mut-var.stderr
+++ b/tests/ui/closures/closure-immut-capture-error.stderr
@@ -1,8 +1,8 @@
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
-  --> $DIR/cannot-mutate-captured-non-mut-var.rs:9:25
+  --> $DIR/closure-immut-capture-error.rs:14:9
    |
-LL |     to_fn_once(move|| { x = 2; });
-   |                         ^^^^^ cannot assign
+LL |         x = 2;
+   |         ^^^^^ cannot assign
    |
 help: consider changing this to be mutable
    |
@@ -10,10 +10,10 @@ LL |     let mut x = 1;
    |         +++
 
 error[E0596]: cannot borrow `s` as mutable, as it is not declared as mutable
-  --> $DIR/cannot-mutate-captured-non-mut-var.rs:13:25
+  --> $DIR/closure-immut-capture-error.rs:20:9
    |
-LL |     to_fn_once(move|| { s.read_to_end(&mut Vec::new()); });
-   |                         ^ cannot borrow as mutable
+LL |         s.read_to_end(&mut Vec::new());
+   |         ^ cannot borrow as mutable
    |
 help: consider changing this to be mutable
    |
diff --git a/tests/ui/codegen/rvalue-mut-ref-box-drop.rs b/tests/ui/codegen/rvalue-mut-ref-box-drop.rs
new file mode 100644
index 00000000000..441820ad64e
--- /dev/null
+++ b/tests/ui/codegen/rvalue-mut-ref-box-drop.rs
@@ -0,0 +1,13 @@
+//! Tests cleanup of a temporary `Box` rvalue passed as a mutable reference.
+//!
+//! - Issue: <https://github.com/rust-lang/rust/issues/7972>.
+
+//@ run-pass
+
+fn foo(x: &mut Box<u8>) {
+    *x = Box::new(5);
+}
+
+pub fn main() {
+    foo(&mut Box::new(4));
+}
diff --git a/tests/ui/coercion/issue-73886.stderr b/tests/ui/coercion/issue-73886.stderr
index a287aa29e11..891931d0bf8 100644
--- a/tests/ui/coercion/issue-73886.stderr
+++ b/tests/ui/coercion/issue-73886.stderr
@@ -10,9 +10,8 @@ error[E0605]: non-primitive cast: `u32` as `Option<_>`
   --> $DIR/issue-73886.rs:4:13
    |
 LL |     let _ = 7u32 as Option<_>;
-   |             ^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
    |
-   = note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
 help: consider using the `From` trait instead
    |
 LL -     let _ = 7u32 as Option<_>;
diff --git a/tests/ui/coercion/non-primitive-cast-135412.stderr b/tests/ui/coercion/non-primitive-cast-135412.stderr
index 7e5861f83e9..e5e9ee13459 100644
--- a/tests/ui/coercion/non-primitive-cast-135412.stderr
+++ b/tests/ui/coercion/non-primitive-cast-135412.stderr
@@ -2,9 +2,8 @@ error[E0605]: non-primitive cast: `u32` as `Option<_>`
   --> $DIR/non-primitive-cast-135412.rs:6:13
    |
 LL |     let _ = 7u32 as Option<_>;
-   |             ^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
    |
-   = note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
 help: consider using the `From` trait instead
    |
 LL -     let _ = 7u32 as Option<_>;
@@ -15,9 +14,8 @@ error[E0605]: non-primitive cast: `&'static str` as `Arc<str>`
   --> $DIR/non-primitive-cast-135412.rs:8:13
    |
 LL |     let _ = "String" as Arc<str>;
-   |             ^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
    |
-   = note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
 help: consider using the `From` trait instead
    |
 LL -     let _ = "String" as Arc<str>;
diff --git a/tests/ui/coherence/const-errs-dont-conflict-103369.stderr b/tests/ui/coherence/const-errs-dont-conflict-103369.stderr
index e577a36cc10..c8ed75abf72 100644
--- a/tests/ui/coherence/const-errs-dont-conflict-103369.stderr
+++ b/tests/ui/coherence/const-errs-dont-conflict-103369.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: Some error occurred
   --> $DIR/const-errs-dont-conflict-103369.rs:5:25
    |
 LL | impl ConstGenericTrait<{my_fn(1)}> for () {}
-   |                         ^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^ evaluation of `<() as ConstGenericTrait<{my_fn(1)}>>::{constant#0}` failed inside this call
    |
 note: inside `my_fn`
   --> $DIR/const-errs-dont-conflict-103369.rs:10:5
@@ -14,7 +14,7 @@ error[E0080]: evaluation panicked: Some error occurred
   --> $DIR/const-errs-dont-conflict-103369.rs:7:25
    |
 LL | impl ConstGenericTrait<{my_fn(2)}> for () {}
-   |                         ^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^ evaluation of `<() as ConstGenericTrait<{my_fn(2)}>>::{constant#0}` failed inside this call
    |
 note: inside `my_fn`
   --> $DIR/const-errs-dont-conflict-103369.rs:10:5
diff --git a/tests/ui/complex.rs b/tests/ui/complex.rs
deleted file mode 100644
index d1da9d189ca..00000000000
--- a/tests/ui/complex.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-//@ run-pass
-
-#![allow(unconditional_recursion)]
-#![allow(non_camel_case_types)]
-#![allow(dead_code)]
-#![allow(unused_mut)]
-
-
-
-type t = isize;
-
-fn nothing() { }
-
-fn putstr(_s: String) { }
-
-fn putint(_i: isize) {
-    let mut i: isize = 33;
-    while i < 36 { putstr("hi".to_string()); i = i + 1; }
-}
-
-fn zerg(i: isize) -> isize { return i; }
-
-fn foo(x: isize) -> isize {
-    let mut y: t = x + 2;
-    putstr("hello".to_string());
-    while y < 10 { putint(y); if y * 3 == 4 { y = y + 2; nothing(); } }
-    let mut z: t;
-    z = 0x55;
-    foo(z);
-    return 0;
-}
-
-pub fn main() {
-    let x: isize = 2 + 2;
-    println!("{}", x);
-    println!("hello, world");
-    println!("{}", 10);
-}
diff --git a/tests/ui/const-generics/defaults/default-param-wf-concrete.next.stderr b/tests/ui/const-generics/defaults/default-param-wf-concrete.next.stderr
index 3299c27a0e7..133d8f6b0f0 100644
--- a/tests/ui/const-generics/defaults/default-param-wf-concrete.next.stderr
+++ b/tests/ui/const-generics/defaults/default-param-wf-concrete.next.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `u8::MAX + 1_u8`, which would overflow
   --> $DIR/default-param-wf-concrete.rs:4:28
    |
 LL | struct Foo<const N: u8 = { 255 + 1 }>;
-   |                            ^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^ evaluation of `Foo::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/defaults/default-param-wf-concrete.old.stderr b/tests/ui/const-generics/defaults/default-param-wf-concrete.old.stderr
index 3299c27a0e7..133d8f6b0f0 100644
--- a/tests/ui/const-generics/defaults/default-param-wf-concrete.old.stderr
+++ b/tests/ui/const-generics/defaults/default-param-wf-concrete.old.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `u8::MAX + 1_u8`, which would overflow
   --> $DIR/default-param-wf-concrete.rs:4:28
    |
 LL | struct Foo<const N: u8 = { 255 + 1 }>;
-   |                            ^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^ evaluation of `Foo::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/defaults/wfness.stderr b/tests/ui/const-generics/defaults/wfness.stderr
index ef5167cfc00..4f42afed81d 100644
--- a/tests/ui/const-generics/defaults/wfness.stderr
+++ b/tests/ui/const-generics/defaults/wfness.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `u8::MAX + 1_u8`, which would overflow
   --> $DIR/wfness.rs:1:33
    |
 LL | struct Ooopsies<const N: u8 = { u8::MAX + 1 }>;
-   |                                 ^^^^^^^^^^^ evaluation of constant value failed here
+   |                                 ^^^^^^^^^^^ evaluation of `Ooopsies::{constant#0}` failed here
 
 error[E0277]: the trait bound `(): Trait<2>` is not satisfied
   --> $DIR/wfness.rs:8:9
diff --git a/tests/ui/const-generics/early/invalid-const-arguments.stderr b/tests/ui/const-generics/early/invalid-const-arguments.stderr
index 86b4d006454..3a9868836ec 100644
--- a/tests/ui/const-generics/early/invalid-const-arguments.stderr
+++ b/tests/ui/const-generics/early/invalid-const-arguments.stderr
@@ -51,9 +51,13 @@ error[E0747]: type provided when a constant was expected
   --> $DIR/invalid-const-arguments.rs:10:19
    |
 LL | impl<N> Foo for B<N> {}
-   |      -            ^
-   |      |
-   |      help: consider changing this type parameter to a const parameter: `const N: u8`
+   |                   ^
+   |
+help: consider changing this type parameter to a const parameter
+   |
+LL - impl<N> Foo for B<N> {}
+LL + impl<const N: u8> Foo for B<N> {}
+   |
 
 error[E0747]: unresolved item provided when a constant was expected
   --> $DIR/invalid-const-arguments.rs:14:32
diff --git a/tests/ui/const-generics/issues/issue-100313.stderr b/tests/ui/const-generics/issues/issue-100313.stderr
index 2ae4c30e15f..d1a0249728e 100644
--- a/tests/ui/const-generics/issues/issue-100313.stderr
+++ b/tests/ui/const-generics/issues/issue-100313.stderr
@@ -2,7 +2,7 @@ error[E0080]: writing to ALLOC0 which is read-only
   --> $DIR/issue-100313.rs:18:5
    |
 LL |     x.set_false();
-   |     ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^ evaluation of `_` failed inside this call
    |
 note: inside `T::<&true>::set_false`
   --> $DIR/issue-100313.rs:11:13
diff --git a/tests/ui/const-generics/kind_mismatch.stderr b/tests/ui/const-generics/kind_mismatch.stderr
index 1487b189619..12a2ab141a6 100644
--- a/tests/ui/const-generics/kind_mismatch.stderr
+++ b/tests/ui/const-generics/kind_mismatch.stderr
@@ -2,17 +2,25 @@ error[E0747]: type provided when a constant was expected
   --> $DIR/kind_mismatch.rs:11:38
    |
 LL | impl<K> ContainsKey<K> for KeyHolder<K> {}
-   |      -                               ^
-   |      |
-   |      help: consider changing this type parameter to a const parameter: `const K: u8`
+   |                                      ^
+   |
+help: consider changing this type parameter to a const parameter
+   |
+LL - impl<K> ContainsKey<K> for KeyHolder<K> {}
+LL + impl<const K: u8> ContainsKey<K> for KeyHolder<K> {}
+   |
 
 error[E0747]: type provided when a constant was expected
   --> $DIR/kind_mismatch.rs:11:21
    |
 LL | impl<K> ContainsKey<K> for KeyHolder<K> {}
-   |      -              ^
-   |      |
-   |      help: consider changing this type parameter to a const parameter: `const K: u8`
+   |                     ^
+   |
+help: consider changing this type parameter to a const parameter
+   |
+LL - impl<K> ContainsKey<K> for KeyHolder<K> {}
+LL + impl<const K: u8> ContainsKey<K> for KeyHolder<K> {}
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
index 172fd37fa69..92b226fe0f7 100644
--- a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
+++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/invalid-patterns.rs:40:32
    |
 LL |   get_flag::<false, { unsafe { char_raw.character } }>();
-   |                                ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^ evaluation of `main::{constant#7}` failed here
 
 error[E0080]: constructing invalid value: encountered 0x42, but expected a boolean
   --> $DIR/invalid-patterns.rs:42:14
@@ -30,7 +30,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/invalid-patterns.rs:44:58
    |
 LL |   get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
-   |                                                          ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                                          ^^^^^^^^^^^^^^^^^^ evaluation of `main::{constant#11}` failed here
 
 error[E0308]: mismatched types
   --> $DIR/invalid-patterns.rs:31:21
diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
index 172fd37fa69..92b226fe0f7 100644
--- a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
+++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/invalid-patterns.rs:40:32
    |
 LL |   get_flag::<false, { unsafe { char_raw.character } }>();
-   |                                ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^ evaluation of `main::{constant#7}` failed here
 
 error[E0080]: constructing invalid value: encountered 0x42, but expected a boolean
   --> $DIR/invalid-patterns.rs:42:14
@@ -30,7 +30,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/invalid-patterns.rs:44:58
    |
 LL |   get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
-   |                                                          ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                                          ^^^^^^^^^^^^^^^^^^ evaluation of `main::{constant#11}` failed here
 
 error[E0308]: mismatched types
   --> $DIR/invalid-patterns.rs:31:21
diff --git a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr
index 177ff20fbf9..f68fdb3b651 100644
--- a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr
+++ b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr
@@ -1,10 +1,17 @@
-warning: elided lifetime has a name
-  --> $DIR/issue-71348.rs:18:68
+warning: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/issue-71348.rs:18:40
    |
 LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
-   |            -- lifetime `'a` declared here                          ^ this elided lifetime gets resolved as `'a`
+   |                                        ^^           -- ------------------------ the lifetimes get resolved as `'a`
+   |                                        |            |
+   |                                        |            the lifetimes get resolved as `'a`
+   |                                        this lifetime flows to the output
    |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
+   = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
+help: one option is to consistently use `'a`
+   |
+LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<'a, N>>::Target
+   |                                                                     +++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
index 8995c415863..c491469bcbd 100644
--- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
+++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
@@ -1,11 +1,3 @@
-warning: elided lifetime has a name
-  --> $DIR/issue-71348.rs:18:68
-   |
-LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
-   |            -- lifetime `'a` declared here                          ^ this elided lifetime gets resolved as `'a`
-   |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
-
 error: `&'static str` is forbidden as the type of a const generic parameter
   --> $DIR/issue-71348.rs:10:24
    |
@@ -38,5 +30,5 @@ help: add `#![feature(unsized_const_params)]` to the crate attributes to enable
 LL + #![feature(unsized_const_params)]
    |
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/type-dependent/issue-71348.rs b/tests/ui/const-generics/type-dependent/issue-71348.rs
index 97e786405fe..c6563c80305 100644
--- a/tests/ui/const-generics/type-dependent/issue-71348.rs
+++ b/tests/ui/const-generics/type-dependent/issue-71348.rs
@@ -17,7 +17,7 @@ trait Get<'a, const N: &'static str> {
 impl Foo {
     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
     //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter
-    //~^^ WARNING elided lifetime has a name
+    //[full]~^^ WARNING lifetime flowing from input to output with different syntax
     where
         Self: Get<'a, N>,
     {
diff --git a/tests/ui/const-ptr/forbidden_slices.stderr b/tests/ui/const-ptr/forbidden_slices.stderr
index d4dcc6e66b1..25d6f0461a9 100644
--- a/tests/ui/const-ptr/forbidden_slices.stderr
+++ b/tests/ui/const-ptr/forbidden_slices.stderr
@@ -103,13 +103,13 @@ error[E0080]: evaluation panicked: assertion failed: 0 < pointee_size && pointee
   --> $DIR/forbidden_slices.rs:50:33
    |
 LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; // errors inside libcore
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `R1` failed here
 
 error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by 8 bytes, but got ALLOC10 which is only 4 bytes from the end of the allocation
   --> $DIR/forbidden_slices.rs:54:25
    |
 LL |     from_ptr_range(ptr..ptr.add(2)) // errors inside libcore
-   |                         ^^^^^^^^^^ evaluation of static initializer failed here
+   |                         ^^^^^^^^^^ evaluation of `R2` failed here
 
 error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitialized memory, but expected an integer
   --> $DIR/forbidden_slices.rs:57:1
@@ -161,19 +161,19 @@ error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer
   --> $DIR/forbidden_slices.rs:79:25
    |
 LL |     from_ptr_range(ptr..ptr.add(1))
-   |                         ^^^^^^^^^^ evaluation of static initializer failed here
+   |                         ^^^^^^^^^^ evaluation of `R8` failed here
 
 error[E0080]: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
   --> $DIR/forbidden_slices.rs:85:34
    |
 LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) };
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `R9` failed here
 
 error[E0080]: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
   --> $DIR/forbidden_slices.rs:87:35
    |
 LL | pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `R10` failed here
 
 error: aborting due to 18 previous errors
 
diff --git a/tests/ui/const-ptr/out_of_bounds_read.stderr b/tests/ui/const-ptr/out_of_bounds_read.stderr
index e921a5f4987..a98765b15f2 100644
--- a/tests/ui/const-ptr/out_of_bounds_read.stderr
+++ b/tests/ui/const-ptr/out_of_bounds_read.stderr
@@ -2,19 +2,19 @@ error[E0080]: memory access failed: attempting to access 4 bytes, but got ALLOC0
   --> $DIR/out_of_bounds_read.rs:8:33
    |
 LL |     const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::_READ` failed here
 
 error[E0080]: memory access failed: attempting to access 4 bytes, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes
   --> $DIR/out_of_bounds_read.rs:10:39
    |
 LL |     const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
-   |                                       ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                       ^^^^^^^^^^^^^^^^^^^ evaluation of `main::_CONST_READ` failed here
 
 error[E0080]: memory access failed: attempting to access 4 bytes, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes
   --> $DIR/out_of_bounds_read.rs:12:37
    |
 LL |     const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::_MUT_READ` failed here
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/constructor-lifetime-args.rs b/tests/ui/constructor-lifetime-args.rs
deleted file mode 100644
index f5802e7d8b1..00000000000
--- a/tests/ui/constructor-lifetime-args.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-// All lifetime parameters in struct constructors are currently considered early bound,
-// i.e., `S::<ARGS>` is interpreted kinda like an associated item `S::<ARGS>::ctor`.
-// This behavior is a bit weird, because if equivalent constructor were written manually
-// it would get late bound lifetime parameters.
-// Variant constructors behave in the same way, lifetime parameters are considered
-// belonging to the enum and being early bound.
-// https://github.com/rust-lang/rust/issues/30904
-
-struct S<'a, 'b>(&'a u8, &'b u8);
-enum E<'a, 'b> {
-    V(&'a u8),
-    U(&'b u8),
-}
-
-fn main() {
-    S(&0, &0); // OK
-    S::<'static>(&0, &0);
-    //~^ ERROR struct takes 2 lifetime arguments
-    S::<'static, 'static, 'static>(&0, &0);
-    //~^ ERROR struct takes 2 lifetime arguments
-    E::V(&0); // OK
-    E::V::<'static>(&0);
-    //~^ ERROR enum takes 2 lifetime arguments
-    E::V::<'static, 'static, 'static>(&0);
-    //~^ ERROR enum takes 2 lifetime arguments
-}
diff --git a/tests/ui/consts/assert-type-intrinsics.stderr b/tests/ui/consts/assert-type-intrinsics.stderr
index 90f003716d1..92fc90aebe4 100644
--- a/tests/ui/consts/assert-type-intrinsics.stderr
+++ b/tests/ui/consts/assert-type-intrinsics.stderr
@@ -2,19 +2,19 @@ error[E0080]: evaluation panicked: aborted execution: attempted to instantiate u
   --> $DIR/assert-type-intrinsics.rs:11:9
    |
 LL |         MaybeUninit::<!>::uninit().assume_init();
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::_BAD1` failed here
 
 error[E0080]: evaluation panicked: aborted execution: attempted to leave type `&i32` uninitialized, which is invalid
   --> $DIR/assert-type-intrinsics.rs:15:9
    |
 LL |         intrinsics::assert_mem_uninitialized_valid::<&'static i32>();
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::_BAD2` failed here
 
 error[E0080]: evaluation panicked: aborted execution: attempted to zero-initialize type `&i32`, which is invalid
   --> $DIR/assert-type-intrinsics.rs:19:9
    |
 LL |         intrinsics::assert_zero_valid::<&'static i32>();
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::_BAD3` failed here
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/consts/const-array-oob.stderr b/tests/ui/consts/const-array-oob.stderr
index d4a02664490..7d5f23473c1 100644
--- a/tests/ui/consts/const-array-oob.stderr
+++ b/tests/ui/consts/const-array-oob.stderr
@@ -2,13 +2,13 @@ error[E0080]: index out of bounds: the length is 3 but the index is 4
   --> $DIR/const-array-oob.rs:5:19
    |
 LL | const BLUB: [u32; FOO[4]] = [5, 6];
-   |                   ^^^^^^ evaluation of constant value failed here
+   |                   ^^^^^^ evaluation of `BLUB::{constant#0}` failed here
 
 error[E0080]: index out of bounds: the length is 3 but the index is 5
   --> $DIR/const-array-oob.rs:2:20
    |
 LL | const BAR: usize = FOO[5];
-   |                    ^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^ evaluation of `BAR` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-assert-unchecked-ub.stderr b/tests/ui/consts/const-assert-unchecked-ub.stderr
index 0a785942cf4..d8e68fc9bee 100644
--- a/tests/ui/consts/const-assert-unchecked-ub.stderr
+++ b/tests/ui/consts/const-assert-unchecked-ub.stderr
@@ -2,7 +2,7 @@ error[E0080]: `assume` called with `false`
   --> $DIR/const-assert-unchecked-ub.rs:3:5
    |
 LL |     std::hint::assert_unchecked(n < 32);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr b/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr
index a3d5054ced3..54982391b66 100644
--- a/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr
+++ b/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr
@@ -13,9 +13,8 @@ LL | struct Bar;
    |
 help: create an inline `const` block
    |
-LL -     let _: [Option<Bar>; 2] = [no_copy(); 2];
-LL +     let _: [Option<Bar>; 2] = [const { no_copy() }; 2];
-   |
+LL |     let _: [Option<Bar>; 2] = [const { no_copy() }; 2];
+   |                                +++++++           +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr
index 58ddc047d03..601d067e3d8 100644
--- a/tests/ui/consts/const-blocks/trait-error.stderr
+++ b/tests/ui/consts/const-blocks/trait-error.stderr
@@ -2,10 +2,7 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/trait-error.rs:5:6
    |
 LL |     [Foo(String::new()); 4];
-   |      ^^^^^^^^^^^^^^^^^^
-   |      |
-   |      the trait `Copy` is not implemented for `String`
-   |      help: create an inline `const` block: `const { Foo(String::new()) }`
+   |      ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
 note: required for `Foo<String>` to implement `Copy`
   --> $DIR/trait-error.rs:1:10
@@ -13,6 +10,10 @@ note: required for `Foo<String>` to implement `Copy`
 LL | #[derive(Copy, Clone)]
    |          ^^^^ unsatisfied trait bound introduced in this `derive` macro
    = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: create an inline `const` block
+   |
+LL |     [const { Foo(String::new()) }; 4];
+   |      +++++++                    +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-compare-bytes-ub.stderr b/tests/ui/consts/const-compare-bytes-ub.stderr
index 1b3824f22d0..c1706a8c4b0 100644
--- a/tests/ui/consts/const-compare-bytes-ub.stderr
+++ b/tests/ui/consts/const-compare-bytes-ub.stderr
@@ -2,49 +2,49 @@ error[E0080]: memory access failed: attempting to access 1 byte, but got null po
   --> $DIR/const-compare-bytes-ub.rs:9:9
    |
 LL |         compare_bytes(0 as *const u8, 2 as *const u8, 1)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::LHS_NULL` failed here
 
 error[E0080]: memory access failed: attempting to access 1 byte, but got 0x1[noalloc] which is a dangling pointer (it has no provenance)
   --> $DIR/const-compare-bytes-ub.rs:13:9
    |
 LL |         compare_bytes(1 as *const u8, 0 as *const u8, 1)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::RHS_NULL` failed here
 
 error[E0080]: memory access failed: attempting to access 1 byte, but got 0x1[noalloc] which is a dangling pointer (it has no provenance)
   --> $DIR/const-compare-bytes-ub.rs:17:9
    |
 LL |         compare_bytes(1 as *const u8, 2 as *const u8, 1)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::DANGLING_PTR_NON_ZERO_LENGTH` failed here
 
 error[E0080]: memory access failed: attempting to access 4 bytes, but got ALLOC0 which is only 3 bytes from the end of the allocation
   --> $DIR/const-compare-bytes-ub.rs:21:9
    |
 LL |         compare_bytes([1, 2, 3].as_ptr(), [1, 2, 3, 4].as_ptr(), 4)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::LHS_OUT_OF_BOUNDS` failed here
 
 error[E0080]: memory access failed: attempting to access 4 bytes, but got ALLOC1 which is only 3 bytes from the end of the allocation
   --> $DIR/const-compare-bytes-ub.rs:25:9
    |
 LL |         compare_bytes([1, 2, 3, 4].as_ptr(), [1, 2, 3].as_ptr(), 4)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::RHS_OUT_OF_BOUNDS` failed here
 
 error[E0080]: reading memory at ALLOC2[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory
   --> $DIR/const-compare-bytes-ub.rs:29:9
    |
 LL |         compare_bytes(MaybeUninit::uninit().as_ptr(), [1].as_ptr(), 1)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::LHS_UNINIT` failed here
 
 error[E0080]: reading memory at ALLOC3[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory
   --> $DIR/const-compare-bytes-ub.rs:33:9
    |
 LL |         compare_bytes([1].as_ptr(), MaybeUninit::uninit().as_ptr(), 1)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::RHS_UNINIT` failed here
 
 error[E0080]: unable to turn pointer into integer
   --> $DIR/const-compare-bytes-ub.rs:37:9
    |
 LL |         compare_bytes([&1].as_ptr().cast(), [&2].as_ptr().cast(), std::mem::size_of::<usize>())
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::WITH_PROVENANCE` failed here
    |
    = 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
diff --git a/tests/ui/consts/const-deref-ptr.stderr b/tests/ui/consts/const-deref-ptr.stderr
index f233b7d94bd..aa89aedac31 100644
--- a/tests/ui/consts/const-deref-ptr.stderr
+++ b/tests/ui/consts/const-deref-ptr.stderr
@@ -2,7 +2,7 @@ error[E0080]: memory access failed: attempting to access 8 bytes, but got 0xdead
   --> $DIR/const-deref-ptr.rs:4:30
    |
 LL |     static C: u64 = unsafe { *(0xdeadbeef as *const u64) };
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::C` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-err-early.stderr b/tests/ui/consts/const-err-early.stderr
index 98f9b4fbd2a..2d8dd08c1c8 100644
--- a/tests/ui/consts/const-err-early.stderr
+++ b/tests/ui/consts/const-err-early.stderr
@@ -2,31 +2,31 @@ error[E0080]: attempt to negate `i8::MIN`, which would overflow
   --> $DIR/const-err-early.rs:1:19
    |
 LL | pub const A: i8 = -i8::MIN;
-   |                   ^^^^^^^^ evaluation of constant value failed here
+   |                   ^^^^^^^^ evaluation of `A` failed here
 
 error[E0080]: attempt to compute `200_u8 + 200_u8`, which would overflow
   --> $DIR/const-err-early.rs:2:19
    |
 LL | pub const B: u8 = 200u8 + 200u8;
-   |                   ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                   ^^^^^^^^^^^^^ evaluation of `B` failed here
 
 error[E0080]: attempt to compute `200_u8 * 4_u8`, which would overflow
   --> $DIR/const-err-early.rs:3:19
    |
 LL | pub const C: u8 = 200u8 * 4;
-   |                   ^^^^^^^^^ evaluation of constant value failed here
+   |                   ^^^^^^^^^ evaluation of `C` failed here
 
 error[E0080]: attempt to compute `42_u8 - 43_u8`, which would overflow
   --> $DIR/const-err-early.rs:4:19
    |
 LL | pub const D: u8 = 42u8 - (42u8 + 1);
-   |                   ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                   ^^^^^^^^^^^^^^^^^ evaluation of `D` failed here
 
 error[E0080]: index out of bounds: the length is 1 but the index is 1
   --> $DIR/const-err-early.rs:5:19
    |
 LL | pub const E: u8 = [5u8][1];
-   |                   ^^^^^^^^ evaluation of constant value failed here
+   |                   ^^^^^^^^ evaluation of `E` failed here
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/consts/const-err-enum-discriminant.stderr b/tests/ui/consts/const-err-enum-discriminant.stderr
index 702d85b2f93..8724333ad7a 100644
--- a/tests/ui/consts/const-err-enum-discriminant.stderr
+++ b/tests/ui/consts/const-err-enum-discriminant.stderr
@@ -2,7 +2,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/const-err-enum-discriminant.rs:8:21
    |
 LL |     Boo = [unsafe { Foo { b: () }.a }; 4][3],
-   |                     ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                     ^^^^^^^^^^^^^^^ evaluation of `Bar::Boo::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-err-multi.rs b/tests/ui/consts/const-err-multi.rs
index 2fb0d291245..90214b656ab 100644
--- a/tests/ui/consts/const-err-multi.rs
+++ b/tests/ui/consts/const-err-multi.rs
@@ -1,12 +1,12 @@
 pub const A: i8 = -i8::MIN;
-//~^ NOTE constant
+//~^ NOTE failed here
 //~| ERROR attempt to negate `i8::MIN`, which would overflow
 pub const B: i8 = A;
-//~^ NOTE constant
+//~^ NOTE erroneous constant
 pub const C: u8 = A as u8;
-//~^ NOTE constant
+//~^ NOTE erroneous constant
 pub const D: i8 = 50 - A;
-//~^ NOTE constant
+//~^ NOTE erroneous constant
 
 fn main() {
     let _ = (A, B, C, D);
diff --git a/tests/ui/consts/const-err-multi.stderr b/tests/ui/consts/const-err-multi.stderr
index 9e1554eb265..515316523f6 100644
--- a/tests/ui/consts/const-err-multi.stderr
+++ b/tests/ui/consts/const-err-multi.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to negate `i8::MIN`, which would overflow
   --> $DIR/const-err-multi.rs:1:19
    |
 LL | pub const A: i8 = -i8::MIN;
-   |                   ^^^^^^^^ evaluation of constant value failed here
+   |                   ^^^^^^^^ evaluation of `A` failed here
 
 note: erroneous constant encountered
   --> $DIR/const-err-multi.rs:4:19
diff --git a/tests/ui/consts/const-eval-fail-too-big.stderr b/tests/ui/consts/const-eval-fail-too-big.stderr
index 3bc20ded5bf..d58efbf6d8c 100644
--- a/tests/ui/consts/const-eval-fail-too-big.stderr
+++ b/tests/ui/consts/const-eval-fail-too-big.stderr
@@ -2,7 +2,7 @@ error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target a
   --> $DIR/const-eval-fail-too-big.rs:4:28
    |
 LL |                    let x = [0u8; !0usize];
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `B::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/assign-to-static-within-other-static.stderr b/tests/ui/consts/const-eval/assign-to-static-within-other-static.stderr
index b19d0eaa116..b232cbf25e7 100644
--- a/tests/ui/consts/const-eval/assign-to-static-within-other-static.stderr
+++ b/tests/ui/consts/const-eval/assign-to-static-within-other-static.stderr
@@ -2,7 +2,7 @@ error[E0080]: modifying a static's initial value from another static's initializ
   --> $DIR/assign-to-static-within-other-static.rs:8:5
    |
 LL |     FOO = 5;
-   |     ^^^^^^^ evaluation of static initializer failed here
+   |     ^^^^^^^ evaluation of `BOO` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/conditional_array_execution.stderr b/tests/ui/consts/const-eval/conditional_array_execution.stderr
index 65ae9a9fb8a..9a0a7527277 100644
--- a/tests/ui/consts/const-eval/conditional_array_execution.stderr
+++ b/tests/ui/consts/const-eval/conditional_array_execution.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `5_u32 - 6_u32`, which would overflow
   --> $DIR/conditional_array_execution.rs:3:19
    |
 LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
-   |                   ^^^^^ evaluation of constant value failed here
+   |                   ^^^^^ evaluation of `FOO` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-2.stderr b/tests/ui/consts/const-eval/const-eval-overflow-2.stderr
index 90b94600aed..ffb8cade923 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow-2.stderr
+++ b/tests/ui/consts/const-eval/const-eval-overflow-2.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to negate `i8::MIN`, which would overflow
   --> $DIR/const-eval-overflow-2.rs:11:25
    |
 LL | const NEG_NEG_128: i8 = -NEG_128;
-   |                         ^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^ evaluation of `NEG_NEG_128` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3.stderr b/tests/ui/consts/const-eval/const-eval-overflow-3.stderr
index 5ad7d08bdb3..aeb88716f16 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow-3.stderr
+++ b/tests/ui/consts/const-eval/const-eval-overflow-3.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `i8::MAX + 1_i8`, which would overflow
   --> $DIR/const-eval-overflow-3.rs:18:11
    |
 LL |     = [0; (i8::MAX + 1) as usize];
-   |           ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |           ^^^^^^^^^^^^^ evaluation of `A_I8_I::{constant#1}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4.stderr
index c14a880849f..daabb33e0f3 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow-4.stderr
+++ b/tests/ui/consts/const-eval/const-eval-overflow-4.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `i8::MAX + 1_i8`, which would overflow
   --> $DIR/const-eval-overflow-4.rs:11:13
    |
 LL |     : [u32; (i8::MAX as i8 + 1i8) as usize]
-   |             ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |             ^^^^^^^^^^^^^^^^^^^^^ evaluation of `A_I8_T::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr
index 1a0832b8ba0..b996370ea3d 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr
+++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr
@@ -23,7 +23,7 @@ error[E0604]: only `u8` can be cast as `char`, not `i8`
 LL |     : [u32; 5i8 as char as usize]
    |             ^^^^^^^^^^^ invalid cast
    |
-help: try casting from `u8` instead
+help: consider casting from `u8` instead
   --> $DIR/const-eval-overflow-4b.rs:24:13
    |
 LL |     : [u32; 5i8 as char as usize]
diff --git a/tests/ui/consts/const-eval/const-eval-overflow2.stderr b/tests/ui/consts/const-eval/const-eval-overflow2.stderr
index a705604e383..6ec3fa73cb7 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow2.stderr
+++ b/tests/ui/consts/const-eval/const-eval-overflow2.stderr
@@ -2,49 +2,49 @@ error[E0080]: attempt to compute `i8::MIN - 1_i8`, which would overflow
   --> $DIR/const-eval-overflow2.rs:12:6
    |
 LL |      i8::MIN - 1,
-   |      ^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^ evaluation of `VALS_I8` failed here
 
 error[E0080]: attempt to compute `i16::MIN - 1_i16`, which would overflow
   --> $DIR/const-eval-overflow2.rs:18:6
    |
 LL |      i16::MIN - 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_I16` failed here
 
 error[E0080]: attempt to compute `i32::MIN - 1_i32`, which would overflow
   --> $DIR/const-eval-overflow2.rs:24:6
    |
 LL |      i32::MIN - 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_I32` failed here
 
 error[E0080]: attempt to compute `i64::MIN - 1_i64`, which would overflow
   --> $DIR/const-eval-overflow2.rs:30:6
    |
 LL |      i64::MIN - 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_I64` failed here
 
 error[E0080]: attempt to compute `0_u8 - 1_u8`, which would overflow
   --> $DIR/const-eval-overflow2.rs:36:6
    |
 LL |      u8::MIN - 1,
-   |      ^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^ evaluation of `VALS_U8` failed here
 
 error[E0080]: attempt to compute `0_u16 - 1_u16`, which would overflow
   --> $DIR/const-eval-overflow2.rs:41:6
    |
 LL |      u16::MIN - 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_U16` failed here
 
 error[E0080]: attempt to compute `0_u32 - 1_u32`, which would overflow
   --> $DIR/const-eval-overflow2.rs:46:6
    |
 LL |      u32::MIN - 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_U32` failed here
 
 error[E0080]: attempt to compute `0_u64 - 1_u64`, which would overflow
   --> $DIR/const-eval-overflow2.rs:52:6
    |
 LL |      u64::MIN - 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_U64` failed here
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/consts/const-eval/const-eval-overflow2b.stderr b/tests/ui/consts/const-eval/const-eval-overflow2b.stderr
index 33de4b6ed32..5b8e559d046 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow2b.stderr
+++ b/tests/ui/consts/const-eval/const-eval-overflow2b.stderr
@@ -2,49 +2,49 @@ error[E0080]: attempt to compute `i8::MAX + 1_i8`, which would overflow
   --> $DIR/const-eval-overflow2b.rs:12:6
    |
 LL |      i8::MAX + 1,
-   |      ^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^ evaluation of `VALS_I8` failed here
 
 error[E0080]: attempt to compute `i16::MAX + 1_i16`, which would overflow
   --> $DIR/const-eval-overflow2b.rs:18:6
    |
 LL |      i16::MAX + 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_I16` failed here
 
 error[E0080]: attempt to compute `i32::MAX + 1_i32`, which would overflow
   --> $DIR/const-eval-overflow2b.rs:24:6
    |
 LL |      i32::MAX + 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_I32` failed here
 
 error[E0080]: attempt to compute `i64::MAX + 1_i64`, which would overflow
   --> $DIR/const-eval-overflow2b.rs:30:6
    |
 LL |      i64::MAX + 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_I64` failed here
 
 error[E0080]: attempt to compute `u8::MAX + 1_u8`, which would overflow
   --> $DIR/const-eval-overflow2b.rs:36:6
    |
 LL |      u8::MAX + 1,
-   |      ^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^ evaluation of `VALS_U8` failed here
 
 error[E0080]: attempt to compute `u16::MAX + 1_u16`, which would overflow
   --> $DIR/const-eval-overflow2b.rs:41:6
    |
 LL |      u16::MAX + 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_U16` failed here
 
 error[E0080]: attempt to compute `u32::MAX + 1_u32`, which would overflow
   --> $DIR/const-eval-overflow2b.rs:46:6
    |
 LL |      u32::MAX + 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_U32` failed here
 
 error[E0080]: attempt to compute `u64::MAX + 1_u64`, which would overflow
   --> $DIR/const-eval-overflow2b.rs:52:6
    |
 LL |      u64::MAX + 1,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_U64` failed here
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/consts/const-eval/const-eval-overflow2c.stderr b/tests/ui/consts/const-eval/const-eval-overflow2c.stderr
index 69949b57904..99eeadf6b0d 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow2c.stderr
+++ b/tests/ui/consts/const-eval/const-eval-overflow2c.stderr
@@ -2,49 +2,49 @@ error[E0080]: attempt to compute `i8::MIN * 2_i8`, which would overflow
   --> $DIR/const-eval-overflow2c.rs:12:6
    |
 LL |      i8::MIN * 2,
-   |      ^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^ evaluation of `VALS_I8` failed here
 
 error[E0080]: attempt to compute `i16::MIN * 2_i16`, which would overflow
   --> $DIR/const-eval-overflow2c.rs:18:6
    |
 LL |      i16::MIN * 2,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_I16` failed here
 
 error[E0080]: attempt to compute `i32::MIN * 2_i32`, which would overflow
   --> $DIR/const-eval-overflow2c.rs:24:6
    |
 LL |      i32::MIN * 2,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_I32` failed here
 
 error[E0080]: attempt to compute `i64::MIN * 2_i64`, which would overflow
   --> $DIR/const-eval-overflow2c.rs:30:6
    |
 LL |      i64::MIN * 2,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_I64` failed here
 
 error[E0080]: attempt to compute `u8::MAX * 2_u8`, which would overflow
   --> $DIR/const-eval-overflow2c.rs:36:6
    |
 LL |      u8::MAX * 2,
-   |      ^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^ evaluation of `VALS_U8` failed here
 
 error[E0080]: attempt to compute `u16::MAX * 2_u16`, which would overflow
   --> $DIR/const-eval-overflow2c.rs:41:6
    |
 LL |      u16::MAX * 2,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_U16` failed here
 
 error[E0080]: attempt to compute `u32::MAX * 2_u32`, which would overflow
   --> $DIR/const-eval-overflow2c.rs:46:6
    |
 LL |      u32::MAX * 2,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_U32` failed here
 
 error[E0080]: attempt to compute `u64::MAX * 2_u64`, which would overflow
   --> $DIR/const-eval-overflow2c.rs:52:6
    |
 LL |      u64::MAX * 2,
-   |      ^^^^^^^^^^^^ evaluation of constant value failed here
+   |      ^^^^^^^^^^^^ evaluation of `VALS_U64` failed here
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/consts/const-eval/const-eval-query-stack.stderr b/tests/ui/consts/const-eval/const-eval-query-stack.stderr
index d5b7e67724d..96206dc5078 100644
--- a/tests/ui/consts/const-eval/const-eval-query-stack.stderr
+++ b/tests/ui/consts/const-eval/const-eval-query-stack.stderr
@@ -2,7 +2,7 @@ error: internal compiler error[E0080]: attempt to divide `1_i32` by zero
   --> $DIR/const-eval-query-stack.rs:16:16
    |
 LL | const X: i32 = 1 / 0;
-   |                ^^^^^ evaluation of constant value failed here
+   |                ^^^^^ evaluation of `X` failed here
 
 
 note: please make sure that you have updated to the latest nightly
diff --git a/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
index 3a1e8c734d4..d28d6841ca9 100644
--- a/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
+++ b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:27:49
    |
 LL |     const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_USIZE_UNION` failed here
    |
    = 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
@@ -11,7 +11,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:30:43
    |
 LL |     const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 };
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_U8_UNION` failed here
    |
    = 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
@@ -20,7 +20,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:33:45
    |
 LL |     const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_U16_UNION` failed here
    |
    = 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
@@ -29,7 +29,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:36:45
    |
 LL |     const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_U32_UNION` failed here
    |
    = 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
@@ -38,7 +38,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:39:45
    |
 LL |     const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_U64_UNION` failed here
    |
    = 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
@@ -47,13 +47,13 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/const-pointer-values-in-various-types.rs:42:47
    |
 LL |     const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_U128_UNION` failed here
 
 error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:45:43
    |
 LL |     const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_I8_UNION` failed here
    |
    = 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
@@ -62,7 +62,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:48:45
    |
 LL |     const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_I16_UNION` failed here
    |
    = 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
@@ -71,7 +71,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:51:45
    |
 LL |     const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_I32_UNION` failed here
    |
    = 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
@@ -80,7 +80,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:54:45
    |
 LL |     const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_I64_UNION` failed here
    |
    = 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
@@ -89,13 +89,13 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/const-pointer-values-in-various-types.rs:57:47
    |
 LL |     const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_I128_UNION` failed here
 
 error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:60:45
    |
 LL |     const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_F32_UNION` failed here
    |
    = 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
@@ -104,7 +104,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:63:45
    |
 LL |     const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_F64_UNION` failed here
    |
    = 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
@@ -113,7 +113,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:66:47
    |
 LL |     const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_BOOL_UNION` failed here
    |
    = 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
@@ -122,7 +122,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:69:47
    |
 LL |     const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_CHAR_UNION` failed here
    |
    = 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
@@ -131,7 +131,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:72:39
    |
 LL |     const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
-   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_U8_UNION` failed here
    |
    = 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
@@ -140,7 +140,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:75:41
    |
 LL |     const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_U16_UNION` failed here
    |
    = 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
@@ -149,7 +149,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:78:41
    |
 LL |     const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_U32_UNION` failed here
    |
    = 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
@@ -158,7 +158,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:81:41
    |
 LL |     const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_U64_UNION` failed here
    |
    = 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
@@ -167,7 +167,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:84:43
    |
 LL |     const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_U128_UNION` failed here
    |
    = 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
@@ -176,7 +176,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:87:39
    |
 LL |     const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
-   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_I8_UNION` failed here
    |
    = 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
@@ -185,7 +185,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:90:41
    |
 LL |     const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_I16_UNION` failed here
    |
    = 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
@@ -194,7 +194,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:93:41
    |
 LL |     const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_I32_UNION` failed here
    |
    = 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
@@ -203,7 +203,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:96:41
    |
 LL |     const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_I64_UNION` failed here
    |
    = 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
@@ -212,7 +212,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:99:43
    |
 LL |     const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_I128_UNION` failed here
    |
    = 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
@@ -221,7 +221,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:102:41
    |
 LL |     const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_F32_UNION` failed here
    |
    = 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
@@ -230,7 +230,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:105:41
    |
 LL |     const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_F64_UNION` failed here
    |
    = 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
@@ -239,7 +239,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:108:43
    |
 LL |     const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_BOOL_UNION` failed here
    |
    = 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
@@ -248,7 +248,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/const-pointer-values-in-various-types.rs:111:43
    |
 LL |     const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::STR_CHAR_UNION` failed here
    |
    = 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
diff --git a/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs b/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs
index 03976a05b75..8d928e26378 100644
--- a/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs
+++ b/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs
@@ -14,10 +14,10 @@ const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
 }
 
 const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
-//~^ NOTE evaluation of constant value failed
+//~^ NOTE failed inside this call
 //~| ERROR calling non-const function `double`
 const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
-//~^ NOTE evaluation of constant value failed
+//~^ NOTE failed inside this call
 //~| ERROR calling non-const function `double`
 
 fn main() {
diff --git a/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr
index 6eddb72bae8..3ac96b40994 100644
--- a/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr
+++ b/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr
@@ -2,7 +2,7 @@ error[E0080]: calling non-const function `double`
   --> $DIR/const_fn_ptr_fail2.rs:16:18
    |
 LL | const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
-   |                  ^^^^^^^^^ evaluation of constant value failed here
+   |                  ^^^^^^^^^ evaluation of `Y` failed inside this call
    |
 note: inside `bar`
   --> $DIR/const_fn_ptr_fail2.rs:9:5
@@ -14,7 +14,7 @@ error[E0080]: calling non-const function `double`
   --> $DIR/const_fn_ptr_fail2.rs:19:18
    |
 LL | const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
-   |                  ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                  ^^^^^^^^^^^^^^ evaluation of `Z` failed inside this call
    |
 note: inside `bar`
   --> $DIR/const_fn_ptr_fail2.rs:9:5
diff --git a/tests/ui/consts/const-eval/const_panic-normalize-tabs-115498.stderr b/tests/ui/consts/const-eval/const_panic-normalize-tabs-115498.stderr
index 6e5e0e727fb..7e7b59ce43f 100644
--- a/tests/ui/consts/const-eval/const_panic-normalize-tabs-115498.stderr
+++ b/tests/ui/consts/const-eval/const_panic-normalize-tabs-115498.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked:
   --> $DIR/const_panic-normalize-tabs-115498.rs:3:17
    |
 LL | struct Bug([u8; panic!{"\t"}]);
-   |                 ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                 ^^^^^^^^^^^^ evaluation of `Bug::0::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/const_panic.stderr b/tests/ui/consts/const-eval/const_panic.stderr
index 1b5421276c3..46b36ecfa6a 100644
--- a/tests/ui/consts/const-eval/const_panic.stderr
+++ b/tests/ui/consts/const-eval/const_panic.stderr
@@ -2,25 +2,25 @@ error[E0080]: evaluation panicked: cheese
   --> $DIR/const_panic.rs:6:15
    |
 LL | const Z: () = std::panic!("cheese");
-   |               ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^^^^^^ evaluation of `Z` failed here
 
 error[E0080]: evaluation panicked: explicit panic
   --> $DIR/const_panic.rs:9:16
    |
 LL | const Z2: () = std::panic!();
-   |                ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                ^^^^^^^^^^^^^ evaluation of `Z2` failed here
 
 error[E0080]: evaluation panicked: internal error: entered unreachable code
   --> $DIR/const_panic.rs:12:15
    |
 LL | const Y: () = std::unreachable!();
-   |               ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^^^^ evaluation of `Y` failed here
 
 error[E0080]: evaluation panicked: not implemented
   --> $DIR/const_panic.rs:15:15
    |
 LL | const X: () = std::unimplemented!();
-   |               ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^^^^^^ evaluation of `X` failed here
    |
    = note: this error originates in the macro `std::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -28,37 +28,37 @@ error[E0080]: evaluation panicked: hello
   --> $DIR/const_panic.rs:18:15
    |
 LL | const W: () = std::panic!(MSG);
-   |               ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^ evaluation of `W` failed here
 
 error[E0080]: evaluation panicked: hello
   --> $DIR/const_panic.rs:21:16
    |
 LL | const W2: () = std::panic!("{}", MSG);
-   |                ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `W2` failed here
 
 error[E0080]: evaluation panicked: cheese
   --> $DIR/const_panic.rs:24:20
    |
 LL | const Z_CORE: () = core::panic!("cheese");
-   |                    ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Z_CORE` failed here
 
 error[E0080]: evaluation panicked: explicit panic
   --> $DIR/const_panic.rs:27:21
    |
 LL | const Z2_CORE: () = core::panic!();
-   |                     ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                     ^^^^^^^^^^^^^^ evaluation of `Z2_CORE` failed here
 
 error[E0080]: evaluation panicked: internal error: entered unreachable code
   --> $DIR/const_panic.rs:30:20
    |
 LL | const Y_CORE: () = core::unreachable!();
-   |                    ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^^^^^ evaluation of `Y_CORE` failed here
 
 error[E0080]: evaluation panicked: not implemented
   --> $DIR/const_panic.rs:33:20
    |
 LL | const X_CORE: () = core::unimplemented!();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `X_CORE` failed here
    |
    = note: this error originates in the macro `core::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -66,13 +66,13 @@ error[E0080]: evaluation panicked: hello
   --> $DIR/const_panic.rs:36:20
    |
 LL | const W_CORE: () = core::panic!(MSG);
-   |                    ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^^ evaluation of `W_CORE` failed here
 
 error[E0080]: evaluation panicked: hello
   --> $DIR/const_panic.rs:39:21
    |
 LL | const W2_CORE: () = core::panic!("{}", MSG);
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `W2_CORE` failed here
 
 error: aborting due to 12 previous errors
 
diff --git a/tests/ui/consts/const-eval/const_panic_2021.stderr b/tests/ui/consts/const-eval/const_panic_2021.stderr
index 15b173f9400..ba771a35d03 100644
--- a/tests/ui/consts/const-eval/const_panic_2021.stderr
+++ b/tests/ui/consts/const-eval/const_panic_2021.stderr
@@ -2,25 +2,25 @@ error[E0080]: evaluation panicked: blåhaj
   --> $DIR/const_panic_2021.rs:6:15
    |
 LL | const A: () = std::panic!("blåhaj");
-   |               ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^^^^^^ evaluation of `A` failed here
 
 error[E0080]: evaluation panicked: explicit panic
   --> $DIR/const_panic_2021.rs:9:15
    |
 LL | const B: () = std::panic!();
-   |               ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^ evaluation of `B` failed here
 
 error[E0080]: evaluation panicked: internal error: entered unreachable code
   --> $DIR/const_panic_2021.rs:12:15
    |
 LL | const C: () = std::unreachable!();
-   |               ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^^^^ evaluation of `C` failed here
 
 error[E0080]: evaluation panicked: not implemented
   --> $DIR/const_panic_2021.rs:15:15
    |
 LL | const D: () = std::unimplemented!();
-   |               ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^^^^^^ evaluation of `D` failed here
    |
    = note: this error originates in the macro `std::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -28,31 +28,31 @@ error[E0080]: evaluation panicked: hello
   --> $DIR/const_panic_2021.rs:18:15
    |
 LL | const E: () = std::panic!("{}", MSG);
-   |               ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `E` failed here
 
 error[E0080]: evaluation panicked: shark
   --> $DIR/const_panic_2021.rs:21:20
    |
 LL | const A_CORE: () = core::panic!("shark");
-   |                    ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^^^^^^ evaluation of `A_CORE` failed here
 
 error[E0080]: evaluation panicked: explicit panic
   --> $DIR/const_panic_2021.rs:24:20
    |
 LL | const B_CORE: () = core::panic!();
-   |                    ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^ evaluation of `B_CORE` failed here
 
 error[E0080]: evaluation panicked: internal error: entered unreachable code
   --> $DIR/const_panic_2021.rs:27:20
    |
 LL | const C_CORE: () = core::unreachable!();
-   |                    ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^^^^^ evaluation of `C_CORE` failed here
 
 error[E0080]: evaluation panicked: not implemented
   --> $DIR/const_panic_2021.rs:30:20
    |
 LL | const D_CORE: () = core::unimplemented!();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `D_CORE` failed here
    |
    = note: this error originates in the macro `core::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -60,7 +60,7 @@ error[E0080]: evaluation panicked: hello
   --> $DIR/const_panic_2021.rs:33:20
    |
 LL | const E_CORE: () = core::panic!("{}", MSG);
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `E_CORE` failed here
 
 error: aborting due to 10 previous errors
 
diff --git a/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr b/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr
index 3c308e38850..e07b172d426 100644
--- a/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr
+++ b/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr
@@ -2,19 +2,19 @@ error[E0080]: evaluation panicked: cheese
   --> $DIR/const_panic_libcore_bin.rs:8:15
    |
 LL | const Z: () = panic!("cheese");
-   |               ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^ evaluation of `Z` failed here
 
 error[E0080]: evaluation panicked: internal error: entered unreachable code
   --> $DIR/const_panic_libcore_bin.rs:11:15
    |
 LL | const Y: () = unreachable!();
-   |               ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^ evaluation of `Y` failed here
 
 error[E0080]: evaluation panicked: not implemented
   --> $DIR/const_panic_libcore_bin.rs:14:15
    |
 LL | const X: () = unimplemented!();
-   |               ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^ evaluation of `X` failed here
    |
    = note: this error originates in the macro `unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/consts/const-eval/const_panic_track_caller.rs b/tests/ui/consts/const-eval/const_panic_track_caller.rs
index 5f5d853eb97..f5ede567b82 100644
--- a/tests/ui/consts/const-eval/const_panic_track_caller.rs
+++ b/tests/ui/consts/const-eval/const_panic_track_caller.rs
@@ -17,5 +17,5 @@ const fn c() -> u32 {
 }
 
 const X: u32 = c();
-//~^ NOTE evaluation of constant value failed
+//~^ NOTE failed inside this call
 //~| ERROR hey
diff --git a/tests/ui/consts/const-eval/const_panic_track_caller.stderr b/tests/ui/consts/const-eval/const_panic_track_caller.stderr
index b4017ccf8da..4793c5398fc 100644
--- a/tests/ui/consts/const-eval/const_panic_track_caller.stderr
+++ b/tests/ui/consts/const-eval/const_panic_track_caller.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: hey
   --> $DIR/const_panic_track_caller.rs:19:16
    |
 LL | const X: u32 = c();
-   |                ^^^ evaluation of constant value failed here
+   |                ^^^ evaluation of `X` failed inside this call
    |
 note: inside `c`
   --> $DIR/const_panic_track_caller.rs:15:5
diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr b/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr
index 6f096ee5ce7..6341292789c 100644
--- a/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr
+++ b/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr
@@ -2,13 +2,13 @@ error[E0080]: memory access failed: attempting to access 4 bytes, but got 0x2a[n
   --> $DIR/const_raw_ptr_ops2.rs:7:26
    |
 LL | const Z2: i32 = unsafe { *(42 as *const i32) };
-   |                          ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^^^ evaluation of `Z2` failed here
 
 error[E0080]: memory access failed: attempting to access 4 bytes, but got 0x2c[noalloc] which is a dangling pointer (it has no provenance)
   --> $DIR/const_raw_ptr_ops2.rs:8:26
    |
 LL | const Z3: i32 = unsafe { *(44 as *const i32) };
-   |                          ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^^^ evaluation of `Z3` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr
index 9132c7e9cd4..a1f0b7b2beb 100644
--- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr
@@ -2,7 +2,7 @@ error[E0080]: invalid align passed to `const_allocate`: 3 is not a power of 2
   --> $DIR/alloc_intrinsic_errors.rs:7:18
    |
 LL | const FOO: i32 = foo();
-   |                  ^^^^^ evaluation of constant value failed here
+   |                  ^^^^^ evaluation of `FOO` failed inside this call
    |
 note: inside `foo`
   --> $DIR/alloc_intrinsic_errors.rs:10:17
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
index cb419f2f739..d4039e1952c 100644
--- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
@@ -13,7 +13,7 @@ error[E0080]: memory access failed: ALLOC1 has been freed, so this pointer is da
   --> $DIR/dealloc_intrinsic_dangling.rs:22:5
    |
 LL |     *reference
-   |     ^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^ evaluation of `_Y` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr
index 3038d60f202..803b772615f 100644
--- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr
@@ -2,7 +2,7 @@ error[E0080]: memory access failed: ALLOC0 has been freed, so this pointer is da
   --> $DIR/dealloc_intrinsic_duplicate.rs:9:5
    |
 LL |     intrinsics::const_deallocate(ptr, 4, 4);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_X` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.stderr
index dea55c6086e..2d61f06ac5c 100644
--- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.stderr
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.stderr
@@ -2,25 +2,25 @@ error[E0080]: incorrect layout on deallocation: ALLOC0 has size 4 and alignment
   --> $DIR/dealloc_intrinsic_incorrect_layout.rs:8:5
    |
 LL |     intrinsics::const_deallocate(ptr, 4, 2);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_X` failed here
 
 error[E0080]: incorrect layout on deallocation: ALLOC1 has size 4 and alignment 4, but gave size 2 and alignment 4
   --> $DIR/dealloc_intrinsic_incorrect_layout.rs:13:5
    |
 LL |     intrinsics::const_deallocate(ptr, 2, 4);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_Y` failed here
 
 error[E0080]: incorrect layout on deallocation: ALLOC2 has size 4 and alignment 4, but gave size 3 and alignment 4
   --> $DIR/dealloc_intrinsic_incorrect_layout.rs:19:5
    |
 LL |     intrinsics::const_deallocate(ptr, 3, 4);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_Z` failed here
 
 error[E0080]: invalid align passed to `const_deallocate`: 3 is not a power of 2
   --> $DIR/dealloc_intrinsic_incorrect_layout.rs:25:5
    |
 LL |     intrinsics::const_deallocate(ptr, 4, 3);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_W` failed here
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/consts/const-eval/index_out_of_bounds.stderr b/tests/ui/consts/const-eval/index_out_of_bounds.stderr
index f4ec4c516fd..56e340cfebd 100644
--- a/tests/ui/consts/const-eval/index_out_of_bounds.stderr
+++ b/tests/ui/consts/const-eval/index_out_of_bounds.stderr
@@ -2,7 +2,7 @@ error[E0080]: index out of bounds: the length is 0 but the index is 0
   --> $DIR/index_out_of_bounds.rs:1:19
    |
 LL | static FOO: i32 = [][0];
-   |                   ^^^^^ evaluation of static initializer failed here
+   |                   ^^^^^ evaluation of `FOO` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/issue-43197.stderr b/tests/ui/consts/const-eval/issue-43197.stderr
index cad23becff7..c525fd1c13b 100644
--- a/tests/ui/consts/const-eval/issue-43197.stderr
+++ b/tests/ui/consts/const-eval/issue-43197.stderr
@@ -2,13 +2,13 @@ error[E0080]: attempt to compute `0_u32 - 1_u32`, which would overflow
   --> $DIR/issue-43197.rs:6:20
    |
 LL |     const X: u32 = 0 - 1;
-   |                    ^^^^^ evaluation of constant value failed here
+   |                    ^^^^^ evaluation of `main::X` failed here
 
 error[E0080]: attempt to compute `0_u32 - 1_u32`, which would overflow
   --> $DIR/issue-43197.rs:8:24
    |
 LL |     const Y: u32 = foo(0 - 1);
-   |                        ^^^^^ evaluation of constant value failed here
+   |                        ^^^^^ evaluation of `main::Y` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/issue-49296.stderr b/tests/ui/consts/const-eval/issue-49296.stderr
index 4a66ec6c940..9da3e3d6d30 100644
--- a/tests/ui/consts/const-eval/issue-49296.stderr
+++ b/tests/ui/consts/const-eval/issue-49296.stderr
@@ -2,7 +2,7 @@ error[E0080]: memory access failed: ALLOC0 has been freed, so this pointer is da
   --> $DIR/issue-49296.rs:9:16
    |
 LL | const X: u64 = *wat(42);
-   |                ^^^^^^^^ evaluation of constant value failed here
+   |                ^^^^^^^^ evaluation of `X` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr
index ffff7594e3d..d2c1e4fde9c 100644
--- a/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr
+++ b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr
@@ -2,7 +2,7 @@ error[E0080]: `extern type` field does not have a known offset
   --> $DIR/issue-91827-extern-types-field-offset.rs:38:17
    |
 LL |     let field = &x.a;
-   |                 ^^^^ evaluation of constant value failed here
+   |                 ^^^^ evaluation of `OFFSET` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/mod-static-with-const-fn.stderr b/tests/ui/consts/const-eval/mod-static-with-const-fn.stderr
index f8cf6096095..f8a6fa24a36 100644
--- a/tests/ui/consts/const-eval/mod-static-with-const-fn.stderr
+++ b/tests/ui/consts/const-eval/mod-static-with-const-fn.stderr
@@ -2,7 +2,7 @@ error[E0080]: modifying a static's initial value from another static's initializ
   --> $DIR/mod-static-with-const-fn.rs:14:5
    |
 LL |     *FOO.0.get() = 5;
-   |     ^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |     ^^^^^^^^^^^^^^^^ evaluation of `BAR` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr b/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr
index 32ae9475560..8dbb05c1572 100644
--- a/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr
+++ b/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr
@@ -2,7 +2,7 @@ error[E0080]: memory access failed: attempting to access 1 byte, but got 0x1[noa
   --> $DIR/nonnull_as_ref_ub.rs:4:29
    |
 LL | const _: () = assert!(42 == *unsafe { NON_NULL.as_ref() });
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr
index 64c9f92d5ee..d3a29314928 100644
--- a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr
+++ b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/panic-assoc-never-type.rs:10:21
    |
 LL |     const VOID: ! = panic!();
-   |                     ^^^^^^^^ evaluation of constant value failed here
+   |                     ^^^^^^^^ evaluation of `PrintName::VOID` failed here
 
 note: erroneous constant encountered
   --> $DIR/panic-assoc-never-type.rs:15:13
diff --git a/tests/ui/consts/const-eval/panic-never-type.stderr b/tests/ui/consts/const-eval/panic-never-type.stderr
index cacce93babe..317be64205e 100644
--- a/tests/ui/consts/const-eval/panic-never-type.stderr
+++ b/tests/ui/consts/const-eval/panic-never-type.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/panic-never-type.rs:4:17
    |
 LL | const VOID: ! = panic!();
-   |                 ^^^^^^^^ evaluation of constant value failed here
+   |                 ^^^^^^^^ evaluation of `VOID` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/parse_ints.stderr b/tests/ui/consts/const-eval/parse_ints.stderr
index 99aad805a2d..7e529c03725 100644
--- a/tests/ui/consts/const-eval/parse_ints.stderr
+++ b/tests/ui/consts/const-eval/parse_ints.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: from_ascii_radix: radix must lie in the range
   --> $DIR/parse_ints.rs:5:24
    |
 LL | const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); };
-   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_TOO_LOW` failed inside this call
    |
 note: inside `core::num::<impl u64>::from_str_radix`
   --> $SRC_DIR/core/src/num/mod.rs:LL:COL
@@ -14,7 +14,7 @@ error[E0080]: evaluation panicked: from_ascii_radix: radix must lie in the range
   --> $DIR/parse_ints.rs:6:25
    |
 LL | const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); };
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_TOO_HIGH` failed inside this call
    |
 note: inside `core::num::<impl u64>::from_str_radix`
   --> $SRC_DIR/core/src/num/mod.rs:LL:COL
diff --git a/tests/ui/consts/const-eval/partial_ptr_overwrite.stderr b/tests/ui/consts/const-eval/partial_ptr_overwrite.stderr
index 4d514495e73..6ef1cfd35c8 100644
--- a/tests/ui/consts/const-eval/partial_ptr_overwrite.stderr
+++ b/tests/ui/consts/const-eval/partial_ptr_overwrite.stderr
@@ -2,7 +2,7 @@ error[E0080]: unable to overwrite parts of a pointer in memory at ALLOC0
   --> $DIR/partial_ptr_overwrite.rs:7:9
    |
 LL |         *(ptr as *mut u8) = 123;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `PARTIAL_OVERWRITE` failed here
    |
    = 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
diff --git a/tests/ui/consts/const-eval/raw-pointer-ub.rs b/tests/ui/consts/const-eval/raw-pointer-ub.rs
index c8d1e36e88b..df7bc2fe4fb 100644
--- a/tests/ui/consts/const-eval/raw-pointer-ub.rs
+++ b/tests/ui/consts/const-eval/raw-pointer-ub.rs
@@ -1,14 +1,14 @@
 const MISALIGNED_LOAD: () = unsafe {
     let mem = [0u32; 8];
     let ptr = mem.as_ptr().byte_add(1);
-    let _val = *ptr; //~NOTE: evaluation of constant value failed
+    let _val = *ptr; //~NOTE: failed here
     //~^ERROR: based on pointer with alignment 1, but alignment 4 is required
 };
 
 const MISALIGNED_STORE: () = unsafe {
     let mut mem = [0u32; 8];
     let ptr = mem.as_mut_ptr().byte_add(1);
-    *ptr = 0; //~NOTE: evaluation of constant value failed
+    *ptr = 0; //~NOTE: failed here
     //~^ERROR: based on pointer with alignment 1, but alignment 4 is required
 };
 
@@ -17,7 +17,7 @@ const MISALIGNED_COPY: () = unsafe {
     let y = x.as_ptr().cast::<u32>();
     let mut z = 123;
     y.copy_to_nonoverlapping(&mut z, 1);
-    //~^ NOTE evaluation of constant value failed
+    //~^ NOTE failed inside this call
     //~| NOTE inside `std::ptr::copy_nonoverlapping::<u32>`
     //~| ERROR accessing memory with alignment 1, but alignment 4 is required
     // The actual error points into the implementation of `copy_to_nonoverlapping`.
@@ -30,14 +30,14 @@ const MISALIGNED_FIELD: () = unsafe {
     let mem = [0f32; 8];
     let ptr = mem.as_ptr().cast::<Aligned>();
     // Accessing an f32 field but we still require the alignment of the pointer type.
-    let _val = (*ptr).0; //~NOTE: evaluation of constant value failed
+    let _val = (*ptr).0; //~NOTE: failed here
     //~^ERROR: based on pointer with alignment 4, but alignment 16 is required
 };
 
 const OOB: () = unsafe {
     let mem = [0u32; 1];
     let ptr = mem.as_ptr().cast::<u64>();
-    let _val = *ptr; //~NOTE: evaluation of constant value failed
+    let _val = *ptr; //~NOTE: failed here
     //~^ERROR: is only 4 bytes from the end of the allocation
 };
 
diff --git a/tests/ui/consts/const-eval/raw-pointer-ub.stderr b/tests/ui/consts/const-eval/raw-pointer-ub.stderr
index e424924e14b..00af20a722d 100644
--- a/tests/ui/consts/const-eval/raw-pointer-ub.stderr
+++ b/tests/ui/consts/const-eval/raw-pointer-ub.stderr
@@ -2,19 +2,19 @@ error[E0080]: accessing memory based on pointer with alignment 1, but alignment
   --> $DIR/raw-pointer-ub.rs:4:16
    |
 LL |     let _val = *ptr;
-   |                ^^^^ evaluation of constant value failed here
+   |                ^^^^ evaluation of `MISALIGNED_LOAD` failed here
 
 error[E0080]: accessing memory based on pointer with alignment 1, but alignment 4 is required
   --> $DIR/raw-pointer-ub.rs:11:5
    |
 LL |     *ptr = 0;
-   |     ^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^ evaluation of `MISALIGNED_STORE` failed here
 
 error[E0080]: accessing memory with alignment 1, but alignment 4 is required
   --> $DIR/raw-pointer-ub.rs:19:5
    |
 LL |     y.copy_to_nonoverlapping(&mut z, 1);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MISALIGNED_COPY` failed inside this call
    |
 note: inside `std::ptr::copy_nonoverlapping::<u32>`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
@@ -23,13 +23,13 @@ error[E0080]: accessing memory based on pointer with alignment 4, but alignment
   --> $DIR/raw-pointer-ub.rs:33:16
    |
 LL |     let _val = (*ptr).0;
-   |                ^^^^^^^^ evaluation of constant value failed here
+   |                ^^^^^^^^ evaluation of `MISALIGNED_FIELD` failed here
 
 error[E0080]: memory access failed: attempting to access 8 bytes, but got ALLOC0 which is only 4 bytes from the end of the allocation
   --> $DIR/raw-pointer-ub.rs:40:16
    |
 LL |     let _val = *ptr;
-   |                ^^^^ evaluation of constant value failed here
+   |                ^^^^ evaluation of `OOB` failed here
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr b/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr
index be86541434b..e435a1ed7ec 100644
--- a/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr
+++ b/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ref_to_int_match.rs:24:27
    |
 LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
-   |                           ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                           ^^^^^^^^^^^^^^^^ evaluation of `BAR` failed here
    |
    = 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
diff --git a/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr b/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr
index be86541434b..e435a1ed7ec 100644
--- a/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr
+++ b/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr
@@ -2,7 +2,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ref_to_int_match.rs:24:27
    |
 LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
-   |                           ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                           ^^^^^^^^^^^^^^^^ evaluation of `BAR` failed here
    |
    = 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
diff --git a/tests/ui/consts/const-eval/shift_overflow.stderr b/tests/ui/consts/const-eval/shift_overflow.stderr
index e5703fb1d77..8c32ddb5908 100644
--- a/tests/ui/consts/const-eval/shift_overflow.stderr
+++ b/tests/ui/consts/const-eval/shift_overflow.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to shift left by `4294967296_u64`, which would overflow
   --> $DIR/shift_overflow.rs:3:9
    |
 LL |     X = 1 << ((u32::MAX as u64) + 1),
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Foo::X::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/transmute-size-mismatch.rs b/tests/ui/consts/const-eval/transmute-size-mismatch.rs
index ea5cdceda88..15b69af14e9 100644
--- a/tests/ui/consts/const-eval/transmute-size-mismatch.rs
+++ b/tests/ui/consts/const-eval/transmute-size-mismatch.rs
@@ -19,10 +19,10 @@ const unsafe fn mir_transmute<T, U>(x: T) -> U {
     }
 }
 
-const FROM_BIGGER: u16 = unsafe { mir_transmute(123_i32) }; //~ NOTE evaluation of constant value failed
+const FROM_BIGGER: u16 = unsafe { mir_transmute(123_i32) }; //~ NOTE failed inside this call
 //~^ ERROR transmuting from 4-byte type to 2-byte type: `i32` -> `u16`
 
-const FROM_SMALLER: u32 = unsafe { mir_transmute(123_i16) }; //~ NOTE evaluation of constant value failed
+const FROM_SMALLER: u32 = unsafe { mir_transmute(123_i16) }; //~ NOTE failed inside this call
 //~^ ERROR transmuting from 2-byte type to 4-byte type: `i16` -> `u32`
 
 fn main() {}
diff --git a/tests/ui/consts/const-eval/transmute-size-mismatch.stderr b/tests/ui/consts/const-eval/transmute-size-mismatch.stderr
index 92088a4749a..d0457e3ebee 100644
--- a/tests/ui/consts/const-eval/transmute-size-mismatch.stderr
+++ b/tests/ui/consts/const-eval/transmute-size-mismatch.stderr
@@ -2,7 +2,7 @@ error[E0080]: transmuting from 4-byte type to 2-byte type: `i32` -> `u16`
   --> $DIR/transmute-size-mismatch.rs:22:35
    |
 LL | const FROM_BIGGER: u16 = unsafe { mir_transmute(123_i32) };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `FROM_BIGGER` failed inside this call
    |
 note: inside `mir_transmute::<i32, u16>`
   --> $DIR/transmute-size-mismatch.rs:12:13
@@ -14,7 +14,7 @@ error[E0080]: transmuting from 2-byte type to 4-byte type: `i16` -> `u32`
   --> $DIR/transmute-size-mismatch.rs:25:36
    |
 LL | const FROM_SMALLER: u32 = unsafe { mir_transmute(123_i16) };
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `FROM_SMALLER` failed inside this call
    |
 note: inside `mir_transmute::<i16, u32>`
   --> $DIR/transmute-size-mismatch.rs:12:13
diff --git a/tests/ui/consts/const-eval/ub-enum-overwrite.stderr b/tests/ui/consts/const-eval/ub-enum-overwrite.stderr
index 0c1a606904c..52af52d3236 100644
--- a/tests/ui/consts/const-eval/ub-enum-overwrite.stderr
+++ b/tests/ui/consts/const-eval/ub-enum-overwrite.stderr
@@ -2,7 +2,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/ub-enum-overwrite.rs:11:14
    |
 LL |     unsafe { *p }
-   |              ^^ evaluation of constant value failed here
+   |              ^^ evaluation of `_` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/ub-enum.stderr b/tests/ui/consts/const-eval/ub-enum.stderr
index 7015102a50a..29f7a1f051a 100644
--- a/tests/ui/consts/const-eval/ub-enum.stderr
+++ b/tests/ui/consts/const-eval/ub-enum.stderr
@@ -13,7 +13,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-enum.rs:32:1
    |
 LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM_PTR` failed here
    |
    = 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
@@ -22,7 +22,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-enum.rs:35:1
    |
 LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM_WRAPPED` failed here
    |
    = 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
@@ -42,7 +42,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-enum.rs:49:1
    |
 LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM2_PTR` failed here
    |
    = 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
@@ -51,7 +51,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-enum.rs:52:1
    |
 LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM2_WRAPPED` failed here
    |
    = 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
@@ -60,13 +60,13 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/ub-enum.rs:61:41
    |
 LL | const BAD_ENUM2_UNDEF: Enum2 = unsafe { MaybeUninit { uninit: () }.init };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM2_UNDEF` failed here
 
 error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-enum.rs:65:1
    |
 LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM2_OPTION_PTR` failed here
    |
    = 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
@@ -108,19 +108,19 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabi
   --> $DIR/ub-enum.rs:97:77
    |
 LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
-   |                                                                             ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                                                             ^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_UNINHABITED_WITH_DATA1` failed here
 
 error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant
   --> $DIR/ub-enum.rs:99:77
    |
 LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
-   |                                                                             ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                                                             ^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_UNINHABITED_WITH_DATA2` failed here
 
 error[E0080]: read discriminant of an uninhabited enum variant
   --> $DIR/ub-enum.rs:105:9
    |
 LL |         std::mem::discriminant(&*(&() as *const () as *const Never));
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `TEST_ICE_89765` failed inside this call
    |
 note: inside `discriminant::<Never>`
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
diff --git a/tests/ui/consts/const-eval/ub-invalid-values.rs b/tests/ui/consts/const-eval/ub-invalid-values.rs
index e5d387fa7cc..8c47b1119f4 100644
--- a/tests/ui/consts/const-eval/ub-invalid-values.rs
+++ b/tests/ui/consts/const-eval/ub-invalid-values.rs
@@ -5,7 +5,7 @@ const fn bool_cast(ptr: *const bool) { unsafe {
 
 const _: () = {
     let v = 3_u8;
-    bool_cast(&v as *const u8 as *const bool); //~ NOTE: evaluation of constant value failed
+    bool_cast(&v as *const u8 as *const bool); //~ NOTE: failed inside this call
     //~^ ERROR interpreting an invalid 8-bit value as a bool
 };
 
diff --git a/tests/ui/consts/const-eval/ub-invalid-values.stderr b/tests/ui/consts/const-eval/ub-invalid-values.stderr
index 83879eeb716..3a3b9bc16b8 100644
--- a/tests/ui/consts/const-eval/ub-invalid-values.stderr
+++ b/tests/ui/consts/const-eval/ub-invalid-values.stderr
@@ -2,7 +2,7 @@ error[E0080]: interpreting an invalid 8-bit value as a bool: 0x03
   --> $DIR/ub-invalid-values.rs:8:5
    |
 LL |     bool_cast(&v as *const u8 as *const bool);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed inside this call
    |
 note: inside `bool_cast`
   --> $DIR/ub-invalid-values.rs:2:16
diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr
index 0a02dbb16bf..314141e4837 100644
--- a/tests/ui/consts/const-eval/ub-nonnull.stderr
+++ b/tests/ui/consts/const-eval/ub-nonnull.stderr
@@ -13,7 +13,7 @@ error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer
   --> $DIR/ub-nonnull.rs:22:29
    |
 LL |     let out_of_bounds_ptr = &ptr[255];
-   |                             ^^^^^^^^^ evaluation of constant value failed here
+   |                             ^^^^^^^^^ evaluation of `OUT_OF_BOUNDS_PTR` failed here
 
 error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
   --> $DIR/ub-nonnull.rs:26:1
@@ -41,7 +41,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/ub-nonnull.rs:36:38
    |
 LL | const UNINIT: NonZero<u8> = unsafe { MaybeUninit { uninit: () }.init };
-   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT` failed here
 
 error[E0080]: constructing invalid value: encountered 42, but expected something in the range 10..=30
   --> $DIR/ub-nonnull.rs:44:1
diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr
index e10f21b02af..d5ccc396b90 100644
--- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr
+++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr
@@ -46,7 +46,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-ref-ptr.rs:33:1
    |
 LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE` failed here
    |
    = 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
@@ -55,7 +55,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-ref-ptr.rs:36:39
    |
 LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
-   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE_SLICE` failed here
    |
    = 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
@@ -70,7 +70,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-ref-ptr.rs:39:86
    |
 LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
-   |                                                                                      ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                                                                      ^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE_BOX_SLICE` failed here
    |
    = 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
@@ -107,7 +107,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/ub-ref-ptr.rs:48:41
    |
 LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_PTR` failed here
 
 error[E0080]: constructing invalid value: encountered null pointer, but expected a function pointer
   --> $DIR/ub-ref-ptr.rs:51:1
@@ -124,7 +124,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/ub-ref-ptr.rs:53:38
    |
 LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
-   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_FN_PTR` failed here
 
 error[E0080]: constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
   --> $DIR/ub-ref-ptr.rs:55:1
@@ -152,7 +152,7 @@ error[E0080]: accessing memory based on pointer with alignment 1, but alignment
   --> $DIR/ub-ref-ptr.rs:64:5
    |
 LL |     ptr.read();
-   |     ^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^ evaluation of `UNALIGNED_READ` failed here
 
 error: aborting due to 15 previous errors
 
diff --git a/tests/ui/consts/const-eval/ub-uninhabit.stderr b/tests/ui/consts/const-eval/ub-uninhabit.stderr
index 582a7a07be9..b0f475fe938 100644
--- a/tests/ui/consts/const-eval/ub-uninhabit.stderr
+++ b/tests/ui/consts/const-eval/ub-uninhabit.stderr
@@ -2,7 +2,7 @@ error[E0080]: constructing invalid value: encountered a value of uninhabited typ
   --> $DIR/ub-uninhabit.rs:20:35
    |
 LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_BAD_BAD` failed here
 
 error[E0080]: constructing invalid value: encountered a reference pointing to uninhabited type Bar
   --> $DIR/ub-uninhabit.rs:23:1
@@ -19,13 +19,13 @@ error[E0080]: constructing invalid value at [0]: encountered a value of uninhabi
   --> $DIR/ub-uninhabit.rs:26:42
    |
 LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init };
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_BAD_ARRAY` failed here
 
 error[E0080]: constructing invalid value: encountered a value of the never type `!`
   --> $DIR/ub-uninhabit.rs:32:16
    |
 LL |     let _val = intrinsics::read_via_copy(ptr);
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `READ_NEVER` failed here
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.stderr b/tests/ui/consts/const-eval/ub-wide-ptr.stderr
index a586f154ca1..8724dd9a3c0 100644
--- a/tests/ui/consts/const-eval/ub-wide-ptr.stderr
+++ b/tests/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -24,7 +24,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-wide-ptr.rs:44:1
    |
 LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `STR_LENGTH_PTR` failed here
    |
    = 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
@@ -33,7 +33,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-wide-ptr.rs:47:1
    |
 LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MY_STR_LENGTH_PTR` failed here
    |
    = 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
@@ -75,7 +75,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/ub-wide-ptr.rs:63:1
    |
 LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SLICE_LENGTH_UNINIT` failed here
 
 error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
   --> $DIR/ub-wide-ptr.rs:69:1
@@ -103,7 +103,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-wide-ptr.rs:75:1
    |
 LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SLICE_LENGTH_PTR` failed here
    |
    = 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
@@ -123,7 +123,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/ub-wide-ptr.rs:81:1
    |
 LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SLICE_LENGTH_PTR_BOX` failed here
    |
    = 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
@@ -183,7 +183,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/ub-wide-ptr.rs:101:1
    |
 LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `RAW_SLICE_LENGTH_UNINIT` failed here
 
 error[E0080]: constructing invalid value at .0: encountered ALLOC12<imm>, but expected a vtable pointer
   --> $DIR/ub-wide-ptr.rs:109:1
diff --git a/tests/ui/consts/const-eval/ub-write-through-immutable.stderr b/tests/ui/consts/const-eval/ub-write-through-immutable.stderr
index dbcd07110cc..13b2585d4dc 100644
--- a/tests/ui/consts/const-eval/ub-write-through-immutable.stderr
+++ b/tests/ui/consts/const-eval/ub-write-through-immutable.stderr
@@ -2,13 +2,13 @@ error[E0080]: writing through a pointer that was derived from a shared (immutabl
   --> $DIR/ub-write-through-immutable.rs:10:5
    |
 LL |     *ptr = 0;
-   |     ^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^ evaluation of `WRITE_AFTER_CAST` failed here
 
 error[E0080]: writing through a pointer that was derived from a shared (immutable) reference
   --> $DIR/ub-write-through-immutable.rs:16:5
    |
 LL |     *ptr = 0;
-   |     ^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^ evaluation of `WRITE_AFTER_TRANSMUTE` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/union-const-eval-field.stderr b/tests/ui/consts/const-eval/union-const-eval-field.stderr
index eb3906a4ecc..07ff4c3ca36 100644
--- a/tests/ui/consts/const-eval/union-const-eval-field.stderr
+++ b/tests/ui/consts/const-eval/union-const-eval-field.stderr
@@ -2,7 +2,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/union-const-eval-field.rs:28:37
    |
 LL |     const FIELD3: Field3 = unsafe { UNION.field3 };
-   |                                     ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                     ^^^^^^^^^^^^ evaluation of `read_field3::FIELD3` failed here
 
 note: erroneous constant encountered
   --> $DIR/union-const-eval-field.rs:30:5
diff --git a/tests/ui/consts/const-eval/union-ice.stderr b/tests/ui/consts/const-eval/union-ice.stderr
index 86c42713095..b00fcc91d68 100644
--- a/tests/ui/consts/const-eval/union-ice.stderr
+++ b/tests/ui/consts/const-eval/union-ice.stderr
@@ -2,19 +2,19 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/union-ice.rs:14:33
    |
 LL | const FIELD3: Field3 = unsafe { UNION.field3 };
-   |                                 ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                 ^^^^^^^^^^^^ evaluation of `FIELD3` failed here
 
 error[E0080]: using uninitialized data, but this operation requires initialized memory
   --> $DIR/union-ice.rs:19:17
    |
 LL |     b: unsafe { UNION.field3 },
-   |                 ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                 ^^^^^^^^^^^^ evaluation of `FIELD_PATH` failed here
 
 error[E0080]: using uninitialized data, but this operation requires initialized memory
   --> $DIR/union-ice.rs:31:18
    |
 LL |         unsafe { UNION.field3 },
-   |                  ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                  ^^^^^^^^^^^^ evaluation of `FIELD_PATH2` failed here
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/consts/const-eval/union-ub.32bit.stderr b/tests/ui/consts/const-eval/union-ub.32bit.stderr
index 7b263c20d33..9f0697984e4 100644
--- a/tests/ui/consts/const-eval/union-ub.32bit.stderr
+++ b/tests/ui/consts/const-eval/union-ub.32bit.stderr
@@ -13,7 +13,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/union-ub.rs:35:36
    |
 LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool };
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_BOOL` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/union-ub.64bit.stderr b/tests/ui/consts/const-eval/union-ub.64bit.stderr
index 7b263c20d33..9f0697984e4 100644
--- a/tests/ui/consts/const-eval/union-ub.64bit.stderr
+++ b/tests/ui/consts/const-eval/union-ub.64bit.stderr
@@ -13,7 +13,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/union-ub.rs:35:36
    |
 LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool };
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_BOOL` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/unused-broken-const.stderr b/tests/ui/consts/const-eval/unused-broken-const.stderr
index 5745539cb56..57bce6ce650 100644
--- a/tests/ui/consts/const-eval/unused-broken-const.stderr
+++ b/tests/ui/consts/const-eval/unused-broken-const.stderr
@@ -2,7 +2,7 @@ error[E0080]: index out of bounds: the length is 0 but the index is 0
   --> $DIR/unused-broken-const.rs:5:18
    |
 LL | const FOO: i32 = [][0];
-   |                  ^^^^^ evaluation of constant value failed here
+   |                  ^^^^^ evaluation of `FOO` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/unwind-abort.stderr b/tests/ui/consts/const-eval/unwind-abort.stderr
index 94cf3acec45..cccfe569acb 100644
--- a/tests/ui/consts/const-eval/unwind-abort.stderr
+++ b/tests/ui/consts/const-eval/unwind-abort.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/unwind-abort.rs:7:15
    |
 LL | const _: () = foo();
-   |               ^^^^^ evaluation of constant value failed here
+   |               ^^^^^ evaluation of `_` failed inside this call
    |
 note: inside `foo`
   --> $DIR/unwind-abort.rs:4:5
diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr
index 4557b392907..848c65f4764 100644
--- a/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr
+++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.stderr
@@ -2,7 +2,7 @@ error[E0080]: constructing invalid value: encountered a value of the never type
   --> $DIR/validate_uninhabited_zsts.rs:17:33
    |
 LL | const FOO: [empty::Empty; 3] = [foo(); 3];
-   |                                 ^^^^^ evaluation of constant value failed here
+   |                                 ^^^^^ evaluation of `FOO` failed inside this call
    |
 note: inside `foo`
   --> $DIR/validate_uninhabited_zsts.rs:4:14
@@ -14,7 +14,7 @@ error[E0080]: constructing invalid value at .0: encountered a value of uninhabit
   --> $DIR/validate_uninhabited_zsts.rs:20:42
    |
 LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAR` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/validation-ice-extern-type-field.stderr b/tests/ui/consts/const-eval/validation-ice-extern-type-field.stderr
index 08d791f4953..61087392b76 100644
--- a/tests/ui/consts/const-eval/validation-ice-extern-type-field.stderr
+++ b/tests/ui/consts/const-eval/validation-ice-extern-type-field.stderr
@@ -2,7 +2,7 @@ error[E0080]: `extern type` field does not have a known offset
   --> $DIR/validation-ice-extern-type-field.rs:12:1
    |
 LL | const C1: &ThinDst = unsafe { std::mem::transmute(b"d".as_ptr()) };
-   | ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^ evaluation of `C1` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-external-macro-const-err.stderr b/tests/ui/consts/const-external-macro-const-err.stderr
index 7cd646b1c45..3ec9e4f3200 100644
--- a/tests/ui/consts/const-external-macro-const-err.stderr
+++ b/tests/ui/consts/const-external-macro-const-err.stderr
@@ -2,7 +2,7 @@ error[E0080]: index out of bounds: the length is 1 but the index is 1
   --> $DIR/const-external-macro-const-err.rs:12:5
    |
 LL |     static_assert!(2 + 2 == 5);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::_` failed here
    |
    = note: this error originates in the macro `static_assert` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/consts/const-fn-in-vec.stderr b/tests/ui/consts/const-fn-in-vec.stderr
index 5be26d7c121..890eb8040b9 100644
--- a/tests/ui/consts/const-fn-in-vec.stderr
+++ b/tests/ui/consts/const-fn-in-vec.stderr
@@ -2,36 +2,39 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/const-fn-in-vec.rs:1:47
    |
 LL | static _MAYBE_STRINGS: [Option<String>; 5] = [None; 5];
-   |                                               ^^^^
-   |                                               |
-   |                                               the trait `Copy` is not implemented for `String`
-   |                                               help: create an inline `const` block: `const { None }`
+   |                                               ^^^^ the trait `Copy` is not implemented for `String`
    |
    = note: required for `Option<String>` to implement `Copy`
    = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: create an inline `const` block
+   |
+LL | static _MAYBE_STRINGS: [Option<String>; 5] = [const { None }; 5];
+   |                                               +++++++      +
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/const-fn-in-vec.rs:7:34
    |
 LL |     let _strings: [String; 5] = [String::new(); 5];
-   |                                  ^^^^^^^^^^^^^
-   |                                  |
-   |                                  the trait `Copy` is not implemented for `String`
-   |                                  help: create an inline `const` block: `const { String::new() }`
+   |                                  ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
    = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: create an inline `const` block
+   |
+LL |     let _strings: [String; 5] = [const { String::new() }; 5];
+   |                                  +++++++               +
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/const-fn-in-vec.rs:12:48
    |
 LL |     let _maybe_strings: [Option<String>; 5] = [None; 5];
-   |                                                ^^^^
-   |                                                |
-   |                                                the trait `Copy` is not implemented for `String`
-   |                                                help: create an inline `const` block: `const { None }`
+   |                                                ^^^^ the trait `Copy` is not implemented for `String`
    |
    = note: required for `Option<String>` to implement `Copy`
    = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: create an inline `const` block
+   |
+LL |     let _maybe_strings: [Option<String>; 5] = [const { None }; 5];
+   |                                                +++++++      +
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/consts/const-int-unchecked.stderr b/tests/ui/consts/const-int-unchecked.stderr
index 20c109b9265..65a116295c7 100644
--- a/tests/ui/consts/const-int-unchecked.stderr
+++ b/tests/ui/consts/const-int-unchecked.stderr
@@ -2,295 +2,295 @@ error[E0080]: overflowing shift by 8 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:14:29
    |
 LL | const SHL_U8: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) };
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_U8` failed here
 
 error[E0080]: overflowing shift by 16 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:16:31
    |
 LL | const SHL_U16: u16 = unsafe { intrinsics::unchecked_shl(5_u16, 16) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_U16` failed here
 
 error[E0080]: overflowing shift by 32 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:18:31
    |
 LL | const SHL_U32: u32 = unsafe { intrinsics::unchecked_shl(5_u32, 32) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_U32` failed here
 
 error[E0080]: overflowing shift by 64 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:20:31
    |
 LL | const SHL_U64: u64 = unsafe { intrinsics::unchecked_shl(5_u64, 64) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_U64` failed here
 
 error[E0080]: overflowing shift by 128 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:22:33
    |
 LL | const SHL_U128: u128 = unsafe { intrinsics::unchecked_shl(5_u128, 128) };
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_U128` failed here
 
 error[E0080]: overflowing shift by 8 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:27:29
    |
 LL | const SHL_I8: i8 = unsafe { intrinsics::unchecked_shl(5_i8, 8) };
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I8` failed here
 
 error[E0080]: overflowing shift by 16 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:29:31
    |
 LL | const SHL_I16: i16 = unsafe { intrinsics::unchecked_shl(5_i16, 16) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I16` failed here
 
 error[E0080]: overflowing shift by 32 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:31:31
    |
 LL | const SHL_I32: i32 = unsafe { intrinsics::unchecked_shl(5_i32, 32) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I32` failed here
 
 error[E0080]: overflowing shift by 64 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:33:31
    |
 LL | const SHL_I64: i64 = unsafe { intrinsics::unchecked_shl(5_i64, 64) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I64` failed here
 
 error[E0080]: overflowing shift by 128 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:35:33
    |
 LL | const SHL_I128: i128 = unsafe { intrinsics::unchecked_shl(5_i128, 128) };
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I128` failed here
 
 error[E0080]: overflowing shift by -1 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:40:33
    |
 LL | const SHL_I8_NEG: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -1) };
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I8_NEG` failed here
 
 error[E0080]: overflowing shift by -1 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:42:35
    |
 LL | const SHL_I16_NEG: i16 = unsafe { intrinsics::unchecked_shl(5_i16, -1) };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I16_NEG` failed here
 
 error[E0080]: overflowing shift by -1 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:44:35
    |
 LL | const SHL_I32_NEG: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -1) };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I32_NEG` failed here
 
 error[E0080]: overflowing shift by -1 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:46:35
    |
 LL | const SHL_I64_NEG: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -1) };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I64_NEG` failed here
 
 error[E0080]: overflowing shift by -1 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:48:37
    |
 LL | const SHL_I128_NEG: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -1) };
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I128_NEG` failed here
 
 error[E0080]: overflowing shift by -6 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:54:40
    |
 LL | const SHL_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -6) };
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I8_NEG_RANDOM` failed here
 
 error[E0080]: overflowing shift by -13 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:56:42
    |
 LL | const SHL_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shl(5_i16, -13) };
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I16_NEG_RANDOM` failed here
 
 error[E0080]: overflowing shift by -25 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:58:42
    |
 LL | const SHL_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -25) };
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I32_NEG_RANDOM` failed here
 
 error[E0080]: overflowing shift by -30 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:60:42
    |
 LL | const SHL_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -30) };
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I64_NEG_RANDOM` failed here
 
 error[E0080]: overflowing shift by -93 in `unchecked_shl`
   --> $DIR/const-int-unchecked.rs:62:44
    |
 LL | const SHL_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -93) };
-   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHL_I128_NEG_RANDOM` failed here
 
 error[E0080]: overflowing shift by 8 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:69:29
    |
 LL | const SHR_U8: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) };
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_U8` failed here
 
 error[E0080]: overflowing shift by 16 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:71:31
    |
 LL | const SHR_U16: u16 = unsafe { intrinsics::unchecked_shr(5_u16, 16) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_U16` failed here
 
 error[E0080]: overflowing shift by 32 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:73:31
    |
 LL | const SHR_U32: u32 = unsafe { intrinsics::unchecked_shr(5_u32, 32) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_U32` failed here
 
 error[E0080]: overflowing shift by 64 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:75:31
    |
 LL | const SHR_U64: u64 = unsafe { intrinsics::unchecked_shr(5_u64, 64) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_U64` failed here
 
 error[E0080]: overflowing shift by 128 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:77:33
    |
 LL | const SHR_U128: u128 = unsafe { intrinsics::unchecked_shr(5_u128, 128) };
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_U128` failed here
 
 error[E0080]: overflowing shift by 8 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:82:29
    |
 LL | const SHR_I8: i8 = unsafe { intrinsics::unchecked_shr(5_i8, 8) };
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I8` failed here
 
 error[E0080]: overflowing shift by 16 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:84:31
    |
 LL | const SHR_I16: i16 = unsafe { intrinsics::unchecked_shr(5_i16, 16) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I16` failed here
 
 error[E0080]: overflowing shift by 32 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:86:31
    |
 LL | const SHR_I32: i32 = unsafe { intrinsics::unchecked_shr(5_i32, 32) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I32` failed here
 
 error[E0080]: overflowing shift by 64 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:88:31
    |
 LL | const SHR_I64: i64 = unsafe { intrinsics::unchecked_shr(5_i64, 64) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I64` failed here
 
 error[E0080]: overflowing shift by 128 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:90:33
    |
 LL | const SHR_I128: i128 = unsafe { intrinsics::unchecked_shr(5_i128, 128) };
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I128` failed here
 
 error[E0080]: overflowing shift by -1 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:95:33
    |
 LL | const SHR_I8_NEG: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -1) };
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I8_NEG` failed here
 
 error[E0080]: overflowing shift by -1 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:97:35
    |
 LL | const SHR_I16_NEG: i16 = unsafe { intrinsics::unchecked_shr(5_i16, -1) };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I16_NEG` failed here
 
 error[E0080]: overflowing shift by -1 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:99:35
    |
 LL | const SHR_I32_NEG: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -1) };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I32_NEG` failed here
 
 error[E0080]: overflowing shift by -1 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:101:35
    |
 LL | const SHR_I64_NEG: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -1) };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I64_NEG` failed here
 
 error[E0080]: overflowing shift by -1 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:103:37
    |
 LL | const SHR_I128_NEG: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -1) };
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I128_NEG` failed here
 
 error[E0080]: overflowing shift by -6 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:109:40
    |
 LL | const SHR_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -6) };
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I8_NEG_RANDOM` failed here
 
 error[E0080]: overflowing shift by -13 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:111:42
    |
 LL | const SHR_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shr(5_i16, -13) };
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I16_NEG_RANDOM` failed here
 
 error[E0080]: overflowing shift by -25 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:113:42
    |
 LL | const SHR_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -25) };
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I32_NEG_RANDOM` failed here
 
 error[E0080]: overflowing shift by -30 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:115:42
    |
 LL | const SHR_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -30) };
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I64_NEG_RANDOM` failed here
 
 error[E0080]: overflowing shift by -93 in `unchecked_shr`
   --> $DIR/const-int-unchecked.rs:117:44
    |
 LL | const SHR_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -93) };
-   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SHR_I128_NEG_RANDOM` failed here
 
 error[E0080]: arithmetic overflow in `unchecked_add`
   --> $DIR/const-int-unchecked.rs:122:25
    |
 LL | const _: u16 = unsafe { std::intrinsics::unchecked_add(40000u16, 30000) };
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error[E0080]: arithmetic overflow in `unchecked_sub`
   --> $DIR/const-int-unchecked.rs:125:25
    |
 LL | const _: u32 = unsafe { std::intrinsics::unchecked_sub(14u32, 22) };
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error[E0080]: arithmetic overflow in `unchecked_mul`
   --> $DIR/const-int-unchecked.rs:128:25
    |
 LL | const _: u16 = unsafe { std::intrinsics::unchecked_mul(300u16, 250u16) };
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error[E0080]: dividing by zero
   --> $DIR/const-int-unchecked.rs:131:25
    |
 LL | const _: i32 = unsafe { std::intrinsics::unchecked_div(1, 0) };
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error[E0080]: overflow in signed division (dividing MIN by -1)
   --> $DIR/const-int-unchecked.rs:133:25
    |
 LL | const _: i32 = unsafe { std::intrinsics::unchecked_div(i32::MIN, -1) };
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error[E0080]: calculating the remainder with a divisor of zero
   --> $DIR/const-int-unchecked.rs:136:25
    |
 LL | const _: i32 = unsafe { std::intrinsics::unchecked_rem(1, 0) };
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error[E0080]: overflow in signed remainder (dividing MIN by -1)
   --> $DIR/const-int-unchecked.rs:138:25
    |
 LL | const _: i32 = unsafe { std::intrinsics::unchecked_rem(i32::MIN, -1) };
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error[E0080]: `ctlz_nonzero` called on 0
   --> $DIR/const-int-unchecked.rs:143:25
    |
 LL | const _: u32 = unsafe { std::intrinsics::ctlz_nonzero(0) };
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error[E0080]: `cttz_nonzero` called on 0
   --> $DIR/const-int-unchecked.rs:145:25
    |
 LL | const _: u32 = unsafe { std::intrinsics::cttz_nonzero(0) };
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error: aborting due to 49 previous errors
 
diff --git a/tests/ui/consts/const-len-underflow-separate-spans.next.stderr b/tests/ui/consts/const-len-underflow-separate-spans.next.stderr
index 510b9cdc406..ef46522f7f5 100644
--- a/tests/ui/consts/const-len-underflow-separate-spans.next.stderr
+++ b/tests/ui/consts/const-len-underflow-separate-spans.next.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `1_usize - 2_usize`, which would overflow
   --> $DIR/const-len-underflow-separate-spans.rs:10:20
    |
 LL | const LEN: usize = ONE - TWO;
-   |                    ^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^ evaluation of `LEN` failed here
 
 note: erroneous constant encountered
   --> $DIR/const-len-underflow-separate-spans.rs:15:17
diff --git a/tests/ui/consts/const-len-underflow-separate-spans.old.stderr b/tests/ui/consts/const-len-underflow-separate-spans.old.stderr
index 510b9cdc406..ef46522f7f5 100644
--- a/tests/ui/consts/const-len-underflow-separate-spans.old.stderr
+++ b/tests/ui/consts/const-len-underflow-separate-spans.old.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `1_usize - 2_usize`, which would overflow
   --> $DIR/const-len-underflow-separate-spans.rs:10:20
    |
 LL | const LEN: usize = ONE - TWO;
-   |                    ^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^ evaluation of `LEN` failed here
 
 note: erroneous constant encountered
   --> $DIR/const-len-underflow-separate-spans.rs:15:17
diff --git a/tests/ui/consts/const-len-underflow-separate-spans.rs b/tests/ui/consts/const-len-underflow-separate-spans.rs
index a815ecaef70..ee8c79dafa7 100644
--- a/tests/ui/consts/const-len-underflow-separate-spans.rs
+++ b/tests/ui/consts/const-len-underflow-separate-spans.rs
@@ -8,7 +8,7 @@
 const ONE: usize = 1;
 const TWO: usize = 2;
 const LEN: usize = ONE - TWO;
-//~^ NOTE constant
+//~^ NOTE failed here
 //~| ERROR attempt to compute `1_usize - 2_usize`, which would overflow
 
 fn main() {
diff --git a/tests/ui/consts/const-len-underflow-subspans.stderr b/tests/ui/consts/const-len-underflow-subspans.stderr
index 42d744147d6..51825a03db8 100644
--- a/tests/ui/consts/const-len-underflow-subspans.stderr
+++ b/tests/ui/consts/const-len-underflow-subspans.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `1_usize - 2_usize`, which would overflow
   --> $DIR/const-len-underflow-subspans.rs:8:17
    |
 LL |     let a: [i8; ONE - TWO] = unimplemented!();
-   |                 ^^^^^^^^^ evaluation of constant value failed here
+   |                 ^^^^^^^^^ evaluation of `main::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-ptr-is-null.stderr b/tests/ui/consts/const-ptr-is-null.stderr
index 9d83f8d51a7..be0a1346c64 100644
--- a/tests/ui/consts/const-ptr-is-null.stderr
+++ b/tests/ui/consts/const-ptr-is-null.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: null-ness of this pointer cannot be determine
   --> $DIR/const-ptr-is-null.rs:22:14
    |
 LL |     assert!(!ptr.wrapping_sub(512).is_null());
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MAYBE_NULL` failed inside this call
    |
 note: inside `std::ptr::const_ptr::<impl *const i32>::is_null`
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr
index 714d85bb394..64b7a4129e0 100644
--- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr
+++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr
@@ -2,13 +2,13 @@ error[E0080]: `extern type` does not have known layout
   --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:31
    |
 LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_SIZE` failed here
 
 error[E0080]: `extern type` does not have known layout
   --> $DIR/const-size_of_val-align_of_val-extern-type.rs:11:32
    |
 LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) };
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_ALIGN` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-slice-oob.stderr b/tests/ui/consts/const-slice-oob.stderr
index d93c4783e27..9435baa0407 100644
--- a/tests/ui/consts/const-slice-oob.stderr
+++ b/tests/ui/consts/const-slice-oob.stderr
@@ -2,7 +2,7 @@ error[E0080]: index out of bounds: the length is 3 but the index is 5
   --> $DIR/const-slice-oob.rs:2:18
    |
 LL | const BAR: u32 = FOO[5];
-   |                  ^^^^^^ evaluation of constant value failed here
+   |                  ^^^^^^ evaluation of `BAR` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-unwrap.stderr b/tests/ui/consts/const-unwrap.stderr
index 88c9185eeb6..0b3e92d389f 100644
--- a/tests/ui/consts/const-unwrap.stderr
+++ b/tests/ui/consts/const-unwrap.stderr
@@ -2,13 +2,13 @@ error[E0080]: evaluation panicked: called `Option::unwrap()` on a `None` value
   --> $DIR/const-unwrap.rs:6:18
    |
 LL | const BAR: i32 = Option::<i32>::None.unwrap();
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAR` failed here
 
 error[E0080]: evaluation panicked: absolutely not!
   --> $DIR/const-unwrap.rs:9:18
    |
 LL | const BAZ: i32 = Option::<i32>::None.expect("absolutely not!");
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAZ` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const_refs_to_static_fail.stderr b/tests/ui/consts/const_refs_to_static_fail.stderr
index 96a6593279d..86d6c11dc0c 100644
--- a/tests/ui/consts/const_refs_to_static_fail.stderr
+++ b/tests/ui/consts/const_refs_to_static_fail.stderr
@@ -19,7 +19,7 @@ error[E0080]: constant accesses mutable global memory
   --> $DIR/const_refs_to_static_fail.rs:18:13
    |
 LL |     assert!(*C2 == 0);
-   |             ^^^ evaluation of constant value failed here
+   |             ^^^ evaluation of `C2_READ` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const_unsafe_unreachable_ub.rs b/tests/ui/consts/const_unsafe_unreachable_ub.rs
index 7c6c7a608b8..39f05395127 100644
--- a/tests/ui/consts/const_unsafe_unreachable_ub.rs
+++ b/tests/ui/consts/const_unsafe_unreachable_ub.rs
@@ -8,7 +8,7 @@ const unsafe fn foo(x: bool) -> bool {
 }
 
 const BAR: bool = unsafe { foo(false) };
-//~^ NOTE evaluation of constant value failed
+//~^ NOTE failed inside this call
 //~| ERROR entering unreachable code
 
 fn main() {
diff --git a/tests/ui/consts/const_unsafe_unreachable_ub.stderr b/tests/ui/consts/const_unsafe_unreachable_ub.stderr
index 6d9f8c1d73b..7d2448cc3c6 100644
--- a/tests/ui/consts/const_unsafe_unreachable_ub.stderr
+++ b/tests/ui/consts/const_unsafe_unreachable_ub.stderr
@@ -2,7 +2,7 @@ error[E0080]: entering unreachable code
   --> $DIR/const_unsafe_unreachable_ub.rs:10:28
    |
 LL | const BAR: bool = unsafe { foo(false) };
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `BAR` failed inside this call
    |
 note: inside `foo`
   --> $DIR/const_unsafe_unreachable_ub.rs:4:18
diff --git a/tests/ui/consts/control-flow/assert.stderr b/tests/ui/consts/control-flow/assert.stderr
index 6b68f706f90..026097a6ba0 100644
--- a/tests/ui/consts/control-flow/assert.stderr
+++ b/tests/ui/consts/control-flow/assert.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: assertion failed: false
   --> $DIR/assert.rs:5:15
    |
 LL | const _: () = assert!(false);
-   |               ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/copy-intrinsic.stderr b/tests/ui/consts/copy-intrinsic.stderr
index b9d89cf78ba..41cf7e51357 100644
--- a/tests/ui/consts/copy-intrinsic.stderr
+++ b/tests/ui/consts/copy-intrinsic.stderr
@@ -2,25 +2,25 @@ error[E0080]: memory access failed: attempting to access 4 bytes, but got 0x100[
   --> $DIR/copy-intrinsic.rs:20:5
    |
 LL |     copy_nonoverlapping(0x100 as *const i32, dangle, 1);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `COPY_OOB_1` failed here
 
 error[E0080]: memory access failed: attempting to access 4 bytes, but got ALLOC0+0x28 which is at or beyond the end of the allocation of size 4 bytes
   --> $DIR/copy-intrinsic.rs:28:5
    |
 LL |     copy_nonoverlapping(dangle, 0x100 as *mut i32, 1);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `COPY_OOB_2` failed here
 
 error[E0080]: overflow computing total size of `copy`
   --> $DIR/copy-intrinsic.rs:34:5
    |
 LL |     copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `COPY_SIZE_OVERFLOW` failed here
 
 error[E0080]: overflow computing total size of `copy_nonoverlapping`
   --> $DIR/copy-intrinsic.rs:39:5
    |
 LL |     copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `COPY_NONOVERLAPPING_SIZE_OVERFLOW` failed here
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/consts/eval-enum.stderr b/tests/ui/consts/eval-enum.stderr
index adfb7c79fea..d647485bc5d 100644
--- a/tests/ui/consts/eval-enum.stderr
+++ b/tests/ui/consts/eval-enum.stderr
@@ -2,13 +2,13 @@ error[E0080]: attempt to divide `1_isize` by zero
   --> $DIR/eval-enum.rs:2:15
    |
 LL |     DivZero = 1 / 0,
-   |               ^^^^^ evaluation of constant value failed here
+   |               ^^^^^ evaluation of `Test::DivZero::{constant#0}` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_isize` with a divisor of zero
   --> $DIR/eval-enum.rs:4:15
    |
 LL |     RemZero = 1 % 0,
-   |               ^^^^^ evaluation of constant value failed here
+   |               ^^^^^ evaluation of `Test::RemZero::{constant#0}` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
index 0d8fd5aece9..6af72868045 100644
--- a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
+++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
@@ -2,13 +2,13 @@ error[E0080]: constructing invalid value: encountered 0x03, but expected a boole
   --> $DIR/detect-extra-ub.rs:30:20
    |
 LL |     let _x: bool = transmute(3u8);
-   |                    ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^ evaluation of `INVALID_BOOL` failed here
 
 error[E0080]: constructing invalid value: encountered a pointer, but expected an integer
   --> $DIR/detect-extra-ub.rs:35:21
    |
 LL |     let _x: usize = transmute(&3u8);
-   |                     ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                     ^^^^^^^^^^^^^^^ evaluation of `INVALID_PTR_IN_INT` failed here
    |
    = 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
@@ -17,7 +17,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered a pointer,
   --> $DIR/detect-extra-ub.rs:40:28
    |
 LL |     let _x: PtrSizedEnum = transmute(&3u8);
-   |                            ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^ evaluation of `INVALID_PTR_IN_ENUM` failed here
    |
    = 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
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value at .0: encountered a pointer, but expec
   --> $DIR/detect-extra-ub.rs:46:30
    |
 LL |     let _x: (usize, usize) = transmute(x);
-   |                              ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^ evaluation of `INVALID_SLICE_TO_USIZE_TRANSMUTE` failed here
    |
    = 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
@@ -35,19 +35,19 @@ error[E0080]: constructing invalid value: encountered an unaligned reference (re
   --> $DIR/detect-extra-ub.rs:51:20
    |
 LL |     let _x: &u32 = transmute(&[0u8; 4]);
-   |                    ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^^^^^ evaluation of `UNALIGNED_PTR` failed here
 
 error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant
   --> $DIR/detect-extra-ub.rs:58:13
    |
 LL |     let v = *addr_of!(data).cast::<UninhDiscriminant>();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINHABITED_VARIANT` failed here
 
 error[E0080]: constructing invalid value at [0]: encountered a partial pointer or a mix of pointers
   --> $DIR/detect-extra-ub.rs:77:16
    |
 LL |     let _val = *(&mem as *const Align as *const [*const u8; 2]);
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `PARTIAL_POINTER` failed here
    |
    = 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
@@ -56,7 +56,7 @@ error[E0080]: constructing invalid value: encountered invalid reference metadata
   --> $DIR/detect-extra-ub.rs:91:16
    |
 LL |     let _val = &*slice;
-   |                ^^^^^^^ evaluation of constant value failed here
+   |                ^^^^^^^ evaluation of `OVERSIZED_REF` failed here
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/consts/issue-32829.stderr b/tests/ui/consts/issue-32829.stderr
index 0a04c66df96..b02b9122cec 100644
--- a/tests/ui/consts/issue-32829.stderr
+++ b/tests/ui/consts/issue-32829.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: foo
   --> $DIR/issue-32829.rs:1:22
    |
 LL | static S : u64 = { { panic!("foo"); 0 } };
-   |                      ^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                      ^^^^^^^^^^^^^ evaluation of `S` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/issue-64506.stderr b/tests/ui/consts/issue-64506.stderr
index dfb2c454031..9fce07c5850 100644
--- a/tests/ui/consts/issue-64506.stderr
+++ b/tests/ui/consts/issue-64506.stderr
@@ -2,7 +2,7 @@ error[E0080]: constructing invalid value at .inner: encountered a value of uninh
   --> $DIR/issue-64506.rs:16:22
    |
 LL |     let x = unsafe { Foo { b: () }.a };
-   |                      ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^^^ evaluation of `FOO` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/issue-66693-panic-in-array-len.stderr b/tests/ui/consts/issue-66693-panic-in-array-len.stderr
index e0db2138d74..241643a83be 100644
--- a/tests/ui/consts/issue-66693-panic-in-array-len.stderr
+++ b/tests/ui/consts/issue-66693-panic-in-array-len.stderr
@@ -8,7 +8,7 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/issue-66693-panic-in-array-len.rs:10:21
    |
 LL |     let _ = [false; panic!()];
-   |                     ^^^^^^^^ evaluation of constant value failed here
+   |                     ^^^^^^^^ evaluation of `main::{constant#1}` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/issue-66693.stderr b/tests/ui/consts/issue-66693.stderr
index 6d6edf8a513..5540d4f2d22 100644
--- a/tests/ui/consts/issue-66693.stderr
+++ b/tests/ui/consts/issue-66693.stderr
@@ -14,13 +14,13 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/issue-66693.rs:16:15
    |
 LL | const _: () = panic!();
-   |               ^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^ evaluation of `_` failed here
 
 error[E0080]: evaluation panicked: panic in static
   --> $DIR/issue-66693.rs:18:19
    |
 LL | static _BAR: () = panic!("panic in static");
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_BAR` failed here
 
 error: argument to `panic!()` in a const context must have type `&str`
   --> $DIR/issue-66693.rs:11:5
diff --git a/tests/ui/consts/issue-76064.stderr b/tests/ui/consts/issue-76064.stderr
index 97225178ee0..17dcb22aa1a 100644
--- a/tests/ui/consts/issue-76064.stderr
+++ b/tests/ui/consts/issue-76064.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: panic
   --> $DIR/issue-76064.rs:1:17
    |
 LL | struct Bug([u8; panic!("panic")]);
-   |                 ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                 ^^^^^^^^^^^^^^^ evaluation of `Bug::0::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/issue-miri-1910.stderr b/tests/ui/consts/issue-miri-1910.stderr
index 8166b68d2e0..140b1861bb4 100644
--- a/tests/ui/consts/issue-miri-1910.stderr
+++ b/tests/ui/consts/issue-miri-1910.stderr
@@ -2,7 +2,7 @@ error[E0080]: unable to turn pointer into integer
   --> $DIR/issue-miri-1910.rs:7:5
    |
 LL |     (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `C` failed here
    |
    = 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
diff --git a/tests/ui/consts/large_const_alloc.stderr b/tests/ui/consts/large_const_alloc.stderr
index 8f19def22e7..a0b21555608 100644
--- a/tests/ui/consts/large_const_alloc.stderr
+++ b/tests/ui/consts/large_const_alloc.stderr
@@ -2,13 +2,13 @@ error[E0080]: tried to allocate more memory than available to compiler
   --> $DIR/large_const_alloc.rs:11:13
    |
 LL |     let x = [0_u8; (1 << 47) - 1];
-   |             ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |             ^^^^^^^^^^^^^^^^^^^^^ evaluation of `FOO` failed here
 
 error[E0080]: tried to allocate more memory than available to compiler
   --> $DIR/large_const_alloc.rs:16:13
    |
 LL |     let x = [0_u8; (1 << 47) - 1];
-   |             ^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |             ^^^^^^^^^^^^^^^^^^^^^ evaluation of `FOO2` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/miri_unleashed/abi-mismatch.rs b/tests/ui/consts/miri_unleashed/abi-mismatch.rs
index 91115f8511d..843de1e63c6 100644
--- a/tests/ui/consts/miri_unleashed/abi-mismatch.rs
+++ b/tests/ui/consts/miri_unleashed/abi-mismatch.rs
@@ -9,7 +9,7 @@ const fn call_rust_fn(my_fn: extern "Rust" fn()) {
 }
 
 static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
-//~^ NOTE evaluation of static initializer failed here
+//~^ NOTE failed inside this call
 //~| ERROR calling a function with calling convention "C" using calling convention "Rust"
 
 fn main() {}
diff --git a/tests/ui/consts/miri_unleashed/abi-mismatch.stderr b/tests/ui/consts/miri_unleashed/abi-mismatch.stderr
index 6cd2a0b4bc5..4576eed2c88 100644
--- a/tests/ui/consts/miri_unleashed/abi-mismatch.stderr
+++ b/tests/ui/consts/miri_unleashed/abi-mismatch.stderr
@@ -2,7 +2,7 @@ error[E0080]: calling a function with calling convention "C" using calling conve
   --> $DIR/abi-mismatch.rs:11:18
    |
 LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `VAL` failed inside this call
    |
 note: inside `call_rust_fn`
   --> $DIR/abi-mismatch.rs:7:5
diff --git a/tests/ui/consts/miri_unleashed/assoc_const.stderr b/tests/ui/consts/miri_unleashed/assoc_const.stderr
index b6dcb86f360..1ba4f3b2896 100644
--- a/tests/ui/consts/miri_unleashed/assoc_const.stderr
+++ b/tests/ui/consts/miri_unleashed/assoc_const.stderr
@@ -2,7 +2,7 @@ error[E0080]: calling non-const function `<Vec<u32> as Drop>::drop`
   --> $DIR/assoc_const.rs:12:31
    |
 LL |     const F: u32 = (U::X, 42).1;
-   |                               ^ evaluation of `drop_in_place::<Vec<u32>> - shim(Some(Vec<u32>))` failed here
+   |                               ^ evaluation of `<std::string::String as Bar<std::vec::Vec<u32>, std::string::String>>::F` failed inside this call
    |
 note: inside `drop_in_place::<(Vec<u32>, u32)> - shim(Some((Vec<u32>, u32)))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
diff --git a/tests/ui/consts/miri_unleashed/box.stderr b/tests/ui/consts/miri_unleashed/box.stderr
index d6ceeebf87f..25b717660ea 100644
--- a/tests/ui/consts/miri_unleashed/box.stderr
+++ b/tests/ui/consts/miri_unleashed/box.stderr
@@ -2,7 +2,7 @@ error[E0080]: calling non-const function `Box::<i32>::new`
   --> $DIR/box.rs:8:11
    |
 LL |     &mut *(Box::new(0))
-   |           ^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |           ^^^^^^^^^^^^^ evaluation of `TEST_BAD` failed here
 
 warning: skipping const checks
    |
diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr
index f0161988b76..eed3b4d9065 100644
--- a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr
+++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr
@@ -2,19 +2,19 @@ error[E0080]: calling non-const function `AtomicUsize::fetch_add`
   --> $DIR/const_refers_to_static.rs:11:5
    |
 LL |     FOO.fetch_add(1, Ordering::Relaxed)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MUTATE_INTERIOR_MUT` failed here
 
 error[E0080]: constant accesses mutable global memory
   --> $DIR/const_refers_to_static.rs:16:14
    |
 LL |     unsafe { *(&FOO as *const _ as *const usize) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `READ_INTERIOR_MUT` failed here
 
 error[E0080]: constant accesses mutable global memory
   --> $DIR/const_refers_to_static.rs:20:32
    |
 LL | const READ_MUT: u32 = unsafe { MUTABLE };
-   |                                ^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^ evaluation of `READ_MUT` failed here
 
 error[E0080]: constructing invalid value: encountered reference to mutable memory in `const`
   --> $DIR/const_refers_to_static.rs:23:1
diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr
index 8c176d562ee..8af3a1948f0 100644
--- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr
+++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr
@@ -35,7 +35,7 @@ error[E0080]: constant accesses mutable global memory
   --> $DIR/const_refers_to_static_cross_crate.rs:30:15
    |
 LL |         match static_cross_crate::OPT_ZERO {
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `U8_MUT3` failed here
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/consts/miri_unleashed/drop.rs b/tests/ui/consts/miri_unleashed/drop.rs
index 6921ffa4f94..46af3388a96 100644
--- a/tests/ui/consts/miri_unleashed/drop.rs
+++ b/tests/ui/consts/miri_unleashed/drop.rs
@@ -13,7 +13,7 @@ static TEST_OK: () = {
 // The actual error is tested by the error-pattern above.
 static TEST_BAD: () = {
     let _v: Vec<i32> = Vec::new();
-}; //~ NOTE evaluation of static initializer failed here
+}; //~ NOTE failed inside this call
    //~| ERROR calling non-const function `<Vec<i32> as Drop>::drop`
    //~| NOTE inside `drop_in_place::<Vec<i32>> - shim(Some(Vec<i32>))`
 
diff --git a/tests/ui/consts/miri_unleashed/drop.stderr b/tests/ui/consts/miri_unleashed/drop.stderr
index f0a776d8702..a66422956be 100644
--- a/tests/ui/consts/miri_unleashed/drop.stderr
+++ b/tests/ui/consts/miri_unleashed/drop.stderr
@@ -2,7 +2,7 @@ error[E0080]: calling non-const function `<Vec<i32> as Drop>::drop`
   --> $DIR/drop.rs:16:1
    |
 LL | };
-   | ^ evaluation of static initializer failed here
+   | ^ evaluation of `TEST_BAD` failed inside this call
    |
 note: inside `drop_in_place::<Vec<i32>> - shim(Some(Vec<i32>))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
diff --git a/tests/ui/consts/miri_unleashed/extern-static.stderr b/tests/ui/consts/miri_unleashed/extern-static.stderr
index a1e4be5bd9c..57b4f07b2fc 100644
--- a/tests/ui/consts/miri_unleashed/extern-static.stderr
+++ b/tests/ui/consts/miri_unleashed/extern-static.stderr
@@ -2,13 +2,13 @@ error[E0080]: cannot access extern static `DATA`
   --> $DIR/extern-static.rs:11:25
    |
 LL |     unsafe { let _val = DATA; }
-   |                         ^^^^ evaluation of static initializer failed here
+   |                         ^^^^ evaluation of `TEST_READ` failed here
 
 error[E0080]: cannot access extern static `DATA`
   --> $DIR/extern-static.rs:15:14
    |
 LL |     unsafe { DATA = 0; }
-   |              ^^^^^^^^ evaluation of static initializer failed here
+   |              ^^^^^^^^ evaluation of `TEST_WRITE` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/miri_unleashed/inline_asm.stderr b/tests/ui/consts/miri_unleashed/inline_asm.stderr
index 2f9d2dc2143..49e54825695 100644
--- a/tests/ui/consts/miri_unleashed/inline_asm.stderr
+++ b/tests/ui/consts/miri_unleashed/inline_asm.stderr
@@ -2,7 +2,7 @@ error[E0080]: inline assembly is not supported
   --> $DIR/inline_asm.rs:10:14
    |
 LL |     unsafe { asm!("nop"); }
-   |              ^^^^^^^^^^^ evaluation of static initializer failed here
+   |              ^^^^^^^^^^^ evaluation of `TEST_BAD` failed here
 
 warning: skipping const checks
    |
diff --git a/tests/ui/consts/miri_unleashed/mutable_references.stderr b/tests/ui/consts/miri_unleashed/mutable_references.stderr
index aaea7bda332..22860e4f6d9 100644
--- a/tests/ui/consts/miri_unleashed/mutable_references.stderr
+++ b/tests/ui/consts/miri_unleashed/mutable_references.stderr
@@ -113,7 +113,7 @@ error[E0080]: constant accesses mutable global memory
   --> $DIR/mutable_references.rs:70:43
    |
 LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
-   |                                           ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                           ^^^^^^^^^^^^^ evaluation of `POINTS_TO_MUTABLE2` failed here
 
 error: encountered mutable pointer in final value of constant
   --> $DIR/mutable_references.rs:73:1
diff --git a/tests/ui/consts/miri_unleashed/mutating_global.stderr b/tests/ui/consts/miri_unleashed/mutating_global.stderr
index 706bc8e5d23..f97f88a4b90 100644
--- a/tests/ui/consts/miri_unleashed/mutating_global.stderr
+++ b/tests/ui/consts/miri_unleashed/mutating_global.stderr
@@ -2,7 +2,7 @@ error[E0080]: modifying a static's initial value from another static's initializ
   --> $DIR/mutating_global.rs:9:9
    |
 LL |         GLOBAL = 99
-   |         ^^^^^^^^^^^ evaluation of static initializer failed here
+   |         ^^^^^^^^^^^ evaluation of `MUTATING_GLOBAL` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/miri_unleashed/non_const_fn.stderr b/tests/ui/consts/miri_unleashed/non_const_fn.stderr
index f490e51f546..7755183cef0 100644
--- a/tests/ui/consts/miri_unleashed/non_const_fn.stderr
+++ b/tests/ui/consts/miri_unleashed/non_const_fn.stderr
@@ -2,7 +2,7 @@ error[E0080]: calling non-const function `foo`
   --> $DIR/non_const_fn.rs:7:16
    |
 LL | static C: () = foo();
-   |                ^^^^^ evaluation of static initializer failed here
+   |                ^^^^^ evaluation of `C` failed here
 
 warning: skipping const checks
    |
diff --git a/tests/ui/consts/miri_unleashed/ptr_arith.stderr b/tests/ui/consts/miri_unleashed/ptr_arith.stderr
index 280c76c42c1..661a8de6a15 100644
--- a/tests/ui/consts/miri_unleashed/ptr_arith.stderr
+++ b/tests/ui/consts/miri_unleashed/ptr_arith.stderr
@@ -2,13 +2,13 @@ error[E0080]: exposing pointers is not possible at compile-time
   --> $DIR/ptr_arith.rs:7:13
    |
 LL |     let x = &0 as *const _ as usize;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |             ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `PTR_INT_CAST` failed here
 
 error[E0080]: unable to turn pointer into integer
   --> $DIR/ptr_arith.rs:14:14
    |
 LL |     let _v = x + 0;
-   |              ^ evaluation of static initializer failed here
+   |              ^ evaluation of `PTR_INT_TRANSMUTE` failed here
    |
    = 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
diff --git a/tests/ui/consts/miri_unleashed/tls.stderr b/tests/ui/consts/miri_unleashed/tls.stderr
index cdfe8bfff4e..08e069dc3ff 100644
--- a/tests/ui/consts/miri_unleashed/tls.stderr
+++ b/tests/ui/consts/miri_unleashed/tls.stderr
@@ -2,13 +2,13 @@ error[E0080]: cannot access thread local static `A`
   --> $DIR/tls.rs:11:25
    |
 LL |     unsafe { let _val = A; }
-   |                         ^ evaluation of static initializer failed here
+   |                         ^ evaluation of `TEST_BAD` failed here
 
 error[E0080]: cannot access thread local static `A`
   --> $DIR/tls.rs:19:26
    |
 LL |     unsafe { let _val = &A; }
-   |                          ^ evaluation of static initializer failed here
+   |                          ^ evaluation of `TEST_BAD_REF` failed here
 
 warning: skipping const checks
    |
diff --git a/tests/ui/consts/missing_span_in_backtrace.stderr b/tests/ui/consts/missing_span_in_backtrace.stderr
index 5ba5e34b4c1..de4acbffa28 100644
--- a/tests/ui/consts/missing_span_in_backtrace.stderr
+++ b/tests/ui/consts/missing_span_in_backtrace.stderr
@@ -6,7 +6,7 @@ error[E0080]: unable to copy parts of a pointer from memory at ALLOC0
 16 | |             &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
 17 | |             mem::size_of::<&i32>(),
 18 | |         );
-   | |_________^ evaluation of constant value failed here
+   | |_________^ evaluation of `X` failed inside this call
    |
    = 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
diff --git a/tests/ui/consts/no-ice-from-static-in-const-issue-52060.stderr b/tests/ui/consts/no-ice-from-static-in-const-issue-52060.stderr
index 318082f5452..210bb345e7b 100644
--- a/tests/ui/consts/no-ice-from-static-in-const-issue-52060.stderr
+++ b/tests/ui/consts/no-ice-from-static-in-const-issue-52060.stderr
@@ -2,7 +2,7 @@ error[E0080]: constant accesses mutable global memory
   --> $DIR/no-ice-from-static-in-const-issue-52060.rs:5:35
    |
 LL | static B: [u32; 1] = [0; unsafe { A.len() }];
-   |                                   ^ evaluation of constant value failed here
+   |                                   ^ evaluation of `B::{constant#1}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/offset_from_ub.stderr b/tests/ui/consts/offset_from_ub.stderr
index 842698e239d..558e1ea02c6 100644
--- a/tests/ui/consts/offset_from_ub.stderr
+++ b/tests/ui/consts/offset_from_ub.stderr
@@ -2,13 +2,13 @@ error[E0080]: `ptr_offset_from` called on two different pointers that are not bo
   --> $DIR/offset_from_ub.rs:20:27
    |
 LL |     let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) };
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `DIFFERENT_ALLOC` failed here
 
 error[E0080]: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
   --> $DIR/offset_from_ub.rs:26:14
    |
 LL |     unsafe { (42 as *const u8).offset_from(&5u8) as usize }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `NOT_PTR` failed inside this call
    |
 note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
@@ -17,67 +17,67 @@ error[E0080]: exact_div: 1_isize cannot be divided by 2_isize without remainder
   --> $DIR/offset_from_ub.rs:34:14
    |
 LL |     unsafe { ptr_offset_from(field_ptr, base_ptr as *const u16) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `NOT_MULTIPLE_OF_SIZE` failed here
 
 error[E0080]: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
   --> $DIR/offset_from_ub.rs:42:14
    |
 LL |     unsafe { ptr_offset_from(ptr2, ptr1) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `DIFFERENT_INT` failed here
 
 error[E0080]: `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation
   --> $DIR/offset_from_ub.rs:51:14
    |
 LL |     unsafe { ptr_offset_from(end_ptr, start_ptr) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `OUT_OF_BOUNDS_1` failed here
 
 error[E0080]: `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation
   --> $DIR/offset_from_ub.rs:60:14
    |
 LL |     unsafe { ptr_offset_from(start_ptr, end_ptr) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `OUT_OF_BOUNDS_2` failed here
 
 error[E0080]: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation
   --> $DIR/offset_from_ub.rs:69:14
    |
 LL |     unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `DIFFERENT_ALLOC_UNSIGNED` failed here
 
 error[E0080]: `ptr_offset_from` called when first pointer is too far ahead of second
   --> $DIR/offset_from_ub.rs:76:14
    |
 LL |     unsafe { ptr_offset_from(ptr2, ptr1) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `TOO_FAR_APART1` failed here
 
 error[E0080]: `ptr_offset_from` called when first pointer is too far before second
   --> $DIR/offset_from_ub.rs:82:14
    |
 LL |     unsafe { ptr_offset_from(ptr1, ptr2) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `TOO_FAR_APART2` failed here
 
 error[E0080]: `ptr_offset_from` called when first pointer is too far before second
   --> $DIR/offset_from_ub.rs:90:14
    |
 LL |     unsafe { ptr_offset_from(ptr1, ptr2) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `TOO_FAR_APART3` failed here
 
 error[E0080]: `ptr_offset_from_unsigned` called when first pointer has smaller offset than second: 0 < 8
   --> $DIR/offset_from_ub.rs:97:14
    |
 LL |     unsafe { ptr_offset_from_unsigned(p, p.add(2)) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `WRONG_ORDER_UNSIGNED` failed here
 
 error[E0080]: `ptr_offset_from_unsigned` called when first pointer is too far ahead of second
   --> $DIR/offset_from_ub.rs:104:14
    |
 LL |     unsafe { ptr_offset_from_unsigned(ptr2, ptr1) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `TOO_FAR_APART_UNSIGNED` failed here
 
 error[E0080]: `ptr_offset_from` called on two different pointers that are not both derived from the same allocation
   --> $DIR/offset_from_ub.rs:112:14
    |
 LL |     unsafe { ptr2.offset_from(ptr1) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `OFFSET_VERY_FAR1` failed inside this call
    |
 note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
@@ -86,7 +86,7 @@ error[E0080]: `ptr_offset_from` called when first pointer is too far before seco
   --> $DIR/offset_from_ub.rs:118:14
    |
 LL |     unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `OFFSET_VERY_FAR2` failed inside this call
    |
 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/consts/offset_ub.stderr b/tests/ui/consts/offset_ub.stderr
index 4135804da20..255583ce91c 100644
--- a/tests/ui/consts/offset_ub.stderr
+++ b/tests/ui/consts/offset_ub.stderr
@@ -2,67 +2,67 @@ error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer
   --> $DIR/offset_ub.rs:8:46
    |
 LL | pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) };
-   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BEFORE_START` failed here
 
 error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by $BYTES bytes, but got ALLOC1 which is only 1 byte from the end of the allocation
   --> $DIR/offset_ub.rs:9:43
    |
 LL | pub const AFTER_END: *const u8 = unsafe { (&0u8 as *const u8).offset(2) };
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `AFTER_END` failed here
 
 error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by $BYTES bytes, but got ALLOC2 which is only $BYTES bytes from the end of the allocation
   --> $DIR/offset_ub.rs:10:45
    |
 LL | pub const AFTER_ARRAY: *const u8 = unsafe { [0u8; 100].as_ptr().offset(101) };
-   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `AFTER_ARRAY` failed here
 
 error[E0080]: overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize`
   --> $DIR/offset_ub.rs:12:43
    |
 LL | pub const OVERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MAX) };
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `OVERFLOW` failed here
 
 error[E0080]: overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize`
   --> $DIR/offset_ub.rs:13:44
    |
 LL | pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) };
-   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNDERFLOW` failed here
 
 error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by $BYTES bytes, but got 0xf..f[noalloc] which is a dangling pointer (it has no provenance)
   --> $DIR/offset_ub.rs:14:56
    |
 LL | pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) };
-   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `OVERFLOW_ADDRESS_SPACE` failed here
 
 error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by -$BYTES bytes, but got 0x1[noalloc] which is a dangling pointer (it has no provenance)
   --> $DIR/offset_ub.rs:15:57
    |
 LL | pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) };
-   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNDERFLOW_ADDRESS_SPACE` failed here
 
 error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by -$BYTES bytes, but got ALLOC3-0x2 which is only $BYTES bytes from the beginning of the allocation
   --> $DIR/offset_ub.rs:16:49
    |
 LL | pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) };
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `NEGATIVE_OFFSET` failed here
 
 error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by 1 byte, but got ALLOC4 which is at or beyond the end of the allocation of size $BYTES bytes
   --> $DIR/offset_ub.rs:18:50
    |
 LL | pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) };
-   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `ZERO_SIZED_ALLOC` failed here
 
 error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by $BYTES bytes, but got 0x1[noalloc] which is a dangling pointer (it has no provenance)
   --> $DIR/offset_ub.rs:19:42
    |
 LL | pub const DANGLING: *const u8 = unsafe { ptr::NonNull::<u8>::dangling().as_ptr().offset(4) };
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `DANGLING` failed here
 
 error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by -$BYTES bytes, but got 0xf..f[noalloc] which is a dangling pointer (it has no provenance)
   --> $DIR/offset_ub.rs:22:47
    |
 LL | pub const UNDERFLOW_ABS: *const u8 = unsafe { (usize::MAX as *const u8).offset(isize::MIN) };
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNDERFLOW_ABS` failed here
 
 error: aborting due to 11 previous errors
 
diff --git a/tests/ui/consts/overflowing-consts.noopt.stderr b/tests/ui/consts/overflowing-consts.noopt.stderr
index e317060a141..1ef2a60b647 100644
--- a/tests/ui/consts/overflowing-consts.noopt.stderr
+++ b/tests/ui/consts/overflowing-consts.noopt.stderr
@@ -2,1021 +2,1021 @@ error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:18:22
    |
 LL | const _NI8_SHL: i8 = 1i8 << 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NI8_SHL` failed here
 
 error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:19:26
    |
 LL | const _NI8_SHL_P: &i8 = &(1i8 << 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NI8_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:21:24
    |
 LL | const _NI16_SHL: i16 = 1i16 << 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI16_SHL` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:22:28
    |
 LL | const _NI16_SHL_P: &i16 = &(1i16 << 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI16_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:24:24
    |
 LL | const _NI32_SHL: i32 = 1i32 << 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI32_SHL` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:25:28
    |
 LL | const _NI32_SHL_P: &i32 = &(1i32 << 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI32_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:27:24
    |
 LL | const _NI64_SHL: i64 = 1i64 << 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI64_SHL` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:28:28
    |
 LL | const _NI64_SHL_P: &i64 = &(1i64 << 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI64_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:30:26
    |
 LL | const _NI128_SHL: i128 = 1i128 << 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NI128_SHL` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:31:30
    |
 LL | const _NI128_SHL_P: &i128 = &(1i128 << 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NI128_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:33:22
    |
 LL | const _NU8_SHL: u8 = 1u8 << 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NU8_SHL` failed here
 
 error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:34:26
    |
 LL | const _NU8_SHL_P: &u8 = &(1u8 << 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NU8_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:36:24
    |
 LL | const _NU16_SHL: u16 = 1u16 << 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU16_SHL` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:37:28
    |
 LL | const _NU16_SHL_P: &u16 = &(1u16 << 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU16_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:39:24
    |
 LL | const _NU32_SHL: u32 = 1u32 << 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU32_SHL` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:40:28
    |
 LL | const _NU32_SHL_P: &u32 = &(1u32 << 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU32_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:42:24
    |
 LL | const _NU64_SHL: u64 = 1u64 << 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU64_SHL` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:43:28
    |
 LL | const _NU64_SHL_P: &u64 = &(1u64 << 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU64_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:45:26
    |
 LL | const _NU128_SHL: u128 = 1u128 << 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NU128_SHL` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:46:30
    |
 LL | const _NU128_SHL_P: &u128 = &(1u128 << 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NU128_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:48:28
    |
 LL | const _NISIZE_SHL: isize = 1isize << BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHL` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:49:32
    |
 LL | const _NISIZE_SHL_P: &isize = &(1isize << BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:51:28
    |
 LL | const _NUSIZE_SHL: usize = 1usize << BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHL` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:52:32
    |
 LL | const _NUSIZE_SHL_P: &usize = &(1usize << BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHL_P` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:55:22
    |
 LL | const _NI8_SHR: i8 = 1i8 >> 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NI8_SHR` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:56:26
    |
 LL | const _NI8_SHR_P: &i8 = &(1i8 >> 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NI8_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:58:24
    |
 LL | const _NI16_SHR: i16 = 1i16 >> 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI16_SHR` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:59:28
    |
 LL | const _NI16_SHR_P: &i16 = &(1i16 >> 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI16_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:61:24
    |
 LL | const _NI32_SHR: i32 = 1i32 >> 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI32_SHR` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:62:28
    |
 LL | const _NI32_SHR_P: &i32 = &(1i32 >> 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI32_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:64:24
    |
 LL | const _NI64_SHR: i64 = 1i64 >> 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI64_SHR` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:65:28
    |
 LL | const _NI64_SHR_P: &i64 = &(1i64 >> 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI64_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:67:26
    |
 LL | const _NI128_SHR: i128 = 1i128 >> 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NI128_SHR` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:68:30
    |
 LL | const _NI128_SHR_P: &i128 = &(1i128 >> 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NI128_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:70:22
    |
 LL | const _NU8_SHR: u8 = 1u8 >> 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NU8_SHR` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:71:26
    |
 LL | const _NU8_SHR_P: &u8 = &(1u8 >> 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NU8_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:73:24
    |
 LL | const _NU16_SHR: u16 = 1u16 >> 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU16_SHR` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:74:28
    |
 LL | const _NU16_SHR_P: &u16 = &(1u16 >> 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU16_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:76:24
    |
 LL | const _NU32_SHR: u32 = 1u32 >> 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU32_SHR` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:77:28
    |
 LL | const _NU32_SHR_P: &u32 = &(1u32 >> 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU32_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:79:24
    |
 LL | const _NU64_SHR: u64 = 1u64 >> 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU64_SHR` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:80:28
    |
 LL | const _NU64_SHR_P: &u64 = &(1u64 >> 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU64_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:82:26
    |
 LL | const _NU128_SHR: u128 = 1u128 >> 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NU128_SHR` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:83:30
    |
 LL | const _NU128_SHR_P: &u128 = &(1u128 >> 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NU128_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:85:28
    |
 LL | const _NISIZE_SHR: isize = 1isize >> BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHR` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:86:32
    |
 LL | const _NISIZE_SHR_P: &isize = &(1isize >> BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:88:28
    |
 LL | const _NUSIZE_SHR: usize = 1usize >> BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHR` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:89:32
    |
 LL | const _NUSIZE_SHR_P: &usize = &(1usize >> BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHR_P` failed here
 
 error[E0080]: attempt to compute `1_i8 + i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:92:22
    |
 LL | const _NI8_ADD: i8 = 1i8 + i8::MAX;
-   |                      ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^ evaluation of `_NI8_ADD` failed here
 
 error[E0080]: attempt to compute `1_i8 + i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:93:26
    |
 LL | const _NI8_ADD_P: &i8 = &(1i8 + i8::MAX);
-   |                          ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^ evaluation of `_NI8_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i16 + i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:95:24
    |
 LL | const _NI16_ADD: i16 = 1i16 + i16::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NI16_ADD` failed here
 
 error[E0080]: attempt to compute `1_i16 + i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:96:28
    |
 LL | const _NI16_ADD_P: &i16 = &(1i16 + i16::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NI16_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i32 + i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:98:24
    |
 LL | const _NI32_ADD: i32 = 1i32 + i32::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NI32_ADD` failed here
 
 error[E0080]: attempt to compute `1_i32 + i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:99:28
    |
 LL | const _NI32_ADD_P: &i32 = &(1i32 + i32::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NI32_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i64 + i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:101:24
    |
 LL | const _NI64_ADD: i64 = 1i64 + i64::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NI64_ADD` failed here
 
 error[E0080]: attempt to compute `1_i64 + i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:102:28
    |
 LL | const _NI64_ADD_P: &i64 = &(1i64 + i64::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NI64_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i128 + i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:104:26
    |
 LL | const _NI128_ADD: i128 = 1i128 + i128::MAX;
-   |                          ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^ evaluation of `_NI128_ADD` failed here
 
 error[E0080]: attempt to compute `1_i128 + i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:105:30
    |
 LL | const _NI128_ADD_P: &i128 = &(1i128 + i128::MAX);
-   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of `_NI128_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u8 + u8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:107:22
    |
 LL | const _NU8_ADD: u8 = 1u8 + u8::MAX;
-   |                      ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^ evaluation of `_NU8_ADD` failed here
 
 error[E0080]: attempt to compute `1_u8 + u8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:108:26
    |
 LL | const _NU8_ADD_P: &u8 = &(1u8 + u8::MAX);
-   |                          ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^ evaluation of `_NU8_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u16 + u16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:110:24
    |
 LL | const _NU16_ADD: u16 = 1u16 + u16::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NU16_ADD` failed here
 
 error[E0080]: attempt to compute `1_u16 + u16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:111:28
    |
 LL | const _NU16_ADD_P: &u16 = &(1u16 + u16::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NU16_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u32 + u32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:113:24
    |
 LL | const _NU32_ADD: u32 = 1u32 + u32::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NU32_ADD` failed here
 
 error[E0080]: attempt to compute `1_u32 + u32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:114:28
    |
 LL | const _NU32_ADD_P: &u32 = &(1u32 + u32::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NU32_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u64 + u64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:116:24
    |
 LL | const _NU64_ADD: u64 = 1u64 + u64::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NU64_ADD` failed here
 
 error[E0080]: attempt to compute `1_u64 + u64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:117:28
    |
 LL | const _NU64_ADD_P: &u64 = &(1u64 + u64::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NU64_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u128 + u128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:119:26
    |
 LL | const _NU128_ADD: u128 = 1u128 + u128::MAX;
-   |                          ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^ evaluation of `_NU128_ADD` failed here
 
 error[E0080]: attempt to compute `1_u128 + u128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:120:30
    |
 LL | const _NU128_ADD_P: &u128 = &(1u128 + u128::MAX);
-   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of `_NU128_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_isize + isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:122:28
    |
 LL | const _NISIZE_ADD: isize = 1isize + isize::MAX;
-   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_ADD` failed here
 
 error[E0080]: attempt to compute `1_isize + isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:123:32
    |
 LL | const _NISIZE_ADD_P: &isize = &(1isize + isize::MAX);
-   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_usize + usize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:125:28
    |
 LL | const _NUSIZE_ADD: usize = 1usize + usize::MAX;
-   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_ADD` failed here
 
 error[E0080]: attempt to compute `1_usize + usize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:126:32
    |
 LL | const _NUSIZE_ADD_P: &usize = &(1usize + usize::MAX);
-   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_ADD_P` failed here
 
 error[E0080]: attempt to compute `-5_i8 - i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:129:22
    |
 LL | const _NI8_SUB: i8 = -5i8 - i8::MAX;
-   |                      ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^^ evaluation of `_NI8_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i8 - i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:130:26
    |
 LL | const _NI8_SUB_P: &i8 = &(-5i8 - i8::MAX);
-   |                          ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^ evaluation of `_NI8_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i16 - i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:132:24
    |
 LL | const _NI16_SUB: i16 = -5i16 - i16::MAX;
-   |                        ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^^ evaluation of `_NI16_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i16 - i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:133:28
    |
 LL | const _NI16_SUB_P: &i16 = &(-5i16 - i16::MAX);
-   |                            ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^ evaluation of `_NI16_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i32 - i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:135:24
    |
 LL | const _NI32_SUB: i32 = -5i32 - i32::MAX;
-   |                        ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^^ evaluation of `_NI32_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i32 - i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:136:28
    |
 LL | const _NI32_SUB_P: &i32 = &(-5i32 - i32::MAX);
-   |                            ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^ evaluation of `_NI32_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i64 - i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:138:24
    |
 LL | const _NI64_SUB: i64 = -5i64 - i64::MAX;
-   |                        ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^^ evaluation of `_NI64_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i64 - i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:139:28
    |
 LL | const _NI64_SUB_P: &i64 = &(-5i64 - i64::MAX);
-   |                            ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^ evaluation of `_NI64_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i128 - i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:141:26
    |
 LL | const _NI128_SUB: i128 = -5i128 - i128::MAX;
-   |                          ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^^ evaluation of `_NI128_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i128 - i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:142:30
    |
 LL | const _NI128_SUB_P: &i128 = &(-5i128 - i128::MAX);
-   |                              ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^^^^^^ evaluation of `_NI128_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u8 - 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:144:22
    |
 LL | const _NU8_SUB: u8 = 1u8 - 5;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NU8_SUB` failed here
 
 error[E0080]: attempt to compute `1_u8 - 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:145:26
    |
 LL | const _NU8_SUB_P: &u8 = &(1u8 - 5);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU8_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u16 - 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:147:24
    |
 LL | const _NU16_SUB: u16 = 1u16 - 5;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU16_SUB` failed here
 
 error[E0080]: attempt to compute `1_u16 - 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:148:28
    |
 LL | const _NU16_SUB_P: &u16 = &(1u16 - 5);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU16_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u32 - 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:150:24
    |
 LL | const _NU32_SUB: u32 = 1u32 - 5;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU32_SUB` failed here
 
 error[E0080]: attempt to compute `1_u32 - 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:151:28
    |
 LL | const _NU32_SUB_P: &u32 = &(1u32 - 5);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU32_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u64 - 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:153:24
    |
 LL | const _NU64_SUB: u64 = 1u64 - 5;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU64_SUB` failed here
 
 error[E0080]: attempt to compute `1_u64 - 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:154:28
    |
 LL | const _NU64_SUB_P: &u64 = &(1u64 - 5);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU64_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u128 - 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:156:26
    |
 LL | const _NU128_SUB: u128 = 1u128 - 5;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU128_SUB` failed here
 
 error[E0080]: attempt to compute `1_u128 - 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:157:30
    |
 LL | const _NU128_SUB_P: &u128 = &(1u128 - 5);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NU128_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_isize - isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:159:28
    |
 LL | const _NISIZE_SUB: isize = -5isize - isize::MAX;
-   |                            ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SUB` failed here
 
 error[E0080]: attempt to compute `-5_isize - isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:160:32
    |
 LL | const _NISIZE_SUB_P: &isize = &(-5isize - isize::MAX);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_usize - 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:162:28
    |
 LL | const _NUSIZE_SUB: usize = 1usize - 5;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NUSIZE_SUB` failed here
 
 error[E0080]: attempt to compute `1_usize - 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:163:32
    |
 LL | const _NUSIZE_SUB_P: &usize = &(1usize - 5);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NUSIZE_SUB_P` failed here
 
 error[E0080]: attempt to compute `i8::MAX * 5_i8`, which would overflow
   --> $DIR/overflowing-consts.rs:166:22
    |
 LL | const _NI8_MUL: i8 = i8::MAX * 5;
-   |                      ^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^ evaluation of `_NI8_MUL` failed here
 
 error[E0080]: attempt to compute `i8::MAX * 5_i8`, which would overflow
   --> $DIR/overflowing-consts.rs:167:26
    |
 LL | const _NI8_MUL_P: &i8 = &(i8::MAX * 5);
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NI8_MUL_P` failed here
 
 error[E0080]: attempt to compute `i16::MAX * 5_i16`, which would overflow
   --> $DIR/overflowing-consts.rs:169:24
    |
 LL | const _NI16_MUL: i16 = i16::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI16_MUL` failed here
 
 error[E0080]: attempt to compute `i16::MAX * 5_i16`, which would overflow
   --> $DIR/overflowing-consts.rs:170:28
    |
 LL | const _NI16_MUL_P: &i16 = &(i16::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI16_MUL_P` failed here
 
 error[E0080]: attempt to compute `i32::MAX * 5_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:172:24
    |
 LL | const _NI32_MUL: i32 = i32::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI32_MUL` failed here
 
 error[E0080]: attempt to compute `i32::MAX * 5_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:173:28
    |
 LL | const _NI32_MUL_P: &i32 = &(i32::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI32_MUL_P` failed here
 
 error[E0080]: attempt to compute `i64::MAX * 5_i64`, which would overflow
   --> $DIR/overflowing-consts.rs:175:24
    |
 LL | const _NI64_MUL: i64 = i64::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI64_MUL` failed here
 
 error[E0080]: attempt to compute `i64::MAX * 5_i64`, which would overflow
   --> $DIR/overflowing-consts.rs:176:28
    |
 LL | const _NI64_MUL_P: &i64 = &(i64::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI64_MUL_P` failed here
 
 error[E0080]: attempt to compute `i128::MAX * 5_i128`, which would overflow
   --> $DIR/overflowing-consts.rs:178:26
    |
 LL | const _NI128_MUL: i128 = i128::MAX * 5;
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NI128_MUL` failed here
 
 error[E0080]: attempt to compute `i128::MAX * 5_i128`, which would overflow
   --> $DIR/overflowing-consts.rs:179:30
    |
 LL | const _NI128_MUL_P: &i128 = &(i128::MAX * 5);
-   |                              ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^ evaluation of `_NI128_MUL_P` failed here
 
 error[E0080]: attempt to compute `u8::MAX * 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:181:22
    |
 LL | const _NU8_MUL: u8 = u8::MAX * 5;
-   |                      ^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^ evaluation of `_NU8_MUL` failed here
 
 error[E0080]: attempt to compute `u8::MAX * 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:182:26
    |
 LL | const _NU8_MUL_P: &u8 = &(u8::MAX * 5);
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NU8_MUL_P` failed here
 
 error[E0080]: attempt to compute `u16::MAX * 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:184:24
    |
 LL | const _NU16_MUL: u16 = u16::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NU16_MUL` failed here
 
 error[E0080]: attempt to compute `u16::MAX * 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:185:28
    |
 LL | const _NU16_MUL_P: &u16 = &(u16::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NU16_MUL_P` failed here
 
 error[E0080]: attempt to compute `u32::MAX * 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:187:24
    |
 LL | const _NU32_MUL: u32 = u32::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NU32_MUL` failed here
 
 error[E0080]: attempt to compute `u32::MAX * 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:188:28
    |
 LL | const _NU32_MUL_P: &u32 = &(u32::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NU32_MUL_P` failed here
 
 error[E0080]: attempt to compute `u64::MAX * 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:190:24
    |
 LL | const _NU64_MUL: u64 = u64::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NU64_MUL` failed here
 
 error[E0080]: attempt to compute `u64::MAX * 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:191:28
    |
 LL | const _NU64_MUL_P: &u64 = &(u64::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NU64_MUL_P` failed here
 
 error[E0080]: attempt to compute `u128::MAX * 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:193:26
    |
 LL | const _NU128_MUL: u128 = u128::MAX * 5;
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NU128_MUL` failed here
 
 error[E0080]: attempt to compute `u128::MAX * 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:194:30
    |
 LL | const _NU128_MUL_P: &u128 = &(u128::MAX * 5);
-   |                              ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^ evaluation of `_NU128_MUL_P` failed here
 
 error[E0080]: attempt to compute `isize::MAX * 5_isize`, which would overflow
   --> $DIR/overflowing-consts.rs:196:28
    |
 LL | const _NISIZE_MUL: isize = isize::MAX * 5;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NISIZE_MUL` failed here
 
 error[E0080]: attempt to compute `isize::MAX * 5_isize`, which would overflow
   --> $DIR/overflowing-consts.rs:197:32
    |
 LL | const _NISIZE_MUL_P: &isize = &(isize::MAX * 5);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_MUL_P` failed here
 
 error[E0080]: attempt to compute `usize::MAX * 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:199:28
    |
 LL | const _NUSIZE_MUL: usize = usize::MAX * 5;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NUSIZE_MUL` failed here
 
 error[E0080]: attempt to compute `usize::MAX * 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:200:32
    |
 LL | const _NUSIZE_MUL_P: &usize = &(usize::MAX * 5);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_MUL_P` failed here
 
 error[E0080]: attempt to divide `1_i8` by zero
   --> $DIR/overflowing-consts.rs:203:22
    |
 LL | const _NI8_DIV: i8 = 1i8 / 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NI8_DIV` failed here
 
 error[E0080]: attempt to divide `1_i8` by zero
   --> $DIR/overflowing-consts.rs:204:26
    |
 LL | const _NI8_DIV_P: &i8 = &(1i8 / 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI8_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i16` by zero
   --> $DIR/overflowing-consts.rs:206:24
    |
 LL | const _NI16_DIV: i16 = 1i16 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI16_DIV` failed here
 
 error[E0080]: attempt to divide `1_i16` by zero
   --> $DIR/overflowing-consts.rs:207:28
    |
 LL | const _NI16_DIV_P: &i16 = &(1i16 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI16_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i32` by zero
   --> $DIR/overflowing-consts.rs:209:24
    |
 LL | const _NI32_DIV: i32 = 1i32 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI32_DIV` failed here
 
 error[E0080]: attempt to divide `1_i32` by zero
   --> $DIR/overflowing-consts.rs:210:28
    |
 LL | const _NI32_DIV_P: &i32 = &(1i32 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI32_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i64` by zero
   --> $DIR/overflowing-consts.rs:212:24
    |
 LL | const _NI64_DIV: i64 = 1i64 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI64_DIV` failed here
 
 error[E0080]: attempt to divide `1_i64` by zero
   --> $DIR/overflowing-consts.rs:213:28
    |
 LL | const _NI64_DIV_P: &i64 = &(1i64 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI64_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i128` by zero
   --> $DIR/overflowing-consts.rs:215:26
    |
 LL | const _NI128_DIV: i128 = 1i128 / 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI128_DIV` failed here
 
 error[E0080]: attempt to divide `1_i128` by zero
   --> $DIR/overflowing-consts.rs:216:30
    |
 LL | const _NI128_DIV_P: &i128 = &(1i128 / 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NI128_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u8` by zero
   --> $DIR/overflowing-consts.rs:218:22
    |
 LL | const _NU8_DIV: u8 = 1u8 / 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NU8_DIV` failed here
 
 error[E0080]: attempt to divide `1_u8` by zero
   --> $DIR/overflowing-consts.rs:219:26
    |
 LL | const _NU8_DIV_P: &u8 = &(1u8 / 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU8_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u16` by zero
   --> $DIR/overflowing-consts.rs:221:24
    |
 LL | const _NU16_DIV: u16 = 1u16 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU16_DIV` failed here
 
 error[E0080]: attempt to divide `1_u16` by zero
   --> $DIR/overflowing-consts.rs:222:28
    |
 LL | const _NU16_DIV_P: &u16 = &(1u16 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU16_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u32` by zero
   --> $DIR/overflowing-consts.rs:224:24
    |
 LL | const _NU32_DIV: u32 = 1u32 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU32_DIV` failed here
 
 error[E0080]: attempt to divide `1_u32` by zero
   --> $DIR/overflowing-consts.rs:225:28
    |
 LL | const _NU32_DIV_P: &u32 = &(1u32 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU32_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u64` by zero
   --> $DIR/overflowing-consts.rs:227:24
    |
 LL | const _NU64_DIV: u64 = 1u64 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU64_DIV` failed here
 
 error[E0080]: attempt to divide `1_u64` by zero
   --> $DIR/overflowing-consts.rs:228:28
    |
 LL | const _NU64_DIV_P: &u64 = &(1u64 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU64_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u128` by zero
   --> $DIR/overflowing-consts.rs:230:26
    |
 LL | const _NU128_DIV: u128 = 1u128 / 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU128_DIV` failed here
 
 error[E0080]: attempt to divide `1_u128` by zero
   --> $DIR/overflowing-consts.rs:231:30
    |
 LL | const _NU128_DIV_P: &u128 = &(1u128 / 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NU128_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_isize` by zero
   --> $DIR/overflowing-consts.rs:233:28
    |
 LL | const _NISIZE_DIV: isize = 1isize / 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NISIZE_DIV` failed here
 
 error[E0080]: attempt to divide `1_isize` by zero
   --> $DIR/overflowing-consts.rs:234:32
    |
 LL | const _NISIZE_DIV_P: &isize = &(1isize / 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NISIZE_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_usize` by zero
   --> $DIR/overflowing-consts.rs:236:28
    |
 LL | const _NUSIZE_DIV: usize = 1usize / 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NUSIZE_DIV` failed here
 
 error[E0080]: attempt to divide `1_usize` by zero
   --> $DIR/overflowing-consts.rs:237:32
    |
 LL | const _NUSIZE_DIV_P: &usize = &(1usize / 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NUSIZE_DIV_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:240:22
    |
 LL | const _NI8_MOD: i8 = 1i8 % 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NI8_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:241:26
    |
 LL | const _NI8_MOD_P: &i8 = &(1i8 % 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI8_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:243:24
    |
 LL | const _NI16_MOD: i16 = 1i16 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI16_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:244:28
    |
 LL | const _NI16_MOD_P: &i16 = &(1i16 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI16_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:246:24
    |
 LL | const _NI32_MOD: i32 = 1i32 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI32_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:247:28
    |
 LL | const _NI32_MOD_P: &i32 = &(1i32 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI32_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:249:24
    |
 LL | const _NI64_MOD: i64 = 1i64 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI64_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:250:28
    |
 LL | const _NI64_MOD_P: &i64 = &(1i64 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI64_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:252:26
    |
 LL | const _NI128_MOD: i128 = 1i128 % 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI128_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:253:30
    |
 LL | const _NI128_MOD_P: &i128 = &(1i128 % 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NI128_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:255:22
    |
 LL | const _NU8_MOD: u8 = 1u8 % 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NU8_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:256:26
    |
 LL | const _NU8_MOD_P: &u8 = &(1u8 % 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU8_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:258:24
    |
 LL | const _NU16_MOD: u16 = 1u16 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU16_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:259:28
    |
 LL | const _NU16_MOD_P: &u16 = &(1u16 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU16_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:261:24
    |
 LL | const _NU32_MOD: u32 = 1u32 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU32_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:262:28
    |
 LL | const _NU32_MOD_P: &u32 = &(1u32 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU32_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:264:24
    |
 LL | const _NU64_MOD: u64 = 1u64 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU64_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:265:28
    |
 LL | const _NU64_MOD_P: &u64 = &(1u64 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU64_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:267:26
    |
 LL | const _NU128_MOD: u128 = 1u128 % 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU128_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:268:30
    |
 LL | const _NU128_MOD_P: &u128 = &(1u128 % 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NU128_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_isize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:270:28
    |
 LL | const _NISIZE_MOD: isize = 1isize % 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NISIZE_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_isize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:271:32
    |
 LL | const _NISIZE_MOD_P: &isize = &(1isize % 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NISIZE_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_usize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:273:28
    |
 LL | const _NUSIZE_MOD: usize = 1usize % 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NUSIZE_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_usize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:274:32
    |
 LL | const _NUSIZE_MOD_P: &usize = &(1usize % 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NUSIZE_MOD_P` failed here
 
 error[E0080]: index out of bounds: the length is 3 but the index is 4
   --> $DIR/overflowing-consts.rs:277:24
    |
 LL | const _NI32_OOB: i32 = [1, 2, 3][4];
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI32_OOB` failed here
 
 error[E0080]: index out of bounds: the length is 3 but the index is 4
   --> $DIR/overflowing-consts.rs:278:28
    |
 LL | const _NI32_OOB_P: &i32 = &([1, 2, 3][4]);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI32_OOB_P` failed here
 
 error: aborting due to 170 previous errors
 
diff --git a/tests/ui/consts/overflowing-consts.opt.stderr b/tests/ui/consts/overflowing-consts.opt.stderr
index e317060a141..1ef2a60b647 100644
--- a/tests/ui/consts/overflowing-consts.opt.stderr
+++ b/tests/ui/consts/overflowing-consts.opt.stderr
@@ -2,1021 +2,1021 @@ error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:18:22
    |
 LL | const _NI8_SHL: i8 = 1i8 << 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NI8_SHL` failed here
 
 error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:19:26
    |
 LL | const _NI8_SHL_P: &i8 = &(1i8 << 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NI8_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:21:24
    |
 LL | const _NI16_SHL: i16 = 1i16 << 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI16_SHL` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:22:28
    |
 LL | const _NI16_SHL_P: &i16 = &(1i16 << 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI16_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:24:24
    |
 LL | const _NI32_SHL: i32 = 1i32 << 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI32_SHL` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:25:28
    |
 LL | const _NI32_SHL_P: &i32 = &(1i32 << 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI32_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:27:24
    |
 LL | const _NI64_SHL: i64 = 1i64 << 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI64_SHL` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:28:28
    |
 LL | const _NI64_SHL_P: &i64 = &(1i64 << 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI64_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:30:26
    |
 LL | const _NI128_SHL: i128 = 1i128 << 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NI128_SHL` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:31:30
    |
 LL | const _NI128_SHL_P: &i128 = &(1i128 << 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NI128_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:33:22
    |
 LL | const _NU8_SHL: u8 = 1u8 << 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NU8_SHL` failed here
 
 error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:34:26
    |
 LL | const _NU8_SHL_P: &u8 = &(1u8 << 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NU8_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:36:24
    |
 LL | const _NU16_SHL: u16 = 1u16 << 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU16_SHL` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:37:28
    |
 LL | const _NU16_SHL_P: &u16 = &(1u16 << 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU16_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:39:24
    |
 LL | const _NU32_SHL: u32 = 1u32 << 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU32_SHL` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:40:28
    |
 LL | const _NU32_SHL_P: &u32 = &(1u32 << 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU32_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:42:24
    |
 LL | const _NU64_SHL: u64 = 1u64 << 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU64_SHL` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:43:28
    |
 LL | const _NU64_SHL_P: &u64 = &(1u64 << 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU64_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:45:26
    |
 LL | const _NU128_SHL: u128 = 1u128 << 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NU128_SHL` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:46:30
    |
 LL | const _NU128_SHL_P: &u128 = &(1u128 << 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NU128_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:48:28
    |
 LL | const _NISIZE_SHL: isize = 1isize << BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHL` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:49:32
    |
 LL | const _NISIZE_SHL_P: &isize = &(1isize << BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:51:28
    |
 LL | const _NUSIZE_SHL: usize = 1usize << BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHL` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:52:32
    |
 LL | const _NUSIZE_SHL_P: &usize = &(1usize << BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHL_P` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:55:22
    |
 LL | const _NI8_SHR: i8 = 1i8 >> 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NI8_SHR` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:56:26
    |
 LL | const _NI8_SHR_P: &i8 = &(1i8 >> 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NI8_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:58:24
    |
 LL | const _NI16_SHR: i16 = 1i16 >> 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI16_SHR` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:59:28
    |
 LL | const _NI16_SHR_P: &i16 = &(1i16 >> 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI16_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:61:24
    |
 LL | const _NI32_SHR: i32 = 1i32 >> 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI32_SHR` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:62:28
    |
 LL | const _NI32_SHR_P: &i32 = &(1i32 >> 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI32_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:64:24
    |
 LL | const _NI64_SHR: i64 = 1i64 >> 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI64_SHR` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:65:28
    |
 LL | const _NI64_SHR_P: &i64 = &(1i64 >> 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI64_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:67:26
    |
 LL | const _NI128_SHR: i128 = 1i128 >> 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NI128_SHR` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:68:30
    |
 LL | const _NI128_SHR_P: &i128 = &(1i128 >> 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NI128_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:70:22
    |
 LL | const _NU8_SHR: u8 = 1u8 >> 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NU8_SHR` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:71:26
    |
 LL | const _NU8_SHR_P: &u8 = &(1u8 >> 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NU8_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:73:24
    |
 LL | const _NU16_SHR: u16 = 1u16 >> 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU16_SHR` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:74:28
    |
 LL | const _NU16_SHR_P: &u16 = &(1u16 >> 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU16_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:76:24
    |
 LL | const _NU32_SHR: u32 = 1u32 >> 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU32_SHR` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:77:28
    |
 LL | const _NU32_SHR_P: &u32 = &(1u32 >> 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU32_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:79:24
    |
 LL | const _NU64_SHR: u64 = 1u64 >> 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU64_SHR` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:80:28
    |
 LL | const _NU64_SHR_P: &u64 = &(1u64 >> 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU64_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:82:26
    |
 LL | const _NU128_SHR: u128 = 1u128 >> 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NU128_SHR` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:83:30
    |
 LL | const _NU128_SHR_P: &u128 = &(1u128 >> 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NU128_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:85:28
    |
 LL | const _NISIZE_SHR: isize = 1isize >> BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHR` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:86:32
    |
 LL | const _NISIZE_SHR_P: &isize = &(1isize >> BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:88:28
    |
 LL | const _NUSIZE_SHR: usize = 1usize >> BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHR` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:89:32
    |
 LL | const _NUSIZE_SHR_P: &usize = &(1usize >> BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHR_P` failed here
 
 error[E0080]: attempt to compute `1_i8 + i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:92:22
    |
 LL | const _NI8_ADD: i8 = 1i8 + i8::MAX;
-   |                      ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^ evaluation of `_NI8_ADD` failed here
 
 error[E0080]: attempt to compute `1_i8 + i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:93:26
    |
 LL | const _NI8_ADD_P: &i8 = &(1i8 + i8::MAX);
-   |                          ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^ evaluation of `_NI8_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i16 + i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:95:24
    |
 LL | const _NI16_ADD: i16 = 1i16 + i16::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NI16_ADD` failed here
 
 error[E0080]: attempt to compute `1_i16 + i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:96:28
    |
 LL | const _NI16_ADD_P: &i16 = &(1i16 + i16::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NI16_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i32 + i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:98:24
    |
 LL | const _NI32_ADD: i32 = 1i32 + i32::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NI32_ADD` failed here
 
 error[E0080]: attempt to compute `1_i32 + i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:99:28
    |
 LL | const _NI32_ADD_P: &i32 = &(1i32 + i32::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NI32_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i64 + i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:101:24
    |
 LL | const _NI64_ADD: i64 = 1i64 + i64::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NI64_ADD` failed here
 
 error[E0080]: attempt to compute `1_i64 + i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:102:28
    |
 LL | const _NI64_ADD_P: &i64 = &(1i64 + i64::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NI64_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i128 + i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:104:26
    |
 LL | const _NI128_ADD: i128 = 1i128 + i128::MAX;
-   |                          ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^ evaluation of `_NI128_ADD` failed here
 
 error[E0080]: attempt to compute `1_i128 + i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:105:30
    |
 LL | const _NI128_ADD_P: &i128 = &(1i128 + i128::MAX);
-   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of `_NI128_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u8 + u8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:107:22
    |
 LL | const _NU8_ADD: u8 = 1u8 + u8::MAX;
-   |                      ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^ evaluation of `_NU8_ADD` failed here
 
 error[E0080]: attempt to compute `1_u8 + u8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:108:26
    |
 LL | const _NU8_ADD_P: &u8 = &(1u8 + u8::MAX);
-   |                          ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^ evaluation of `_NU8_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u16 + u16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:110:24
    |
 LL | const _NU16_ADD: u16 = 1u16 + u16::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NU16_ADD` failed here
 
 error[E0080]: attempt to compute `1_u16 + u16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:111:28
    |
 LL | const _NU16_ADD_P: &u16 = &(1u16 + u16::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NU16_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u32 + u32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:113:24
    |
 LL | const _NU32_ADD: u32 = 1u32 + u32::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NU32_ADD` failed here
 
 error[E0080]: attempt to compute `1_u32 + u32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:114:28
    |
 LL | const _NU32_ADD_P: &u32 = &(1u32 + u32::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NU32_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u64 + u64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:116:24
    |
 LL | const _NU64_ADD: u64 = 1u64 + u64::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NU64_ADD` failed here
 
 error[E0080]: attempt to compute `1_u64 + u64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:117:28
    |
 LL | const _NU64_ADD_P: &u64 = &(1u64 + u64::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NU64_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u128 + u128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:119:26
    |
 LL | const _NU128_ADD: u128 = 1u128 + u128::MAX;
-   |                          ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^ evaluation of `_NU128_ADD` failed here
 
 error[E0080]: attempt to compute `1_u128 + u128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:120:30
    |
 LL | const _NU128_ADD_P: &u128 = &(1u128 + u128::MAX);
-   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of `_NU128_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_isize + isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:122:28
    |
 LL | const _NISIZE_ADD: isize = 1isize + isize::MAX;
-   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_ADD` failed here
 
 error[E0080]: attempt to compute `1_isize + isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:123:32
    |
 LL | const _NISIZE_ADD_P: &isize = &(1isize + isize::MAX);
-   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_usize + usize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:125:28
    |
 LL | const _NUSIZE_ADD: usize = 1usize + usize::MAX;
-   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_ADD` failed here
 
 error[E0080]: attempt to compute `1_usize + usize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:126:32
    |
 LL | const _NUSIZE_ADD_P: &usize = &(1usize + usize::MAX);
-   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_ADD_P` failed here
 
 error[E0080]: attempt to compute `-5_i8 - i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:129:22
    |
 LL | const _NI8_SUB: i8 = -5i8 - i8::MAX;
-   |                      ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^^ evaluation of `_NI8_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i8 - i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:130:26
    |
 LL | const _NI8_SUB_P: &i8 = &(-5i8 - i8::MAX);
-   |                          ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^ evaluation of `_NI8_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i16 - i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:132:24
    |
 LL | const _NI16_SUB: i16 = -5i16 - i16::MAX;
-   |                        ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^^ evaluation of `_NI16_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i16 - i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:133:28
    |
 LL | const _NI16_SUB_P: &i16 = &(-5i16 - i16::MAX);
-   |                            ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^ evaluation of `_NI16_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i32 - i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:135:24
    |
 LL | const _NI32_SUB: i32 = -5i32 - i32::MAX;
-   |                        ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^^ evaluation of `_NI32_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i32 - i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:136:28
    |
 LL | const _NI32_SUB_P: &i32 = &(-5i32 - i32::MAX);
-   |                            ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^ evaluation of `_NI32_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i64 - i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:138:24
    |
 LL | const _NI64_SUB: i64 = -5i64 - i64::MAX;
-   |                        ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^^ evaluation of `_NI64_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i64 - i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:139:28
    |
 LL | const _NI64_SUB_P: &i64 = &(-5i64 - i64::MAX);
-   |                            ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^ evaluation of `_NI64_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i128 - i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:141:26
    |
 LL | const _NI128_SUB: i128 = -5i128 - i128::MAX;
-   |                          ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^^ evaluation of `_NI128_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i128 - i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:142:30
    |
 LL | const _NI128_SUB_P: &i128 = &(-5i128 - i128::MAX);
-   |                              ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^^^^^^ evaluation of `_NI128_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u8 - 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:144:22
    |
 LL | const _NU8_SUB: u8 = 1u8 - 5;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NU8_SUB` failed here
 
 error[E0080]: attempt to compute `1_u8 - 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:145:26
    |
 LL | const _NU8_SUB_P: &u8 = &(1u8 - 5);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU8_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u16 - 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:147:24
    |
 LL | const _NU16_SUB: u16 = 1u16 - 5;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU16_SUB` failed here
 
 error[E0080]: attempt to compute `1_u16 - 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:148:28
    |
 LL | const _NU16_SUB_P: &u16 = &(1u16 - 5);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU16_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u32 - 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:150:24
    |
 LL | const _NU32_SUB: u32 = 1u32 - 5;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU32_SUB` failed here
 
 error[E0080]: attempt to compute `1_u32 - 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:151:28
    |
 LL | const _NU32_SUB_P: &u32 = &(1u32 - 5);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU32_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u64 - 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:153:24
    |
 LL | const _NU64_SUB: u64 = 1u64 - 5;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU64_SUB` failed here
 
 error[E0080]: attempt to compute `1_u64 - 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:154:28
    |
 LL | const _NU64_SUB_P: &u64 = &(1u64 - 5);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU64_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u128 - 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:156:26
    |
 LL | const _NU128_SUB: u128 = 1u128 - 5;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU128_SUB` failed here
 
 error[E0080]: attempt to compute `1_u128 - 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:157:30
    |
 LL | const _NU128_SUB_P: &u128 = &(1u128 - 5);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NU128_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_isize - isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:159:28
    |
 LL | const _NISIZE_SUB: isize = -5isize - isize::MAX;
-   |                            ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SUB` failed here
 
 error[E0080]: attempt to compute `-5_isize - isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:160:32
    |
 LL | const _NISIZE_SUB_P: &isize = &(-5isize - isize::MAX);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_usize - 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:162:28
    |
 LL | const _NUSIZE_SUB: usize = 1usize - 5;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NUSIZE_SUB` failed here
 
 error[E0080]: attempt to compute `1_usize - 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:163:32
    |
 LL | const _NUSIZE_SUB_P: &usize = &(1usize - 5);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NUSIZE_SUB_P` failed here
 
 error[E0080]: attempt to compute `i8::MAX * 5_i8`, which would overflow
   --> $DIR/overflowing-consts.rs:166:22
    |
 LL | const _NI8_MUL: i8 = i8::MAX * 5;
-   |                      ^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^ evaluation of `_NI8_MUL` failed here
 
 error[E0080]: attempt to compute `i8::MAX * 5_i8`, which would overflow
   --> $DIR/overflowing-consts.rs:167:26
    |
 LL | const _NI8_MUL_P: &i8 = &(i8::MAX * 5);
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NI8_MUL_P` failed here
 
 error[E0080]: attempt to compute `i16::MAX * 5_i16`, which would overflow
   --> $DIR/overflowing-consts.rs:169:24
    |
 LL | const _NI16_MUL: i16 = i16::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI16_MUL` failed here
 
 error[E0080]: attempt to compute `i16::MAX * 5_i16`, which would overflow
   --> $DIR/overflowing-consts.rs:170:28
    |
 LL | const _NI16_MUL_P: &i16 = &(i16::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI16_MUL_P` failed here
 
 error[E0080]: attempt to compute `i32::MAX * 5_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:172:24
    |
 LL | const _NI32_MUL: i32 = i32::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI32_MUL` failed here
 
 error[E0080]: attempt to compute `i32::MAX * 5_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:173:28
    |
 LL | const _NI32_MUL_P: &i32 = &(i32::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI32_MUL_P` failed here
 
 error[E0080]: attempt to compute `i64::MAX * 5_i64`, which would overflow
   --> $DIR/overflowing-consts.rs:175:24
    |
 LL | const _NI64_MUL: i64 = i64::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI64_MUL` failed here
 
 error[E0080]: attempt to compute `i64::MAX * 5_i64`, which would overflow
   --> $DIR/overflowing-consts.rs:176:28
    |
 LL | const _NI64_MUL_P: &i64 = &(i64::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI64_MUL_P` failed here
 
 error[E0080]: attempt to compute `i128::MAX * 5_i128`, which would overflow
   --> $DIR/overflowing-consts.rs:178:26
    |
 LL | const _NI128_MUL: i128 = i128::MAX * 5;
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NI128_MUL` failed here
 
 error[E0080]: attempt to compute `i128::MAX * 5_i128`, which would overflow
   --> $DIR/overflowing-consts.rs:179:30
    |
 LL | const _NI128_MUL_P: &i128 = &(i128::MAX * 5);
-   |                              ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^ evaluation of `_NI128_MUL_P` failed here
 
 error[E0080]: attempt to compute `u8::MAX * 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:181:22
    |
 LL | const _NU8_MUL: u8 = u8::MAX * 5;
-   |                      ^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^ evaluation of `_NU8_MUL` failed here
 
 error[E0080]: attempt to compute `u8::MAX * 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:182:26
    |
 LL | const _NU8_MUL_P: &u8 = &(u8::MAX * 5);
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NU8_MUL_P` failed here
 
 error[E0080]: attempt to compute `u16::MAX * 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:184:24
    |
 LL | const _NU16_MUL: u16 = u16::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NU16_MUL` failed here
 
 error[E0080]: attempt to compute `u16::MAX * 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:185:28
    |
 LL | const _NU16_MUL_P: &u16 = &(u16::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NU16_MUL_P` failed here
 
 error[E0080]: attempt to compute `u32::MAX * 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:187:24
    |
 LL | const _NU32_MUL: u32 = u32::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NU32_MUL` failed here
 
 error[E0080]: attempt to compute `u32::MAX * 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:188:28
    |
 LL | const _NU32_MUL_P: &u32 = &(u32::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NU32_MUL_P` failed here
 
 error[E0080]: attempt to compute `u64::MAX * 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:190:24
    |
 LL | const _NU64_MUL: u64 = u64::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NU64_MUL` failed here
 
 error[E0080]: attempt to compute `u64::MAX * 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:191:28
    |
 LL | const _NU64_MUL_P: &u64 = &(u64::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NU64_MUL_P` failed here
 
 error[E0080]: attempt to compute `u128::MAX * 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:193:26
    |
 LL | const _NU128_MUL: u128 = u128::MAX * 5;
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NU128_MUL` failed here
 
 error[E0080]: attempt to compute `u128::MAX * 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:194:30
    |
 LL | const _NU128_MUL_P: &u128 = &(u128::MAX * 5);
-   |                              ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^ evaluation of `_NU128_MUL_P` failed here
 
 error[E0080]: attempt to compute `isize::MAX * 5_isize`, which would overflow
   --> $DIR/overflowing-consts.rs:196:28
    |
 LL | const _NISIZE_MUL: isize = isize::MAX * 5;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NISIZE_MUL` failed here
 
 error[E0080]: attempt to compute `isize::MAX * 5_isize`, which would overflow
   --> $DIR/overflowing-consts.rs:197:32
    |
 LL | const _NISIZE_MUL_P: &isize = &(isize::MAX * 5);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_MUL_P` failed here
 
 error[E0080]: attempt to compute `usize::MAX * 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:199:28
    |
 LL | const _NUSIZE_MUL: usize = usize::MAX * 5;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NUSIZE_MUL` failed here
 
 error[E0080]: attempt to compute `usize::MAX * 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:200:32
    |
 LL | const _NUSIZE_MUL_P: &usize = &(usize::MAX * 5);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_MUL_P` failed here
 
 error[E0080]: attempt to divide `1_i8` by zero
   --> $DIR/overflowing-consts.rs:203:22
    |
 LL | const _NI8_DIV: i8 = 1i8 / 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NI8_DIV` failed here
 
 error[E0080]: attempt to divide `1_i8` by zero
   --> $DIR/overflowing-consts.rs:204:26
    |
 LL | const _NI8_DIV_P: &i8 = &(1i8 / 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI8_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i16` by zero
   --> $DIR/overflowing-consts.rs:206:24
    |
 LL | const _NI16_DIV: i16 = 1i16 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI16_DIV` failed here
 
 error[E0080]: attempt to divide `1_i16` by zero
   --> $DIR/overflowing-consts.rs:207:28
    |
 LL | const _NI16_DIV_P: &i16 = &(1i16 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI16_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i32` by zero
   --> $DIR/overflowing-consts.rs:209:24
    |
 LL | const _NI32_DIV: i32 = 1i32 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI32_DIV` failed here
 
 error[E0080]: attempt to divide `1_i32` by zero
   --> $DIR/overflowing-consts.rs:210:28
    |
 LL | const _NI32_DIV_P: &i32 = &(1i32 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI32_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i64` by zero
   --> $DIR/overflowing-consts.rs:212:24
    |
 LL | const _NI64_DIV: i64 = 1i64 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI64_DIV` failed here
 
 error[E0080]: attempt to divide `1_i64` by zero
   --> $DIR/overflowing-consts.rs:213:28
    |
 LL | const _NI64_DIV_P: &i64 = &(1i64 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI64_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i128` by zero
   --> $DIR/overflowing-consts.rs:215:26
    |
 LL | const _NI128_DIV: i128 = 1i128 / 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI128_DIV` failed here
 
 error[E0080]: attempt to divide `1_i128` by zero
   --> $DIR/overflowing-consts.rs:216:30
    |
 LL | const _NI128_DIV_P: &i128 = &(1i128 / 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NI128_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u8` by zero
   --> $DIR/overflowing-consts.rs:218:22
    |
 LL | const _NU8_DIV: u8 = 1u8 / 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NU8_DIV` failed here
 
 error[E0080]: attempt to divide `1_u8` by zero
   --> $DIR/overflowing-consts.rs:219:26
    |
 LL | const _NU8_DIV_P: &u8 = &(1u8 / 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU8_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u16` by zero
   --> $DIR/overflowing-consts.rs:221:24
    |
 LL | const _NU16_DIV: u16 = 1u16 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU16_DIV` failed here
 
 error[E0080]: attempt to divide `1_u16` by zero
   --> $DIR/overflowing-consts.rs:222:28
    |
 LL | const _NU16_DIV_P: &u16 = &(1u16 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU16_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u32` by zero
   --> $DIR/overflowing-consts.rs:224:24
    |
 LL | const _NU32_DIV: u32 = 1u32 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU32_DIV` failed here
 
 error[E0080]: attempt to divide `1_u32` by zero
   --> $DIR/overflowing-consts.rs:225:28
    |
 LL | const _NU32_DIV_P: &u32 = &(1u32 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU32_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u64` by zero
   --> $DIR/overflowing-consts.rs:227:24
    |
 LL | const _NU64_DIV: u64 = 1u64 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU64_DIV` failed here
 
 error[E0080]: attempt to divide `1_u64` by zero
   --> $DIR/overflowing-consts.rs:228:28
    |
 LL | const _NU64_DIV_P: &u64 = &(1u64 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU64_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u128` by zero
   --> $DIR/overflowing-consts.rs:230:26
    |
 LL | const _NU128_DIV: u128 = 1u128 / 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU128_DIV` failed here
 
 error[E0080]: attempt to divide `1_u128` by zero
   --> $DIR/overflowing-consts.rs:231:30
    |
 LL | const _NU128_DIV_P: &u128 = &(1u128 / 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NU128_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_isize` by zero
   --> $DIR/overflowing-consts.rs:233:28
    |
 LL | const _NISIZE_DIV: isize = 1isize / 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NISIZE_DIV` failed here
 
 error[E0080]: attempt to divide `1_isize` by zero
   --> $DIR/overflowing-consts.rs:234:32
    |
 LL | const _NISIZE_DIV_P: &isize = &(1isize / 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NISIZE_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_usize` by zero
   --> $DIR/overflowing-consts.rs:236:28
    |
 LL | const _NUSIZE_DIV: usize = 1usize / 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NUSIZE_DIV` failed here
 
 error[E0080]: attempt to divide `1_usize` by zero
   --> $DIR/overflowing-consts.rs:237:32
    |
 LL | const _NUSIZE_DIV_P: &usize = &(1usize / 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NUSIZE_DIV_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:240:22
    |
 LL | const _NI8_MOD: i8 = 1i8 % 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NI8_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:241:26
    |
 LL | const _NI8_MOD_P: &i8 = &(1i8 % 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI8_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:243:24
    |
 LL | const _NI16_MOD: i16 = 1i16 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI16_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:244:28
    |
 LL | const _NI16_MOD_P: &i16 = &(1i16 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI16_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:246:24
    |
 LL | const _NI32_MOD: i32 = 1i32 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI32_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:247:28
    |
 LL | const _NI32_MOD_P: &i32 = &(1i32 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI32_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:249:24
    |
 LL | const _NI64_MOD: i64 = 1i64 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI64_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:250:28
    |
 LL | const _NI64_MOD_P: &i64 = &(1i64 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI64_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:252:26
    |
 LL | const _NI128_MOD: i128 = 1i128 % 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI128_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:253:30
    |
 LL | const _NI128_MOD_P: &i128 = &(1i128 % 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NI128_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:255:22
    |
 LL | const _NU8_MOD: u8 = 1u8 % 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NU8_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:256:26
    |
 LL | const _NU8_MOD_P: &u8 = &(1u8 % 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU8_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:258:24
    |
 LL | const _NU16_MOD: u16 = 1u16 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU16_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:259:28
    |
 LL | const _NU16_MOD_P: &u16 = &(1u16 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU16_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:261:24
    |
 LL | const _NU32_MOD: u32 = 1u32 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU32_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:262:28
    |
 LL | const _NU32_MOD_P: &u32 = &(1u32 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU32_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:264:24
    |
 LL | const _NU64_MOD: u64 = 1u64 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU64_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:265:28
    |
 LL | const _NU64_MOD_P: &u64 = &(1u64 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU64_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:267:26
    |
 LL | const _NU128_MOD: u128 = 1u128 % 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU128_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:268:30
    |
 LL | const _NU128_MOD_P: &u128 = &(1u128 % 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NU128_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_isize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:270:28
    |
 LL | const _NISIZE_MOD: isize = 1isize % 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NISIZE_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_isize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:271:32
    |
 LL | const _NISIZE_MOD_P: &isize = &(1isize % 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NISIZE_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_usize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:273:28
    |
 LL | const _NUSIZE_MOD: usize = 1usize % 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NUSIZE_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_usize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:274:32
    |
 LL | const _NUSIZE_MOD_P: &usize = &(1usize % 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NUSIZE_MOD_P` failed here
 
 error[E0080]: index out of bounds: the length is 3 but the index is 4
   --> $DIR/overflowing-consts.rs:277:24
    |
 LL | const _NI32_OOB: i32 = [1, 2, 3][4];
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI32_OOB` failed here
 
 error[E0080]: index out of bounds: the length is 3 but the index is 4
   --> $DIR/overflowing-consts.rs:278:28
    |
 LL | const _NI32_OOB_P: &i32 = &([1, 2, 3][4]);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI32_OOB_P` failed here
 
 error: aborting due to 170 previous errors
 
diff --git a/tests/ui/consts/overflowing-consts.opt_with_overflow_checks.stderr b/tests/ui/consts/overflowing-consts.opt_with_overflow_checks.stderr
index e317060a141..1ef2a60b647 100644
--- a/tests/ui/consts/overflowing-consts.opt_with_overflow_checks.stderr
+++ b/tests/ui/consts/overflowing-consts.opt_with_overflow_checks.stderr
@@ -2,1021 +2,1021 @@ error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:18:22
    |
 LL | const _NI8_SHL: i8 = 1i8 << 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NI8_SHL` failed here
 
 error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:19:26
    |
 LL | const _NI8_SHL_P: &i8 = &(1i8 << 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NI8_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:21:24
    |
 LL | const _NI16_SHL: i16 = 1i16 << 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI16_SHL` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:22:28
    |
 LL | const _NI16_SHL_P: &i16 = &(1i16 << 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI16_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:24:24
    |
 LL | const _NI32_SHL: i32 = 1i32 << 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI32_SHL` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:25:28
    |
 LL | const _NI32_SHL_P: &i32 = &(1i32 << 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI32_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:27:24
    |
 LL | const _NI64_SHL: i64 = 1i64 << 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI64_SHL` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:28:28
    |
 LL | const _NI64_SHL_P: &i64 = &(1i64 << 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI64_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:30:26
    |
 LL | const _NI128_SHL: i128 = 1i128 << 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NI128_SHL` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:31:30
    |
 LL | const _NI128_SHL_P: &i128 = &(1i128 << 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NI128_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:33:22
    |
 LL | const _NU8_SHL: u8 = 1u8 << 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NU8_SHL` failed here
 
 error[E0080]: attempt to shift left by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:34:26
    |
 LL | const _NU8_SHL_P: &u8 = &(1u8 << 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NU8_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:36:24
    |
 LL | const _NU16_SHL: u16 = 1u16 << 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU16_SHL` failed here
 
 error[E0080]: attempt to shift left by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:37:28
    |
 LL | const _NU16_SHL_P: &u16 = &(1u16 << 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU16_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:39:24
    |
 LL | const _NU32_SHL: u32 = 1u32 << 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU32_SHL` failed here
 
 error[E0080]: attempt to shift left by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:40:28
    |
 LL | const _NU32_SHL_P: &u32 = &(1u32 << 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU32_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:42:24
    |
 LL | const _NU64_SHL: u64 = 1u64 << 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU64_SHL` failed here
 
 error[E0080]: attempt to shift left by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:43:28
    |
 LL | const _NU64_SHL_P: &u64 = &(1u64 << 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU64_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:45:26
    |
 LL | const _NU128_SHL: u128 = 1u128 << 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NU128_SHL` failed here
 
 error[E0080]: attempt to shift left by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:46:30
    |
 LL | const _NU128_SHL_P: &u128 = &(1u128 << 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NU128_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:48:28
    |
 LL | const _NISIZE_SHL: isize = 1isize << BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHL` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:49:32
    |
 LL | const _NISIZE_SHL_P: &isize = &(1isize << BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHL_P` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:51:28
    |
 LL | const _NUSIZE_SHL: usize = 1usize << BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHL` failed here
 
 error[E0080]: attempt to shift left by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:52:32
    |
 LL | const _NUSIZE_SHL_P: &usize = &(1usize << BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHL_P` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:55:22
    |
 LL | const _NI8_SHR: i8 = 1i8 >> 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NI8_SHR` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:56:26
    |
 LL | const _NI8_SHR_P: &i8 = &(1i8 >> 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NI8_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:58:24
    |
 LL | const _NI16_SHR: i16 = 1i16 >> 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI16_SHR` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:59:28
    |
 LL | const _NI16_SHR_P: &i16 = &(1i16 >> 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI16_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:61:24
    |
 LL | const _NI32_SHR: i32 = 1i32 >> 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI32_SHR` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:62:28
    |
 LL | const _NI32_SHR_P: &i32 = &(1i32 >> 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI32_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:64:24
    |
 LL | const _NI64_SHR: i64 = 1i64 >> 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NI64_SHR` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:65:28
    |
 LL | const _NI64_SHR_P: &i64 = &(1i64 >> 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NI64_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:67:26
    |
 LL | const _NI128_SHR: i128 = 1i128 >> 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NI128_SHR` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:68:30
    |
 LL | const _NI128_SHR_P: &i128 = &(1i128 >> 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NI128_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:70:22
    |
 LL | const _NU8_SHR: u8 = 1u8 >> 8;
-   |                      ^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^ evaluation of `_NU8_SHR` failed here
 
 error[E0080]: attempt to shift right by `8_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:71:26
    |
 LL | const _NU8_SHR_P: &u8 = &(1u8 >> 8);
-   |                          ^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^ evaluation of `_NU8_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:73:24
    |
 LL | const _NU16_SHR: u16 = 1u16 >> 16;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU16_SHR` failed here
 
 error[E0080]: attempt to shift right by `16_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:74:28
    |
 LL | const _NU16_SHR_P: &u16 = &(1u16 >> 16);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU16_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:76:24
    |
 LL | const _NU32_SHR: u32 = 1u32 >> 32;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU32_SHR` failed here
 
 error[E0080]: attempt to shift right by `32_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:77:28
    |
 LL | const _NU32_SHR_P: &u32 = &(1u32 >> 32);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU32_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:79:24
    |
 LL | const _NU64_SHR: u64 = 1u64 >> 64;
-   |                        ^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^ evaluation of `_NU64_SHR` failed here
 
 error[E0080]: attempt to shift right by `64_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:80:28
    |
 LL | const _NU64_SHR_P: &u64 = &(1u64 >> 64);
-   |                            ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^ evaluation of `_NU64_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:82:26
    |
 LL | const _NU128_SHR: u128 = 1u128 >> 128;
-   |                          ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^ evaluation of `_NU128_SHR` failed here
 
 error[E0080]: attempt to shift right by `128_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:83:30
    |
 LL | const _NU128_SHR_P: &u128 = &(1u128 >> 128);
-   |                              ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^ evaluation of `_NU128_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:85:28
    |
 LL | const _NISIZE_SHR: isize = 1isize >> BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHR` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:86:32
    |
 LL | const _NISIZE_SHR_P: &isize = &(1isize >> BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SHR_P` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:88:28
    |
 LL | const _NUSIZE_SHR: usize = 1usize >> BITS;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHR` failed here
 
 error[E0080]: attempt to shift right by `%BITS%`, which would overflow
   --> $DIR/overflowing-consts.rs:89:32
    |
 LL | const _NUSIZE_SHR_P: &usize = &(1usize >> BITS);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_SHR_P` failed here
 
 error[E0080]: attempt to compute `1_i8 + i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:92:22
    |
 LL | const _NI8_ADD: i8 = 1i8 + i8::MAX;
-   |                      ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^ evaluation of `_NI8_ADD` failed here
 
 error[E0080]: attempt to compute `1_i8 + i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:93:26
    |
 LL | const _NI8_ADD_P: &i8 = &(1i8 + i8::MAX);
-   |                          ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^ evaluation of `_NI8_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i16 + i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:95:24
    |
 LL | const _NI16_ADD: i16 = 1i16 + i16::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NI16_ADD` failed here
 
 error[E0080]: attempt to compute `1_i16 + i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:96:28
    |
 LL | const _NI16_ADD_P: &i16 = &(1i16 + i16::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NI16_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i32 + i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:98:24
    |
 LL | const _NI32_ADD: i32 = 1i32 + i32::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NI32_ADD` failed here
 
 error[E0080]: attempt to compute `1_i32 + i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:99:28
    |
 LL | const _NI32_ADD_P: &i32 = &(1i32 + i32::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NI32_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i64 + i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:101:24
    |
 LL | const _NI64_ADD: i64 = 1i64 + i64::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NI64_ADD` failed here
 
 error[E0080]: attempt to compute `1_i64 + i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:102:28
    |
 LL | const _NI64_ADD_P: &i64 = &(1i64 + i64::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NI64_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_i128 + i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:104:26
    |
 LL | const _NI128_ADD: i128 = 1i128 + i128::MAX;
-   |                          ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^ evaluation of `_NI128_ADD` failed here
 
 error[E0080]: attempt to compute `1_i128 + i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:105:30
    |
 LL | const _NI128_ADD_P: &i128 = &(1i128 + i128::MAX);
-   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of `_NI128_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u8 + u8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:107:22
    |
 LL | const _NU8_ADD: u8 = 1u8 + u8::MAX;
-   |                      ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^ evaluation of `_NU8_ADD` failed here
 
 error[E0080]: attempt to compute `1_u8 + u8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:108:26
    |
 LL | const _NU8_ADD_P: &u8 = &(1u8 + u8::MAX);
-   |                          ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^ evaluation of `_NU8_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u16 + u16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:110:24
    |
 LL | const _NU16_ADD: u16 = 1u16 + u16::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NU16_ADD` failed here
 
 error[E0080]: attempt to compute `1_u16 + u16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:111:28
    |
 LL | const _NU16_ADD_P: &u16 = &(1u16 + u16::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NU16_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u32 + u32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:113:24
    |
 LL | const _NU32_ADD: u32 = 1u32 + u32::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NU32_ADD` failed here
 
 error[E0080]: attempt to compute `1_u32 + u32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:114:28
    |
 LL | const _NU32_ADD_P: &u32 = &(1u32 + u32::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NU32_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u64 + u64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:116:24
    |
 LL | const _NU64_ADD: u64 = 1u64 + u64::MAX;
-   |                        ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^ evaluation of `_NU64_ADD` failed here
 
 error[E0080]: attempt to compute `1_u64 + u64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:117:28
    |
 LL | const _NU64_ADD_P: &u64 = &(1u64 + u64::MAX);
-   |                            ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^ evaluation of `_NU64_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_u128 + u128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:119:26
    |
 LL | const _NU128_ADD: u128 = 1u128 + u128::MAX;
-   |                          ^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^ evaluation of `_NU128_ADD` failed here
 
 error[E0080]: attempt to compute `1_u128 + u128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:120:30
    |
 LL | const _NU128_ADD_P: &u128 = &(1u128 + u128::MAX);
-   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^^^^^ evaluation of `_NU128_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_isize + isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:122:28
    |
 LL | const _NISIZE_ADD: isize = 1isize + isize::MAX;
-   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_ADD` failed here
 
 error[E0080]: attempt to compute `1_isize + isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:123:32
    |
 LL | const _NISIZE_ADD_P: &isize = &(1isize + isize::MAX);
-   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_ADD_P` failed here
 
 error[E0080]: attempt to compute `1_usize + usize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:125:28
    |
 LL | const _NUSIZE_ADD: usize = 1usize + usize::MAX;
-   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_ADD` failed here
 
 error[E0080]: attempt to compute `1_usize + usize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:126:32
    |
 LL | const _NUSIZE_ADD_P: &usize = &(1usize + usize::MAX);
-   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_ADD_P` failed here
 
 error[E0080]: attempt to compute `-5_i8 - i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:129:22
    |
 LL | const _NI8_SUB: i8 = -5i8 - i8::MAX;
-   |                      ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^^^^ evaluation of `_NI8_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i8 - i8::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:130:26
    |
 LL | const _NI8_SUB_P: &i8 = &(-5i8 - i8::MAX);
-   |                          ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^ evaluation of `_NI8_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i16 - i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:132:24
    |
 LL | const _NI16_SUB: i16 = -5i16 - i16::MAX;
-   |                        ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^^ evaluation of `_NI16_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i16 - i16::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:133:28
    |
 LL | const _NI16_SUB_P: &i16 = &(-5i16 - i16::MAX);
-   |                            ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^ evaluation of `_NI16_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i32 - i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:135:24
    |
 LL | const _NI32_SUB: i32 = -5i32 - i32::MAX;
-   |                        ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^^ evaluation of `_NI32_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i32 - i32::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:136:28
    |
 LL | const _NI32_SUB_P: &i32 = &(-5i32 - i32::MAX);
-   |                            ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^ evaluation of `_NI32_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i64 - i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:138:24
    |
 LL | const _NI64_SUB: i64 = -5i64 - i64::MAX;
-   |                        ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^^^^^ evaluation of `_NI64_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i64 - i64::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:139:28
    |
 LL | const _NI64_SUB_P: &i64 = &(-5i64 - i64::MAX);
-   |                            ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^ evaluation of `_NI64_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_i128 - i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:141:26
    |
 LL | const _NI128_SUB: i128 = -5i128 - i128::MAX;
-   |                          ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^^ evaluation of `_NI128_SUB` failed here
 
 error[E0080]: attempt to compute `-5_i128 - i128::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:142:30
    |
 LL | const _NI128_SUB_P: &i128 = &(-5i128 - i128::MAX);
-   |                              ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^^^^^^ evaluation of `_NI128_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u8 - 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:144:22
    |
 LL | const _NU8_SUB: u8 = 1u8 - 5;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NU8_SUB` failed here
 
 error[E0080]: attempt to compute `1_u8 - 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:145:26
    |
 LL | const _NU8_SUB_P: &u8 = &(1u8 - 5);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU8_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u16 - 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:147:24
    |
 LL | const _NU16_SUB: u16 = 1u16 - 5;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU16_SUB` failed here
 
 error[E0080]: attempt to compute `1_u16 - 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:148:28
    |
 LL | const _NU16_SUB_P: &u16 = &(1u16 - 5);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU16_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u32 - 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:150:24
    |
 LL | const _NU32_SUB: u32 = 1u32 - 5;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU32_SUB` failed here
 
 error[E0080]: attempt to compute `1_u32 - 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:151:28
    |
 LL | const _NU32_SUB_P: &u32 = &(1u32 - 5);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU32_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u64 - 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:153:24
    |
 LL | const _NU64_SUB: u64 = 1u64 - 5;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU64_SUB` failed here
 
 error[E0080]: attempt to compute `1_u64 - 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:154:28
    |
 LL | const _NU64_SUB_P: &u64 = &(1u64 - 5);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU64_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_u128 - 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:156:26
    |
 LL | const _NU128_SUB: u128 = 1u128 - 5;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU128_SUB` failed here
 
 error[E0080]: attempt to compute `1_u128 - 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:157:30
    |
 LL | const _NU128_SUB_P: &u128 = &(1u128 - 5);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NU128_SUB_P` failed here
 
 error[E0080]: attempt to compute `-5_isize - isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:159:28
    |
 LL | const _NISIZE_SUB: isize = -5isize - isize::MAX;
-   |                            ^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SUB` failed here
 
 error[E0080]: attempt to compute `-5_isize - isize::MAX`, which would overflow
   --> $DIR/overflowing-consts.rs:160:32
    |
 LL | const _NISIZE_SUB_P: &isize = &(-5isize - isize::MAX);
-   |                                ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_SUB_P` failed here
 
 error[E0080]: attempt to compute `1_usize - 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:162:28
    |
 LL | const _NUSIZE_SUB: usize = 1usize - 5;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NUSIZE_SUB` failed here
 
 error[E0080]: attempt to compute `1_usize - 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:163:32
    |
 LL | const _NUSIZE_SUB_P: &usize = &(1usize - 5);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NUSIZE_SUB_P` failed here
 
 error[E0080]: attempt to compute `i8::MAX * 5_i8`, which would overflow
   --> $DIR/overflowing-consts.rs:166:22
    |
 LL | const _NI8_MUL: i8 = i8::MAX * 5;
-   |                      ^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^ evaluation of `_NI8_MUL` failed here
 
 error[E0080]: attempt to compute `i8::MAX * 5_i8`, which would overflow
   --> $DIR/overflowing-consts.rs:167:26
    |
 LL | const _NI8_MUL_P: &i8 = &(i8::MAX * 5);
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NI8_MUL_P` failed here
 
 error[E0080]: attempt to compute `i16::MAX * 5_i16`, which would overflow
   --> $DIR/overflowing-consts.rs:169:24
    |
 LL | const _NI16_MUL: i16 = i16::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI16_MUL` failed here
 
 error[E0080]: attempt to compute `i16::MAX * 5_i16`, which would overflow
   --> $DIR/overflowing-consts.rs:170:28
    |
 LL | const _NI16_MUL_P: &i16 = &(i16::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI16_MUL_P` failed here
 
 error[E0080]: attempt to compute `i32::MAX * 5_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:172:24
    |
 LL | const _NI32_MUL: i32 = i32::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI32_MUL` failed here
 
 error[E0080]: attempt to compute `i32::MAX * 5_i32`, which would overflow
   --> $DIR/overflowing-consts.rs:173:28
    |
 LL | const _NI32_MUL_P: &i32 = &(i32::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI32_MUL_P` failed here
 
 error[E0080]: attempt to compute `i64::MAX * 5_i64`, which would overflow
   --> $DIR/overflowing-consts.rs:175:24
    |
 LL | const _NI64_MUL: i64 = i64::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI64_MUL` failed here
 
 error[E0080]: attempt to compute `i64::MAX * 5_i64`, which would overflow
   --> $DIR/overflowing-consts.rs:176:28
    |
 LL | const _NI64_MUL_P: &i64 = &(i64::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI64_MUL_P` failed here
 
 error[E0080]: attempt to compute `i128::MAX * 5_i128`, which would overflow
   --> $DIR/overflowing-consts.rs:178:26
    |
 LL | const _NI128_MUL: i128 = i128::MAX * 5;
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NI128_MUL` failed here
 
 error[E0080]: attempt to compute `i128::MAX * 5_i128`, which would overflow
   --> $DIR/overflowing-consts.rs:179:30
    |
 LL | const _NI128_MUL_P: &i128 = &(i128::MAX * 5);
-   |                              ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^ evaluation of `_NI128_MUL_P` failed here
 
 error[E0080]: attempt to compute `u8::MAX * 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:181:22
    |
 LL | const _NU8_MUL: u8 = u8::MAX * 5;
-   |                      ^^^^^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^^^^^ evaluation of `_NU8_MUL` failed here
 
 error[E0080]: attempt to compute `u8::MAX * 5_u8`, which would overflow
   --> $DIR/overflowing-consts.rs:182:26
    |
 LL | const _NU8_MUL_P: &u8 = &(u8::MAX * 5);
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NU8_MUL_P` failed here
 
 error[E0080]: attempt to compute `u16::MAX * 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:184:24
    |
 LL | const _NU16_MUL: u16 = u16::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NU16_MUL` failed here
 
 error[E0080]: attempt to compute `u16::MAX * 5_u16`, which would overflow
   --> $DIR/overflowing-consts.rs:185:28
    |
 LL | const _NU16_MUL_P: &u16 = &(u16::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NU16_MUL_P` failed here
 
 error[E0080]: attempt to compute `u32::MAX * 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:187:24
    |
 LL | const _NU32_MUL: u32 = u32::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NU32_MUL` failed here
 
 error[E0080]: attempt to compute `u32::MAX * 5_u32`, which would overflow
   --> $DIR/overflowing-consts.rs:188:28
    |
 LL | const _NU32_MUL_P: &u32 = &(u32::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NU32_MUL_P` failed here
 
 error[E0080]: attempt to compute `u64::MAX * 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:190:24
    |
 LL | const _NU64_MUL: u64 = u64::MAX * 5;
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NU64_MUL` failed here
 
 error[E0080]: attempt to compute `u64::MAX * 5_u64`, which would overflow
   --> $DIR/overflowing-consts.rs:191:28
    |
 LL | const _NU64_MUL_P: &u64 = &(u64::MAX * 5);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NU64_MUL_P` failed here
 
 error[E0080]: attempt to compute `u128::MAX * 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:193:26
    |
 LL | const _NU128_MUL: u128 = u128::MAX * 5;
-   |                          ^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^ evaluation of `_NU128_MUL` failed here
 
 error[E0080]: attempt to compute `u128::MAX * 5_u128`, which would overflow
   --> $DIR/overflowing-consts.rs:194:30
    |
 LL | const _NU128_MUL_P: &u128 = &(u128::MAX * 5);
-   |                              ^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^^^^^ evaluation of `_NU128_MUL_P` failed here
 
 error[E0080]: attempt to compute `isize::MAX * 5_isize`, which would overflow
   --> $DIR/overflowing-consts.rs:196:28
    |
 LL | const _NISIZE_MUL: isize = isize::MAX * 5;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NISIZE_MUL` failed here
 
 error[E0080]: attempt to compute `isize::MAX * 5_isize`, which would overflow
   --> $DIR/overflowing-consts.rs:197:32
    |
 LL | const _NISIZE_MUL_P: &isize = &(isize::MAX * 5);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NISIZE_MUL_P` failed here
 
 error[E0080]: attempt to compute `usize::MAX * 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:199:28
    |
 LL | const _NUSIZE_MUL: usize = usize::MAX * 5;
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NUSIZE_MUL` failed here
 
 error[E0080]: attempt to compute `usize::MAX * 5_usize`, which would overflow
   --> $DIR/overflowing-consts.rs:200:32
    |
 LL | const _NUSIZE_MUL_P: &usize = &(usize::MAX * 5);
-   |                                ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^ evaluation of `_NUSIZE_MUL_P` failed here
 
 error[E0080]: attempt to divide `1_i8` by zero
   --> $DIR/overflowing-consts.rs:203:22
    |
 LL | const _NI8_DIV: i8 = 1i8 / 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NI8_DIV` failed here
 
 error[E0080]: attempt to divide `1_i8` by zero
   --> $DIR/overflowing-consts.rs:204:26
    |
 LL | const _NI8_DIV_P: &i8 = &(1i8 / 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI8_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i16` by zero
   --> $DIR/overflowing-consts.rs:206:24
    |
 LL | const _NI16_DIV: i16 = 1i16 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI16_DIV` failed here
 
 error[E0080]: attempt to divide `1_i16` by zero
   --> $DIR/overflowing-consts.rs:207:28
    |
 LL | const _NI16_DIV_P: &i16 = &(1i16 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI16_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i32` by zero
   --> $DIR/overflowing-consts.rs:209:24
    |
 LL | const _NI32_DIV: i32 = 1i32 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI32_DIV` failed here
 
 error[E0080]: attempt to divide `1_i32` by zero
   --> $DIR/overflowing-consts.rs:210:28
    |
 LL | const _NI32_DIV_P: &i32 = &(1i32 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI32_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i64` by zero
   --> $DIR/overflowing-consts.rs:212:24
    |
 LL | const _NI64_DIV: i64 = 1i64 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI64_DIV` failed here
 
 error[E0080]: attempt to divide `1_i64` by zero
   --> $DIR/overflowing-consts.rs:213:28
    |
 LL | const _NI64_DIV_P: &i64 = &(1i64 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI64_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_i128` by zero
   --> $DIR/overflowing-consts.rs:215:26
    |
 LL | const _NI128_DIV: i128 = 1i128 / 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI128_DIV` failed here
 
 error[E0080]: attempt to divide `1_i128` by zero
   --> $DIR/overflowing-consts.rs:216:30
    |
 LL | const _NI128_DIV_P: &i128 = &(1i128 / 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NI128_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u8` by zero
   --> $DIR/overflowing-consts.rs:218:22
    |
 LL | const _NU8_DIV: u8 = 1u8 / 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NU8_DIV` failed here
 
 error[E0080]: attempt to divide `1_u8` by zero
   --> $DIR/overflowing-consts.rs:219:26
    |
 LL | const _NU8_DIV_P: &u8 = &(1u8 / 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU8_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u16` by zero
   --> $DIR/overflowing-consts.rs:221:24
    |
 LL | const _NU16_DIV: u16 = 1u16 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU16_DIV` failed here
 
 error[E0080]: attempt to divide `1_u16` by zero
   --> $DIR/overflowing-consts.rs:222:28
    |
 LL | const _NU16_DIV_P: &u16 = &(1u16 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU16_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u32` by zero
   --> $DIR/overflowing-consts.rs:224:24
    |
 LL | const _NU32_DIV: u32 = 1u32 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU32_DIV` failed here
 
 error[E0080]: attempt to divide `1_u32` by zero
   --> $DIR/overflowing-consts.rs:225:28
    |
 LL | const _NU32_DIV_P: &u32 = &(1u32 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU32_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u64` by zero
   --> $DIR/overflowing-consts.rs:227:24
    |
 LL | const _NU64_DIV: u64 = 1u64 / 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU64_DIV` failed here
 
 error[E0080]: attempt to divide `1_u64` by zero
   --> $DIR/overflowing-consts.rs:228:28
    |
 LL | const _NU64_DIV_P: &u64 = &(1u64 / 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU64_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_u128` by zero
   --> $DIR/overflowing-consts.rs:230:26
    |
 LL | const _NU128_DIV: u128 = 1u128 / 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU128_DIV` failed here
 
 error[E0080]: attempt to divide `1_u128` by zero
   --> $DIR/overflowing-consts.rs:231:30
    |
 LL | const _NU128_DIV_P: &u128 = &(1u128 / 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NU128_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_isize` by zero
   --> $DIR/overflowing-consts.rs:233:28
    |
 LL | const _NISIZE_DIV: isize = 1isize / 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NISIZE_DIV` failed here
 
 error[E0080]: attempt to divide `1_isize` by zero
   --> $DIR/overflowing-consts.rs:234:32
    |
 LL | const _NISIZE_DIV_P: &isize = &(1isize / 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NISIZE_DIV_P` failed here
 
 error[E0080]: attempt to divide `1_usize` by zero
   --> $DIR/overflowing-consts.rs:236:28
    |
 LL | const _NUSIZE_DIV: usize = 1usize / 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NUSIZE_DIV` failed here
 
 error[E0080]: attempt to divide `1_usize` by zero
   --> $DIR/overflowing-consts.rs:237:32
    |
 LL | const _NUSIZE_DIV_P: &usize = &(1usize / 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NUSIZE_DIV_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:240:22
    |
 LL | const _NI8_MOD: i8 = 1i8 % 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NI8_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:241:26
    |
 LL | const _NI8_MOD_P: &i8 = &(1i8 % 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI8_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:243:24
    |
 LL | const _NI16_MOD: i16 = 1i16 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI16_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:244:28
    |
 LL | const _NI16_MOD_P: &i16 = &(1i16 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI16_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:246:24
    |
 LL | const _NI32_MOD: i32 = 1i32 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI32_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:247:28
    |
 LL | const _NI32_MOD_P: &i32 = &(1i32 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI32_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:249:24
    |
 LL | const _NI64_MOD: i64 = 1i64 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NI64_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:250:28
    |
 LL | const _NI64_MOD_P: &i64 = &(1i64 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NI64_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:252:26
    |
 LL | const _NI128_MOD: i128 = 1i128 % 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NI128_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_i128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:253:30
    |
 LL | const _NI128_MOD_P: &i128 = &(1i128 % 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NI128_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:255:22
    |
 LL | const _NU8_MOD: u8 = 1u8 % 0;
-   |                      ^^^^^^^ evaluation of constant value failed here
+   |                      ^^^^^^^ evaluation of `_NU8_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u8` with a divisor of zero
   --> $DIR/overflowing-consts.rs:256:26
    |
 LL | const _NU8_MOD_P: &u8 = &(1u8 % 0);
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU8_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:258:24
    |
 LL | const _NU16_MOD: u16 = 1u16 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU16_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u16` with a divisor of zero
   --> $DIR/overflowing-consts.rs:259:28
    |
 LL | const _NU16_MOD_P: &u16 = &(1u16 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU16_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:261:24
    |
 LL | const _NU32_MOD: u32 = 1u32 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU32_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u32` with a divisor of zero
   --> $DIR/overflowing-consts.rs:262:28
    |
 LL | const _NU32_MOD_P: &u32 = &(1u32 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU32_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:264:24
    |
 LL | const _NU64_MOD: u64 = 1u64 % 0;
-   |                        ^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^ evaluation of `_NU64_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u64` with a divisor of zero
   --> $DIR/overflowing-consts.rs:265:28
    |
 LL | const _NU64_MOD_P: &u64 = &(1u64 % 0);
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NU64_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:267:26
    |
 LL | const _NU128_MOD: u128 = 1u128 % 0;
-   |                          ^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^ evaluation of `_NU128_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_u128` with a divisor of zero
   --> $DIR/overflowing-consts.rs:268:30
    |
 LL | const _NU128_MOD_P: &u128 = &(1u128 % 0);
-   |                              ^^^^^^^^^^^ evaluation of constant value failed here
+   |                              ^^^^^^^^^^^ evaluation of `_NU128_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_isize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:270:28
    |
 LL | const _NISIZE_MOD: isize = 1isize % 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NISIZE_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_isize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:271:32
    |
 LL | const _NISIZE_MOD_P: &isize = &(1isize % 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NISIZE_MOD_P` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_usize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:273:28
    |
 LL | const _NUSIZE_MOD: usize = 1usize % 0;
-   |                            ^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^ evaluation of `_NUSIZE_MOD` failed here
 
 error[E0080]: attempt to calculate the remainder of `1_usize` with a divisor of zero
   --> $DIR/overflowing-consts.rs:274:32
    |
 LL | const _NUSIZE_MOD_P: &usize = &(1usize % 0);
-   |                                ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^ evaluation of `_NUSIZE_MOD_P` failed here
 
 error[E0080]: index out of bounds: the length is 3 but the index is 4
   --> $DIR/overflowing-consts.rs:277:24
    |
 LL | const _NI32_OOB: i32 = [1, 2, 3][4];
-   |                        ^^^^^^^^^^^^ evaluation of constant value failed here
+   |                        ^^^^^^^^^^^^ evaluation of `_NI32_OOB` failed here
 
 error[E0080]: index out of bounds: the length is 3 but the index is 4
   --> $DIR/overflowing-consts.rs:278:28
    |
 LL | const _NI32_OOB_P: &i32 = &([1, 2, 3][4]);
-   |                            ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                            ^^^^^^^^^^^^^^ evaluation of `_NI32_OOB_P` failed here
 
 error: aborting due to 170 previous errors
 
diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr
index 6c09a1faed2..a5a50c580d0 100644
--- a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr
+++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr
@@ -2,7 +2,7 @@ error[E0080]: tried to allocate more memory than available to compiler
   --> $DIR/promoted_running_out_of_memory_issue-130687.rs:13:32
    |
 LL | const _: &'static Data = &Data([0; (1 << 47) - 1]);
-   |                                ^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                                ^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/promoted_size_overflow.stderr b/tests/ui/consts/promoted_size_overflow.stderr
index 226c78ec01b..529b232c77c 100644
--- a/tests/ui/consts/promoted_size_overflow.stderr
+++ b/tests/ui/consts/promoted_size_overflow.stderr
@@ -2,7 +2,7 @@ error[E0080]: values of the type `[u8; 4611686018427387903]` are too big for the
   --> $DIR/promoted_size_overflow.rs:3:29
    |
 LL | const _: &'static [Data] = &[];
-   |                             ^^ evaluation of constant value failed here
+   |                             ^^ evaluation of `_` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.stderr b/tests/ui/consts/qualif-indirect-mutation-fail.stderr
index 6cd7741103f..79724ee8d6a 100644
--- a/tests/ui/consts/qualif-indirect-mutation-fail.stderr
+++ b/tests/ui/consts/qualif-indirect-mutation-fail.stderr
@@ -11,7 +11,7 @@ error[E0080]: calling non-const function `<Vec<u8> as Drop>::drop`
   --> $DIR/qualif-indirect-mutation-fail.rs:18:1
    |
 LL | };
-   | ^ evaluation of constant value failed here
+   | ^ evaluation of `A1` failed inside this call
    |
 note: inside `drop_in_place::<Option<String>> - shim(Some(Option<String>))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
@@ -32,7 +32,7 @@ error[E0080]: calling non-const function `<Vec<u8> as Drop>::drop`
   --> $DIR/qualif-indirect-mutation-fail.rs:29:1
    |
 LL | };
-   | ^ evaluation of constant value failed here
+   | ^ evaluation of `A2` failed inside this call
    |
 note: inside `drop_in_place::<Option<String>> - shim(Some(Option<String>))`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
diff --git a/tests/ui/consts/recursive-zst-static.default.stderr b/tests/ui/consts/recursive-zst-static.default.stderr
index 80661825d53..fee33a892d0 100644
--- a/tests/ui/consts/recursive-zst-static.default.stderr
+++ b/tests/ui/consts/recursive-zst-static.default.stderr
@@ -2,7 +2,7 @@ error[E0080]: encountered static that tried to initialize itself with itself
   --> $DIR/recursive-zst-static.rs:10:18
    |
 LL | static FOO: () = FOO;
-   |                  ^^^ evaluation of static initializer failed here
+   |                  ^^^ evaluation of `FOO` failed here
 
 error[E0391]: cycle detected when evaluating initializer of static `A`
   --> $DIR/recursive-zst-static.rs:13:16
diff --git a/tests/ui/consts/recursive-zst-static.unleash.stderr b/tests/ui/consts/recursive-zst-static.unleash.stderr
index 80661825d53..fee33a892d0 100644
--- a/tests/ui/consts/recursive-zst-static.unleash.stderr
+++ b/tests/ui/consts/recursive-zst-static.unleash.stderr
@@ -2,7 +2,7 @@ error[E0080]: encountered static that tried to initialize itself with itself
   --> $DIR/recursive-zst-static.rs:10:18
    |
 LL | static FOO: () = FOO;
-   |                  ^^^ evaluation of static initializer failed here
+   |                  ^^^ evaluation of `FOO` failed here
 
 error[E0391]: cycle detected when evaluating initializer of static `A`
   --> $DIR/recursive-zst-static.rs:13:16
diff --git a/tests/ui/consts/recursive.stderr b/tests/ui/consts/recursive.stderr
index 97fa9e7e75e..a382fabf7b7 100644
--- a/tests/ui/consts/recursive.stderr
+++ b/tests/ui/consts/recursive.stderr
@@ -13,7 +13,7 @@ error[E0080]: reached the configured maximum number of stack frames
   --> $DIR/recursive.rs:7:15
    |
 LL | const X: () = f(1);
-   |               ^^^^ evaluation of constant value failed here
+   |               ^^^^ evaluation of `X` failed inside this call
    |
 note: [... 126 additional calls inside `f::<i32>` ...]
   --> $DIR/recursive.rs:4:5
diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr b/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr
index b14c9aff7ba..12c5acd02a4 100644
--- a/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr
+++ b/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr
@@ -2,7 +2,7 @@ error[E0080]: entering unreachable code
   --> $DIR/interpret-in-promoted.rs:15:28
    |
 LL |     let _x: &'static () = &ub();
-   |                            ^^^^ evaluation of constant value failed here
+   |                            ^^^^ evaluation of `FOO` failed inside this call
    |
 note: inside `ub`
   --> $DIR/interpret-in-promoted.rs:9:5
diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr b/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr
index b14c9aff7ba..12c5acd02a4 100644
--- a/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr
+++ b/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr
@@ -2,7 +2,7 @@ error[E0080]: entering unreachable code
   --> $DIR/interpret-in-promoted.rs:15:28
    |
 LL |     let _x: &'static () = &ub();
-   |                            ^^^^ evaluation of constant value failed here
+   |                            ^^^^ evaluation of `FOO` failed inside this call
    |
 note: inside `ub`
   --> $DIR/interpret-in-promoted.rs:9:5
diff --git a/tests/ui/consts/slice-index-overflow-issue-130284.stderr b/tests/ui/consts/slice-index-overflow-issue-130284.stderr
index 641aed349dd..63c355b4b0f 100644
--- a/tests/ui/consts/slice-index-overflow-issue-130284.stderr
+++ b/tests/ui/consts/slice-index-overflow-issue-130284.stderr
@@ -2,7 +2,7 @@ error[E0080]: overflowing pointer arithmetic: the total offset in bytes does not
   --> $DIR/slice-index-overflow-issue-130284.rs:7:20
    |
 LL |         let _ice = (*fat)[usize::MAX - 1];
-   |                    ^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `C` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/static_mut_containing_mut_ref2.stderr b/tests/ui/consts/static_mut_containing_mut_ref2.stderr
index 49b35dacd3a..556a4d956ed 100644
--- a/tests/ui/consts/static_mut_containing_mut_ref2.stderr
+++ b/tests/ui/consts/static_mut_containing_mut_ref2.stderr
@@ -2,7 +2,7 @@ error[E0080]: modifying a static's initial value from another static's initializ
   --> $DIR/static_mut_containing_mut_ref2.rs:6:5
    |
 LL |     *(&mut STDERR_BUFFER_SPACE) = 42;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `STDERR_BUFFER` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/static_mut_containing_mut_ref3.stderr b/tests/ui/consts/static_mut_containing_mut_ref3.stderr
index 71d701434a3..b8ad2310a78 100644
--- a/tests/ui/consts/static_mut_containing_mut_ref3.stderr
+++ b/tests/ui/consts/static_mut_containing_mut_ref3.stderr
@@ -2,7 +2,7 @@ error[E0080]: modifying a static's initial value from another static's initializ
   --> $DIR/static_mut_containing_mut_ref3.rs:3:31
    |
 LL | static mut BAR: () = unsafe { FOO.0 = 99; };
-   |                               ^^^^^^^^^^ evaluation of static initializer failed here
+   |                               ^^^^^^^^^^ evaluation of `BAR` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/uninhabited-const-issue-61744.rs b/tests/ui/consts/uninhabited-const-issue-61744.rs
index d33f9c268a5..56f0939ef18 100644
--- a/tests/ui/consts/uninhabited-const-issue-61744.rs
+++ b/tests/ui/consts/uninhabited-const-issue-61744.rs
@@ -11,6 +11,7 @@ pub const unsafe fn hint_unreachable() -> ! {
 
 trait Const {
     const CONSTANT: i32 = unsafe { fake_type() }; //~ ERROR reached the configured maximum number of stack frames
+    //~^ NOTE evaluation of `<i32 as Const>::CONSTANT` failed inside this call
 }
 
 impl<T> Const for T {}
diff --git a/tests/ui/consts/uninhabited-const-issue-61744.stderr b/tests/ui/consts/uninhabited-const-issue-61744.stderr
index 3c5b5196aeb..cae4f8c3323 100644
--- a/tests/ui/consts/uninhabited-const-issue-61744.stderr
+++ b/tests/ui/consts/uninhabited-const-issue-61744.stderr
@@ -2,7 +2,7 @@ error[E0080]: reached the configured maximum number of stack frames
   --> $DIR/uninhabited-const-issue-61744.rs:13:36
    |
 LL |     const CONSTANT: i32 = unsafe { fake_type() };
-   |                                    ^^^^^^^^^^^ evaluation of `fake_type::<!>` failed here
+   |                                    ^^^^^^^^^^^ evaluation of `<i32 as Const>::CONSTANT` failed inside this call
    |
 note: inside `fake_type::<i32>`
   --> $DIR/uninhabited-const-issue-61744.rs:5:5
diff --git a/tests/ui/consts/write-to-static-mut-in-static.stderr b/tests/ui/consts/write-to-static-mut-in-static.stderr
index c98c7d895fc..bb5e217afb9 100644
--- a/tests/ui/consts/write-to-static-mut-in-static.stderr
+++ b/tests/ui/consts/write-to-static-mut-in-static.stderr
@@ -2,13 +2,13 @@ error[E0080]: modifying a static's initial value from another static's initializ
   --> $DIR/write-to-static-mut-in-static.rs:2:33
    |
 LL | pub static mut B: () = unsafe { A = 1; };
-   |                                 ^^^^^ evaluation of static initializer failed here
+   |                                 ^^^^^ evaluation of `B` failed here
 
 error[E0080]: encountered static that tried to initialize itself with itself
   --> $DIR/write-to-static-mut-in-static.rs:7:21
    |
 LL | pub static D: u32 = D;
-   |                     ^ evaluation of static initializer failed here
+   |                     ^ evaluation of `D` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/coroutine/unresolved-ct-var.stderr b/tests/ui/coroutine/unresolved-ct-var.stderr
index da2ec272f9f..86b73e4b062 100644
--- a/tests/ui/coroutine/unresolved-ct-var.stderr
+++ b/tests/ui/coroutine/unresolved-ct-var.stderr
@@ -2,15 +2,18 @@ error[E0277]: `[(); _]` is not a future
   --> $DIR/unresolved-ct-var.rs:6:45
    |
 LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ----------------------------^^^^^
-   |                 |                          ||
-   |                 |                          |`[(); _]` is not a future
-   |                 |                          help: remove the `.await`
+   |                 --------------------------- ^^^^^ `[(); _]` is not a future
+   |                 |
    |                 this call returns `[(); _]`
    |
    = help: the trait `Future` is not implemented for `[(); _]`
    = note: [(); _] must be a future or must implement `IntoFuture` to be awaited
    = note: required for `[(); _]` to implement `IntoFuture`
+help: remove the `.await`
+   |
+LL -         let s = std::array::from_fn(|_| ()).await;
+LL +         let s = std::array::from_fn(|_| ());
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs b/tests/ui/cross-crate/auxiliary/method_reexport_aux.rs
index 06413e13526..7579f033dc6 100644
--- a/tests/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs
+++ b/tests/ui/cross-crate/auxiliary/method_reexport_aux.rs
@@ -1,4 +1,6 @@
-#![crate_name="crate_method_reexport_grrrrrrr2"]
+//! Used by `tests/ui/cross-crate/cross-crate-method-reexport.rs`
+
+#![crate_name="method_reexport_aux"]
 
 pub use name_pool::add;
 
diff --git a/tests/ui/crate-method-reexport-grrrrrrr.rs b/tests/ui/cross-crate/cross-crate-method-reexport.rs
index aca399f4e20..e9eab99e214 100644
--- a/tests/ui/crate-method-reexport-grrrrrrr.rs
+++ b/tests/ui/cross-crate/cross-crate-method-reexport.rs
@@ -4,13 +4,13 @@
 // name_pool::methods impl in the other crate is reachable from this
 // crate.
 
-//@ aux-build:crate-method-reexport-grrrrrrr2.rs
+//@ aux-build:method_reexport_aux.rs
 
-extern crate crate_method_reexport_grrrrrrr2;
+extern crate method_reexport_aux;
 
 pub fn main() {
-    use crate_method_reexport_grrrrrrr2::rust::add;
-    use crate_method_reexport_grrrrrrr2::rust::cx;
+    use method_reexport_aux::rust::add;
+    use method_reexport_aux::rust::cx;
     let x: Box<_> = Box::new(());
     x.cx();
     let y = ();
diff --git a/tests/ui/default-method-parsing.rs b/tests/ui/default-method-parsing.rs
deleted file mode 100644
index 84c3ab747c8..00000000000
--- a/tests/ui/default-method-parsing.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ check-pass
-
-trait Foo {
-    fn m(&self, _:isize) { }
-}
-
-pub fn main() { }
diff --git a/tests/ui/deprecation/deprecated_no_stack_check.rs b/tests/ui/deprecation/deprecated_no_stack_check.rs
index 8e1f5bbf045..ef482098634 100644
--- a/tests/ui/deprecation/deprecated_no_stack_check.rs
+++ b/tests/ui/deprecation/deprecated_no_stack_check.rs
@@ -1,3 +1,5 @@
+//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION"
+
 #![deny(warnings)]
 #![feature(no_stack_check)]
 //~^ ERROR: feature has been removed [E0557]
diff --git a/tests/ui/deprecation/deprecated_no_stack_check.stderr b/tests/ui/deprecation/deprecated_no_stack_check.stderr
index d78ca20f10b..2d08b1b8db5 100644
--- a/tests/ui/deprecation/deprecated_no_stack_check.stderr
+++ b/tests/ui/deprecation/deprecated_no_stack_check.stderr
@@ -1,8 +1,10 @@
 error[E0557]: feature has been removed
-  --> $DIR/deprecated_no_stack_check.rs:2:12
+  --> $DIR/deprecated_no_stack_check.rs:4:12
    |
 LL | #![feature(no_stack_check)]
    |            ^^^^^^^^^^^^^^ feature has been removed
+   |
+   = note: removed in 1.0.0 (you are using $RUSTC_VERSION); see <https://github.com/rust-lang/rust/pull/40110> for more information
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/command-line-diagnostics.rs b/tests/ui/diagnostic-width/command-line-error-format-human.rs
index 8a6cf5b8e32..a2cfbbcbeb1 100644
--- a/tests/ui/command-line-diagnostics.rs
+++ b/tests/ui/diagnostic-width/command-line-error-format-human.rs
@@ -1,4 +1,5 @@
-// This test checks the output format without the intermediate json representation
+//! This test checks the output format without the intermediate json representation
+
 //@ compile-flags: --error-format=human
 
 pub fn main() {
diff --git a/tests/ui/command-line-diagnostics.stderr b/tests/ui/diagnostic-width/command-line-error-format-human.stderr
index 6d33fb4172f..b4b78239f88 100644
--- a/tests/ui/command-line-diagnostics.stderr
+++ b/tests/ui/diagnostic-width/command-line-error-format-human.stderr
@@ -1,5 +1,5 @@
 error[E0384]: cannot assign twice to immutable variable `x`
-  --> $DIR/command-line-diagnostics.rs:6:5
+  --> $DIR/command-line-error-format-human.rs:7:5
    |
 LL |     let x = 42;
    |         - first assignment to `x`
diff --git a/tests/ui/conservative_impl_trait.rs b/tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.rs
index b7f795eadb7..05588932395 100644
--- a/tests/ui/conservative_impl_trait.rs
+++ b/tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.rs
@@ -1,4 +1,4 @@
-// #39872, #39553
+//! Test for #39872 and #39553
 
 fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
     //~^ ERROR `()` is not an iterator
diff --git a/tests/ui/conservative_impl_trait.stderr b/tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.stderr
index eecdb6f9266..0146fa7a28b 100644
--- a/tests/ui/conservative_impl_trait.stderr
+++ b/tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `()` is not an iterator
-  --> $DIR/conservative_impl_trait.rs:3:33
+  --> $DIR/impl-trait-invalid-iterator-error.rs:3:33
    |
 LL | fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
diff --git a/tests/ui/drop/drop-order-comparisons.e2021.fixed b/tests/ui/drop/drop-order-comparisons.e2021.fixed
index 6c8d2d3fa9c..42f805923ec 100644
--- a/tests/ui/drop/drop-order-comparisons.e2021.fixed
+++ b/tests/ui/drop/drop-order-comparisons.e2021.fixed
@@ -589,7 +589,7 @@ impl Events {
         Ok(LogDrop(self, m))
     }
     /// Return an `Err` value that logs its drop.
-    fn err(&self, m: u64) -> Result<LogDrop, LogDrop> {
+    fn err(&self, m: u64) -> Result<LogDrop<'_>, LogDrop<'_>> {
         Err(LogDrop(self, m))
     }
     /// Log an event.
diff --git a/tests/ui/drop/drop-order-comparisons.rs b/tests/ui/drop/drop-order-comparisons.rs
index 9a10a08a3ff..e7425159aa2 100644
--- a/tests/ui/drop/drop-order-comparisons.rs
+++ b/tests/ui/drop/drop-order-comparisons.rs
@@ -589,7 +589,7 @@ impl Events {
         Ok(LogDrop(self, m))
     }
     /// Return an `Err` value that logs its drop.
-    fn err(&self, m: u64) -> Result<LogDrop, LogDrop> {
+    fn err(&self, m: u64) -> Result<LogDrop<'_>, LogDrop<'_>> {
         Err(LogDrop(self, m))
     }
     /// Log an event.
diff --git a/tests/ui/drop/drop_order.rs b/tests/ui/drop/drop_order.rs
index b96e55a2535..34b1a0e8f75 100644
--- a/tests/ui/drop/drop_order.rs
+++ b/tests/ui/drop/drop_order.rs
@@ -23,11 +23,11 @@ impl Drop for LoudDrop<'_> {
 }
 
 impl DropOrderCollector {
-    fn option_loud_drop(&self, n: u32) -> Option<LoudDrop> {
+    fn option_loud_drop(&self, n: u32) -> Option<LoudDrop<'_>> {
         Some(LoudDrop(self, n))
     }
 
-    fn loud_drop(&self, n: u32) -> LoudDrop {
+    fn loud_drop(&self, n: u32) -> LoudDrop<'_> {
         LoudDrop(self, n)
     }
 
diff --git a/tests/ui/drop/drop_order_if_let_rescope.rs b/tests/ui/drop/drop_order_if_let_rescope.rs
index 27bced5fa62..e96ceedd5cb 100644
--- a/tests/ui/drop/drop_order_if_let_rescope.rs
+++ b/tests/ui/drop/drop_order_if_let_rescope.rs
@@ -18,7 +18,7 @@ impl Drop for LoudDrop<'_> {
 }
 
 impl DropOrderCollector {
-    fn option_loud_drop(&self, n: u32) -> Option<LoudDrop> {
+    fn option_loud_drop(&self, n: u32) -> Option<LoudDrop<'_>> {
         Some(LoudDrop(self, n))
     }
 
diff --git a/tests/ui/drop/for-expr-temporary-drop-scope.rs b/tests/ui/drop/for-expr-temporary-drop-scope.rs
new file mode 100644
index 00000000000..c6f80842ee6
--- /dev/null
+++ b/tests/ui/drop/for-expr-temporary-drop-scope.rs
@@ -0,0 +1,33 @@
+//! Check that temporaries in the for into-iterable expr are not dropped
+//! until the end of the for expr.
+
+//@ run-pass
+
+static mut FLAGS: u64 = 0;
+
+struct AddFlags {
+    bits: u64,
+}
+
+impl Drop for AddFlags {
+    fn drop(&mut self) {
+        unsafe {
+            FLAGS += self.bits;
+        }
+    }
+}
+
+fn check_flags(expected: u64) {
+    unsafe {
+        let actual = FLAGS;
+        FLAGS = 0;
+        assert_eq!(actual, expected, "flags {}, expected {}", actual, expected);
+    }
+}
+
+fn main() {
+    for _ in &[AddFlags { bits: 1 }] {
+        check_flags(0);
+    }
+    check_flags(1);
+}
diff --git a/tests/ui/drop/issue-2735-2.rs b/tests/ui/drop/issue-2735-2.rs
index 7a6ed6ea2f8..43fbafe7a0e 100644
--- a/tests/ui/drop/issue-2735-2.rs
+++ b/tests/ui/drop/issue-2735-2.rs
@@ -1,27 +1,24 @@
 //@ run-pass
-#![allow(non_camel_case_types)]
 
 use std::cell::Cell;
 
 // This test should behave exactly like issue-2735-3
-struct defer<'a> {
+struct Defer<'a> {
     b: &'a Cell<bool>,
 }
 
-impl<'a> Drop for defer<'a> {
+impl<'a> Drop for Defer<'a> {
     fn drop(&mut self) {
         self.b.set(true);
     }
 }
 
-fn defer(b: &Cell<bool>) -> defer {
-    defer {
-        b: b
-    }
+fn defer(b: &Cell<bool>) -> Defer<'_> {
+    Defer { b }
 }
 
 pub fn main() {
     let dtor_ran = &Cell::new(false);
-    let _  = defer(dtor_ran);
+    let _ = defer(dtor_ran);
     assert!(dtor_ran.get());
 }
diff --git a/tests/ui/drop/issue-2735-3.rs b/tests/ui/drop/issue-2735-3.rs
index 3bb4536537c..cc28f96d2b0 100644
--- a/tests/ui/drop/issue-2735-3.rs
+++ b/tests/ui/drop/issue-2735-3.rs
@@ -1,23 +1,20 @@
 //@ run-pass
-#![allow(non_camel_case_types)]
 
 use std::cell::Cell;
 
 // This test should behave exactly like issue-2735-2
-struct defer<'a> {
+struct Defer<'a> {
     b: &'a Cell<bool>,
 }
 
-impl<'a> Drop for defer<'a> {
+impl<'a> Drop for Defer<'a> {
     fn drop(&mut self) {
         self.b.set(true);
     }
 }
 
-fn defer(b: &Cell<bool>) -> defer {
-    defer {
-        b: b
-    }
+fn defer(b: &Cell<bool>) -> Defer<'_> {
+    Defer { b }
 }
 
 pub fn main() {
diff --git a/tests/ui/drop/issue-2735.rs b/tests/ui/drop/issue-2735.rs
index cd7e0b8f461..838b9da109b 100644
--- a/tests/ui/drop/issue-2735.rs
+++ b/tests/ui/drop/issue-2735.rs
@@ -1,15 +1,13 @@
 //@ run-pass
 #![allow(dead_code)]
-#![allow(non_camel_case_types)]
 
-
-trait hax {
-    fn dummy(&self) { }
+trait Hax {
+    fn dummy(&self) {}
 }
-impl<A> hax for A { }
+impl<A> Hax for A {}
 
-fn perform_hax<T: 'static>(x: Box<T>) -> Box<dyn hax+'static> {
-    Box::new(x) as Box<dyn hax+'static>
+fn perform_hax<T: 'static>(x: Box<T>) -> Box<dyn Hax + 'static> {
+    Box::new(x) as Box<dyn Hax + 'static>
 }
 
 fn deadcode() {
diff --git a/tests/ui/drop/issue-979.rs b/tests/ui/drop/issue-979.rs
index 8d98ac4df23..abbcc71de18 100644
--- a/tests/ui/drop/issue-979.rs
+++ b/tests/ui/drop/issue-979.rs
@@ -1,22 +1,19 @@
 //@ run-pass
-#![allow(non_camel_case_types)]
 
 use std::cell::Cell;
 
-struct r<'a> {
+struct R<'a> {
     b: &'a Cell<isize>,
 }
 
-impl<'a> Drop for r<'a> {
+impl<'a> Drop for R<'a> {
     fn drop(&mut self) {
         self.b.set(self.b.get() + 1);
     }
 }
 
-fn r(b: &Cell<isize>) -> r {
-    r {
-        b: b
-    }
+fn r(b: &Cell<isize>) -> R<'_> {
+    R { b }
 }
 
 pub fn main() {
diff --git a/tests/ui/drop/or-pattern-drop-order.rs b/tests/ui/drop/or-pattern-drop-order.rs
new file mode 100644
index 00000000000..fdc28225c35
--- /dev/null
+++ b/tests/ui/drop/or-pattern-drop-order.rs
@@ -0,0 +1,109 @@
+//@ run-pass
+//! Test drop order for different ways of declaring pattern bindings involving or-patterns.
+//! Currently, it's inconsistent between language constructs (#142163).
+
+use std::cell::RefCell;
+use std::ops::Drop;
+
+// For more informative failures, we collect drops in a `Vec` before checking their order.
+struct DropOrder(RefCell<Vec<u32>>);
+struct LogDrop<'o>(&'o DropOrder, u32);
+
+impl<'o> Drop for LogDrop<'o> {
+    fn drop(&mut self) {
+        self.0.0.borrow_mut().push(self.1);
+    }
+}
+
+#[track_caller]
+fn assert_drop_order(expected_drops: impl IntoIterator<Item = u32>, f: impl Fn(&DropOrder)) {
+    let order = DropOrder(RefCell::new(Vec::new()));
+    f(&order);
+    let order = order.0.into_inner();
+    let correct_order: Vec<u32> = expected_drops.into_iter().collect();
+    assert_eq!(order, correct_order);
+}
+
+#[expect(unused_variables, unused_assignments, irrefutable_let_patterns)]
+fn main() {
+    // When bindings are declared with `let pat;`, they're visited in left-to-right order, using the
+    // order given by the first occurrence of each variable. They're later dropped in reverse.
+    assert_drop_order(1..=3, |o| {
+        // Drops are right-to-left: `z`, `y`, `x`.
+        let (x, Ok(y) | Err(y), z);
+        // Assignment order doesn't matter.
+        z = LogDrop(o, 1);
+        y = LogDrop(o, 2);
+        x = LogDrop(o, 3);
+    });
+    assert_drop_order(1..=2, |o| {
+        // The first or-pattern alternative determines the bindings' drop order: `y`, `x`.
+        let ((true, x, y) | (false, y, x));
+        x = LogDrop(o, 2);
+        y = LogDrop(o, 1);
+    });
+
+    // When bindings are declared with `let pat = expr;`, bindings within or-patterns are seen last,
+    // thus they're dropped first.
+    assert_drop_order(1..=3, |o| {
+        // Drops are right-to-left, treating `y` as rightmost: `y`, `z`, `x`.
+        let (x, Ok(y) | Err(y), z) = (LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2));
+    });
+    assert_drop_order(1..=2, |o| {
+        // The first or-pattern alternative determines the bindings' drop order: `y`, `x`.
+        let ((true, x, y) | (false, y, x)) = (true, LogDrop(o, 2), LogDrop(o, 1));
+    });
+    assert_drop_order(1..=2, |o| {
+        // That drop order is used regardless of which or-pattern alternative matches: `y`, `x`.
+        let ((true, x, y) | (false, y, x)) = (false, LogDrop(o, 1), LogDrop(o, 2));
+    });
+
+    // `match` treats or-patterns as last like `let pat = expr;`, but also determines drop order
+    // using the order of the bindings in the *last* or-pattern alternative.
+    assert_drop_order(1..=3, |o| {
+        // Drops are right-to-left, treating `y` as rightmost: `y`, `z`, `x`.
+        match (LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2)) { (x, Ok(y) | Err(y), z) => {} }
+    });
+    assert_drop_order(1..=2, |o| {
+        // The last or-pattern alternative determines the bindings' drop order: `x`, `y`.
+        match (true, LogDrop(o, 1), LogDrop(o, 2)) { (true, x, y) | (false, y, x) => {} }
+    });
+    assert_drop_order(1..=2, |o| {
+        // That drop order is used regardless of which or-pattern alternative matches: `x`, `y`.
+        match (false, LogDrop(o, 2), LogDrop(o, 1)) { (true, x, y) | (false, y, x) => {} }
+    });
+
+    // Function params are visited one-by-one, and the order of bindings within a param's pattern is
+    // the same as `let pat = expr`;
+    assert_drop_order(1..=3, |o| {
+        // Among separate params, the drop order is right-to-left: `z`, `y`, `x`.
+        (|x, (Ok(y) | Err(y)), z| {})(LogDrop(o, 3), Ok(LogDrop(o, 2)), LogDrop(o, 1));
+    });
+    assert_drop_order(1..=3, |o| {
+        // Within a param's pattern, or-patterns are treated as rightmost: `y`, `z`, `x`.
+        (|(x, Ok(y) | Err(y), z)| {})((LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2)));
+    });
+    assert_drop_order(1..=2, |o| {
+        // The first or-pattern alternative determines the bindings' drop order: `y`, `x`.
+        (|((true, x, y) | (false, y, x))| {})((true, LogDrop(o, 2), LogDrop(o, 1)));
+    });
+
+    // `if let` and `let`-`else` see bindings in the same order as `let pat = expr;`.
+    // Vars in or-patterns are seen last (dropped first), and the first alternative's order is used.
+    assert_drop_order(1..=3, |o| {
+        if let (x, Ok(y) | Err(y), z) = (LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2)) {}
+    });
+    assert_drop_order(1..=3, |o| {
+        let (x, Ok(y) | Err(y), z) = (LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2)) else {
+            unreachable!();
+        };
+    });
+    assert_drop_order(1..=2, |o| {
+        if let (true, x, y) | (false, y, x) = (true, LogDrop(o, 2), LogDrop(o, 1)) {}
+    });
+    assert_drop_order(1..=2, |o| {
+        let ((true, x, y) | (false, y, x)) = (true, LogDrop(o, 2), LogDrop(o, 1)) else {
+            unreachable!();
+        };
+    });
+}
diff --git a/tests/ui/drop/tail-expr-drop-order.rs b/tests/ui/drop/tail-expr-drop-order.rs
index f74530fce1e..a6807b16b50 100644
--- a/tests/ui/drop/tail-expr-drop-order.rs
+++ b/tests/ui/drop/tail-expr-drop-order.rs
@@ -28,11 +28,11 @@ impl Drop for LoudDrop<'_> {
 }
 
 impl DropOrderCollector {
-    fn option_loud_drop(&self, n: u32) -> Option<LoudDrop> {
+    fn option_loud_drop(&self, n: u32) -> Option<LoudDrop<'_>> {
         Some(LoudDrop(self, n))
     }
 
-    fn loud_drop(&self, n: u32) -> LoudDrop {
+    fn loud_drop(&self, n: u32) -> LoudDrop<'_> {
         LoudDrop(self, n)
     }
 
diff --git a/tests/ui/dropck/eager-by-ref-binding-for-guards.rs b/tests/ui/dropck/eager-by-ref-binding-for-guards.rs
new file mode 100644
index 00000000000..3f475839171
--- /dev/null
+++ b/tests/ui/dropck/eager-by-ref-binding-for-guards.rs
@@ -0,0 +1,31 @@
+//! The drop check is currently more permissive when match arms have guards, due to eagerly creating
+//! by-ref bindings for the guard (#142057).
+
+struct Struct<T>(T);
+impl<T> Drop for Struct<T> {
+    fn drop(&mut self) {}
+}
+
+fn main() {
+    // This is an error: `short1` is dead before `long1` is dropped.
+    match (Struct(&&0), 1) {
+        (mut long1, ref short1) => long1.0 = &short1,
+        //~^ ERROR `short1` does not live long enough
+    }
+    // This is OK: `short2`'s storage is live until after `long2`'s drop runs.
+    match (Struct(&&0), 1) {
+        (mut long2, ref short2) if true => long2.0 = &short2,
+        _ => unreachable!(),
+    }
+    // This depends on the binding modes of the final or-pattern alternatives (see #142163):
+    let res: &Result<u8, &u8> = &Ok(1);
+    match (Struct(&&0), res) {
+        (mut long3, Ok(short3) | &Err(short3)) if true => long3.0 = &short3,
+        //~^ ERROR `short3` does not live long enough
+        _ => unreachable!(),
+    }
+    match (Struct(&&0), res) {
+        (mut long4, &Err(short4) | Ok(short4)) if true => long4.0 = &short4,
+        _ => unreachable!(),
+    }
+}
diff --git a/tests/ui/dropck/eager-by-ref-binding-for-guards.stderr b/tests/ui/dropck/eager-by-ref-binding-for-guards.stderr
new file mode 100644
index 00000000000..cb1a04cd444
--- /dev/null
+++ b/tests/ui/dropck/eager-by-ref-binding-for-guards.stderr
@@ -0,0 +1,28 @@
+error[E0597]: `short1` does not live long enough
+  --> $DIR/eager-by-ref-binding-for-guards.rs:12:46
+   |
+LL |         (mut long1, ref short1) => long1.0 = &short1,
+   |                     ----------               ^^^^^^-
+   |                     |                        |     |
+   |                     |                        |     `short1` dropped here while still borrowed
+   |                     |                        |     borrow might be used here, when `long1` is dropped and runs the `Drop` code for type `Struct`
+   |                     |                        borrowed value does not live long enough
+   |                     binding `short1` declared here
+   |
+   = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `short3` does not live long enough
+  --> $DIR/eager-by-ref-binding-for-guards.rs:23:69
+   |
+LL |         (mut long3, Ok(short3) | &Err(short3)) if true => long3.0 = &short3,
+   |                        ------                                       ^^^^^^-
+   |                        |                                            |     |
+   |                        |                                            |     `short3` dropped here while still borrowed
+   |                        |                                            |     borrow might be used here, when `long3` is dropped and runs the `Drop` code for type `Struct`
+   |                        binding `short3` declared here               borrowed value does not live long enough
+   |
+   = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/dropck/let-else-more-permissive.rs b/tests/ui/dropck/let-else-more-permissive.rs
new file mode 100644
index 00000000000..0020814aa81
--- /dev/null
+++ b/tests/ui/dropck/let-else-more-permissive.rs
@@ -0,0 +1,30 @@
+//! The drop check is currently more permissive when `let` statements have an `else` block, due to
+//! scheduling drops for bindings' storage before pattern-matching (#142056).
+
+struct Struct<T>(T);
+impl<T> Drop for Struct<T> {
+    fn drop(&mut self) {}
+}
+
+fn main() {
+    {
+        // This is an error: `short1` is dead before `long1` is dropped.
+        let (mut long1, short1) = (Struct(&0), 1);
+        long1.0 = &short1;
+        //~^ ERROR `short1` does not live long enough
+    }
+    {
+        // This is OK: `short2`'s storage is live until after `long2`'s drop runs.
+        #[expect(irrefutable_let_patterns)]
+        let (mut long2, short2) = (Struct(&0), 1) else { unreachable!() };
+        long2.0 = &short2;
+    }
+    {
+        // Sanity check: `short3`'s drop is significant; it's dropped before `long3`:
+        let tmp = Box::new(0);
+        #[expect(irrefutable_let_patterns)]
+        let (mut long3, short3) = (Struct(&tmp), Box::new(1)) else { unreachable!() };
+        long3.0 = &short3;
+        //~^ ERROR `short3` does not live long enough
+    }
+}
diff --git a/tests/ui/dropck/let-else-more-permissive.stderr b/tests/ui/dropck/let-else-more-permissive.stderr
new file mode 100644
index 00000000000..7c37e170afa
--- /dev/null
+++ b/tests/ui/dropck/let-else-more-permissive.stderr
@@ -0,0 +1,35 @@
+error[E0597]: `short1` does not live long enough
+  --> $DIR/let-else-more-permissive.rs:13:19
+   |
+LL |         let (mut long1, short1) = (Struct(&0), 1);
+   |                         ------ binding `short1` declared here
+LL |         long1.0 = &short1;
+   |                   ^^^^^^^ borrowed value does not live long enough
+LL |
+LL |     }
+   |     -
+   |     |
+   |     `short1` dropped here while still borrowed
+   |     borrow might be used here, when `long1` is dropped and runs the `Drop` code for type `Struct`
+   |
+   = note: values in a scope are dropped in the opposite order they are defined
+
+error[E0597]: `short3` does not live long enough
+  --> $DIR/let-else-more-permissive.rs:27:19
+   |
+LL |         let (mut long3, short3) = (Struct(&tmp), Box::new(1)) else { unreachable!() };
+   |                         ------ binding `short3` declared here
+LL |         long3.0 = &short3;
+   |                   ^^^^^^^ borrowed value does not live long enough
+LL |
+LL |     }
+   |     -
+   |     |
+   |     `short3` dropped here while still borrowed
+   |     borrow might be used here, when `long3` is dropped and runs the `Drop` code for type `Struct`
+   |
+   = note: values in a scope are dropped in the opposite order they are defined
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/enum-discriminant/eval-error.stderr b/tests/ui/enum-discriminant/eval-error.stderr
index b4061d7777b..c29d258a90b 100644
--- a/tests/ui/enum-discriminant/eval-error.stderr
+++ b/tests/ui/enum-discriminant/eval-error.stderr
@@ -49,7 +49,7 @@ error[E0080]: the type `Foo` has an unknown layout
   --> $DIR/eval-error.rs:9:30
    |
 LL |         let _: Option<Foo> = None;
-   |                              ^^^^ evaluation of constant value failed here
+   |                              ^^^^ evaluation of `Bar::Boo::{constant#0}` failed here
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/cenum_impl_drop_cast.rs b/tests/ui/enum/enum-drop-cast-error.rs
index f681434dd86..36101573624 100644
--- a/tests/ui/cenum_impl_drop_cast.rs
+++ b/tests/ui/enum/enum-drop-cast-error.rs
@@ -1,3 +1,7 @@
+//! Check that trying to cast an enum with a Drop impl to an integer is rejected.
+//!
+//! Issue: <https://github.com/rust-lang/rust/issues/35941>
+
 enum E {
     A = 0,
 }
diff --git a/tests/ui/cenum_impl_drop_cast.stderr b/tests/ui/enum/enum-drop-cast-error.stderr
index 35c69f4b4b7..b58abbd39d3 100644
--- a/tests/ui/cenum_impl_drop_cast.stderr
+++ b/tests/ui/enum/enum-drop-cast-error.stderr
@@ -1,5 +1,5 @@
 error: cannot cast enum `E` into integer `u32` because it implements `Drop`
-  --> $DIR/cenum_impl_drop_cast.rs:13:13
+  --> $DIR/enum-drop-cast-error.rs:17:13
    |
 LL |     let i = e as u32;
    |             ^^^^^^^^
diff --git a/tests/ui/error-codes/E0080.stderr b/tests/ui/error-codes/E0080.stderr
index 431d4e04454..c78454620d1 100644
--- a/tests/ui/error-codes/E0080.stderr
+++ b/tests/ui/error-codes/E0080.stderr
@@ -2,13 +2,13 @@ error[E0080]: attempt to shift left by `500_i32`, which would overflow
   --> $DIR/E0080.rs:2:9
    |
 LL |     X = (1 << 500),
-   |         ^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^ evaluation of `Enum::X::{constant#0}` failed here
 
 error[E0080]: attempt to divide `1_isize` by zero
   --> $DIR/E0080.rs:3:9
    |
 LL |     Y = (1 / 0),
-   |         ^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^ evaluation of `Enum::Y::{constant#0}` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/error-codes/E0092.rs b/tests/ui/error-codes/E0092.rs
deleted file mode 100644
index 19a7c65a48e..00000000000
--- a/tests/ui/error-codes/E0092.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(intrinsics)]
-
-#[rustc_intrinsic]
-unsafe fn atomic_foo(); //~ ERROR E0092
-
-fn main() {}
diff --git a/tests/ui/error-codes/E0092.stderr b/tests/ui/error-codes/E0092.stderr
deleted file mode 100644
index 003c989fd59..00000000000
--- a/tests/ui/error-codes/E0092.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0092]: unrecognized atomic operation function: `foo`
-  --> $DIR/E0092.rs:4:11
-   |
-LL | unsafe fn atomic_foo();
-   |           ^^^^^^^^^^ unrecognized atomic operation
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0092`.
diff --git a/tests/ui/error-codes/E0604.stderr b/tests/ui/error-codes/E0604.stderr
index e91f74d6b3f..67bbb25958f 100644
--- a/tests/ui/error-codes/E0604.stderr
+++ b/tests/ui/error-codes/E0604.stderr
@@ -2,10 +2,13 @@ error[E0604]: only `u8` can be cast as `char`, not `u32`
   --> $DIR/E0604.rs:2:5
    |
 LL |     1u32 as char;
-   |     ^^^^^^^^^^^^
-   |     |
-   |     invalid cast
-   |     help: try `char::from_u32` instead: `char::from_u32(1u32)`
+   |     ^^^^^^^^^^^^ invalid cast
+   |
+help: consider using `char::from_u32` instead
+   |
+LL -     1u32 as char;
+LL +     char::from_u32(1u32);
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/error-codes/E0620.stderr b/tests/ui/error-codes/E0620.stderr
index 644ba813c96..696407c6f7e 100644
--- a/tests/ui/error-codes/E0620.stderr
+++ b/tests/ui/error-codes/E0620.stderr
@@ -2,9 +2,12 @@ error[E0620]: cast to unsized type: `&[usize; 2]` as `[usize]`
   --> $DIR/E0620.rs:2:16
    |
 LL |     let _foo = &[1_usize, 2] as [usize];
-   |                ^^^^^^^^^^^^^^^^^-------
-   |                                 |
-   |                                 help: try casting to a reference instead: `&[usize]`
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider casting to a reference instead
+   |
+LL |     let _foo = &[1_usize, 2] as &[usize];
+   |                                 +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/error-emitter/error-festival.stderr b/tests/ui/error-emitter/error-festival.stderr
index be484bc8094..6c661eb17a8 100644
--- a/tests/ui/error-emitter/error-festival.stderr
+++ b/tests/ui/error-emitter/error-festival.stderr
@@ -58,10 +58,13 @@ error[E0604]: only `u8` can be cast as `char`, not `u32`
   --> $DIR/error-festival.rs:27:5
    |
 LL |     0u32 as char;
-   |     ^^^^^^^^^^^^
-   |     |
-   |     invalid cast
-   |     help: try `char::from_u32` instead: `char::from_u32(0u32)`
+   |     ^^^^^^^^^^^^ invalid cast
+   |
+help: consider using `char::from_u32` instead
+   |
+LL -     0u32 as char;
+LL +     char::from_u32(0u32);
+   |
 
 error[E0605]: non-primitive cast: `u8` as `Vec<u8>`
   --> $DIR/error-festival.rs:31:5
diff --git a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr
index 2d558e9a561..25e30397c83 100644
--- a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr
+++ b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr
@@ -2,7 +2,7 @@ error[E0080]: reached the configured maximum number of stack frames
   --> $DIR/ctfe-id-unlimited.rs:28:20
    |
 LL | const ID_ED: u32 = rec_id(ORIGINAL);
-   |                    ^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^^^^^^^^^ evaluation of `ID_ED` failed inside this call
    |
 note: inside `rec_id`
   --> $DIR/ctfe-id-unlimited.rs:21:5
diff --git a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs
index bf32232cee3..26fb7b16a55 100644
--- a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs
+++ b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs
@@ -10,7 +10,7 @@ const fn g() {
     //~^ NOTE in this expansion of panic!
 }
 
-const _: () = f(); //~ NOTE evaluation of constant value failed
+const _: () = f(); //~ NOTE failed inside this call
 //~^ ERROR explicit panic
 
 fn main() {}
diff --git a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr
index 457290b76b8..380c2bfb98c 100644
--- a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr
+++ b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/ctfe-tail-call-panic.rs:13:15
    |
 LL | const _: () = f();
-   |               ^^^ evaluation of constant value failed here
+   |               ^^^ evaluation of `_` failed inside this call
    |
 note: inside `g`
   --> $DIR/ctfe-tail-call-panic.rs:9:5
diff --git a/tests/ui/extern/issue-28324.stderr b/tests/ui/extern/issue-28324.stderr
index 89dfab945be..4637163bc5c 100644
--- a/tests/ui/extern/issue-28324.stderr
+++ b/tests/ui/extern/issue-28324.stderr
@@ -2,7 +2,7 @@ error[E0080]: cannot access extern static `error_message_count`
   --> $DIR/issue-28324.rs:5:23
    |
 LL | pub static BAZ: u32 = *&error_message_count;
-   |                       ^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                       ^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAZ` failed here
 
 error[E0133]: use of extern static is unsafe and requires unsafe function or block
   --> $DIR/issue-28324.rs:5:25
diff --git a/tests/ui/feature-gates/feature-gate-coverage-attribute.rs b/tests/ui/feature-gates/feature-gate-coverage-attribute.rs
index 0a463755f13..2cf4b76180e 100644
--- a/tests/ui/feature-gates/feature-gate-coverage-attribute.rs
+++ b/tests/ui/feature-gates/feature-gate-coverage-attribute.rs
@@ -1,3 +1,5 @@
+//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION"
+
 #![crate_type = "lib"]
 #![feature(no_coverage)] //~ ERROR feature has been removed [E0557]
 
diff --git a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr
index 00e0f0afbde..8c23544698d 100644
--- a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr
+++ b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr
@@ -1,13 +1,14 @@
 error[E0557]: feature has been removed
-  --> $DIR/feature-gate-coverage-attribute.rs:2:12
+  --> $DIR/feature-gate-coverage-attribute.rs:4:12
    |
 LL | #![feature(no_coverage)]
    |            ^^^^^^^^^^^ feature has been removed
    |
+   = note: removed in 1.74.0 (you are using $RUSTC_VERSION); see <https://github.com/rust-lang/rust/pull/114656> for more information
    = note: renamed to `coverage_attribute`
 
 error[E0658]: the `#[coverage]` attribute is an experimental feature
-  --> $DIR/feature-gate-coverage-attribute.rs:10:1
+  --> $DIR/feature-gate-coverage-attribute.rs:12:1
    |
 LL | #[coverage(off)]
    | ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/feature-gates/feature-gate-keylocker_x86.rs b/tests/ui/feature-gates/feature-gate-keylocker_x86.rs
deleted file mode 100644
index cef80ad41a8..00000000000
--- a/tests/ui/feature-gates/feature-gate-keylocker_x86.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ 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
deleted file mode 100644
index ed814d3a3ce..00000000000
--- a/tests/ui/feature-gates/feature-gate-keylocker_x86.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-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-sha512_sm_x86.rs b/tests/ui/feature-gates/feature-gate-sha512_sm_x86.rs
deleted file mode 100644
index 176a40ecf53..00000000000
--- a/tests/ui/feature-gates/feature-gate-sha512_sm_x86.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ only-x86_64
-#[target_feature(enable = "sha512")]
-//~^ ERROR: currently unstable
-unsafe fn foo() {}
-
-fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-sha512_sm_x86.stderr b/tests/ui/feature-gates/feature-gate-sha512_sm_x86.stderr
deleted file mode 100644
index da9eea095a3..00000000000
--- a/tests/ui/feature-gates/feature-gate-sha512_sm_x86.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: the target feature `sha512` is currently unstable
-  --> $DIR/feature-gate-sha512_sm_x86.rs:2:18
-   |
-LL | #[target_feature(enable = "sha512")]
-   |                  ^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #126624 <https://github.com/rust-lang/rust/issues/126624> for more information
-   = help: add `#![feature(sha512_sm_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-gated-feature-in-macro-arg.stderr b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr
index aaaaeece67a..fb05273b6ff 100644
--- a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr
+++ b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr
@@ -7,7 +7,7 @@ LL |         #[rustc_intrinsic]
    = help: add `#![feature(intrinsics)]` 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[E0133]: call to unsafe function `atomic_fence` is unsafe and requires unsafe function or block
+error[E0133]: call to unsafe function `main::atomic_fence` is unsafe and requires unsafe function or block
   --> $DIR/feature-gated-feature-in-macro-arg.rs:11:9
    |
 LL |         atomic_fence();
diff --git a/tests/ui/feature-gates/gated-bad-feature.rs b/tests/ui/feature-gates/gated-bad-feature.rs
index 51f2db5556e..3114f661dc5 100644
--- a/tests/ui/feature-gates/gated-bad-feature.rs
+++ b/tests/ui/feature-gates/gated-bad-feature.rs
@@ -1,3 +1,4 @@
+//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION"
 #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
 //~^ ERROR malformed `feature`
 //~| ERROR malformed `feature`
diff --git a/tests/ui/feature-gates/gated-bad-feature.stderr b/tests/ui/feature-gates/gated-bad-feature.stderr
index 2d01bdf3c1d..0e75dff14f8 100644
--- a/tests/ui/feature-gates/gated-bad-feature.stderr
+++ b/tests/ui/feature-gates/gated-bad-feature.stderr
@@ -1,41 +1,43 @@
 error[E0556]: malformed `feature` attribute input
-  --> $DIR/gated-bad-feature.rs:1:25
+  --> $DIR/gated-bad-feature.rs:2:25
    |
 LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
    |                         ^^^^^^^^ help: expected just one word: `foo`
 
 error[E0556]: malformed `feature` attribute input
-  --> $DIR/gated-bad-feature.rs:1:35
+  --> $DIR/gated-bad-feature.rs:2:35
    |
 LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
    |                                   ^^^^^^^^^^^ help: expected just one word: `foo`
 
 error[E0557]: feature has been removed
-  --> $DIR/gated-bad-feature.rs:8:12
+  --> $DIR/gated-bad-feature.rs:9:12
    |
 LL | #![feature(test_removed_feature)]
    |            ^^^^^^^^^^^^^^^^^^^^ feature has been removed
+   |
+   = note: removed in 1.0.0 (you are using $RUSTC_VERSION)
 
 error: malformed `feature` attribute input
-  --> $DIR/gated-bad-feature.rs:6:1
+  --> $DIR/gated-bad-feature.rs:7:1
    |
 LL | #![feature]
    | ^^^^^^^^^^^ help: must be of the form: `#![feature(name1, name2, ...)]`
 
 error: malformed `feature` attribute input
-  --> $DIR/gated-bad-feature.rs:7:1
+  --> $DIR/gated-bad-feature.rs:8:1
    |
 LL | #![feature = "foo"]
    | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![feature(name1, name2, ...)]`
 
 error[E0635]: unknown feature `foo_bar_baz`
-  --> $DIR/gated-bad-feature.rs:1:12
+  --> $DIR/gated-bad-feature.rs:2:12
    |
 LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
    |            ^^^^^^^^^^^
 
 error[E0635]: unknown feature `foo`
-  --> $DIR/gated-bad-feature.rs:1:48
+  --> $DIR/gated-bad-feature.rs:2:48
    |
 LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
    |                                                ^^^
diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs
new file mode 100644
index 00000000000..ec6adb471ba
--- /dev/null
+++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs
@@ -0,0 +1,6 @@
+//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION"
+
+#![feature(external_doc)] //~ ERROR feature has been removed
+#![doc(include("README.md"))] //~ ERROR unknown `doc` attribute `include`
+
+fn main(){}
diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr
new file mode 100644
index 00000000000..43205c7360b
--- /dev/null
+++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr
@@ -0,0 +1,20 @@
+error[E0557]: feature has been removed
+  --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:3:12
+   |
+LL | #![feature(external_doc)]
+   |            ^^^^^^^^^^^^ feature has been removed
+   |
+   = note: removed in 1.54.0 (you are using $RUSTC_VERSION); see <https://github.com/rust-lang/rust/pull/85457> for more information
+   = note: use #[doc = include_str!("filename")] instead, which handles macro invocations
+
+error: unknown `doc` attribute `include`
+  --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:4:8
+   |
+LL | #![doc(include("README.md"))]
+   |        ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[deny(invalid_doc_attributes)]` on by default
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0557`.
diff --git a/tests/ui/frontmatter/frontmatter-inner-hyphens-1.rs b/tests/ui/frontmatter/frontmatter-inner-hyphens-1.rs
new file mode 100644
index 00000000000..985b1cfe988
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-inner-hyphens-1.rs
@@ -0,0 +1,10 @@
+---
+x ---🚧️
+---
+
+// Regression test for #141483
+//@check-pass
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/frontmatter/frontmatter-inner-hyphens-2.rs b/tests/ui/frontmatter/frontmatter-inner-hyphens-2.rs
new file mode 100644
index 00000000000..3d5fb453872
--- /dev/null
+++ b/tests/ui/frontmatter/frontmatter-inner-hyphens-2.rs
@@ -0,0 +1,11 @@
+---
+x ---y
+---
+
+// Test that hypens are allowed inside frontmatters if there is some
+// non-whitespace character preceding them.
+//@check-pass
+
+#![feature(frontmatter)]
+
+fn main() {}
diff --git a/tests/ui/future-incompatible-lint-group.rs b/tests/ui/future-incompatible-lint-group.rs
index c84538318f7..ed2c47bb609 100644
--- a/tests/ui/future-incompatible-lint-group.rs
+++ b/tests/ui/future-incompatible-lint-group.rs
@@ -2,16 +2,14 @@
 // lints for changes that are not tied to an edition
 #![deny(future_incompatible)]
 
+// Error since this is a `future_incompatible` lint
+macro_rules! m { ($i) => {} } //~ ERROR missing fragment specifier
+                              //~| WARN this was previously accepted
+
 trait Tr {
     // Warn only since this is not a `future_incompatible` lint
     fn f(u8) {} //~ WARN anonymous parameters are deprecated
                 //~| WARN this is accepted in the current edition
 }
 
-pub mod submodule {
-    // Error since this is a `future_incompatible` lint
-    #![doc(test(some_test))]
-    //~^ ERROR this attribute can only be applied at the crate level
-}
-
 fn main() {}
diff --git a/tests/ui/future-incompatible-lint-group.stderr b/tests/ui/future-incompatible-lint-group.stderr
index 4e6c434fa29..4c867e0aab3 100644
--- a/tests/ui/future-incompatible-lint-group.stderr
+++ b/tests/ui/future-incompatible-lint-group.stderr
@@ -1,5 +1,20 @@
+error: missing fragment specifier
+  --> $DIR/future-incompatible-lint-group.rs:6:19
+   |
+LL | macro_rules! m { ($i) => {} }
+   |                   ^^
+   |
+   = 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 #40107 <https://github.com/rust-lang/rust/issues/40107>
+note: the lint level is defined here
+  --> $DIR/future-incompatible-lint-group.rs:3:9
+   |
+LL | #![deny(future_incompatible)]
+   |         ^^^^^^^^^^^^^^^^^^^
+   = note: `#[deny(missing_fragment_specifier)]` implied by `#[deny(future_incompatible)]`
+
 warning: anonymous parameters are deprecated and will be removed in the next edition
-  --> $DIR/future-incompatible-lint-group.rs:7:10
+  --> $DIR/future-incompatible-lint-group.rs:11:10
    |
 LL |     fn f(u8) {}
    |          ^^ help: try naming the parameter or explicitly ignoring it: `_: u8`
@@ -8,14 +23,21 @@ LL |     fn f(u8) {}
    = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
    = note: `#[warn(anonymous_parameters)]` on by default
 
-error: this attribute can only be applied at the crate level
-  --> $DIR/future-incompatible-lint-group.rs:13:12
+error: aborting due to 1 previous error; 1 warning emitted
+
+Future incompatibility report: Future breakage diagnostic:
+error: missing fragment specifier
+  --> $DIR/future-incompatible-lint-group.rs:6:19
    |
-LL |     #![doc(test(some_test))]
-   |            ^^^^^^^^^^^^^^^
+LL | macro_rules! m { ($i) => {} }
+   |                   ^^
    |
-   = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
-   = note: `#[deny(invalid_doc_attributes)]` on by default
-
-error: aborting due to 1 previous error; 1 warning emitted
+   = 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 #40107 <https://github.com/rust-lang/rust/issues/40107>
+note: the lint level is defined here
+  --> $DIR/future-incompatible-lint-group.rs:3:9
+   |
+LL | #![deny(future_incompatible)]
+   |         ^^^^^^^^^^^^^^^^^^^
+   = note: `#[deny(missing_fragment_specifier)]` implied by `#[deny(future_incompatible)]`
 
diff --git a/tests/ui/generic-const-items/def-site-eval.fail.stderr b/tests/ui/generic-const-items/def-site-eval.fail.stderr
index b8616547390..e39fbdf7802 100644
--- a/tests/ui/generic-const-items/def-site-eval.fail.stderr
+++ b/tests/ui/generic-const-items/def-site-eval.fail.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/def-site-eval.rs:13:20
    |
 LL | const _<'_a>: () = panic!();
-   |                    ^^^^^^^^ evaluation of constant value failed here
+   |                    ^^^^^^^^ evaluation of `_` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr
index a89356fadfd..e5c3bbb0c7d 100644
--- a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr
+++ b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr
@@ -4,7 +4,7 @@ error[E0080]: entering unreachable code
 LL | / const UNUSABLE: () = ()
 LL | | where
 LL | |     String: Copy;
-   | |_________________^ evaluation of constant value failed here
+   | |_________________^ evaluation of `UNUSABLE` failed here
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/trivially-unsatisfied-bounds-0.rs:11:13
diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr
index 3aa26eb1656..a5f6dd980bd 100644
--- a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr
+++ b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr
@@ -4,7 +4,7 @@ error[E0080]: entering unreachable code
 LL | / const UNUSED: () = ()
 LL | | where
 LL | |     String: Copy;
-   | |_________________^ evaluation of constant value failed here
+   | |_________________^ evaluation of `UNUSED` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/generics/export-name-on-generics.fixed b/tests/ui/generics/export-name-on-generics.fixed
index 4430cd9a299..c8a3fd5798f 100644
--- a/tests/ui/generics/export-name-on-generics.fixed
+++ b/tests/ui/generics/export-name-on-generics.fixed
@@ -1,5 +1,5 @@
 //@ run-rustfix
-#![allow(dead_code, elided_named_lifetimes)]
+#![allow(dead_code, mismatched_lifetime_syntaxes)]
 #![deny(no_mangle_generic_items)]
 
 pub fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
diff --git a/tests/ui/generics/export-name-on-generics.rs b/tests/ui/generics/export-name-on-generics.rs
index cbf11021960..8b38037fe12 100644
--- a/tests/ui/generics/export-name-on-generics.rs
+++ b/tests/ui/generics/export-name-on-generics.rs
@@ -1,5 +1,5 @@
 //@ run-rustfix
-#![allow(dead_code, elided_named_lifetimes)]
+#![allow(dead_code, mismatched_lifetime_syntaxes)]
 #![deny(no_mangle_generic_items)]
 
 #[export_name = "foo"]
diff --git a/tests/ui/generics/generic-no-mangle.fixed b/tests/ui/generics/generic-no-mangle.fixed
index 2776848c45f..e3e41eb9d0d 100644
--- a/tests/ui/generics/generic-no-mangle.fixed
+++ b/tests/ui/generics/generic-no-mangle.fixed
@@ -1,5 +1,5 @@
 //@ run-rustfix
-#![allow(dead_code, elided_named_lifetimes)]
+#![allow(dead_code, mismatched_lifetime_syntaxes)]
 #![deny(no_mangle_generic_items)]
 
 pub fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
diff --git a/tests/ui/generics/generic-no-mangle.rs b/tests/ui/generics/generic-no-mangle.rs
index 5314005d31f..085f8610a54 100644
--- a/tests/ui/generics/generic-no-mangle.rs
+++ b/tests/ui/generics/generic-no-mangle.rs
@@ -1,5 +1,5 @@
 //@ run-rustfix
-#![allow(dead_code, elided_named_lifetimes)]
+#![allow(dead_code, mismatched_lifetime_syntaxes)]
 #![deny(no_mangle_generic_items)]
 
 #[no_mangle]
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs
index c368f265062..e00a31e26aa 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs
@@ -25,7 +25,7 @@ where
 
 impl<T: 'static> Inject for RefMutFamily<T> {
     type I = Self;
-    fn inject(_: &()) -> <Self::I as FamilyLt>::Out {
+    fn inject(_: &()) -> <Self::I as FamilyLt<'_>>::Out {
         unimplemented!()
     }
 }
diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
index a7f38b5c16a..da7530b4e7a 100644
--- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
+++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
@@ -13,7 +13,6 @@ fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
 
 fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
     //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
-    //~| WARNING elided lifetime has a name
     |x| x
 }
 
diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
index 31f39eb9004..40cb6b647d1 100644
--- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
+++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
@@ -1,5 +1,5 @@
 error[E0106]: missing lifetime specifier
-  --> $DIR/impl-fn-hrtb-bounds.rs:20:38
+  --> $DIR/impl-fn-hrtb-bounds.rs:19:38
    |
 LL | fn d() -> impl Fn() -> (impl Debug + '_) {
    |                                      ^^ expected named lifetime parameter
@@ -11,14 +11,6 @@ LL - fn d() -> impl Fn() -> (impl Debug + '_) {
 LL + fn d() -> impl Fn() -> (impl Debug + 'static) {
    |
 
-warning: elided lifetime has a name
-  --> $DIR/impl-fn-hrtb-bounds.rs:14:52
-   |
-LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
-   |                    -- lifetime `'a` declared here  ^^ this elided lifetime gets resolved as `'a`
-   |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
-
 error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/impl-fn-hrtb-bounds.rs:4:41
    |
@@ -55,7 +47,7 @@ note: lifetime declared here
 LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
    |                    ^^
 
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0106, E0657.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs
index 776bb7278ce..199cbbf4fcc 100644
--- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs
+++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs
@@ -2,7 +2,6 @@
 use std::fmt::Debug;
 
 fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
-    //~^ WARNING elided lifetime has a name
     |x| x
     //~^ ERROR expected generic lifetime parameter, found `'_`
 }
diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
index 209186db4cc..6064b09ef09 100644
--- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
+++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
@@ -1,20 +1,11 @@
-warning: elided lifetime has a name
-  --> $DIR/impl-fn-predefined-lifetimes.rs:4:48
-   |
-LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
-   |      -- lifetime `'a` declared here            ^^ this elided lifetime gets resolved as `'a`
-   |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
-
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/impl-fn-predefined-lifetimes.rs:6:9
+  --> $DIR/impl-fn-predefined-lifetimes.rs:5:9
    |
 LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
    |                                                -- this generic parameter must be used with a generic lifetime parameter
-LL |
 LL |     |x| x
    |         ^
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs
index e48441f533d..1ac3c593dbe 100644
--- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs
+++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs
@@ -1,7 +1,7 @@
 //@ check-pass
 
 pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &u32)> {
-    //~^ WARNING elided lifetime has a name
+    //~^ WARNING lifetime flowing from input to output with different syntax
     v.into_iter()
 }
 
diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr
index bff3ffd934a..b9d8674992c 100644
--- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr
+++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr
@@ -1,10 +1,14 @@
-warning: elided lifetime has a name
-  --> $DIR/rpit-assoc-pair-with-lifetime.rs:3:82
+warning: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/rpit-assoc-pair-with-lifetime.rs:3:31
    |
 LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &u32)> {
-   |             -- lifetime `'a` declared here                                       ^ this elided lifetime gets resolved as `'a`
+   |                               ^^ this lifetime flows to the output               ---- the lifetime gets resolved as `'a`
    |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
+   = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
+help: one option is to consistently use `'a`
+   |
+LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &'a u32)> {
+   |                                                                                   ++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/crate-leading-sep.rs b/tests/ui/imports/global-path-resolution-drop.rs
index 6f4dd0bcfd7..29a6afa10c9 100644
--- a/tests/ui/crate-leading-sep.rs
+++ b/tests/ui/imports/global-path-resolution-drop.rs
@@ -1,3 +1,5 @@
+//! Checks global path resolution of `mem::drop` using a leading `::`.
+
 //@ run-pass
 
 #![allow(dropping_copy_types)]
diff --git a/tests/ui/infinite/infinite-recursion-const-fn.stderr b/tests/ui/infinite/infinite-recursion-const-fn.stderr
index 529bad510c9..f5f6e2a58fd 100644
--- a/tests/ui/infinite/infinite-recursion-const-fn.stderr
+++ b/tests/ui/infinite/infinite-recursion-const-fn.stderr
@@ -2,7 +2,7 @@ error[E0080]: reached the configured maximum number of stack frames
   --> $DIR/infinite-recursion-const-fn.rs:9:18
    |
 LL | const ARR: [i32; a()] = [5; 6];
-   |                  ^^^ evaluation of constant value failed here
+   |                  ^^^ evaluation of `ARR::{constant#0}` failed inside this call
    |
 note: inside `a`
   --> $DIR/infinite-recursion-const-fn.rs:4:5
diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs
index a9795d1569c..cc0d757885d 100644
--- a/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs
+++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs
@@ -23,3 +23,9 @@ fn main() {
         }
     }
 }
+
+const FOO: () = break;
+//~^ ERROR: `break` outside of a loop or labeled block
+
+static BAR: () = break;
+//~^ ERROR: `break` outside of a loop or labeled block
diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr
index 300cd45ad69..6a967c59864 100644
--- a/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr
+++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr
@@ -11,6 +11,19 @@ LL |             break;
    |             ^^^^^ cannot `break` outside of a loop or labeled block
 
 error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-inline-const-issue-128604.rs:9:13
+   |
+LL |             break;
+   |             ^^^^^ cannot `break` outside of a loop or labeled block
+   |
+help: consider labeling this block to be able to break within it
+   |
+LL ~         'block: {
+LL |
+LL ~             break 'block;
+   |
+
+error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/break-inside-inline-const-issue-128604.rs:2:21
    |
 LL |     let _ = ['a'; { break 2; 1 }];
@@ -22,18 +35,17 @@ LL |     let _ = ['a'; 'block: { break 'block 2; 1 }];
    |                   +++++++         ++++++
 
 error[E0268]: `break` outside of a loop or labeled block
-  --> $DIR/break-inside-inline-const-issue-128604.rs:9:13
-   |
-LL |             break;
-   |             ^^^^^ cannot `break` outside of a loop or labeled block
-   |
-help: consider labeling this block to be able to break within it
+  --> $DIR/break-inside-inline-const-issue-128604.rs:27:17
    |
-LL ~         'block: {
-LL |
-LL ~             break 'block;
+LL | const FOO: () = break;
+   |                 ^^^^^ cannot `break` outside of a loop or labeled block
+
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-inline-const-issue-128604.rs:30:18
    |
+LL | static BAR: () = break;
+   |                  ^^^^^ cannot `break` outside of a loop or labeled block
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0268`.
diff --git a/tests/ui/inline-const/cross-const-control-flow-125846.stderr b/tests/ui/inline-const/cross-const-control-flow-125846.stderr
index 0a910e70d09..5ea571fe98a 100644
--- a/tests/ui/inline-const/cross-const-control-flow-125846.stderr
+++ b/tests/ui/inline-const/cross-const-control-flow-125846.stderr
@@ -39,6 +39,16 @@ LL |     const { async {}.await }
    |           |          only allowed inside `async` functions and blocks
    |           this is not `async`
 
+error[E0572]: return statement outside of function body
+  --> $DIR/cross-const-control-flow-125846.rs:4:13
+   |
+LL | / fn foo() {
+LL | |     const { return }
+   | |           --^^^^^^-- the return is part of this body...
+LL | |
+LL | | }
+   | |_- ...not the enclosing function body
+
 error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/cross-const-control-flow-125846.rs:9:19
    |
@@ -63,16 +73,6 @@ error[E0268]: `continue` outside of a loop
 LL |         const { continue }
    |                 ^^^^^^^^ cannot `continue` outside of a loop
 
-error[E0572]: return statement outside of function body
-  --> $DIR/cross-const-control-flow-125846.rs:4:13
-   |
-LL | / fn foo() {
-LL | |     const { return }
-   | |           --^^^^^^-- the return is part of this body...
-LL | |
-LL | | }
-   | |_- ...not the enclosing function body
-
 error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0268, E0435, E0572, E0728, E0767.
diff --git a/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs b/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs
index 1014ac6f560..95fc673f434 100644
--- a/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs
+++ b/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs
@@ -1,11 +1,12 @@
-#![feature(intrinsics)]
+#![feature(intrinsics, adt_const_params)]
 
-pub mod rusti {
+mod rusti {
     #[rustc_intrinsic]
-    pub unsafe fn atomic_xchg_seqcst<T>(dst: *mut T, src: T) -> T;
+    pub unsafe fn size_of_val<T: ?Sized>(ptr: *const T) -> usize;
 }
 
+// A monomorphic function, inlined cross-crate, referencing an intrinsic.
 #[inline(always)]
-pub fn atomic_xchg_seqcst(dst: *mut isize, src: isize) -> isize {
-    unsafe { rusti::atomic_xchg_seqcst(dst, src) }
+pub fn size_of_val(val: &[u8]) -> usize {
+    unsafe { rusti::size_of_val(val) }
 }
diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs
index a467c445d61..30a523f364c 100644
--- a/tests/ui/intrinsics/intrinsic-alignment.rs
+++ b/tests/ui/intrinsics/intrinsic-alignment.rs
@@ -23,18 +23,12 @@ use std::intrinsics as rusti;
 mod m {
     #[cfg(target_arch = "x86")]
     pub fn main() {
-        unsafe {
-            assert_eq!(crate::rusti::pref_align_of::<u64>(), 8);
-            assert_eq!(crate::rusti::min_align_of::<u64>(), 4);
-        }
+        assert_eq!(crate::rusti::min_align_of::<u64>(), 4);
     }
 
     #[cfg(not(target_arch = "x86"))]
     pub fn main() {
-        unsafe {
-            assert_eq!(crate::rusti::pref_align_of::<u64>(), 8);
-            assert_eq!(crate::rusti::min_align_of::<u64>(), 8);
-        }
+        assert_eq!(crate::rusti::min_align_of::<u64>(), 8);
     }
 }
 
@@ -42,30 +36,21 @@ mod m {
 mod m {
     #[cfg(target_arch = "x86_64")]
     pub fn main() {
-        unsafe {
-            assert_eq!(crate::rusti::pref_align_of::<u64>(), 8);
-            assert_eq!(crate::rusti::min_align_of::<u64>(), 8);
-        }
+        assert_eq!(crate::rusti::min_align_of::<u64>(), 8);
     }
 }
 
 #[cfg(target_os = "windows")]
 mod m {
     pub fn main() {
-        unsafe {
-            assert_eq!(crate::rusti::pref_align_of::<u64>(), 8);
-            assert_eq!(crate::rusti::min_align_of::<u64>(), 8);
-        }
+        assert_eq!(crate::rusti::min_align_of::<u64>(), 8);
     }
 }
 
 #[cfg(target_family = "wasm")]
 mod m {
     pub fn main() {
-        unsafe {
-            assert_eq!(crate::rusti::pref_align_of::<u64>(), 8);
-            assert_eq!(crate::rusti::min_align_of::<u64>(), 8);
-        }
+        assert_eq!(crate::rusti::min_align_of::<u64>(), 8);
     }
 }
 
diff --git a/tests/ui/intrinsics/intrinsic-atomics-cc.rs b/tests/ui/intrinsics/intrinsic-atomics-cc.rs
deleted file mode 100644
index 612a21a47cf..00000000000
--- a/tests/ui/intrinsics/intrinsic-atomics-cc.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ run-pass
-//@ aux-build:cci_intrinsic.rs
-
-
-extern crate cci_intrinsic;
-use cci_intrinsic::atomic_xchg_seqcst;
-
-pub fn main() {
-    let mut x = 1;
-    atomic_xchg_seqcst(&mut x, 5);
-    assert_eq!(x, 5);
-}
diff --git a/tests/ui/intrinsics/intrinsic-atomics.rs b/tests/ui/intrinsics/intrinsic-atomics.rs
index f96c6dc832e..2275aafff83 100644
--- a/tests/ui/intrinsics/intrinsic-atomics.rs
+++ b/tests/ui/intrinsics/intrinsic-atomics.rs
@@ -1,50 +1,50 @@
 //@ run-pass
 #![feature(core_intrinsics)]
-use std::intrinsics::{self as rusti, AtomicOrdering};
+use std::intrinsics::{self as rusti, AtomicOrdering::*};
 
 pub fn main() {
     unsafe {
         let mut x: Box<_> = Box::new(1);
 
-        assert_eq!(rusti::atomic_load::<_, { AtomicOrdering::SeqCst }>(&*x), 1);
+        assert_eq!(rusti::atomic_load::<_, { SeqCst }>(&*x), 1);
         *x = 5;
-        assert_eq!(rusti::atomic_load::<_, { AtomicOrdering::Acquire }>(&*x), 5);
+        assert_eq!(rusti::atomic_load::<_, { Acquire }>(&*x), 5);
 
-        rusti::atomic_store_seqcst(&mut *x, 3);
+        rusti::atomic_store::<_, { SeqCst }>(&mut *x, 3);
         assert_eq!(*x, 3);
-        rusti::atomic_store_release(&mut *x, 1);
+        rusti::atomic_store::<_, { Release }>(&mut *x, 1);
         assert_eq!(*x, 1);
 
-        assert_eq!(rusti::atomic_cxchg_seqcst_seqcst(&mut *x, 1, 2), (1, true));
+        assert_eq!(rusti::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(&mut *x, 1, 2), (1, true));
         assert_eq!(*x, 2);
 
-        assert_eq!(rusti::atomic_cxchg_acquire_acquire(&mut *x, 1, 3), (2, false));
+        assert_eq!(rusti::atomic_cxchg::<_, { Acquire }, { Acquire }>(&mut *x, 1, 3), (2, false));
         assert_eq!(*x, 2);
 
-        assert_eq!(rusti::atomic_cxchg_release_relaxed(&mut *x, 2, 1), (2, true));
+        assert_eq!(rusti::atomic_cxchg::<_, { Release }, { Relaxed }>(&mut *x, 2, 1), (2, true));
         assert_eq!(*x, 1);
 
-        assert_eq!(rusti::atomic_xchg_seqcst(&mut *x, 0), 1);
+        assert_eq!(rusti::atomic_xchg::<_, { SeqCst }>(&mut *x, 0), 1);
         assert_eq!(*x, 0);
 
-        assert_eq!(rusti::atomic_xchg_acquire(&mut *x, 1), 0);
+        assert_eq!(rusti::atomic_xchg::<_, { Acquire }>(&mut *x, 1), 0);
         assert_eq!(*x, 1);
 
-        assert_eq!(rusti::atomic_xchg_release(&mut *x, 0), 1);
+        assert_eq!(rusti::atomic_xchg::<_, { Release }>(&mut *x, 0), 1);
         assert_eq!(*x, 0);
 
-        assert_eq!(rusti::atomic_xadd_seqcst(&mut *x, 1), 0);
-        assert_eq!(rusti::atomic_xadd_acquire(&mut *x, 1), 1);
-        assert_eq!(rusti::atomic_xadd_release(&mut *x, 1), 2);
+        assert_eq!(rusti::atomic_xadd::<_, { SeqCst }>(&mut *x, 1), 0);
+        assert_eq!(rusti::atomic_xadd::<_, { Acquire }>(&mut *x, 1), 1);
+        assert_eq!(rusti::atomic_xadd::<_, { Release }>(&mut *x, 1), 2);
         assert_eq!(*x, 3);
 
-        assert_eq!(rusti::atomic_xsub_seqcst(&mut *x, 1), 3);
-        assert_eq!(rusti::atomic_xsub_acquire(&mut *x, 1), 2);
-        assert_eq!(rusti::atomic_xsub_release(&mut *x, 1), 1);
+        assert_eq!(rusti::atomic_xsub::<_, { SeqCst }>(&mut *x, 1), 3);
+        assert_eq!(rusti::atomic_xsub::<_, { Acquire }>(&mut *x, 1), 2);
+        assert_eq!(rusti::atomic_xsub::<_, { Release }>(&mut *x, 1), 1);
         assert_eq!(*x, 0);
 
         loop {
-            let res = rusti::atomic_cxchgweak_seqcst_seqcst(&mut *x, 0, 1);
+            let res = rusti::atomic_cxchgweak::<_, { SeqCst }, { SeqCst }>(&mut *x, 0, 1);
             assert_eq!(res.0, 0);
             if res.1 {
                 break;
@@ -53,7 +53,7 @@ pub fn main() {
         assert_eq!(*x, 1);
 
         loop {
-            let res = rusti::atomic_cxchgweak_acquire_acquire(&mut *x, 1, 2);
+            let res = rusti::atomic_cxchgweak::<_, { Acquire }, { Acquire }>(&mut *x, 1, 2);
             assert_eq!(res.0, 1);
             if res.1 {
                 break;
@@ -62,7 +62,7 @@ pub fn main() {
         assert_eq!(*x, 2);
 
         loop {
-            let res = rusti::atomic_cxchgweak_release_relaxed(&mut *x, 2, 3);
+            let res = rusti::atomic_cxchgweak::<_, { Release }, { Relaxed }>(&mut *x, 2, 3);
             assert_eq!(res.0, 2);
             if res.1 {
                 break;
diff --git a/tests/ui/intrinsics/intrinsic-inline-cc.rs b/tests/ui/intrinsics/intrinsic-inline-cc.rs
new file mode 100644
index 00000000000..f2b961a760b
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-inline-cc.rs
@@ -0,0 +1,9 @@
+//@ run-pass
+//@ aux-build:cci_intrinsic.rs
+
+extern crate cci_intrinsic;
+
+pub fn main() {
+    let val = cci_intrinsic::size_of_val(&[1u8, 2, 3]);
+    assert_eq!(val, 3);
+}
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
index 1d2c263baf1..10f4d8d1a71 100644
--- a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
@@ -2,13 +2,13 @@ error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at
   --> $DIR/intrinsic-raw_eq-const-bad.rs:4:5
    |
 LL |     std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16))
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `RAW_EQ_PADDING` failed here
 
 error[E0080]: unable to turn pointer into integer
   --> $DIR/intrinsic-raw_eq-const-bad.rs:9:5
    |
 LL |     std::intrinsics::raw_eq(&(&0), &(&1))
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `RAW_EQ_PTR` failed here
    |
    = 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
@@ -17,7 +17,7 @@ error[E0080]: accessing memory with alignment 1, but alignment 4 is required
   --> $DIR/intrinsic-raw_eq-const-bad.rs:16:5
    |
 LL |     std::intrinsics::raw_eq(aref, aref)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `RAW_EQ_NOT_ALIGNED` failed here
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/intrinsics/non-integer-atomic.rs b/tests/ui/intrinsics/non-integer-atomic.rs
index 5464bf747fa..853c163710f 100644
--- a/tests/ui/intrinsics/non-integer-atomic.rs
+++ b/tests/ui/intrinsics/non-integer-atomic.rs
@@ -4,7 +4,7 @@
 #![allow(warnings)]
 #![crate_type = "rlib"]
 
-use std::intrinsics::{self, AtomicOrdering};
+use std::intrinsics::{self, AtomicOrdering::*};
 
 #[derive(Copy, Clone)]
 pub struct Foo(i64);
@@ -12,81 +12,81 @@ pub type Bar = &'static dyn Fn();
 pub type Quux = [u8; 100];
 
 pub unsafe fn test_bool_load(p: &mut bool, v: bool) {
-    intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p);
+    intrinsics::atomic_load::<_, { SeqCst }>(p);
     //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `bool`
 }
 
 pub unsafe fn test_bool_store(p: &mut bool, v: bool) {
-    intrinsics::atomic_store_seqcst(p, v);
-    //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool`
+    intrinsics::atomic_store::<_, { SeqCst }>(p, v);
+    //~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `bool`
 }
 
 pub unsafe fn test_bool_xchg(p: &mut bool, v: bool) {
-    intrinsics::atomic_xchg_seqcst(p, v);
-    //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `bool`
+    intrinsics::atomic_xchg::<_, { SeqCst }>(p, v);
+    //~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `bool`
 }
 
 pub unsafe fn test_bool_cxchg(p: &mut bool, v: bool) {
-    intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
-    //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `bool`
+    intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v);
+    //~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `bool`
 }
 
 pub unsafe fn test_Foo_load(p: &mut Foo, v: Foo) {
-    intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p);
+    intrinsics::atomic_load::<_, { SeqCst }>(p);
     //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `Foo`
 }
 
 pub unsafe fn test_Foo_store(p: &mut Foo, v: Foo) {
-    intrinsics::atomic_store_seqcst(p, v);
-    //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo`
+    intrinsics::atomic_store::<_, { SeqCst }>(p, v);
+    //~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `Foo`
 }
 
 pub unsafe fn test_Foo_xchg(p: &mut Foo, v: Foo) {
-    intrinsics::atomic_xchg_seqcst(p, v);
-    //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `Foo`
+    intrinsics::atomic_xchg::<_, { SeqCst }>(p, v);
+    //~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `Foo`
 }
 
 pub unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) {
-    intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
-    //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `Foo`
+    intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v);
+    //~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `Foo`
 }
 
 pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) {
-    intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p);
+    intrinsics::atomic_load::<_, { SeqCst }>(p);
     //~^ ERROR expected basic integer type, found `&dyn Fn()`
 }
 
 pub unsafe fn test_Bar_store(p: &mut Bar, v: Bar) {
-    intrinsics::atomic_store_seqcst(p, v);
+    intrinsics::atomic_store::<_, { SeqCst }>(p, v);
     //~^ ERROR expected basic integer type, found `&dyn Fn()`
 }
 
 pub unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) {
-    intrinsics::atomic_xchg_seqcst(p, v);
+    intrinsics::atomic_xchg::<_, { SeqCst }>(p, v);
     //~^ ERROR expected basic integer type, found `&dyn Fn()`
 }
 
 pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) {
-    intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+    intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v);
     //~^ ERROR expected basic integer type, found `&dyn Fn()`
 }
 
 pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) {
-    intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p);
+    intrinsics::atomic_load::<_, { SeqCst }>(p);
     //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]`
 }
 
 pub unsafe fn test_Quux_store(p: &mut Quux, v: Quux) {
-    intrinsics::atomic_store_seqcst(p, v);
-    //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+    intrinsics::atomic_store::<_, { SeqCst }>(p, v);
+    //~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `[u8; 100]`
 }
 
 pub unsafe fn test_Quux_xchg(p: &mut Quux, v: Quux) {
-    intrinsics::atomic_xchg_seqcst(p, v);
-    //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+    intrinsics::atomic_xchg::<_, { SeqCst }>(p, v);
+    //~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `[u8; 100]`
 }
 
 pub unsafe fn test_Quux_cxchg(p: &mut Quux, v: Quux) {
-    intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
-    //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+    intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v);
+    //~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `[u8; 100]`
 }
diff --git a/tests/ui/intrinsics/non-integer-atomic.stderr b/tests/ui/intrinsics/non-integer-atomic.stderr
index 58c2dc00c66..e539d99b8ae 100644
--- a/tests/ui/intrinsics/non-integer-atomic.stderr
+++ b/tests/ui/intrinsics/non-integer-atomic.stderr
@@ -1,98 +1,98 @@
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `bool`
   --> $DIR/non-integer-atomic.rs:15:5
    |
-LL |     intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_load::<_, { SeqCst }>(p);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool`
+error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `bool`
   --> $DIR/non-integer-atomic.rs:20:5
    |
-LL |     intrinsics::atomic_store_seqcst(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_store::<_, { SeqCst }>(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `bool`
+error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `bool`
   --> $DIR/non-integer-atomic.rs:25:5
    |
-LL |     intrinsics::atomic_xchg_seqcst(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_xchg::<_, { SeqCst }>(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `bool`
+error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `bool`
   --> $DIR/non-integer-atomic.rs:30:5
    |
-LL |     intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `Foo`
   --> $DIR/non-integer-atomic.rs:35:5
    |
-LL |     intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_load::<_, { SeqCst }>(p);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo`
+error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `Foo`
   --> $DIR/non-integer-atomic.rs:40:5
    |
-LL |     intrinsics::atomic_store_seqcst(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_store::<_, { SeqCst }>(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `Foo`
+error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `Foo`
   --> $DIR/non-integer-atomic.rs:45:5
    |
-LL |     intrinsics::atomic_xchg_seqcst(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_xchg::<_, { SeqCst }>(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `Foo`
+error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `Foo`
   --> $DIR/non-integer-atomic.rs:50:5
    |
-LL |     intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `&dyn Fn()`
   --> $DIR/non-integer-atomic.rs:55:5
    |
-LL |     intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_load::<_, { SeqCst }>(p);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
+error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `&dyn Fn()`
   --> $DIR/non-integer-atomic.rs:60:5
    |
-LL |     intrinsics::atomic_store_seqcst(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_store::<_, { SeqCst }>(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
+error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `&dyn Fn()`
   --> $DIR/non-integer-atomic.rs:65:5
    |
-LL |     intrinsics::atomic_xchg_seqcst(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_xchg::<_, { SeqCst }>(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
+error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `&dyn Fn()`
   --> $DIR/non-integer-atomic.rs:70:5
    |
-LL |     intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]`
   --> $DIR/non-integer-atomic.rs:75:5
    |
-LL |     intrinsics::atomic_load::<_, { AtomicOrdering::SeqCst }>(p);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_load::<_, { SeqCst }>(p);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `[u8; 100]`
   --> $DIR/non-integer-atomic.rs:80:5
    |
-LL |     intrinsics::atomic_store_seqcst(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_store::<_, { SeqCst }>(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `[u8; 100]`
   --> $DIR/non-integer-atomic.rs:85:5
    |
-LL |     intrinsics::atomic_xchg_seqcst(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_xchg::<_, { SeqCst }>(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `[u8; 100]`
   --> $DIR/non-integer-atomic.rs:90:5
    |
-LL |     intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_cxchg::<_, { SeqCst }, { SeqCst }>(p, v, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 16 previous errors
 
diff --git a/tests/ui/issues/issue-16048.stderr b/tests/ui/issues/issue-16048.stderr
index 73610942d7a..f97f13152bc 100644
--- a/tests/ui/issues/issue-16048.stderr
+++ b/tests/ui/issues/issue-16048.stderr
@@ -11,9 +11,13 @@ error[E0605]: non-primitive cast: `Foo<'a>` as `T`
   --> $DIR/issue-16048.rs:24:16
    |
 LL |         return *self as T;
-   |                ^^^^^^^^^^ help: consider using the `From` trait instead: `T::from(*self)`
+   |                ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+   |
+help: consider using the `From` trait instead
+   |
+LL -         return *self as T;
+LL +         return T::from(*self);
    |
-   = note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/issues/issue-17441.stderr b/tests/ui/issues/issue-17441.stderr
index 29e50b91c7c..96aad879e24 100644
--- a/tests/ui/issues/issue-17441.stderr
+++ b/tests/ui/issues/issue-17441.stderr
@@ -2,17 +2,23 @@ error[E0620]: cast to unsized type: `&[usize; 2]` as `[usize]`
   --> $DIR/issue-17441.rs:2:16
    |
 LL |     let _foo = &[1_usize, 2] as [usize];
-   |                ^^^^^^^^^^^^^^^^^-------
-   |                                 |
-   |                                 help: try casting to a reference instead: `&[usize]`
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider casting to a reference instead
+   |
+LL |     let _foo = &[1_usize, 2] as &[usize];
+   |                                 +
 
 error[E0620]: cast to unsized type: `Box<usize>` as `dyn Debug`
   --> $DIR/issue-17441.rs:5:16
    |
 LL |     let _bar = Box::new(1_usize) as dyn std::fmt::Debug;
-   |                ^^^^^^^^^^^^^^^^^^^^^-------------------
-   |                                     |
-   |                                     help: you can cast to a `Box` instead: `Box<dyn std::fmt::Debug>`
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: you can cast to a `Box` instead
+   |
+LL |     let _bar = Box::new(1_usize) as Box<dyn std::fmt::Debug>;
+   |                                     ++++                   +
 
 error[E0620]: cast to unsized type: `usize` as `dyn Debug`
   --> $DIR/issue-17441.rs:8:16
diff --git a/tests/ui/issues/issue-2502.rs b/tests/ui/issues/issue-2502.rs
index dfc0995104e..98a52a3b5a7 100644
--- a/tests/ui/issues/issue-2502.rs
+++ b/tests/ui/issues/issue-2502.rs
@@ -14,7 +14,7 @@ impl<'a> font<'a> {
     }
 }
 
-fn font(fontbuf: &Vec<u8> ) -> font {
+fn font(fontbuf: &Vec<u8> ) -> font<'_> {
     font {
         fontbuf: fontbuf
     }
diff --git a/tests/ui/issues/issue-42552.rs b/tests/ui/issues/issue-42552.rs
index 998cde44be0..734921d9b01 100644
--- a/tests/ui/issues/issue-42552.rs
+++ b/tests/ui/issues/issue-42552.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 // Regression test for an obscure issue with the projection cache.
 
-fn into_iter<I: Iterator>(a: &I) -> Groups<I> {
+fn into_iter<I: Iterator>(a: &I) -> Groups<'_, I> {
     Groups { _a: a }
 }
 
diff --git a/tests/ui/issues/issue-5708.rs b/tests/ui/issues/issue-5708.rs
index ce9ef78ffcd..6fa3cfa4724 100644
--- a/tests/ui/issues/issue-5708.rs
+++ b/tests/ui/issues/issue-5708.rs
@@ -25,7 +25,7 @@ struct Outer<'a> {
 }
 
 impl<'a> Outer<'a> {
-    fn new(inner: &dyn Inner) -> Outer {
+    fn new(inner: &dyn Inner) -> Outer<'_> {
         Outer {
             inner: inner
         }
diff --git a/tests/ui/issues/issue-76191.stderr b/tests/ui/issues/issue-76191.stderr
index 1f19db49c43..d8b54be88f4 100644
--- a/tests/ui/issues/issue-76191.stderr
+++ b/tests/ui/issues/issue-76191.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: explicit panic
   --> $DIR/issue-76191.rs:8:37
    |
 LL | const RANGE2: RangeInclusive<i32> = panic!();
-   |                                     ^^^^^^^^ evaluation of constant value failed here
+   |                                     ^^^^^^^^ evaluation of `RANGE2` failed here
 
 error[E0308]: mismatched types
   --> $DIR/issue-76191.rs:14:9
diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs
index 7676b5557d2..25a4ff283ba 100644
--- a/tests/ui/lang-items/lang-item-generic-requirements.rs
+++ b/tests/ui/lang-items/lang-item-generic-requirements.rs
@@ -48,6 +48,7 @@ fn ice() {
 
     // Use index
     let arr = [0; 5];
+    //~^ ERROR requires `copy` lang_item
     let _ = arr[2];
     //~^ ERROR cannot index into a value of type `[{integer}; 5]`
 
@@ -61,5 +62,3 @@ fn ice() {
 
 // use `start`
 fn main() {}
-
-//~? ERROR requires `copy` lang_item
diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr
index 409fa05d637..c82bdb00fd1 100644
--- a/tests/ui/lang-items/lang-item-generic-requirements.stderr
+++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr
@@ -77,13 +77,13 @@ LL |     r + a;
    |     {integer}
 
 error[E0608]: cannot index into a value of type `[{integer}; 5]`
-  --> $DIR/lang-item-generic-requirements.rs:51:16
+  --> $DIR/lang-item-generic-requirements.rs:52:16
    |
 LL |     let _ = arr[2];
    |                ^^^
 
 error[E0308]: mismatched types
-  --> $DIR/lang-item-generic-requirements.rs:58:17
+  --> $DIR/lang-item-generic-requirements.rs:59:17
    |
 LL |     let _: () = Foo;
    |            --   ^^^ expected `()`, found `Foo`
@@ -91,6 +91,10 @@ LL |     let _: () = Foo;
    |            expected due to this
 
 error: requires `copy` lang_item
+  --> $DIR/lang-item-generic-requirements.rs:50:16
+   |
+LL |     let arr = [0; 5];
+   |                ^
 
 error: aborting due to 12 previous errors
 
diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr
index abaa16cdefa..b2ce6385ab6 100644
--- a/tests/ui/layout/debug.stderr
+++ b/tests/ui/layout/debug.stderr
@@ -6,9 +6,8 @@ LL | union EmptyUnion {}
 
 error: layout_of(E) = Layout {
            size: Size(12 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -45,9 +44,8 @@ error: layout_of(E) = Layout {
                variants: [
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -67,9 +65,8 @@ error: layout_of(E) = Layout {
                    },
                    Layout {
                        size: Size(12 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -108,9 +105,8 @@ LL | enum E { Foo, Bar(!, i32, i32) }
 
 error: layout_of(S) = Layout {
            size: Size(8 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -156,9 +152,8 @@ LL | struct S { f1: i32, f2: (), f3: i32 }
 
 error: layout_of(U) = Layout {
            size: Size(8 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -182,9 +177,8 @@ LL | union U { f1: (i32, i32), f3: i32 }
 
 error: layout_of(Result<i32, i32>) = Layout {
            size: Size(8 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -234,9 +228,8 @@ error: layout_of(Result<i32, i32>) = Layout {
                variants: [
                    Layout {
                        size: Size(8 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -273,9 +266,8 @@ error: layout_of(Result<i32, i32>) = Layout {
                    },
                    Layout {
                        size: Size(8 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -323,9 +315,8 @@ LL | type Test = Result<i32, i32>;
 
 error: layout_of(i32) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -353,9 +344,8 @@ LL | type T = impl std::fmt::Debug;
 
 error: layout_of(V) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(2 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -379,9 +369,8 @@ LL | pub union V {
 
 error: layout_of(W) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(2 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -405,9 +394,8 @@ LL | pub union W {
 
 error: layout_of(Y) = Layout {
            size: Size(0 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(2 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -431,9 +419,8 @@ LL | pub union Y {
 
 error: layout_of(P1) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -457,9 +444,8 @@ LL | union P1 { x: u32 }
 
 error: layout_of(P2) = Layout {
            size: Size(8 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -483,9 +469,8 @@ LL | union P2 { x: (u32, u32) }
 
 error: layout_of(P3) = Layout {
            size: Size(16 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -509,9 +494,8 @@ LL | union P3 { x: F32x4 }
 
 error: layout_of(P4) = Layout {
            size: Size(12 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -535,9 +519,8 @@ LL | union P4 { x: E }
 
 error: layout_of(P5) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Union {
@@ -566,9 +549,8 @@ LL | union P5 { zst: [u16; 0], byte: u8 }
 
 error: layout_of(MaybeUninit<u8>) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Union {
diff --git a/tests/ui/layout/enum.stderr b/tests/ui/layout/enum.stderr
index 7f0b38d0a07..f95b577bfc9 100644
--- a/tests/ui/layout/enum.stderr
+++ b/tests/ui/layout/enum.stderr
@@ -1,4 +1,4 @@
-error: align: AbiAndPrefAlign { abi: Align(2 bytes), pref: $PREF_ALIGN }
+error: align: AbiAlign { abi: Align(2 bytes) }
   --> $DIR/enum.rs:9:1
    |
 LL | enum UninhabitedVariantAlign {
diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr
index 9c3a8662d4f..d910456c0e6 100644
--- a/tests/ui/layout/hexagon-enum.stderr
+++ b/tests/ui/layout/hexagon-enum.stderr
@@ -1,8 +1,7 @@
 error: layout_of(A) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: Align(1 bytes),
            },
            backend_repr: Scalar(
                Initialized {
@@ -45,9 +44,8 @@ error: layout_of(A) = Layout {
                variants: [
                    Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: Align(1 bytes),
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -78,9 +76,8 @@ LL | enum A { Apple }
 
 error: layout_of(B) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: Align(1 bytes),
            },
            backend_repr: Scalar(
                Initialized {
@@ -123,9 +120,8 @@ error: layout_of(B) = Layout {
                variants: [
                    Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: Align(1 bytes),
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -156,9 +152,8 @@ LL | enum B { Banana = 255, }
 
 error: layout_of(C) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(2 bytes),
-               pref: Align(2 bytes),
            },
            backend_repr: Scalar(
                Initialized {
@@ -201,9 +196,8 @@ error: layout_of(C) = Layout {
                variants: [
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(2 bytes),
-                           pref: Align(2 bytes),
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -234,9 +228,8 @@ LL | enum C { Chaenomeles = 256, }
 
 error: layout_of(P) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: Align(4 bytes),
            },
            backend_repr: Scalar(
                Initialized {
@@ -279,9 +272,8 @@ error: layout_of(P) = Layout {
                variants: [
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: Align(4 bytes),
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -312,9 +304,8 @@ LL | enum P { Peach = 0x1000_0000isize, }
 
 error: layout_of(T) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: Align(4 bytes),
            },
            backend_repr: Scalar(
                Initialized {
@@ -357,9 +348,8 @@ error: layout_of(T) = Layout {
                variants: [
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: Align(4 bytes),
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/layout/invalid-unsized-const-eval.stderr b/tests/ui/layout/invalid-unsized-const-eval.stderr
index 073568883c4..d5a294d11f4 100644
--- a/tests/ui/layout/invalid-unsized-const-eval.stderr
+++ b/tests/ui/layout/invalid-unsized-const-eval.stderr
@@ -11,7 +11,7 @@ error[E0080]: the type `(dyn Sync, ())` has an unknown layout
   --> $DIR/invalid-unsized-const-eval.rs:12:1
    |
 LL | static EMPTY_SET: LazyLock = todo!();
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `EMPTY_SET` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr b/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr
index e08107f5f8e..1a43fd4ad18 100644
--- a/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr
+++ b/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr
@@ -22,7 +22,7 @@ error[E0080]: the type `MySlice<[bool]>` has an unknown layout
   --> $DIR/invalid-unsized-in-always-sized-tail.rs:15:28
    |
 LL | static CHECK: () = assert!(align_of::<P2>() == 1);
-   |                            ^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                            ^^^^^^^^^^^^^^^^ evaluation of `CHECK` failed inside this call
    |
 note: inside `align_of::<P2>`
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
index ef7f0cd2d1c..2087fedeb19 100644
--- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
+++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
@@ -1,8 +1,7 @@
 error: layout_of(MissingPayloadField) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -51,9 +50,8 @@ error: layout_of(MissingPayloadField) = Layout {
                variants: [
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -89,9 +87,8 @@ error: layout_of(MissingPayloadField) = Layout {
                    },
                    Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -122,9 +119,8 @@ LL | pub enum MissingPayloadField {
 
 error: layout_of(CommonPayloadField) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -174,9 +170,8 @@ error: layout_of(CommonPayloadField) = Layout {
                variants: [
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -213,9 +208,8 @@ error: layout_of(CommonPayloadField) = Layout {
                    },
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -263,9 +257,8 @@ LL | pub enum CommonPayloadField {
 
 error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -314,9 +307,8 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
                variants: [
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -352,9 +344,8 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
                    },
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -401,9 +392,8 @@ LL | pub enum CommonPayloadFieldIsMaybeUninit {
 
 error: layout_of(NicheFirst) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -456,9 +446,8 @@ error: layout_of(NicheFirst) = Layout {
                variants: [
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -506,9 +495,8 @@ error: layout_of(NicheFirst) = Layout {
                    },
                    Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -528,9 +516,8 @@ error: layout_of(NicheFirst) = Layout {
                    },
                    Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -561,9 +548,8 @@ LL | pub enum NicheFirst {
 
 error: layout_of(NicheSecond) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -616,9 +602,8 @@ error: layout_of(NicheSecond) = Layout {
                variants: [
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -666,9 +651,8 @@ error: layout_of(NicheSecond) = Layout {
                    },
                    Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -688,9 +672,8 @@ error: layout_of(NicheSecond) = Layout {
                    },
                    Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr
index a9081afc509..6bcc5b4906b 100644
--- a/tests/ui/layout/issue-96185-overaligned-enum.stderr
+++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr
@@ -1,8 +1,7 @@
 error: layout_of(Aligned1) = Layout {
            size: Size(8 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(8 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -39,9 +38,8 @@ error: layout_of(Aligned1) = Layout {
                variants: [
                    Layout {
                        size: Size(8 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -63,9 +61,8 @@ error: layout_of(Aligned1) = Layout {
                    },
                    Layout {
                        size: Size(8 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -100,9 +97,8 @@ LL | pub enum Aligned1 {
 
 error: layout_of(Aligned2) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -145,9 +141,8 @@ error: layout_of(Aligned2) = Layout {
                variants: [
                    Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -169,9 +164,8 @@ error: layout_of(Aligned2) = Layout {
                    },
                    Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr b/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr
index c85c40d5bda..ea29320002b 100644
--- a/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr
+++ b/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr
@@ -26,7 +26,7 @@ error[E0080]: the type `ArenaSet<Vec<u8>, [u8]>` has an unknown layout
   --> $DIR/issue-unsized-tail-restatic-ice-122488.rs:8:1
    |
 LL | const DATA: *const ArenaSet<Vec<u8>> = std::ptr::null_mut();
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `DATA` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr
index b635d1a45bb..9bd8ced0c02 100644
--- a/tests/ui/layout/thumb-enum.stderr
+++ b/tests/ui/layout/thumb-enum.stderr
@@ -1,8 +1,7 @@
 error: layout_of(A) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: Align(4 bytes),
            },
            backend_repr: Scalar(
                Initialized {
@@ -45,9 +44,8 @@ error: layout_of(A) = Layout {
                variants: [
                    Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: Align(4 bytes),
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -78,9 +76,8 @@ LL | enum A { Apple }
 
 error: layout_of(B) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: Align(4 bytes),
            },
            backend_repr: Scalar(
                Initialized {
@@ -123,9 +120,8 @@ error: layout_of(B) = Layout {
                variants: [
                    Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: Align(4 bytes),
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -156,9 +152,8 @@ LL | enum B { Banana = 255, }
 
 error: layout_of(C) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(2 bytes),
-               pref: Align(4 bytes),
            },
            backend_repr: Scalar(
                Initialized {
@@ -201,9 +196,8 @@ error: layout_of(C) = Layout {
                variants: [
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(2 bytes),
-                           pref: Align(4 bytes),
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -234,9 +228,8 @@ LL | enum C { Chaenomeles = 256, }
 
 error: layout_of(P) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: Align(4 bytes),
            },
            backend_repr: Scalar(
                Initialized {
@@ -279,9 +272,8 @@ error: layout_of(P) = Layout {
                variants: [
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: Align(4 bytes),
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -312,9 +304,8 @@ LL | enum P { Peach = 0x1000_0000isize, }
 
 error: layout_of(T) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: Align(4 bytes),
            },
            backend_repr: Scalar(
                Initialized {
@@ -357,9 +348,8 @@ error: layout_of(T) = Layout {
                variants: [
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: Align(4 bytes),
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr b/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr
index fa58b1f8fe4..43fe9e3a7a7 100644
--- a/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr
+++ b/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr
@@ -2,7 +2,7 @@ error[E0080]: the type `Option<str>` has an unknown layout
   --> $DIR/uncomputable-due-to-trivial-bounds-ice-135138.rs:7:16
    |
 LL |     [(); { let _a: Option<str> = None; 0 }];
-   |                ^^ evaluation of constant value failed here
+   |                ^^ evaluation of `return_str::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/layout/unknown-when-no-type-parameter.rs b/tests/ui/layout/unknown-when-no-type-parameter.rs
index 81386feaacf..f787998868d 100644
--- a/tests/ui/layout/unknown-when-no-type-parameter.rs
+++ b/tests/ui/layout/unknown-when-no-type-parameter.rs
@@ -11,7 +11,7 @@ where
     [(); size_of::<<() as Project>::Assoc>()];
     //~^ ERROR the type `<() as Project>::Assoc` has an unknown layout
     //~| NOTE inside `std::mem::size_of::<<() as Project>::Assoc>`
-    //~| NOTE evaluation of constant value failed
+    //~| NOTE failed inside this call
 }
 
 fn main() {}
diff --git a/tests/ui/layout/unknown-when-no-type-parameter.stderr b/tests/ui/layout/unknown-when-no-type-parameter.stderr
index f0a64960c6a..9bb42c46ec3 100644
--- a/tests/ui/layout/unknown-when-no-type-parameter.stderr
+++ b/tests/ui/layout/unknown-when-no-type-parameter.stderr
@@ -2,7 +2,7 @@ error[E0080]: the type `<() as Project>::Assoc` has an unknown layout
   --> $DIR/unknown-when-no-type-parameter.rs:11:10
    |
 LL |     [(); size_of::<<() as Project>::Assoc>()];
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `foo::{constant#0}` failed inside this call
    |
 note: inside `std::mem::size_of::<<() as Project>::Assoc>`
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
diff --git a/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr b/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr
index 8cf5ce7c22d..fd9eedc9267 100644
--- a/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr
+++ b/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr
@@ -2,7 +2,7 @@ error[E0080]: the type `str` has an unknown layout
   --> $DIR/unknown-when-ptr-metadata-is-DST.rs:8:16
    |
 LL |     [(); { let _a: Option<&str> = None; 0 }];
-   |                ^^ evaluation of constant value failed here
+   |                ^^ evaluation of `return_str::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr
index 1ba184bdace..1707b8aff81 100644
--- a/tests/ui/layout/zero-sized-array-enum-niche.stderr
+++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr
@@ -1,8 +1,7 @@
 error: layout_of(Result<[u32; 0], bool>) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -39,9 +38,8 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
                variants: [
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -65,9 +63,8 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
                    },
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -111,9 +108,8 @@ LL | type AlignedResult = Result<[u32; 0], bool>;
 
 error: layout_of(MultipleAlignments) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -150,9 +146,8 @@ error: layout_of(MultipleAlignments) = Layout {
                variants: [
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(2 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -176,9 +171,8 @@ error: layout_of(MultipleAlignments) = Layout {
                    },
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -202,9 +196,8 @@ error: layout_of(MultipleAlignments) = Layout {
                    },
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -248,9 +241,8 @@ LL | enum MultipleAlignments {
 
 error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -287,9 +279,8 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
                variants: [
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -313,9 +304,8 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
                    },
                    Layout {
                        size: Size(3 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -359,9 +349,8 @@ LL | type NicheLosesToTagged = Result<[u32; 0], Packed<std::num::NonZero<u16>>>;
 
 error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $PREF_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -402,9 +391,8 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
                variants: [
                    Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -428,9 +416,8 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
                    },
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $PREF_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
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
index e0d25742502..b97f770c97f 100644
--- a/tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr
+++ b/tests/ui/lazy-type-alias/def-site-param-defaults-wf.stderr
@@ -2,7 +2,7 @@ error[E0080]: attempt to compute `0_usize - 1_usize`, which would overflow
   --> $DIR/def-site-param-defaults-wf.rs:5:45
    |
 LL | type Alias<T = Vec<str>, const N: usize = { 0 - 1 }> = T;
-   |                                             ^^^^^ evaluation of constant value failed here
+   |                                             ^^^^^ evaluation of `Alias::{constant#0}` failed here
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/def-site-param-defaults-wf.rs:5:16
diff --git a/tests/ui/lifetimes/constructor-lifetime-early-binding-error.rs b/tests/ui/lifetimes/constructor-lifetime-early-binding-error.rs
new file mode 100644
index 00000000000..2d5a444a942
--- /dev/null
+++ b/tests/ui/lifetimes/constructor-lifetime-early-binding-error.rs
@@ -0,0 +1,22 @@
+//! Tests that all lifetime parameters in struct (`S`) and enum (`E`) constructors are
+//! treated as early bound, similar to associated items, rather than late bound as in manual
+//! constructors.
+
+struct S<'a, 'b>(&'a u8, &'b u8);
+enum E<'a, 'b> {
+    V(&'a u8),
+    U(&'b u8),
+}
+
+fn main() {
+    S(&0, &0); // OK
+    S::<'static>(&0, &0);
+    //~^ ERROR struct takes 2 lifetime arguments
+    S::<'static, 'static, 'static>(&0, &0);
+    //~^ ERROR struct takes 2 lifetime arguments
+    E::V(&0); // OK
+    E::V::<'static>(&0);
+    //~^ ERROR enum takes 2 lifetime arguments
+    E::V::<'static, 'static, 'static>(&0);
+    //~^ ERROR enum takes 2 lifetime arguments
+}
diff --git a/tests/ui/constructor-lifetime-args.stderr b/tests/ui/lifetimes/constructor-lifetime-early-binding-error.stderr
index d3759f4b365..94699a3509b 100644
--- a/tests/ui/constructor-lifetime-args.stderr
+++ b/tests/ui/lifetimes/constructor-lifetime-early-binding-error.stderr
@@ -1,5 +1,5 @@
 error[E0107]: struct takes 2 lifetime arguments but 1 lifetime argument was supplied
-  --> $DIR/constructor-lifetime-args.rs:17:5
+  --> $DIR/constructor-lifetime-early-binding-error.rs:13:5
    |
 LL |     S::<'static>(&0, &0);
    |     ^   ------- supplied 1 lifetime argument
@@ -7,7 +7,7 @@ LL |     S::<'static>(&0, &0);
    |     expected 2 lifetime arguments
    |
 note: struct defined here, with 2 lifetime parameters: `'a`, `'b`
-  --> $DIR/constructor-lifetime-args.rs:9:8
+  --> $DIR/constructor-lifetime-early-binding-error.rs:5:8
    |
 LL | struct S<'a, 'b>(&'a u8, &'b u8);
    |        ^ --  --
@@ -17,7 +17,7 @@ LL |     S::<'static, 'static>(&0, &0);
    |                +++++++++
 
 error[E0107]: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
-  --> $DIR/constructor-lifetime-args.rs:19:5
+  --> $DIR/constructor-lifetime-early-binding-error.rs:15:5
    |
 LL |     S::<'static, 'static, 'static>(&0, &0);
    |     ^                   --------- help: remove the lifetime argument
@@ -25,13 +25,13 @@ LL |     S::<'static, 'static, 'static>(&0, &0);
    |     expected 2 lifetime arguments
    |
 note: struct defined here, with 2 lifetime parameters: `'a`, `'b`
-  --> $DIR/constructor-lifetime-args.rs:9:8
+  --> $DIR/constructor-lifetime-early-binding-error.rs:5:8
    |
 LL | struct S<'a, 'b>(&'a u8, &'b u8);
    |        ^ --  --
 
 error[E0107]: enum takes 2 lifetime arguments but 1 lifetime argument was supplied
-  --> $DIR/constructor-lifetime-args.rs:22:8
+  --> $DIR/constructor-lifetime-early-binding-error.rs:18:8
    |
 LL |     E::V::<'static>(&0);
    |        ^   ------- supplied 1 lifetime argument
@@ -39,7 +39,7 @@ LL |     E::V::<'static>(&0);
    |        expected 2 lifetime arguments
    |
 note: enum defined here, with 2 lifetime parameters: `'a`, `'b`
-  --> $DIR/constructor-lifetime-args.rs:10:6
+  --> $DIR/constructor-lifetime-early-binding-error.rs:6:6
    |
 LL | enum E<'a, 'b> {
    |      ^ --  --
@@ -49,7 +49,7 @@ LL |     E::V::<'static, 'static>(&0);
    |                   +++++++++
 
 error[E0107]: enum takes 2 lifetime arguments but 3 lifetime arguments were supplied
-  --> $DIR/constructor-lifetime-args.rs:24:8
+  --> $DIR/constructor-lifetime-early-binding-error.rs:20:8
    |
 LL |     E::V::<'static, 'static, 'static>(&0);
    |        ^                   --------- help: remove the lifetime argument
@@ -57,7 +57,7 @@ LL |     E::V::<'static, 'static, 'static>(&0);
    |        expected 2 lifetime arguments
    |
 note: enum defined here, with 2 lifetime parameters: `'a`, `'b`
-  --> $DIR/constructor-lifetime-args.rs:10:6
+  --> $DIR/constructor-lifetime-early-binding-error.rs:6:6
    |
 LL | enum E<'a, 'b> {
    |      ^ --  --
diff --git a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed
index 2ceaaf0339d..bcc4abc47e1 100644
--- a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed
+++ b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed
@@ -28,6 +28,7 @@ impl Greeter1 for FixedGreeter<'_> {
 struct Greetings(pub Vec<String>);
 
 impl Greetings {
+    #[expect(mismatched_lifetime_syntaxes)]
     pub fn get(&self, i: usize) -> BoxedGreeter {
         (Box::new(FixedGreeter(&self.0[i])), Box::new(FixedGreeter(&self.0[i])))
         //~^ ERROR lifetime may not live long enough
diff --git a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs
index e7d427517b5..9ca6077f47f 100644
--- a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs
+++ b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs
@@ -28,6 +28,7 @@ impl Greeter1 for FixedGreeter<'_> {
 struct Greetings(pub Vec<String>);
 
 impl Greetings {
+    #[expect(mismatched_lifetime_syntaxes)]
     pub fn get(&self, i: usize) -> BoxedGreeter {
         (Box::new(FixedGreeter(&self.0[i])), Box::new(FixedGreeter(&self.0[i])))
         //~^ ERROR lifetime may not live long enough
diff --git a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr
index 24bb9e2ef7d..2eba3ff418b 100644
--- a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr
+++ b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs:32:9
+  --> $DIR/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs:33:9
    |
 LL |     pub fn get(&self, i: usize) -> BoxedGreeter {
    |                - let's call the lifetime of this reference `'1`
diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
index 63a2c9be9eb..d0a8fe795ef 100644
--- a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
+++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
@@ -47,6 +47,5 @@ fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
 
 // This is ok because both `'a` are for the same parameter.
 fn m<'a>(_: &'a Foo<'a>) -> &str { "" }
-//~^ WARNING elided lifetime has a name
 
 fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
index f835d2655bb..23ef36888f0 100644
--- a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
+++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
@@ -105,16 +105,6 @@ help: consider using the `'a` lifetime
 LL | fn l<'a>(_: &'a str, _: &'a str) -> &'a str { "" }
    |                                      ++
 
-warning: elided lifetime has a name
-  --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:49:29
-   |
-LL | fn m<'a>(_: &'a Foo<'a>) -> &str { "" }
-   |      --                     ^ this elided lifetime gets resolved as `'a`
-   |      |
-   |      lifetime `'a` declared here
-   |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
-
-error: aborting due to 7 previous errors; 1 warning emitted
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs
index 598633d7576..5dbc0c556fb 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs
@@ -4,12 +4,8 @@ struct Foo {
 
 impl Foo {
   fn foo<'a>(&'a self, x: &i32) -> &i32 {
-    //~^ WARNING elided lifetime has a name
-
     if true { &self.field } else { x } //~ ERROR explicit lifetime
-
   }
-
 }
 
 fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
index 2d5d4fb0e72..071bda24ef8 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
@@ -1,22 +1,11 @@
-warning: elided lifetime has a name
-  --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:6:36
-   |
-LL |   fn foo<'a>(&'a self, x: &i32) -> &i32 {
-   |          --                        ^ this elided lifetime gets resolved as `'a`
-   |          |
-   |          lifetime `'a` declared here
-   |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
-
 error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:9:36
+  --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:7:36
    |
 LL |   fn foo<'a>(&'a self, x: &i32) -> &i32 {
    |                           ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
-...
 LL |     if true { &self.field } else { x }
    |                                    ^ lifetime `'a` required
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs
index eac7c32a9aa..1804003d367 100644
--- a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.rs
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs
@@ -1,10 +1,10 @@
-#![deny(elided_named_lifetimes)]
+#![deny(mismatched_lifetime_syntaxes)]
 
 struct Foo;
 
 impl Foo {
     pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
-        //~^ ERROR elided lifetime has a name
+        //~^ ERROR lifetime flowing from input to output with different syntax
         unsafe { &mut *(x as *mut _) }
     }
 }
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr
new file mode 100644
index 00000000000..7c7411651d0
--- /dev/null
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr
@@ -0,0 +1,20 @@
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/example-from-issue48686.rs:6:21
+   |
+LL |     pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
+   |                     ^^^^^^^                      ------- the lifetime gets resolved as `'static`
+   |                     |
+   |                     this lifetime flows to the output
+   |
+note: the lint level is defined here
+  --> $DIR/example-from-issue48686.rs:1:9
+   |
+LL | #![deny(mismatched_lifetime_syntaxes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: one option is to consistently use `'static`
+   |
+LL |     pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 {
+   |                                                   +++++++
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs
new file mode 100644
index 00000000000..3d5aab5c829
--- /dev/null
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs
@@ -0,0 +1,27 @@
+#![deny(mismatched_lifetime_syntaxes)]
+
+fn ampersand<'a>(x: &'a u8) -> &u8 {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    x
+}
+
+struct Brackets<'a>(&'a u8);
+
+fn brackets<'a>(x: &'a u8) -> Brackets {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    Brackets(x)
+}
+
+struct Comma<'a, T>(&'a T);
+
+fn comma<'a>(x: &'a u8) -> Comma<u8> {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    Comma(x)
+}
+
+fn underscore<'a>(x: &'a u8) -> &'_ u8 {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    x
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr
new file mode 100644
index 00000000000..681b3c97052
--- /dev/null
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr
@@ -0,0 +1,60 @@
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/missing-lifetime-kind.rs:3:22
+   |
+LL | fn ampersand<'a>(x: &'a u8) -> &u8 {
+   |                      ^^        --- the lifetime gets resolved as `'a`
+   |                      |
+   |                      this lifetime flows to the output
+   |
+note: the lint level is defined here
+  --> $DIR/missing-lifetime-kind.rs:1:9
+   |
+LL | #![deny(mismatched_lifetime_syntaxes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: one option is to consistently use `'a`
+   |
+LL | fn ampersand<'a>(x: &'a u8) -> &'a u8 {
+   |                                 ++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/missing-lifetime-kind.rs:10:21
+   |
+LL | fn brackets<'a>(x: &'a u8) -> Brackets {
+   |                     ^^        -------- the lifetime gets resolved as `'a`
+   |                     |
+   |                     this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL | fn brackets<'a>(x: &'a u8) -> Brackets<'a> {
+   |                                       ++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/missing-lifetime-kind.rs:17:18
+   |
+LL | fn comma<'a>(x: &'a u8) -> Comma<u8> {
+   |                  ^^        --------- the lifetime gets resolved as `'a`
+   |                  |
+   |                  this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL | fn comma<'a>(x: &'a u8) -> Comma<'a, u8> {
+   |                                  +++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/missing-lifetime-kind.rs:22:23
+   |
+LL | fn underscore<'a>(x: &'a u8) -> &'_ u8 {
+   |                       ^^         -- the lifetime gets resolved as `'a`
+   |                       |
+   |                       this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL - fn underscore<'a>(x: &'a u8) -> &'_ u8 {
+LL + fn underscore<'a>(x: &'a u8) -> &'a u8 {
+   |
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs
new file mode 100644
index 00000000000..cc398ab7888
--- /dev/null
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs
@@ -0,0 +1,20 @@
+#![allow(mismatched_lifetime_syntaxes)]
+
+//! Ensure that the lint level of `mismatched_lifetime_syntaxes` can
+//! be adjusted by attributes not applied at the crate-level.
+
+#[warn(mismatched_lifetime_syntaxes)]
+mod foo {
+    fn bar(x: &'static u8) -> &u8 {
+        //~^ WARNING lifetime flowing from input to output with different syntax
+        x
+    }
+
+    #[deny(mismatched_lifetime_syntaxes)]
+    fn baz(x: &'static u8) -> &u8 {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        x
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr
new file mode 100644
index 00000000000..da691225c17
--- /dev/null
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr
@@ -0,0 +1,38 @@
+warning: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/not-tied-to-crate.rs:8:16
+   |
+LL |     fn bar(x: &'static u8) -> &u8 {
+   |                ^^^^^^^        --- the lifetime gets resolved as `'static`
+   |                |
+   |                this lifetime flows to the output
+   |
+note: the lint level is defined here
+  --> $DIR/not-tied-to-crate.rs:6:8
+   |
+LL | #[warn(mismatched_lifetime_syntaxes)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: one option is to consistently use `'static`
+   |
+LL |     fn bar(x: &'static u8) -> &'static u8 {
+   |                                +++++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/not-tied-to-crate.rs:14:16
+   |
+LL |     fn baz(x: &'static u8) -> &u8 {
+   |                ^^^^^^^        --- the lifetime gets resolved as `'static`
+   |                |
+   |                this lifetime flows to the output
+   |
+note: the lint level is defined here
+  --> $DIR/not-tied-to-crate.rs:13:12
+   |
+LL |     #[deny(mismatched_lifetime_syntaxes)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: one option is to consistently use `'static`
+   |
+LL |     fn baz(x: &'static u8) -> &'static u8 {
+   |                                +++++++
+
+error: aborting due to 1 previous error; 1 warning emitted
+
diff --git a/tests/ui/lint/elided-named-lifetimes/static.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs
index dc8222c6e6e..47ae258f138 100644
--- a/tests/ui/lint/elided-named-lifetimes/static.rs
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs
@@ -1,4 +1,4 @@
-#![deny(elided_named_lifetimes)]
+#![deny(mismatched_lifetime_syntaxes)]
 
 use std::borrow::Cow;
 
@@ -14,26 +14,26 @@ impl Trait for () {
 }
 
 fn ampersand(x: &'static u8) -> &u8 {
-    //~^ ERROR elided lifetime has a name
+    //~^ ERROR lifetime flowing from input to output with different syntax
     x
 }
 
 struct Brackets<'a>(&'a u8);
 
 fn brackets(x: &'static u8) -> Brackets {
-    //~^ ERROR elided lifetime has a name
+    //~^ ERROR lifetime flowing from input to output with different syntax
     Brackets(x)
 }
 
 struct Comma<'a, T>(&'a T);
 
 fn comma(x: &'static u8) -> Comma<u8> {
-    //~^ ERROR elided lifetime has a name
+    //~^ ERROR lifetime flowing from input to output with different syntax
     Comma(x)
 }
 
 fn underscore(x: &'static u8) -> &'_ u8 {
-    //~^ ERROR elided lifetime has a name
+    //~^ ERROR lifetime flowing from input to output with different syntax
     x
 }
 
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr
new file mode 100644
index 00000000000..5b9a986bcbe
--- /dev/null
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr
@@ -0,0 +1,60 @@
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/static.rs:16:18
+   |
+LL | fn ampersand(x: &'static u8) -> &u8 {
+   |                  ^^^^^^^        --- the lifetime gets resolved as `'static`
+   |                  |
+   |                  this lifetime flows to the output
+   |
+note: the lint level is defined here
+  --> $DIR/static.rs:1:9
+   |
+LL | #![deny(mismatched_lifetime_syntaxes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: one option is to consistently use `'static`
+   |
+LL | fn ampersand(x: &'static u8) -> &'static u8 {
+   |                                  +++++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/static.rs:23:17
+   |
+LL | fn brackets(x: &'static u8) -> Brackets {
+   |                 ^^^^^^^        -------- the lifetime gets resolved as `'static`
+   |                 |
+   |                 this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL | fn brackets(x: &'static u8) -> Brackets<'static> {
+   |                                        +++++++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/static.rs:30:14
+   |
+LL | fn comma(x: &'static u8) -> Comma<u8> {
+   |              ^^^^^^^        --------- the lifetime gets resolved as `'static`
+   |              |
+   |              this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL | fn comma(x: &'static u8) -> Comma<'static, u8> {
+   |                                   ++++++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/static.rs:35:19
+   |
+LL | fn underscore(x: &'static u8) -> &'_ u8 {
+   |                   ^^^^^^^         -- the lifetime gets resolved as `'static`
+   |                   |
+   |                   this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL - fn underscore(x: &'static u8) -> &'_ u8 {
+LL + fn underscore(x: &'static u8) -> &'static u8 {
+   |
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs
new file mode 100644
index 00000000000..6d8487b99c6
--- /dev/null
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs
@@ -0,0 +1,315 @@
+#![deny(mismatched_lifetime_syntaxes)]
+
+#[derive(Copy, Clone)]
+struct ContainsLifetime<'a>(&'a u8);
+
+struct S(u8);
+
+fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &u8 {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    v
+}
+
+fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    v
+}
+
+// ---
+
+fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime) -> ContainsLifetime<'_> {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    v
+}
+
+fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    v
+}
+
+fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    v
+}
+
+fn explicit_bound_path_to_explicit_anonymous_path<'a>(
+    v: ContainsLifetime<'a>,
+    //~^ ERROR lifetime flowing from input to output with different syntax
+) -> ContainsLifetime<'_> {
+    v
+}
+
+// ---
+
+fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    ContainsLifetime(v)
+}
+
+fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    ContainsLifetime(v)
+}
+
+fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    ContainsLifetime(v)
+}
+
+fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'_> {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    ContainsLifetime(v)
+}
+
+// ---
+
+fn implicit_path_to_implicit_ref(v: ContainsLifetime) -> &u8 {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    v.0
+}
+
+fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    v.0
+}
+
+fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &u8 {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    v.0
+}
+
+fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'_ u8 {
+    //~^ ERROR lifetime flowing from input to output with different syntax
+    v.0
+}
+
+impl S {
+    fn method_explicit_bound_ref_to_implicit_ref<'a>(&'a self) -> &u8 {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        &self.0
+    }
+
+    fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'_ u8 {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        &self.0
+    }
+
+    // ---
+
+    fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        ContainsLifetime(&self.0)
+    }
+
+    fn method_explicit_bound_ref_to_implicit_path<'a>(&'a self) -> ContainsLifetime {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        ContainsLifetime(&self.0)
+    }
+
+    fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'_> {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        ContainsLifetime(&self.0)
+    }
+}
+
+// If a function uses the `'static` lifetime, we should not suggest
+// replacing it with an explicitly anonymous or implicit
+// lifetime. Only suggest using `'static` everywhere.
+mod static_suggestions {
+    #[derive(Copy, Clone)]
+    struct ContainsLifetime<'a>(&'a u8);
+
+    struct S(u8);
+
+    fn static_ref_to_implicit_ref(v: &'static u8) -> &u8 {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        v
+    }
+
+    fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        v
+    }
+
+    fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        ContainsLifetime(v)
+    }
+
+    fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        ContainsLifetime(v)
+    }
+
+    impl S {
+        fn static_ref_to_implicit_ref(&'static self) -> &u8 {
+            //~^ ERROR lifetime flowing from input to output with different syntax
+            &self.0
+        }
+
+        fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 {
+            //~^ ERROR lifetime flowing from input to output with different syntax
+            &self.0
+        }
+
+        fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime {
+            //~^ ERROR lifetime flowing from input to output with different syntax
+            ContainsLifetime(&self.0)
+        }
+
+        fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> {
+            //~^ ERROR lifetime flowing from input to output with different syntax
+            ContainsLifetime(&self.0)
+        }
+    }
+}
+
+/// `impl Trait` uses lifetimes in some additional ways.
+mod impl_trait {
+    #[derive(Copy, Clone)]
+    struct ContainsLifetime<'a>(&'a u8);
+
+    fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + '_ {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        move || _ = v
+    }
+
+    fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'_> {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        move || _ = v
+    }
+
+    fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + '_ {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        move || _ = v
+    }
+
+    fn explicit_bound_path_to_impl_trait_precise_capture<'a>(
+        v: ContainsLifetime<'a>,
+        //~^ ERROR lifetime flowing from input to output with different syntax
+    ) -> impl FnOnce() + use<'_> {
+        move || _ = v
+    }
+}
+
+/// `dyn Trait` uses lifetimes in some additional ways.
+mod dyn_trait {
+    use std::iter;
+
+    #[derive(Copy, Clone)]
+    struct ContainsLifetime<'a>(&'a u8);
+
+    fn explicit_bound_ref_to_dyn_trait_bound<'a>(v: &'a u8) -> Box<dyn Iterator<Item = &u8> + '_> {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        Box::new(iter::once(v))
+    }
+
+    fn explicit_bound_path_to_dyn_trait_bound<'a>(
+        v: ContainsLifetime<'a>,
+        //~^ ERROR lifetime flowing from input to output with different syntax
+    ) -> Box<dyn Iterator<Item = ContainsLifetime> + '_> {
+        Box::new(iter::once(v))
+    }
+}
+
+/// These tests serve to exercise edge cases of the lint formatting
+mod diagnostic_output {
+    fn multiple_outputs<'a>(v: &'a u8) -> (&u8, &u8) {
+        //~^ ERROR lifetime flowing from input to output with different syntax
+        (v, v)
+    }
+}
+
+/// These usages are expected to **not** trigger the lint
+mod acceptable_uses {
+    #[derive(Copy, Clone)]
+    struct ContainsLifetime<'a>(&'a u8);
+
+    struct S(u8);
+
+    fn implicit_ref_to_implicit_ref(v: &u8) -> &u8 {
+        v
+    }
+
+    fn explicit_anonymous_ref_to_explicit_anonymous_ref(v: &'_ u8) -> &'_ u8 {
+        v
+    }
+
+    fn explicit_bound_ref_to_explicit_bound_ref<'a>(v: &'a u8) -> &'a u8 {
+        v
+    }
+
+    fn implicit_path_to_implicit_path(v: ContainsLifetime) -> ContainsLifetime {
+        v
+    }
+
+    fn explicit_anonymous_path_to_explicit_anonymous_path(
+        v: ContainsLifetime<'_>,
+    ) -> ContainsLifetime<'_> {
+        v
+    }
+
+    fn explicit_bound_path_to_explicit_bound_path<'a>(
+        v: ContainsLifetime<'a>,
+    ) -> ContainsLifetime<'a> {
+        v
+    }
+
+    fn explicit_anonymous_ref_to_explicit_anonymous_path(v: &'_ u8) -> ContainsLifetime<'_> {
+        ContainsLifetime(v)
+    }
+
+    fn explicit_bound_ref_to_explicit_bound_path<'a>(v: &'a u8) -> ContainsLifetime<'a> {
+        ContainsLifetime(v)
+    }
+
+    fn explicit_anonymous_path_to_explicit_anonymous_ref(v: ContainsLifetime<'_>) -> &'_ u8 {
+        v.0
+    }
+
+    fn explicit_bound_path_to_explicit_bound_ref<'a>(v: ContainsLifetime<'a>) -> &'a u8 {
+        v.0
+    }
+
+    // These may be surprising, but ampersands count as enough of a
+    // visual indicator that a reference exists that we treat
+    // references with implicit lifetimes the same as if they were
+    // explicitly anonymous.
+    fn implicit_ref_to_explicit_anonymous_ref(v: &u8) -> &'_ u8 {
+        v
+    }
+
+    fn explicit_anonymous_ref_to_implicit_ref(v: &'_ u8) -> &u8 {
+        v
+    }
+
+    fn implicit_ref_to_explicit_anonymous_path(v: &u8) -> ContainsLifetime<'_> {
+        ContainsLifetime(v)
+    }
+
+    fn explicit_anonymous_path_to_implicit_ref(v: ContainsLifetime<'_>) -> &u8 {
+        v.0
+    }
+
+    impl S {
+        fn method_implicit_ref_to_explicit_anonymous_ref(&self) -> &'_ u8 {
+            &self.0
+        }
+
+        fn method_explicit_anonymous_ref_to_implicit_ref(&'_ self) -> &u8 {
+            &self.0
+        }
+
+        fn method_implicit_ref_to_explicit_anonymous_path(&self) -> ContainsLifetime<'_> {
+            ContainsLifetime(&self.0)
+        }
+    }
+
+    // `dyn Trait` has an "embedded" lifetime that we should **not**
+    // lint about.
+    fn dyn_trait_does_not_have_a_lifetime_generic(v: &u8) -> &dyn core::fmt::Debug {
+        v
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr
new file mode 100644
index 00000000000..0ec16a266b6
--- /dev/null
+++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr
@@ -0,0 +1,473 @@
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:8:47
+   |
+LL | fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &u8 {
+   |                                               ^^        --- the lifetime gets resolved as `'a`
+   |                                               |
+   |                                               this lifetime flows to the output
+   |
+note: the lint level is defined here
+  --> $DIR/mismatched-lifetime-syntaxes.rs:1:9
+   |
+LL | #![deny(mismatched_lifetime_syntaxes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: one option is to consistently use `'a`
+   |
+LL | fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &'a u8 {
+   |                                                          ++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:13:57
+   |
+LL | fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 {
+   |                                                         ^^         -- the lifetime gets resolved as `'a`
+   |                                                         |
+   |                                                         this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL - fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 {
+LL + fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'a u8 {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:20:48
+   |
+LL | fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime) -> ContainsLifetime<'_> {
+   |                                                ^^^^^^^^^^^^^^^^                      -- the lifetime gets resolved as `'_`
+   |                                                |
+   |                                                this lifetime flows to the output
+   |
+help: one option is to consistently use `'_`
+   |
+LL | fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime<'_>) -> ContainsLifetime<'_> {
+   |                                                                ++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:25:65
+   |
+LL | fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime {
+   |                                                                 ^^      ---------------- the lifetime gets resolved as `'_`
+   |                                                                 |
+   |                                                                 this lifetime flows to the output
+   |
+help: one option is to consistently use `'_`
+   |
+LL | fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime<'_> {
+   |                                                                                         ++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:30:65
+   |
+LL | fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime {
+   |                                                                 ^^      ---------------- the lifetime gets resolved as `'a`
+   |                                                                 |
+   |                                                                 this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL | fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime<'a> {
+   |                                                                                         ++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:36:25
+   |
+LL |     v: ContainsLifetime<'a>,
+   |                         ^^ this lifetime flows to the output
+LL |
+LL | ) -> ContainsLifetime<'_> {
+   |                       -- the lifetime gets resolved as `'a`
+   |
+help: one option is to consistently use `'a`
+   |
+LL - ) -> ContainsLifetime<'_> {
+LL + ) -> ContainsLifetime<'a> {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:44:37
+   |
+LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime {
+   |                                     ^^^     ---------------- the lifetime gets resolved as `'_`
+   |                                     |
+   |                                     this lifetime flows to the output
+   |
+help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   |
+LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_> {
+   |                                                             ++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:49:48
+   |
+LL | fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime {
+   |                                                ^^        ---------------- the lifetime gets resolved as `'_`
+   |                                                |
+   |                                                this lifetime flows to the output
+   |
+help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   |
+LL - fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime {
+LL + fn explicit_anonymous_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_> {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:54:48
+   |
+LL | fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime {
+   |                                                ^^        ---------------- the lifetime gets resolved as `'a`
+   |                                                |
+   |                                                this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL | fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime<'a> {
+   |                                                                          ++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:59:58
+   |
+LL | fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'_> {
+   |                                                          ^^                         -- the lifetime gets resolved as `'a`
+   |                                                          |
+   |                                                          this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL - fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'_> {
+LL + fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'a> {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:66:37
+   |
+LL | fn implicit_path_to_implicit_ref(v: ContainsLifetime) -> &u8 {
+   |                                     ^^^^^^^^^^^^^^^^     --- the lifetime gets resolved as `'_`
+   |                                     |
+   |                                     this lifetime flows to the output
+   |
+help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   |
+LL | fn implicit_path_to_implicit_ref(v: ContainsLifetime<'_>) -> &u8 {
+   |                                                     ++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:71:47
+   |
+LL | fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 {
+   |                                               ^^^^^^^^^^^^^^^^      -- the lifetime gets resolved as `'_`
+   |                                               |
+   |                                               this lifetime flows to the output
+   |
+help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   |
+LL - fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 {
+LL + fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime<'_>) -> &u8 {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:76:64
+   |
+LL | fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &u8 {
+   |                                                                ^^      --- the lifetime gets resolved as `'a`
+   |                                                                |
+   |                                                                this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL | fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &'a u8 {
+   |                                                                         ++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:81:74
+   |
+LL | fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'_ u8 {
+   |                                                                          ^^       -- the lifetime gets resolved as `'a`
+   |                                                                          |
+   |                                                                          this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL - fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'_ u8 {
+LL + fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'a u8 {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:87:55
+   |
+LL |     fn method_explicit_bound_ref_to_implicit_ref<'a>(&'a self) -> &u8 {
+   |                                                       ^^          --- the lifetime gets resolved as `'a`
+   |                                                       |
+   |                                                       this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL |     fn method_explicit_bound_ref_to_implicit_ref<'a>(&'a self) -> &'a u8 {
+   |                                                                    ++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:92:65
+   |
+LL |     fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'_ u8 {
+   |                                                                 ^^           -- the lifetime gets resolved as `'a`
+   |                                                                 |
+   |                                                                 this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL -     fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'_ u8 {
+LL +     fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'a u8 {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:99:56
+   |
+LL |     fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime {
+   |                                                        ^^          ---------------- the lifetime gets resolved as `'_`
+   |                                                        |
+   |                                                        this lifetime flows to the output
+   |
+help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
+   |
+LL -     fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime {
+LL +     fn method_explicit_anonymous_ref_to_implicit_path(&self) -> ContainsLifetime<'_> {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:104:56
+   |
+LL |     fn method_explicit_bound_ref_to_implicit_path<'a>(&'a self) -> ContainsLifetime {
+   |                                                        ^^          ---------------- the lifetime gets resolved as `'a`
+   |                                                        |
+   |                                                        this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL |     fn method_explicit_bound_ref_to_implicit_path<'a>(&'a self) -> ContainsLifetime<'a> {
+   |                                                                                    ++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:109:66
+   |
+LL |     fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'_> {
+   |                                                                  ^^                           -- the lifetime gets resolved as `'a`
+   |                                                                  |
+   |                                                                  this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL -     fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'_> {
+LL +     fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'a> {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:124:39
+   |
+LL |     fn static_ref_to_implicit_ref(v: &'static u8) -> &u8 {
+   |                                       ^^^^^^^        --- the lifetime gets resolved as `'static`
+   |                                       |
+   |                                       this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL |     fn static_ref_to_implicit_ref(v: &'static u8) -> &'static u8 {
+   |                                                       +++++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:129:49
+   |
+LL |     fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 {
+   |                                                 ^^^^^^^         -- the lifetime gets resolved as `'static`
+   |                                                 |
+   |                                                 this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL -     fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 {
+LL +     fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'static u8 {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:134:40
+   |
+LL |     fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime {
+   |                                        ^^^^^^^        ---------------- the lifetime gets resolved as `'static`
+   |                                        |
+   |                                        this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL |     fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime<'static> {
+   |                                                                       +++++++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:139:50
+   |
+LL |     fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> {
+   |                                                  ^^^^^^^                         -- the lifetime gets resolved as `'static`
+   |                                                  |
+   |                                                  this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL -     fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> {
+LL +     fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'static> {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:145:40
+   |
+LL |         fn static_ref_to_implicit_ref(&'static self) -> &u8 {
+   |                                        ^^^^^^^          --- the lifetime gets resolved as `'static`
+   |                                        |
+   |                                        this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL |         fn static_ref_to_implicit_ref(&'static self) -> &'static u8 {
+   |                                                          +++++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:150:50
+   |
+LL |         fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 {
+   |                                                  ^^^^^^^           -- the lifetime gets resolved as `'static`
+   |                                                  |
+   |                                                  this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL -         fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 {
+LL +         fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'static u8 {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:155:41
+   |
+LL |         fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime {
+   |                                         ^^^^^^^          ---------------- the lifetime gets resolved as `'static`
+   |                                         |
+   |                                         this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL |         fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime<'static> {
+   |                                                                          +++++++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:160:51
+   |
+LL |         fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> {
+   |                                                   ^^^^^^^                           -- the lifetime gets resolved as `'static`
+   |                                                   |
+   |                                                   this lifetime flows to the output
+   |
+help: one option is to consistently use `'static`
+   |
+LL -         fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> {
+LL +         fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'static> {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:172:55
+   |
+LL |     fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + '_ {
+   |                                                       ^^                        -- the lifetime gets resolved as `'a`
+   |                                                       |
+   |                                                       this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL -     fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + '_ {
+LL +     fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + 'a {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:177:65
+   |
+LL |     fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'_> {
+   |                                                                 ^^                            -- the lifetime gets resolved as `'a`
+   |                                                                 |
+   |                                                                 this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL -     fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'_> {
+LL +     fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'a> {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:182:72
+   |
+LL |     fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + '_ {
+   |                                                                        ^^                      -- the lifetime gets resolved as `'a`
+   |                                                                        |
+   |                                                                        this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL -     fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + '_ {
+LL +     fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + 'a {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:188:29
+   |
+LL |         v: ContainsLifetime<'a>,
+   |                             ^^ this lifetime flows to the output
+LL |
+LL |     ) -> impl FnOnce() + use<'_> {
+   |                              -- the lifetime gets resolved as `'a`
+   |
+help: one option is to consistently use `'a`
+   |
+LL -     ) -> impl FnOnce() + use<'_> {
+LL +     ) -> impl FnOnce() + use<'a> {
+   |
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:202:54
+   |
+LL |     fn explicit_bound_ref_to_dyn_trait_bound<'a>(v: &'a u8) -> Box<dyn Iterator<Item = &u8> + '_> {
+   |                                                      ^^                                ---    -- the lifetimes get resolved as `'a`
+   |                                                      |                                 |
+   |                                                      |                                 the lifetimes get resolved as `'a`
+   |                                                      this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL |     fn explicit_bound_ref_to_dyn_trait_bound<'a>(v: &'a u8) -> Box<dyn Iterator<Item = &'a u8> + '_> {
+   |                                                                                         ++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:208:29
+   |
+LL |         v: ContainsLifetime<'a>,
+   |                             ^^ this lifetime flows to the output
+LL |
+LL |     ) -> Box<dyn Iterator<Item = ContainsLifetime> + '_> {
+   |                                  ----------------    -- the lifetimes get resolved as `'a`
+   |                                  |
+   |                                  the lifetimes get resolved as `'a`
+   |
+help: one option is to consistently use `'a`
+   |
+LL |     ) -> Box<dyn Iterator<Item = ContainsLifetime<'a>> + '_> {
+   |                                                  ++++
+
+error: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/mismatched-lifetime-syntaxes.rs:217:33
+   |
+LL |     fn multiple_outputs<'a>(v: &'a u8) -> (&u8, &u8) {
+   |                                 ^^         ---  --- the lifetimes get resolved as `'a`
+   |                                 |          |
+   |                                 |          the lifetimes get resolved as `'a`
+   |                                 this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL |     fn multiple_outputs<'a>(v: &'a u8) -> (&'a u8, &'a u8) {
+   |                                             ++      ++
+
+error: aborting due to 34 previous errors
+
diff --git a/tests/ui/cleanup-shortcircuit.rs b/tests/ui/lifetimes/rvalue-cleanup-shortcircuit.rs
index 40a5dfa94e3..dba899585c4 100644
--- a/tests/ui/cleanup-shortcircuit.rs
+++ b/tests/ui/lifetimes/rvalue-cleanup-shortcircuit.rs
@@ -1,10 +1,9 @@
-//@ run-pass
-// Test that cleanups for the RHS of shortcircuiting operators work.
+//! Test that cleanups for the RHS of shortcircuiting operators work.
 
+//@ run-pass
 
 #![allow(deref_nullptr)]
 
-
 use std::env;
 
 pub fn main() {
@@ -18,6 +17,8 @@ pub fn main() {
 
     if args.len() >= 2 && args[1] == "signal" {
         // Raise a segfault.
-        unsafe { *std::ptr::null_mut::<isize>() = 0; }
+        unsafe {
+            *std::ptr::null_mut::<isize>() = 0;
+        }
     }
 }
diff --git a/tests/ui/lifetimes/rvalue-lifetime-drop-timing.rs b/tests/ui/lifetimes/rvalue-lifetime-drop-timing.rs
new file mode 100644
index 00000000000..9e7b84bfccf
--- /dev/null
+++ b/tests/ui/lifetimes/rvalue-lifetime-drop-timing.rs
@@ -0,0 +1,104 @@
+//! Test that destructors for temporaries run either at end of
+//! statement or end of block as appropriate.
+
+//@ run-pass
+
+#![feature(box_patterns)]
+
+static mut FLAGS: u64 = 0;
+
+struct Box<T> {
+    f: T,
+}
+
+struct AddFlags {
+    bits: u64,
+}
+
+fn add_flags(bits: u64) -> AddFlags {
+    AddFlags { bits }
+}
+
+fn arg(expected: u64, _x: &AddFlags) {
+    check_flags(expected);
+}
+
+fn pass<T>(v: T) -> T {
+    v
+}
+
+fn check_flags(expected: u64) {
+    unsafe {
+        let actual = FLAGS;
+        FLAGS = 0;
+        assert_eq!(actual, expected, "flags {}, expected {}", actual, expected);
+    }
+}
+
+impl AddFlags {
+    fn check_flags(&self, expected: u64) -> &AddFlags {
+        check_flags(expected);
+        self
+    }
+
+    fn bits(&self) -> u64 {
+        self.bits
+    }
+}
+
+impl Drop for AddFlags {
+    fn drop(&mut self) {
+        unsafe {
+            FLAGS += self.bits;
+        }
+    }
+}
+
+macro_rules! end_of_block {
+    ($pat:pat, $expr:expr) => {{
+        {
+            let $pat = $expr;
+            check_flags(0);
+        }
+        check_flags(1);
+    }};
+}
+
+macro_rules! end_of_stmt {
+    ($pat:pat, $expr:expr) => {{
+        {
+            let $pat = $expr;
+            check_flags(1);
+        }
+        check_flags(0);
+    }};
+}
+
+fn main() {
+    end_of_block!(_x, add_flags(1));
+    end_of_block!(_x, &add_flags(1));
+    end_of_block!(_x, &&add_flags(1));
+    end_of_block!(_x, Box { f: add_flags(1) });
+    end_of_block!(_x, Box { f: &add_flags(1) });
+    end_of_block!(_x, pass(add_flags(1)));
+    end_of_block!(ref _x, add_flags(1));
+    end_of_block!(AddFlags { bits: ref _x }, add_flags(1));
+    end_of_block!(&AddFlags { bits: _ }, &add_flags(1));
+    end_of_block!((_, ref _y), (add_flags(1), 22));
+    end_of_block!(box ref _x, std::boxed::Box::new(add_flags(1)));
+    end_of_block!(box _x, std::boxed::Box::new(add_flags(1)));
+    end_of_block!(_, {
+        {
+            check_flags(0);
+            &add_flags(1)
+        }
+    });
+    end_of_block!(_, &((Box { f: add_flags(1) }).f));
+    end_of_block!(_, &(([add_flags(1)])[0]));
+
+    end_of_stmt!(_, add_flags(1));
+    end_of_stmt!((_, _), (add_flags(1), 22));
+    end_of_stmt!(ref _x, arg(0, &add_flags(1)));
+    end_of_stmt!(ref _x, add_flags(1).check_flags(0).bits());
+    end_of_stmt!(AddFlags { bits: _ }, add_flags(1));
+}
diff --git a/tests/ui/limits/huge-static.stderr b/tests/ui/limits/huge-static.stderr
index 63d04b75d99..9073d7b03e9 100644
--- a/tests/ui/limits/huge-static.stderr
+++ b/tests/ui/limits/huge-static.stderr
@@ -2,13 +2,13 @@ error[E0080]: values of the type `[u8; 2305843009213693952]` are too big for the
   --> $DIR/huge-static.rs:18:1
    |
 LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new();
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MY_TOO_BIG_ARRAY_1` failed here
 
 error[E0080]: values of the type `[u8; 2305843009213693952]` are too big for the target architecture
   --> $DIR/huge-static.rs:20:1
    |
 LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE];
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MY_TOO_BIG_ARRAY_2` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr
index 27357796c18..a529efa2ad0 100644
--- a/tests/ui/limits/issue-55878.stderr
+++ b/tests/ui/limits/issue-55878.stderr
@@ -2,7 +2,7 @@ error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target a
   --> $DIR/issue-55878.rs:4:26
    |
 LL |     println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main` failed inside this call
    |
 note: inside `std::mem::size_of::<[u8; usize::MAX]>`
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs
index 48af6b009d3..df69782e154 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs
@@ -3,6 +3,8 @@
 //@ compile-flags: --crate-type lib --emit link
 #[link(name = "foo", kind = "raw-dylib")]
 extern "stdcall" {
+//~^ WARN: calling convention not supported on this target
+//~| WARN: previously accepted
     fn f(x: i32);
     //~^ ERROR ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
 }
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr
index ef022404e7f..e7a32f4c84b 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr
@@ -1,8 +1,41 @@
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported-abi.rs:5:1
+   |
+LL | / extern "stdcall" {
+LL | |
+LL | |
+LL | |     fn f(x: i32);
+LL | |
+LL | | }
+   | |_^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
 error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
-  --> $DIR/unsupported-abi.rs:6:5
+  --> $DIR/unsupported-abi.rs:8:5
    |
 LL |     fn f(x: i32);
    |     ^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 1 previous error; 1 warning emitted
+
+Future incompatibility report: Future breakage diagnostic:
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported-abi.rs:5:1
+   |
+LL | / extern "stdcall" {
+LL | |
+LL | |
+LL | |     fn f(x: i32);
+LL | |
+LL | | }
+   | |_^
+   |
+   = 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 #137018 <https://github.com/rust-lang/rust/issues/137018>
+   = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"`
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
 
diff --git a/tests/ui/crate_type_flag.rs b/tests/ui/linking/crate-type-invalid-flag-error.rs
index 03bea3638e1..3f84184c989 100644
--- a/tests/ui/crate_type_flag.rs
+++ b/tests/ui/linking/crate-type-invalid-flag-error.rs
@@ -1,3 +1,5 @@
+// Test for #70183 that --crate-type flag display valid value.
+
 //@ compile-flags: --crate-type dynlib
 
 fn main() {}
diff --git a/tests/ui/crate_type_flag.stderr b/tests/ui/linking/crate-type-invalid-flag-error.stderr
index 26a3e1fbd68..26a3e1fbd68 100644
--- a/tests/ui/crate_type_flag.stderr
+++ b/tests/ui/linking/crate-type-invalid-flag-error.stderr
diff --git a/tests/ui/lint/dead-code/const-underscore-issue-142104.rs b/tests/ui/lint/dead-code/const-underscore-issue-142104.rs
new file mode 100644
index 00000000000..b255027e0f1
--- /dev/null
+++ b/tests/ui/lint/dead-code/const-underscore-issue-142104.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+
+// This test makes sure we always considers `const _` items as live for dead code analysis.
+
+#![deny(dead_code)]
+
+const fn is_nonzero(x: u8) -> bool {
+    x != 0
+}
+
+const _: () = {
+    assert!(is_nonzero(2));
+};
+
+fn main() {}
diff --git a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr
deleted file mode 100644
index 2d8c6e99643..00000000000
--- a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: elided lifetime has a name
-  --> $DIR/example-from-issue48686.rs:6:50
-   |
-LL |     pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
-   |                                                  ^ this elided lifetime gets resolved as `'static`
-   |
-note: the lint level is defined here
-  --> $DIR/example-from-issue48686.rs:1:9
-   |
-LL | #![deny(elided_named_lifetimes)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
-help: consider specifying it explicitly
-   |
-LL |     pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 {
-   |                                                   +++++++
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs
deleted file mode 100644
index 2f9083ed65f..00000000000
--- a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-#![deny(elided_named_lifetimes)]
-
-fn ampersand<'a>(x: &'a u8) -> &u8 {
-    //~^ ERROR elided lifetime has a name
-    x
-}
-
-struct Brackets<'a>(&'a u8);
-
-fn brackets<'a>(x: &'a u8) -> Brackets {
-    //~^ ERROR elided lifetime has a name
-    Brackets(x)
-}
-
-struct Comma<'a, T>(&'a T);
-
-fn comma<'a>(x: &'a u8) -> Comma<u8> {
-    //~^ ERROR elided lifetime has a name
-    Comma(x)
-}
-
-fn underscore<'a>(x: &'a u8) -> &'_ u8 {
-    //~^ ERROR elided lifetime has a name
-    x
-}
-
-fn main() {}
diff --git a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr
deleted file mode 100644
index 249ae146b16..00000000000
--- a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr
+++ /dev/null
@@ -1,40 +0,0 @@
-error: elided lifetime has a name
-  --> $DIR/missing-lifetime-kind.rs:3:32
-   |
-LL | fn ampersand<'a>(x: &'a u8) -> &u8 {
-   |              --                ^ this elided lifetime gets resolved as `'a`
-   |              |
-   |              lifetime `'a` declared here
-   |
-note: the lint level is defined here
-  --> $DIR/missing-lifetime-kind.rs:1:9
-   |
-LL | #![deny(elided_named_lifetimes)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
-
-error: elided lifetime has a name
-  --> $DIR/missing-lifetime-kind.rs:10:31
-   |
-LL | fn brackets<'a>(x: &'a u8) -> Brackets {
-   |             --                ^^^^^^^^ this elided lifetime gets resolved as `'a`
-   |             |
-   |             lifetime `'a` declared here
-
-error: elided lifetime has a name
-  --> $DIR/missing-lifetime-kind.rs:17:33
-   |
-LL | fn comma<'a>(x: &'a u8) -> Comma<u8> {
-   |          --                     ^ this elided lifetime gets resolved as `'a`
-   |          |
-   |          lifetime `'a` declared here
-
-error: elided lifetime has a name
-  --> $DIR/missing-lifetime-kind.rs:22:34
-   |
-LL | fn underscore<'a>(x: &'a u8) -> &'_ u8 {
-   |               --                 ^^ this elided lifetime gets resolved as `'a`
-   |               |
-   |               lifetime `'a` declared here
-
-error: aborting due to 4 previous errors
-
diff --git a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs
deleted file mode 100644
index 4f9218130fb..00000000000
--- a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-#![allow(elided_named_lifetimes)]
-
-#[warn(elided_named_lifetimes)]
-mod foo {
-    fn bar(x: &'static u8) -> &u8 {
-        //~^ WARNING elided lifetime has a name
-        x
-    }
-
-    #[deny(elided_named_lifetimes)]
-    fn baz(x: &'static u8) -> &u8 {
-        //~^ ERROR elided lifetime has a name
-        x
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr
deleted file mode 100644
index 3c01375d501..00000000000
--- a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr
+++ /dev/null
@@ -1,34 +0,0 @@
-warning: elided lifetime has a name
-  --> $DIR/not-tied-to-crate.rs:5:31
-   |
-LL |     fn bar(x: &'static u8) -> &u8 {
-   |                               ^ this elided lifetime gets resolved as `'static`
-   |
-note: the lint level is defined here
-  --> $DIR/not-tied-to-crate.rs:3:8
-   |
-LL | #[warn(elided_named_lifetimes)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^
-help: consider specifying it explicitly
-   |
-LL |     fn bar(x: &'static u8) -> &'static u8 {
-   |                                +++++++
-
-error: elided lifetime has a name
-  --> $DIR/not-tied-to-crate.rs:11:31
-   |
-LL |     fn baz(x: &'static u8) -> &u8 {
-   |                               ^ this elided lifetime gets resolved as `'static`
-   |
-note: the lint level is defined here
-  --> $DIR/not-tied-to-crate.rs:10:12
-   |
-LL |     #[deny(elided_named_lifetimes)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-help: consider specifying it explicitly
-   |
-LL |     fn baz(x: &'static u8) -> &'static u8 {
-   |                                +++++++
-
-error: aborting due to 1 previous error; 1 warning emitted
-
diff --git a/tests/ui/lint/elided-named-lifetimes/static.stderr b/tests/ui/lint/elided-named-lifetimes/static.stderr
deleted file mode 100644
index 7ad08dbf04b..00000000000
--- a/tests/ui/lint/elided-named-lifetimes/static.stderr
+++ /dev/null
@@ -1,52 +0,0 @@
-error: elided lifetime has a name
-  --> $DIR/static.rs:16:33
-   |
-LL | fn ampersand(x: &'static u8) -> &u8 {
-   |                                 ^ this elided lifetime gets resolved as `'static`
-   |
-note: the lint level is defined here
-  --> $DIR/static.rs:1:9
-   |
-LL | #![deny(elided_named_lifetimes)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
-help: consider specifying it explicitly
-   |
-LL | fn ampersand(x: &'static u8) -> &'static u8 {
-   |                                  +++++++
-
-error: elided lifetime has a name
-  --> $DIR/static.rs:23:32
-   |
-LL | fn brackets(x: &'static u8) -> Brackets {
-   |                                ^^^^^^^^ this elided lifetime gets resolved as `'static`
-   |
-help: consider specifying it explicitly
-   |
-LL | fn brackets(x: &'static u8) -> Brackets<'static> {
-   |                                        +++++++++
-
-error: elided lifetime has a name
-  --> $DIR/static.rs:30:34
-   |
-LL | fn comma(x: &'static u8) -> Comma<u8> {
-   |                                  ^ this elided lifetime gets resolved as `'static`
-   |
-help: consider specifying it explicitly
-   |
-LL | fn comma(x: &'static u8) -> Comma<'static, u8> {
-   |                                   ++++++++
-
-error: elided lifetime has a name
-  --> $DIR/static.rs:35:35
-   |
-LL | fn underscore(x: &'static u8) -> &'_ u8 {
-   |                                   ^^ this elided lifetime gets resolved as `'static`
-   |
-help: consider specifying it explicitly
-   |
-LL - fn underscore(x: &'static u8) -> &'_ u8 {
-LL + fn underscore(x: &'static u8) -> &'static u8 {
-   |
-
-error: aborting due to 4 previous errors
-
diff --git a/tests/ui/lint/force-warn/ice-free.rs b/tests/ui/lint/force-warn/ice-free.rs
new file mode 100644
index 00000000000..99b79f44648
--- /dev/null
+++ b/tests/ui/lint/force-warn/ice-free.rs
@@ -0,0 +1,9 @@
+//@ compile-flags: --force-warn pub_use_of_private_extern_crate
+//@ check-pass
+
+extern crate core;
+pub use core as reexported_core;
+//~^ warning: extern crate `core` is private
+//~| warning: this was previously accepted by the compiler
+
+fn main() {}
diff --git a/tests/ui/lint/force-warn/ice-free.stderr b/tests/ui/lint/force-warn/ice-free.stderr
new file mode 100644
index 00000000000..b64e3b138a2
--- /dev/null
+++ b/tests/ui/lint/force-warn/ice-free.stderr
@@ -0,0 +1,32 @@
+warning[E0365]: extern crate `core` is private and cannot be re-exported
+  --> $DIR/ice-free.rs:5:9
+   |
+LL | pub use core as reexported_core;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #127909 <https://github.com/rust-lang/rust/issues/127909>
+   = note: requested on the command line with `--force-warn pub-use-of-private-extern-crate`
+help: consider making the `extern crate` item publicly accessible
+   |
+LL | pub extern crate core;
+   | +++
+
+warning: 1 warning emitted
+
+For more information about this error, try `rustc --explain E0365`.
+Future incompatibility report: Future breakage diagnostic:
+warning[E0365]: extern crate `core` is private and cannot be re-exported
+  --> $DIR/ice-free.rs:5:9
+   |
+LL | pub use core as reexported_core;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #127909 <https://github.com/rust-lang/rust/issues/127909>
+   = note: requested on the command line with `--force-warn pub-use-of-private-extern-crate`
+help: consider making the `extern crate` item publicly accessible
+   |
+LL | pub extern crate core;
+   | +++
+
diff --git a/tests/ui/lint/implicit_autorefs.fixed b/tests/ui/lint/implicit_autorefs.fixed
index 454dfe76372..7aa21e77458 100644
--- a/tests/ui/lint/implicit_autorefs.fixed
+++ b/tests/ui/lint/implicit_autorefs.fixed
@@ -1,4 +1,4 @@
-//@ check-pass
+//@ check-fail
 //@ run-rustfix
 
 #![allow(dead_code)] // For the rustfix-ed code.
@@ -8,7 +8,7 @@ use std::ops::Deref;
 
 unsafe fn test_const(ptr: *const [u8]) {
     let _ = (&(*ptr))[..16];
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 struct Test {
@@ -17,36 +17,36 @@ struct Test {
 
 unsafe fn test_field(ptr: *const Test) -> *const [u8] {
     let l = (&(*ptr).field).len();
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 
     &raw const (&(*ptr).field)[..l - 1]
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_builtin_index(a: *mut [String]) {
     _ = (&(*a)[0]).len();
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 
     _ = (&(&(*a))[..1][0]).len();
-    //~^ WARN implicit autoref
-    //~^^ WARN implicit autoref
+    //~^ ERROR implicit autoref
+    //~^^ ERROR implicit autoref
 }
 
 unsafe fn test_overloaded_deref_const(ptr: *const ManuallyDrop<Test>) {
     let _ = (&(*ptr)).field;
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
     let _ = &raw const (&(*ptr)).field;
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_overloaded_deref_mut(ptr: *mut ManuallyDrop<Test>) {
     let _ = (&(*ptr)).field;
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_double_overloaded_deref_const(ptr: *const ManuallyDrop<ManuallyDrop<Test>>) {
     let _ = (&(*ptr)).field;
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_manually_overloaded_deref() {
@@ -54,52 +54,55 @@ unsafe fn test_manually_overloaded_deref() {
 
     impl<T> Deref for W<T> {
         type Target = T;
-        fn deref(&self) -> &T { &self.0 }
+        fn deref(&self) -> &T {
+            &self.0
+        }
     }
 
     let w: W<i32> = W(5);
     let w = &raw const w;
     let _p: *const i32 = &raw const *(&**w);
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 struct Test2 {
     // Derefs to `[u8]`.
-    field: &'static [u8]
+    field: &'static [u8],
 }
 
 fn test_more_manual_deref(ptr: *const Test2) -> usize {
     unsafe { (&(*ptr).field).len() }
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_no_attr(ptr: *mut ManuallyDrop<u8>) {
-    ptr.write(ManuallyDrop::new(1)); // Should not warn, as `ManuallyDrop::write` is not
-                                     // annotated with `#[rustc_no_implicit_auto_ref]`
+    // Should not warn, as `ManuallyDrop::write` is not
+    // annotated with `#[rustc_no_implicit_auto_ref]`
+    ptr.write(ManuallyDrop::new(1));
 }
 
 unsafe fn test_vec_get(ptr: *mut Vec<u8>) {
     let _ = (&(*ptr)).get(0);
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
     let _ = (&(*ptr)).get_unchecked(0);
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
     let _ = (&mut (*ptr)).get_mut(0);
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
     let _ = (&mut (*ptr)).get_unchecked_mut(0);
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_string(ptr: *mut String) {
     let _ = (&(*ptr)).len();
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
     let _ = (&(*ptr)).is_empty();
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn slice_ptr_len_because_of_msrv<T>(slice: *const [T]) {
     let _ = (&(&(*slice))[..]).len();
-    //~^ WARN implicit autoref
-    //~^^ WARN implicit autoref
+    //~^ ERROR implicit autoref
+    //~^^ ERROR implicit autoref
 }
 
 fn main() {}
diff --git a/tests/ui/lint/implicit_autorefs.rs b/tests/ui/lint/implicit_autorefs.rs
index 507d6536828..f33cb08e985 100644
--- a/tests/ui/lint/implicit_autorefs.rs
+++ b/tests/ui/lint/implicit_autorefs.rs
@@ -1,4 +1,4 @@
-//@ check-pass
+//@ check-fail
 //@ run-rustfix
 
 #![allow(dead_code)] // For the rustfix-ed code.
@@ -8,7 +8,7 @@ use std::ops::Deref;
 
 unsafe fn test_const(ptr: *const [u8]) {
     let _ = (*ptr)[..16];
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 struct Test {
@@ -17,36 +17,36 @@ struct Test {
 
 unsafe fn test_field(ptr: *const Test) -> *const [u8] {
     let l = (*ptr).field.len();
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 
     &raw const (*ptr).field[..l - 1]
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_builtin_index(a: *mut [String]) {
     _ = (*a)[0].len();
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 
     _ = (*a)[..1][0].len();
-    //~^ WARN implicit autoref
-    //~^^ WARN implicit autoref
+    //~^ ERROR implicit autoref
+    //~^^ ERROR implicit autoref
 }
 
 unsafe fn test_overloaded_deref_const(ptr: *const ManuallyDrop<Test>) {
     let _ = (*ptr).field;
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
     let _ = &raw const (*ptr).field;
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_overloaded_deref_mut(ptr: *mut ManuallyDrop<Test>) {
     let _ = (*ptr).field;
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_double_overloaded_deref_const(ptr: *const ManuallyDrop<ManuallyDrop<Test>>) {
     let _ = (*ptr).field;
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_manually_overloaded_deref() {
@@ -54,52 +54,55 @@ unsafe fn test_manually_overloaded_deref() {
 
     impl<T> Deref for W<T> {
         type Target = T;
-        fn deref(&self) -> &T { &self.0 }
+        fn deref(&self) -> &T {
+            &self.0
+        }
     }
 
     let w: W<i32> = W(5);
     let w = &raw const w;
     let _p: *const i32 = &raw const **w;
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 struct Test2 {
     // Derefs to `[u8]`.
-    field: &'static [u8]
+    field: &'static [u8],
 }
 
 fn test_more_manual_deref(ptr: *const Test2) -> usize {
     unsafe { (*ptr).field.len() }
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_no_attr(ptr: *mut ManuallyDrop<u8>) {
-    ptr.write(ManuallyDrop::new(1)); // Should not warn, as `ManuallyDrop::write` is not
-                                     // annotated with `#[rustc_no_implicit_auto_ref]`
+    // Should not warn, as `ManuallyDrop::write` is not
+    // annotated with `#[rustc_no_implicit_auto_ref]`
+    ptr.write(ManuallyDrop::new(1));
 }
 
 unsafe fn test_vec_get(ptr: *mut Vec<u8>) {
     let _ = (*ptr).get(0);
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
     let _ = (*ptr).get_unchecked(0);
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
     let _ = (*ptr).get_mut(0);
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
     let _ = (*ptr).get_unchecked_mut(0);
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn test_string(ptr: *mut String) {
     let _ = (*ptr).len();
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
     let _ = (*ptr).is_empty();
-    //~^ WARN implicit autoref
+    //~^ ERROR implicit autoref
 }
 
 unsafe fn slice_ptr_len_because_of_msrv<T>(slice: *const [T]) {
     let _ = (*slice)[..].len();
-    //~^ WARN implicit autoref
-    //~^^ WARN implicit autoref
+    //~^ ERROR implicit autoref
+    //~^^ ERROR implicit autoref
 }
 
 fn main() {}
diff --git a/tests/ui/lint/implicit_autorefs.stderr b/tests/ui/lint/implicit_autorefs.stderr
index 80ba8ae2fd2..bd914e2998a 100644
--- a/tests/ui/lint/implicit_autorefs.stderr
+++ b/tests/ui/lint/implicit_autorefs.stderr
@@ -1,4 +1,4 @@
-warning: implicit autoref creates a reference to the dereference of a raw pointer
+error: implicit autoref creates a reference to the dereference of a raw pointer
   --> $DIR/implicit_autorefs.rs:10:13
    |
 LL |     let _ = (*ptr)[..16];
@@ -12,13 +12,13 @@ note: autoref is being applied to this expression, resulting in: `&[u8]`
    |
 LL |     let _ = (*ptr)[..16];
    |             ^^^^^^
-   = note: `#[warn(dangerous_implicit_autorefs)]` on by default
+   = note: `#[deny(dangerous_implicit_autorefs)]` on by default
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = (&(*ptr))[..16];
    |             ++      +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
+error: implicit autoref creates a reference to the dereference of a raw pointer
   --> $DIR/implicit_autorefs.rs:19:13
    |
 LL |     let l = (*ptr).field.len();
@@ -39,7 +39,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let l = (&(*ptr).field).len();
    |             ++            +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
+error: implicit autoref creates a reference to the dereference of a raw pointer
   --> $DIR/implicit_autorefs.rs:22:16
    |
 LL |     &raw const (*ptr).field[..l - 1]
@@ -58,7 +58,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     &raw const (&(*ptr).field)[..l - 1]
    |                ++            +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
+error: implicit autoref creates a reference to the dereference of a raw pointer
   --> $DIR/implicit_autorefs.rs:27:9
    |
 LL |     _ = (*a)[0].len();
@@ -79,7 +79,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     _ = (&(*a)[0]).len();
    |         ++       +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
+error: implicit autoref creates a reference to the dereference of a raw pointer
   --> $DIR/implicit_autorefs.rs:30:9
    |
 LL |     _ = (*a)[..1][0].len();
@@ -100,7 +100,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     _ = (&(*a)[..1][0]).len();
    |         ++            +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
+error: implicit autoref creates a reference to the dereference of a raw pointer
   --> $DIR/implicit_autorefs.rs:30:9
    |
 LL |     _ = (*a)[..1][0].len();
@@ -119,7 +119,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     _ = (&(*a))[..1][0].len();
    |         ++    +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
+error: implicit autoref creates a reference to the dereference of a raw pointer
   --> $DIR/implicit_autorefs.rs:36:13
    |
 LL |     let _ = (*ptr).field;
@@ -134,7 +134,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&(*ptr)).field;
    |             ++      +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
+error: implicit autoref creates a reference to the dereference of a raw pointer
   --> $DIR/implicit_autorefs.rs:38:24
    |
 LL |     let _ = &raw const (*ptr).field;
@@ -149,7 +149,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = &raw const (&(*ptr)).field;
    |                        ++      +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
+error: implicit autoref creates a reference to the dereference of a raw pointer
   --> $DIR/implicit_autorefs.rs:43:13
    |
 LL |     let _ = (*ptr).field;
@@ -164,7 +164,7 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&(*ptr)).field;
    |             ++      +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
+error: implicit autoref creates a reference to the dereference of a raw pointer
   --> $DIR/implicit_autorefs.rs:48:13
    |
 LL |     let _ = (*ptr).field;
@@ -179,8 +179,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&(*ptr)).field;
    |             ++      +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
-  --> $DIR/implicit_autorefs.rs:62:26
+error: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:64:26
    |
 LL |     let _p: *const i32 = &raw const **w;
    |                          ^^^^^^^^^^^^^-
@@ -189,7 +189,7 @@ LL |     let _p: *const i32 = &raw const **w;
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
 note: autoref is being applied to this expression, resulting in: `&W<i32>`
-  --> $DIR/implicit_autorefs.rs:62:38
+  --> $DIR/implicit_autorefs.rs:64:38
    |
 LL |     let _p: *const i32 = &raw const **w;
    |                                      ^^
@@ -198,8 +198,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _p: *const i32 = &raw const *(&**w);
    |                                      +++  +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
-  --> $DIR/implicit_autorefs.rs:72:14
+error: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:74:14
    |
 LL |     unsafe { (*ptr).field.len() }
    |              ^^---^^^^^^^^^^^^^
@@ -208,7 +208,7 @@ LL |     unsafe { (*ptr).field.len() }
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
 note: autoref is being applied to this expression, resulting in: `&[u8]`
-  --> $DIR/implicit_autorefs.rs:72:14
+  --> $DIR/implicit_autorefs.rs:74:14
    |
 LL |     unsafe { (*ptr).field.len() }
    |              ^^^^^^^^^^^^
@@ -219,8 +219,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     unsafe { (&(*ptr).field).len() }
    |              ++            +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
-  --> $DIR/implicit_autorefs.rs:82:13
+error: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:85:13
    |
 LL |     let _ = (*ptr).get(0);
    |             ^^---^^^^^^^^
@@ -229,7 +229,7 @@ LL |     let _ = (*ptr).get(0);
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
 note: autoref is being applied to this expression, resulting in: `&[u8]`
-  --> $DIR/implicit_autorefs.rs:82:13
+  --> $DIR/implicit_autorefs.rs:85:13
    |
 LL |     let _ = (*ptr).get(0);
    |             ^^^^^^
@@ -240,8 +240,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&(*ptr)).get(0);
    |             ++      +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
-  --> $DIR/implicit_autorefs.rs:84:13
+error: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:87:13
    |
 LL |     let _ = (*ptr).get_unchecked(0);
    |             ^^---^^^^^^^^^^^^^^^^^^
@@ -250,7 +250,7 @@ LL |     let _ = (*ptr).get_unchecked(0);
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
 note: autoref is being applied to this expression, resulting in: `&[u8]`
-  --> $DIR/implicit_autorefs.rs:84:13
+  --> $DIR/implicit_autorefs.rs:87:13
    |
 LL |     let _ = (*ptr).get_unchecked(0);
    |             ^^^^^^
@@ -261,8 +261,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&(*ptr)).get_unchecked(0);
    |             ++      +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
-  --> $DIR/implicit_autorefs.rs:86:13
+error: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:89:13
    |
 LL |     let _ = (*ptr).get_mut(0);
    |             ^^---^^^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |     let _ = (*ptr).get_mut(0);
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
 note: autoref is being applied to this expression, resulting in: `&mut [u8]`
-  --> $DIR/implicit_autorefs.rs:86:13
+  --> $DIR/implicit_autorefs.rs:89:13
    |
 LL |     let _ = (*ptr).get_mut(0);
    |             ^^^^^^
@@ -282,8 +282,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&mut (*ptr)).get_mut(0);
    |             +++++       +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
-  --> $DIR/implicit_autorefs.rs:88:13
+error: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:91:13
    |
 LL |     let _ = (*ptr).get_unchecked_mut(0);
    |             ^^---^^^^^^^^^^^^^^^^^^^^^^
@@ -292,7 +292,7 @@ LL |     let _ = (*ptr).get_unchecked_mut(0);
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
 note: autoref is being applied to this expression, resulting in: `&mut [u8]`
-  --> $DIR/implicit_autorefs.rs:88:13
+  --> $DIR/implicit_autorefs.rs:91:13
    |
 LL |     let _ = (*ptr).get_unchecked_mut(0);
    |             ^^^^^^
@@ -303,8 +303,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&mut (*ptr)).get_unchecked_mut(0);
    |             +++++       +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
-  --> $DIR/implicit_autorefs.rs:93:13
+error: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:96:13
    |
 LL |     let _ = (*ptr).len();
    |             ^^---^^^^^^^
@@ -313,7 +313,7 @@ LL |     let _ = (*ptr).len();
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
 note: autoref is being applied to this expression, resulting in: `&String`
-  --> $DIR/implicit_autorefs.rs:93:13
+  --> $DIR/implicit_autorefs.rs:96:13
    |
 LL |     let _ = (*ptr).len();
    |             ^^^^^^
@@ -324,8 +324,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&(*ptr)).len();
    |             ++      +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
-  --> $DIR/implicit_autorefs.rs:95:13
+error: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:98:13
    |
 LL |     let _ = (*ptr).is_empty();
    |             ^^---^^^^^^^^^^^^
@@ -334,7 +334,7 @@ LL |     let _ = (*ptr).is_empty();
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
 note: autoref is being applied to this expression, resulting in: `&String`
-  --> $DIR/implicit_autorefs.rs:95:13
+  --> $DIR/implicit_autorefs.rs:98:13
    |
 LL |     let _ = (*ptr).is_empty();
    |             ^^^^^^
@@ -345,8 +345,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&(*ptr)).is_empty();
    |             ++      +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
-  --> $DIR/implicit_autorefs.rs:100:13
+error: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:103:13
    |
 LL |     let _ = (*slice)[..].len();
    |             ^^-----^^^^^^^^^^^
@@ -355,7 +355,7 @@ LL |     let _ = (*slice)[..].len();
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
 note: autoref is being applied to this expression, resulting in: `&[T]`
-  --> $DIR/implicit_autorefs.rs:100:13
+  --> $DIR/implicit_autorefs.rs:103:13
    |
 LL |     let _ = (*slice)[..].len();
    |             ^^^^^^^^^^^^
@@ -366,8 +366,8 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&(*slice)[..]).len();
    |             ++            +
 
-warning: implicit autoref creates a reference to the dereference of a raw pointer
-  --> $DIR/implicit_autorefs.rs:100:13
+error: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:103:13
    |
 LL |     let _ = (*slice)[..].len();
    |             ^^-----^^^^^
@@ -376,7 +376,7 @@ LL |     let _ = (*slice)[..].len();
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
 note: autoref is being applied to this expression, resulting in: `&[T]`
-  --> $DIR/implicit_autorefs.rs:100:13
+  --> $DIR/implicit_autorefs.rs:103:13
    |
 LL |     let _ = (*slice)[..].len();
    |             ^^^^^^^^
@@ -385,5 +385,5 @@ help: try using a raw pointer method instead; or if this reference is intentiona
 LL |     let _ = (&(*slice))[..].len();
    |             ++        +
 
-warning: 20 warnings emitted
+error: aborting due to 20 previous errors
 
diff --git a/tests/ui/lint/unused/useless-comment.rs b/tests/ui/lint/unused/useless-comment.rs
index 4ec52f20747..898665278e3 100644
--- a/tests/ui/lint/unused/useless-comment.rs
+++ b/tests/ui/lint/unused/useless-comment.rs
@@ -9,8 +9,13 @@ macro_rules! mac {
 /// foo //~ ERROR unused doc comment
 mac!();
 
+/// a //~ ERROR unused doc comment
+#[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment
+unsafe extern "C" { }
+
 fn foo() {
     /// a //~ ERROR unused doc comment
+    #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment
     let x = 12;
 
     /// multi-line //~ ERROR unused doc comment
@@ -19,6 +24,7 @@ fn foo() {
     match x {
         /// c //~ ERROR unused doc comment
         1 => {},
+        #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment
         _ => {}
     }
 
@@ -32,6 +38,7 @@ fn foo() {
     /// bar //~ ERROR unused doc comment
     mac!();
 
+    #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment
     let x = /** comment */ 47; //~ ERROR unused doc comment
 
     /// dox //~ ERROR unused doc comment
diff --git a/tests/ui/lint/unused/useless-comment.stderr b/tests/ui/lint/unused/useless-comment.stderr
index 8bb5bdaeb25..39873b82b75 100644
--- a/tests/ui/lint/unused/useless-comment.stderr
+++ b/tests/ui/lint/unused/useless-comment.stderr
@@ -12,7 +12,28 @@ LL | #![deny(unused_doc_comments)]
    |         ^^^^^^^^^^^^^^^^^^^
 
 error: unused doc comment
-  --> $DIR/useless-comment.rs:32:5
+  --> $DIR/useless-comment.rs:12:1
+   |
+LL | /// a
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[doc(test(attr(allow(dead_code))))]
+LL | unsafe extern "C" { }
+   | --------------------- rustdoc does not generate documentation for extern blocks
+   |
+   = help: use `//` for a plain comment
+
+error: unused doc comment
+  --> $DIR/useless-comment.rs:13:1
+   |
+LL | #[doc(test(attr(allow(dead_code))))]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | unsafe extern "C" { }
+   | --------------------- rustdoc does not generate documentation for extern blocks
+   |
+   = help: use `//` for a plain comment
+
+error: unused doc comment
+  --> $DIR/useless-comment.rs:38:5
    |
 LL |     /// bar
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations
@@ -20,17 +41,28 @@ LL |     /// bar
    = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
 
 error: unused doc comment
-  --> $DIR/useless-comment.rs:13:5
+  --> $DIR/useless-comment.rs:17:5
    |
 LL |     /// a
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[doc(test(attr(allow(dead_code))))]
 LL |     let x = 12;
    |     ----------- rustdoc does not generate documentation for statements
    |
    = help: use `//` for a plain comment
 
 error: unused doc comment
-  --> $DIR/useless-comment.rs:16:5
+  --> $DIR/useless-comment.rs:18:5
+   |
+LL |     #[doc(test(attr(allow(dead_code))))]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let x = 12;
+   |     ----------- rustdoc does not generate documentation for statements
+   |
+   = help: use `//` for a plain comment
+
+error: unused doc comment
+  --> $DIR/useless-comment.rs:21:5
    |
 LL | /     /// multi-line
 LL | |     /// doc comment
@@ -39,6 +71,7 @@ LL | |     /// that is unused
 LL | /     match x {
 LL | |         /// c
 LL | |         1 => {},
+LL | |         #[doc(test(attr(allow(dead_code))))]
 LL | |         _ => {}
 LL | |     }
    | |_____- rustdoc does not generate documentation for expressions
@@ -46,7 +79,7 @@ LL | |     }
    = help: use `//` for a plain comment
 
 error: unused doc comment
-  --> $DIR/useless-comment.rs:20:9
+  --> $DIR/useless-comment.rs:25:9
    |
 LL |         /// c
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +89,17 @@ LL |         1 => {},
    = help: use `//` for a plain comment
 
 error: unused doc comment
-  --> $DIR/useless-comment.rs:25:5
+  --> $DIR/useless-comment.rs:27:9
+   |
+LL |         #[doc(test(attr(allow(dead_code))))]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         _ => {}
+   |         ------- rustdoc does not generate documentation for match arms
+   |
+   = help: use `//` for a plain comment
+
+error: unused doc comment
+  --> $DIR/useless-comment.rs:31:5
    |
 LL |     /// foo
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -66,7 +109,7 @@ LL |     unsafe {}
    = help: use `//` for a plain comment
 
 error: unused doc comment
-  --> $DIR/useless-comment.rs:28:5
+  --> $DIR/useless-comment.rs:34:5
    |
 LL |     #[doc = "foo"]
    |     ^^^^^^^^^^^^^^
@@ -77,7 +120,7 @@ LL |     3;
    = help: use `//` for a plain comment
 
 error: unused doc comment
-  --> $DIR/useless-comment.rs:29:5
+  --> $DIR/useless-comment.rs:35:5
    |
 LL |     #[doc = "bar"]
    |     ^^^^^^^^^^^^^^
@@ -87,7 +130,17 @@ LL |     3;
    = help: use `//` for a plain comment
 
 error: unused doc comment
-  --> $DIR/useless-comment.rs:35:13
+  --> $DIR/useless-comment.rs:41:5
+   |
+LL |     #[doc(test(attr(allow(dead_code))))]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let x = /** comment */ 47;
+   |     -------------------------- rustdoc does not generate documentation for statements
+   |
+   = help: use `//` for a plain comment
+
+error: unused doc comment
+  --> $DIR/useless-comment.rs:42:13
    |
 LL |     let x = /** comment */ 47;
    |             ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions
@@ -95,7 +148,7 @@ LL |     let x = /** comment */ 47;
    = help: use `/* */` for a plain comment
 
 error: unused doc comment
-  --> $DIR/useless-comment.rs:37:5
+  --> $DIR/useless-comment.rs:44:5
    |
 LL |       /// dox
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -106,5 +159,5 @@ LL | |     }
    |
    = help: use `//` for a plain comment
 
-error: aborting due to 10 previous errors
+error: aborting due to 15 previous errors
 
diff --git a/tests/ui/loops/issue-43162.stderr b/tests/ui/loops/issue-43162.stderr
index 40d9200058e..f6b6bf2621c 100644
--- a/tests/ui/loops/issue-43162.stderr
+++ b/tests/ui/loops/issue-43162.stderr
@@ -4,12 +4,6 @@ error[E0268]: `break` outside of a loop or labeled block
 LL |     break true;
    |     ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
 
-error[E0268]: `break` outside of a loop or labeled block
-  --> $DIR/issue-43162.rs:7:5
-   |
-LL |     break {};
-   |     ^^^^^^^^ cannot `break` outside of a loop or labeled block
-
 error[E0308]: mismatched types
   --> $DIR/issue-43162.rs:1:13
    |
@@ -18,6 +12,12 @@ LL | fn foo() -> bool {
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
 
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/issue-43162.rs:7:5
+   |
+LL |     break {};
+   |     ^^^^^^^^ cannot `break` outside of a loop or labeled block
+
 error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0268, E0308.
diff --git a/tests/ui/loops/loop-break-never-type-mismatch.rs b/tests/ui/loops/loop-break-never-type-mismatch.rs
new file mode 100644
index 00000000000..2be4e4f4ac5
--- /dev/null
+++ b/tests/ui/loops/loop-break-never-type-mismatch.rs
@@ -0,0 +1,56 @@
+//! Tests type mismatches with `break` and diverging types in loops
+
+#![feature(never_type)]
+
+fn loop_break_return() -> i32 {
+    let loop_value = loop {
+        break return 0;
+    }; // ok
+}
+
+fn loop_break_loop() -> i32 {
+    let loop_value = loop {
+        break loop {};
+    }; // ok
+}
+
+fn loop_break_break() -> i32 {
+    //~^ ERROR mismatched types
+    let loop_value = loop {
+        break break;
+    };
+}
+
+fn loop_break_return_2() -> i32 {
+    let loop_value = loop {
+        break {
+            return 0;
+            ()
+        };
+    }; // ok
+}
+
+enum Void {}
+
+fn get_void() -> Void {
+    panic!()
+}
+
+fn loop_break_void() -> i32 {
+    //~^ ERROR mismatched types
+    let loop_value = loop {
+        break get_void();
+    };
+}
+
+fn get_never() -> ! {
+    panic!()
+}
+
+fn loop_break_never() -> i32 {
+    let loop_value = loop {
+        break get_never();
+    }; // ok
+}
+
+fn main() {}
diff --git a/tests/ui/break-diverging-value.stderr b/tests/ui/loops/loop-break-never-type-mismatch.stderr
index 69edcd24080..e6868f375e2 100644
--- a/tests/ui/break-diverging-value.stderr
+++ b/tests/ui/loops/loop-break-never-type-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/break-diverging-value.rs:11:26
+  --> $DIR/loop-break-never-type-mismatch.rs:17:26
    |
 LL | fn loop_break_break() -> i32 {
    |    ----------------      ^^^ expected `i32`, found `()`
@@ -7,7 +7,7 @@ LL | fn loop_break_break() -> i32 {
    |    implicitly returns `()` as its body has no tail or `return` expression
 
 error[E0308]: mismatched types
-  --> $DIR/break-diverging-value.rs:25:25
+  --> $DIR/loop-break-never-type-mismatch.rs:39:25
    |
 LL | fn loop_break_void() -> i32 {
    |    ---------------      ^^^ expected `i32`, found `()`
diff --git a/tests/ui/macros/format-args-temporaries.rs b/tests/ui/macros/format-args-temporaries.rs
index ad9792bc796..74714be7653 100644
--- a/tests/ui/macros/format-args-temporaries.rs
+++ b/tests/ui/macros/format-args-temporaries.rs
@@ -5,7 +5,7 @@ use std::fmt::{self, Display};
 struct Mutex;
 
 impl Mutex {
-    fn lock(&self) -> MutexGuard {
+    fn lock(&self) -> MutexGuard<'_> {
         MutexGuard(self)
     }
 }
diff --git a/tests/ui/macros/macro-reexport-removed.rs b/tests/ui/macros/macro-reexport-removed.rs
index 4a054686d77..c1267f14cd8 100644
--- a/tests/ui/macros/macro-reexport-removed.rs
+++ b/tests/ui/macros/macro-reexport-removed.rs
@@ -1,4 +1,5 @@
 //@ aux-build:two_macros.rs
+//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION"
 
 #![feature(macro_reexport)] //~ ERROR feature has been removed
 
diff --git a/tests/ui/macros/macro-reexport-removed.stderr b/tests/ui/macros/macro-reexport-removed.stderr
index 475a586ddc0..d4940eeb775 100644
--- a/tests/ui/macros/macro-reexport-removed.stderr
+++ b/tests/ui/macros/macro-reexport-removed.stderr
@@ -1,13 +1,14 @@
 error[E0557]: feature has been removed
-  --> $DIR/macro-reexport-removed.rs:3:12
+  --> $DIR/macro-reexport-removed.rs:4:12
    |
 LL | #![feature(macro_reexport)]
    |            ^^^^^^^^^^^^^^ feature has been removed
    |
+   = note: removed in 1.0.0 (you are using $RUSTC_VERSION); see <https://github.com/rust-lang/rust/pull/49982> for more information
    = note: subsumed by `pub use`
 
 error: cannot find attribute `macro_reexport` in this scope
-  --> $DIR/macro-reexport-removed.rs:5:3
+  --> $DIR/macro-reexport-removed.rs:6:3
    |
 LL | #[macro_reexport(macro_one)]
    |   ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export`
diff --git a/tests/ui/mir/mir_fat_ptr.rs b/tests/ui/mir/mir_fat_ptr.rs
index f2dd9e6fe40..af9831570d1 100644
--- a/tests/ui/mir/mir_fat_ptr.rs
+++ b/tests/ui/mir/mir_fat_ptr.rs
@@ -20,11 +20,11 @@ fn fat_ptr_via_local(a: &[u8]) -> &[u8] {
     x
 }
 
-fn fat_ptr_from_struct(s: FatPtrContainer) -> &[u8] {
+fn fat_ptr_from_struct(s: FatPtrContainer<'_>) -> &[u8] {
     s.ptr
 }
 
-fn fat_ptr_to_struct(a: &[u8]) -> FatPtrContainer {
+fn fat_ptr_to_struct(a: &[u8]) -> FatPtrContainer<'_> {
     FatPtrContainer { ptr: a }
 }
 
diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr
index a4276395944..a188b7791fd 100644
--- a/tests/ui/mismatched_types/cast-rfc0401.stderr
+++ b/tests/ui/mismatched_types/cast-rfc0401.stderr
@@ -104,10 +104,13 @@ error[E0604]: only `u8` can be cast as `char`, not `u32`
   --> $DIR/cast-rfc0401.rs:41:13
    |
 LL |     let _ = 0x61u32 as char;
-   |             ^^^^^^^^^^^^^^^
-   |             |
-   |             invalid cast
-   |             help: try `char::from_u32` instead: `char::from_u32(0x61u32)`
+   |             ^^^^^^^^^^^^^^^ invalid cast
+   |
+help: consider using `char::from_u32` instead
+   |
+LL -     let _ = 0x61u32 as char;
+LL +     let _ = char::from_u32(0x61u32);
+   |
 
 error[E0606]: casting `bool` as `f32` is invalid
   --> $DIR/cast-rfc0401.rs:43:13
diff --git a/tests/ui/nll/issue-53570.rs b/tests/ui/nll/issue-53570.rs
index 882ce9e1c31..cfc1edd217d 100644
--- a/tests/ui/nll/issue-53570.rs
+++ b/tests/ui/nll/issue-53570.rs
@@ -22,7 +22,7 @@ struct Scratchpad<'a> {
 }
 
 impl<'a> Scratchpad<'a> {
-    fn get<T: GenericVec<T>>(&self) -> Ref<[T]>
+    fn get<T: GenericVec<T>>(&self) -> Ref<'_, [T]>
     where T: 'a
     {
         Ref::map(self.buffers.borrow(), |x| T::unwrap(x.as_ref()))
diff --git a/tests/ui/nll/issue-54556-niconii.rs b/tests/ui/nll/issue-54556-niconii.rs
index 9d37adede6a..dc641524b15 100644
--- a/tests/ui/nll/issue-54556-niconii.rs
+++ b/tests/ui/nll/issue-54556-niconii.rs
@@ -18,7 +18,7 @@ impl Drop for Mutex { fn drop(&mut self) { println!("Mutex::drop"); } }
 impl<'a> Drop for MutexGuard<'a> { fn drop(&mut self) { println!("MutexGuard::drop");  } }
 
 impl Mutex {
-    fn lock(&self) -> Result<MutexGuard, ()> { Ok(MutexGuard(self)) }
+    fn lock(&self) -> Result<MutexGuard<'_>, ()> { Ok(MutexGuard(self)) }
 }
 
 fn main() {
diff --git a/tests/ui/nonscalar-cast.stderr b/tests/ui/nonscalar-cast.stderr
index 01b4a9a7ce0..834d4ea241c 100644
--- a/tests/ui/nonscalar-cast.stderr
+++ b/tests/ui/nonscalar-cast.stderr
@@ -2,9 +2,13 @@ error[E0605]: non-primitive cast: `Foo` as `isize`
   --> $DIR/nonscalar-cast.rs:15:20
    |
 LL |     println!("{}", Foo { x: 1 } as isize);
-   |                    ^^^^^^^^^^^^^^^^^^^^^ help: consider using the `From` trait instead: `isize::from(Foo { x: 1 })`
+   |                    ^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+   |
+help: consider using the `From` trait instead
+   |
+LL -     println!("{}", Foo { x: 1 } as isize);
+LL +     println!("{}", isize::from(Foo { x: 1 }));
    |
-   = note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/object-lifetime/object-lifetime-default-elision.rs b/tests/ui/object-lifetime/object-lifetime-default-elision.rs
index ede6af51174..f7c0261cfbb 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-elision.rs
+++ b/tests/ui/object-lifetime/object-lifetime-default-elision.rs
@@ -46,8 +46,6 @@ fn load1(ss: &dyn SomeTrait) -> &dyn SomeTrait {
 }
 
 fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait {
-    //~^ WARNING elided lifetime has a name
-
     // Same as `load1` but with an explicit name thrown in for fun.
 
     ss
diff --git a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr
index b44a184c684..b5995687927 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr
+++ b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr
@@ -1,15 +1,5 @@
-warning: elided lifetime has a name
-  --> $DIR/object-lifetime-default-elision.rs:48:40
-   |
-LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait {
-   |          --                            ^ this elided lifetime gets resolved as `'a`
-   |          |
-   |          lifetime `'a` declared here
-   |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
-
 error: lifetime may not live long enough
-  --> $DIR/object-lifetime-default-elision.rs:73:5
+  --> $DIR/object-lifetime-default-elision.rs:71:5
    |
 LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {
    |          -- -- lifetime `'b` defined here
@@ -21,5 +11,5 @@ LL |     ss
    |
    = help: consider adding the following bound: `'a: 'b`
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs b/tests/ui/panics/rvalue-cleanup-during-box-panic.rs
index 4c59df24e4b..84c5d85d7e0 100644
--- a/tests/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs
+++ b/tests/ui/panics/rvalue-cleanup-during-box-panic.rs
@@ -25,16 +25,20 @@
 use std::thread;
 
 enum Conzabble {
-    Bickwick(Foo)
+    Bickwick(Foo),
 }
 
-struct Foo { field: Box<usize> }
+struct Foo {
+    field: Box<usize>,
+}
 
 fn do_it(x: &[usize]) -> Foo {
     panic!()
 }
 
-fn get_bar(x: usize) -> Vec<usize> { vec![x * 2] }
+fn get_bar(x: usize) -> Vec<usize> {
+    vec![x * 2]
+}
 
 pub fn fails() {
     let x = 2;
diff --git a/tests/ui/privacy/trait-object-method-error.rs b/tests/ui/privacy/trait-object-method-error.rs
new file mode 100644
index 00000000000..f0214dc6361
--- /dev/null
+++ b/tests/ui/privacy/trait-object-method-error.rs
@@ -0,0 +1,20 @@
+//! Trait objects only allow access to methods defined in the trait.
+
+trait MyTrait {
+    fn trait_method(&mut self);
+}
+
+struct ImplType;
+
+impl MyTrait for ImplType {
+    fn trait_method(&mut self) {}
+}
+
+impl ImplType {
+    fn struct_impl_method(&mut self) {}
+}
+
+fn main() {
+    let obj: Box<dyn MyTrait> = Box::new(ImplType);
+    obj.struct_impl_method(); //~ ERROR no method named `struct_impl_method` found
+}
diff --git a/tests/ui/privacy/trait-object-method-error.stderr b/tests/ui/privacy/trait-object-method-error.stderr
new file mode 100644
index 00000000000..40dde8fc47e
--- /dev/null
+++ b/tests/ui/privacy/trait-object-method-error.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no method named `struct_impl_method` found for struct `Box<dyn MyTrait>` in the current scope
+  --> $DIR/trait-object-method-error.rs:19:9
+   |
+LL |     obj.struct_impl_method();
+   |         ^^^^^^^^^^^^^^^^^^
+   |
+help: there is a method `trait_method` with a similar name
+   |
+LL -     obj.struct_impl_method();
+LL +     obj.trait_method();
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/query-system/issue-83479.rs b/tests/ui/query-system/issue-83479.rs
index 32676dfe9c8..94ceccf49f4 100644
--- a/tests/ui/query-system/issue-83479.rs
+++ b/tests/ui/query-system/issue-83479.rs
@@ -8,6 +8,7 @@ type PairCoupledTypes: Trait<
     }],
 > = impl Trait<
     //~^ ERROR: cannot find trait `Trait` in this scope
+    //~| ERROR: unconstrained opaque type
     [u32; {
         static FOO: usize; //~ ERROR: free static item without body
     }],
diff --git a/tests/ui/query-system/issue-83479.stderr b/tests/ui/query-system/issue-83479.stderr
index 7cb41f5cbe5..79764d01b3b 100644
--- a/tests/ui/query-system/issue-83479.stderr
+++ b/tests/ui/query-system/issue-83479.stderr
@@ -20,7 +20,7 @@ LL |         static FOO: usize;
    |                          help: provide a definition for the static: `= <expr>;`
 
 error: free static item without body
-  --> $DIR/issue-83479.rs:12:9
+  --> $DIR/issue-83479.rs:13:9
    |
 LL |         static FOO: usize;
    |         ^^^^^^^^^^^^^^^^^-
@@ -39,6 +39,21 @@ error[E0405]: cannot find trait `Trait` in this scope
 LL | > = impl Trait<
    |          ^^^^^ not found in this scope
 
-error: aborting due to 5 previous errors
+error: unconstrained opaque type
+  --> $DIR/issue-83479.rs:9:5
+   |
+LL |   > = impl Trait<
+   |  _____^
+LL | |
+LL | |
+LL | |     [u32; {
+LL | |         static FOO: usize;
+LL | |     }],
+LL | | >;
+   | |_^
+   |
+   = note: `PairCoupledTypes` must be used in combination with a concrete type within the same crate
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0405`.
diff --git a/tests/ui/recursion/recursive-static-definition.stderr b/tests/ui/recursion/recursive-static-definition.stderr
index 7063e5c3c66..ce93c41bc67 100644
--- a/tests/ui/recursion/recursive-static-definition.stderr
+++ b/tests/ui/recursion/recursive-static-definition.stderr
@@ -2,13 +2,13 @@ error[E0080]: encountered static that tried to initialize itself with itself
   --> $DIR/recursive-static-definition.rs:1:23
    |
 LL | pub static FOO: u32 = FOO;
-   |                       ^^^ evaluation of static initializer failed here
+   |                       ^^^ evaluation of `FOO` failed here
 
 error[E0080]: encountered static that tried to initialize itself with itself
   --> $DIR/recursive-static-definition.rs:9:23
    |
 LL | pub static BAR: Foo = BAR;
-   |                       ^^^ evaluation of static initializer failed here
+   |                       ^^^ evaluation of `BAR` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/regions/init-res-into-things.rs b/tests/ui/regions/init-res-into-things.rs
index 64909b32919..7b100d32533 100644
--- a/tests/ui/regions/init-res-into-things.rs
+++ b/tests/ui/regions/init-res-into-things.rs
@@ -20,7 +20,7 @@ impl<'a> Drop for r<'a> {
     }
 }
 
-fn r(i: &Cell<isize>) -> r {
+fn r(i: &Cell<isize>) -> r<'_> {
     r {
         i: i
     }
diff --git a/tests/ui/regions/regions-nullary-variant.rs b/tests/ui/regions/regions-nullary-variant.rs
index 8624f9961f6..24c5c6765a8 100644
--- a/tests/ui/regions/regions-nullary-variant.rs
+++ b/tests/ui/regions/regions-nullary-variant.rs
@@ -7,7 +7,7 @@ enum roption<'a> {
     a, b(&'a usize)
 }
 
-fn mk(cond: bool, ptr: &usize) -> roption {
+fn mk(cond: bool, ptr: &usize) -> roption<'_> {
     if cond {roption::a} else {roption::b(ptr)}
 }
 
diff --git a/tests/ui/repeat-expr/copy-check-when-count-inferred-later.stderr b/tests/ui/repeat-expr/copy-check-when-count-inferred-later.stderr
index d974f5add50..1c862f2b606 100644
--- a/tests/ui/repeat-expr/copy-check-when-count-inferred-later.stderr
+++ b/tests/ui/repeat-expr/copy-check-when-count-inferred-later.stderr
@@ -2,12 +2,13 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
   --> $DIR/copy-check-when-count-inferred-later.rs:8:14
    |
 LL |     let a = [String::new(); _];
-   |              ^^^^^^^^^^^^^
-   |              |
-   |              the trait `Copy` is not implemented for `String`
-   |              help: create an inline `const` block: `const { String::new() }`
+   |              ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
    = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: create an inline `const` block
+   |
+LL |     let a = [const { String::new() }; _];
+   |              +++++++               +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
index c11acc98637..63d685951d9 100644
--- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
@@ -1,8 +1,7 @@
 error: layout_of(Univariant) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout {
                variants: [
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Scalar(
                            Initialized {
@@ -88,9 +86,8 @@ LL | enum Univariant {
 
 error: layout_of(TwoVariants) = Layout {
            size: Size(8 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout {
                variants: [
                    Layout {
                        size: Size(8 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout {
                    },
                    Layout {
                        size: Size(8 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -226,9 +221,8 @@ LL | enum TwoVariants {
 
 error: layout_of(DeadBranchHasOtherField) = Layout {
            size: Size(16 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(8 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                variants: [
                    Layout {
                        size: Size(16 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                    },
                    Layout {
                        size: Size(16 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
index a7888155dea..555471be027 100644
--- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
@@ -1,8 +1,7 @@
 error: layout_of(Univariant) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout {
                variants: [
                    Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Scalar(
                            Initialized {
@@ -88,9 +86,8 @@ LL | enum Univariant {
 
 error: layout_of(TwoVariants) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout {
                variants: [
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout {
                    },
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -226,9 +221,8 @@ LL | enum TwoVariants {
 
 error: layout_of(DeadBranchHasOtherField) = Layout {
            size: Size(16 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(8 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                variants: [
                    Layout {
                        size: Size(16 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                    },
                    Layout {
                        size: Size(16 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
index c11acc98637..63d685951d9 100644
--- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
@@ -1,8 +1,7 @@
 error: layout_of(Univariant) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout {
                variants: [
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Scalar(
                            Initialized {
@@ -88,9 +86,8 @@ LL | enum Univariant {
 
 error: layout_of(TwoVariants) = Layout {
            size: Size(8 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout {
                variants: [
                    Layout {
                        size: Size(8 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout {
                    },
                    Layout {
                        size: Size(8 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -226,9 +221,8 @@ LL | enum TwoVariants {
 
 error: layout_of(DeadBranchHasOtherField) = Layout {
            size: Size(16 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(8 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                variants: [
                    Layout {
                        size: Size(16 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                    },
                    Layout {
                        size: Size(16 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
index c11acc98637..63d685951d9 100644
--- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
@@ -1,8 +1,7 @@
 error: layout_of(Univariant) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout {
                variants: [
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Scalar(
                            Initialized {
@@ -88,9 +86,8 @@ LL | enum Univariant {
 
 error: layout_of(TwoVariants) = Layout {
            size: Size(8 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout {
                variants: [
                    Layout {
                        size: Size(8 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout {
                    },
                    Layout {
                        size: Size(8 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -226,9 +221,8 @@ LL | enum TwoVariants {
 
 error: layout_of(DeadBranchHasOtherField) = Layout {
            size: Size(16 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(8 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                variants: [
                    Layout {
                        size: Size(16 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                    },
                    Layout {
                        size: Size(16 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr
index f63574182c2..d88a842f884 100644
--- a/tests/ui/repr/repr-c-int-dead-variants.stderr
+++ b/tests/ui/repr/repr-c-int-dead-variants.stderr
@@ -1,8 +1,7 @@
 error: layout_of(UnivariantU8) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -45,9 +44,8 @@ error: layout_of(UnivariantU8) = Layout {
                variants: [
                    Layout {
                        size: Size(1 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Scalar(
                            Initialized {
@@ -88,9 +86,8 @@ LL | enum UnivariantU8 {
 
 error: layout_of(TwoVariantsU8) = Layout {
            size: Size(2 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: ScalarPair(
                Initialized {
@@ -139,9 +136,8 @@ error: layout_of(TwoVariantsU8) = Layout {
                variants: [
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -177,9 +173,8 @@ error: layout_of(TwoVariantsU8) = Layout {
                    },
                    Layout {
                        size: Size(2 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: ScalarPair(
                            Initialized {
@@ -226,9 +221,8 @@ LL | enum TwoVariantsU8 {
 
 error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
            size: Size(16 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(8 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Memory {
                sized: true,
@@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                variants: [
                    Layout {
                        size: Size(16 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                    },
                    Layout {
                        size: Size(16 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(8 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
diff --git a/tests/ui/resource-assign-is-not-copy.rs b/tests/ui/resource-assign-is-not-copy.rs
index 078824cea1b..ab426016901 100644
--- a/tests/ui/resource-assign-is-not-copy.rs
+++ b/tests/ui/resource-assign-is-not-copy.rs
@@ -14,7 +14,7 @@ impl<'a> Drop for r<'a> {
     }
 }
 
-fn r(i: &Cell<isize>) -> r {
+fn r(i: &Cell<isize>) -> r<'_> {
     r {
         i: i
     }
diff --git a/tests/ui/resource-destruct.rs b/tests/ui/resource-destruct.rs
index cbb17bb6ba6..480cbe091a7 100644
--- a/tests/ui/resource-destruct.rs
+++ b/tests/ui/resource-destruct.rs
@@ -17,7 +17,7 @@ impl<'a> shrinky_pointer<'a> {
     pub fn look_at(&self) -> isize { return self.i.get(); }
 }
 
-fn shrinky_pointer(i: &Cell<isize>) -> shrinky_pointer {
+fn shrinky_pointer(i: &Cell<isize>) -> shrinky_pointer<'_> {
     shrinky_pointer {
         i: i
     }
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/temporary-early-drop.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/temporary-early-drop.rs
index 9edbc3243c7..9bf6cfcccba 100644
--- a/tests/ui/rfcs/rfc-2294-if-let-guard/temporary-early-drop.rs
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/temporary-early-drop.rs
@@ -10,7 +10,7 @@
 struct Pd;
 
 impl Pd {
-    fn it(&self) -> It {
+    fn it(&self) -> It<'_> {
         todo!()
     }
 }
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs
index 5dd928dbce5..a61be38a23a 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs
@@ -33,7 +33,7 @@ impl DropOrderCollector {
         println!("{n}");
         self.0.borrow_mut().push(n)
     }
-    fn some_loud(&self, n: u32) -> Option<LoudDrop> {
+    fn some_loud(&self, n: u32) -> Option<LoudDrop<'_>> {
         Some(LoudDrop(self, n))
     }
 
diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs
index 7d8dfe37135..3e4fae2e84e 100644
--- a/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs
+++ b/tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs
@@ -8,7 +8,7 @@
 struct Pd;
 
 impl Pd {
-    fn it(&self) -> It {
+    fn it(&self) -> It<'_> {
         todo!()
     }
 }
diff --git a/tests/ui/deep.rs b/tests/ui/runtime/deep_recursion.rs
index 5a631d068b1..bf220f174a1 100644
--- a/tests/ui/deep.rs
+++ b/tests/ui/runtime/deep_recursion.rs
@@ -1,3 +1,5 @@
+//! Checks deep recursion behavior.
+
 //@ run-pass
 //@ ignore-emscripten apparently blows the stack
 
diff --git a/tests/ui/rustdoc/doc-test-attr-pass.rs b/tests/ui/rustdoc/doc-test-attr-pass.rs
index f0120b7c2d0..60d1e3722bd 100644
--- a/tests/ui/rustdoc/doc-test-attr-pass.rs
+++ b/tests/ui/rustdoc/doc-test-attr-pass.rs
@@ -6,4 +6,46 @@
 #![doc(test(attr(deny(warnings))))]
 #![doc(test())]
 
+mod test {
+    #![doc(test(attr(allow(warnings))))]
+}
+
+#[doc(test(attr(allow(dead_code))))]
+static S: u32 = 5;
+
+#[doc(test(attr(allow(dead_code))))]
+const C: u32 = 5;
+
+#[doc(test(attr(deny(dead_code))))]
+struct A {
+    #[doc(test(attr(allow(dead_code))))]
+    field: u32
+}
+
+#[doc(test(attr(deny(dead_code))))]
+union U {
+    #[doc(test(attr(allow(dead_code))))]
+    field: u32,
+    field2: u64,
+}
+
+#[doc(test(attr(deny(dead_code))))]
+enum Enum {
+    #[doc(test(attr(allow(dead_code))))]
+    Variant1,
+}
+
+#[doc(test(attr(deny(dead_code))))]
+impl A {
+    #[doc(test(attr(deny(dead_code))))]
+    fn method() {}
+}
+
+#[doc(test(attr(deny(dead_code))))]
+trait MyTrait {
+    #[doc(test(attr(deny(dead_code))))]
+    fn my_trait_fn();
+}
+
+#[doc(test(attr(deny(dead_code))))]
 pub fn foo() {}
diff --git a/tests/ui/rustdoc/renamed-features-rustdoc_internals.rs b/tests/ui/rustdoc/renamed-features-rustdoc_internals.rs
index 739c624d0c6..2257130280d 100644
--- a/tests/ui/rustdoc/renamed-features-rustdoc_internals.rs
+++ b/tests/ui/rustdoc/renamed-features-rustdoc_internals.rs
@@ -1,3 +1,5 @@
+//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION"
+
 #![feature(doc_keyword)] //~ ERROR
 #![feature(doc_primitive)] //~ ERROR
 #![crate_type = "lib"]
diff --git a/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr b/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr
index d0979ce97ac..9c664da8ee6 100644
--- a/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr
+++ b/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr
@@ -1,17 +1,19 @@
 error[E0557]: feature has been removed
-  --> $DIR/renamed-features-rustdoc_internals.rs:1:12
+  --> $DIR/renamed-features-rustdoc_internals.rs:3:12
    |
 LL | #![feature(doc_keyword)]
    |            ^^^^^^^^^^^ feature has been removed
    |
+   = note: removed in 1.58.0 (you are using $RUSTC_VERSION); see <https://github.com/rust-lang/rust/pull/90420> for more information
    = note: merged into `#![feature(rustdoc_internals)]`
 
 error[E0557]: feature has been removed
-  --> $DIR/renamed-features-rustdoc_internals.rs:2:12
+  --> $DIR/renamed-features-rustdoc_internals.rs:4:12
    |
 LL | #![feature(doc_primitive)]
    |            ^^^^^^^^^^^^^ feature has been removed
    |
+   = note: removed in 1.58.0 (you are using $RUSTC_VERSION); see <https://github.com/rust-lang/rust/pull/90420> for more information
    = note: merged into `#![feature(rustdoc_internals)]`
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.rs b/tests/ui/self/elision/ignore-non-reference-lifetimes.rs
index cedc6f0f9bc..ecd669059ed 100644
--- a/tests/ui/self/elision/ignore-non-reference-lifetimes.rs
+++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.rs
@@ -4,11 +4,11 @@ struct Foo<'a>(&'a str);
 
 impl<'b> Foo<'b> {
     fn a<'a>(self: Self, a: &'a str) -> &str {
-        //~^ WARNING elided lifetime has a name
+        //~^ WARNING lifetime flowing from input to output with different syntax
         a
     }
     fn b<'a>(self: Foo<'b>, a: &'a str) -> &str {
-        //~^ WARNING elided lifetime has a name
+        //~^ WARNING lifetime flowing from input to output with different syntax
         a
     }
 }
diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
index 4465dbae529..5351bf3c94c 100644
--- a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
+++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
@@ -1,16 +1,29 @@
-warning: elided lifetime has a name
-  --> $DIR/ignore-non-reference-lifetimes.rs:6:41
+warning: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/ignore-non-reference-lifetimes.rs:6:30
    |
 LL |     fn a<'a>(self: Self, a: &'a str) -> &str {
-   |          -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a`
+   |                              ^^         ---- the lifetime gets resolved as `'a`
+   |                              |
+   |                              this lifetime flows to the output
    |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
+   = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
+help: one option is to consistently use `'a`
+   |
+LL |     fn a<'a>(self: Self, a: &'a str) -> &'a str {
+   |                                          ++
 
-warning: elided lifetime has a name
-  --> $DIR/ignore-non-reference-lifetimes.rs:10:44
+warning: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/ignore-non-reference-lifetimes.rs:10:33
    |
 LL |     fn b<'a>(self: Foo<'b>, a: &'a str) -> &str {
-   |          -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
+   |                                 ^^         ---- the lifetime gets resolved as `'a`
+   |                                 |
+   |                                 this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL |     fn b<'a>(self: Foo<'b>, a: &'a str) -> &'a str {
+   |                                             ++
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/self/elision/lt-ref-self-async.fixed b/tests/ui/self/elision/lt-ref-self-async.fixed
index aae94f7a6cc..191610336de 100644
--- a/tests/ui/self/elision/lt-ref-self-async.fixed
+++ b/tests/ui/self/elision/lt-ref-self-async.fixed
@@ -1,6 +1,6 @@
 //@ edition:2018
 //@ run-rustfix
-#![allow(non_snake_case, dead_code, elided_named_lifetimes)]
+#![allow(non_snake_case, dead_code, mismatched_lifetime_syntaxes)]
 
 use std::pin::Pin;
 
diff --git a/tests/ui/self/elision/lt-ref-self-async.rs b/tests/ui/self/elision/lt-ref-self-async.rs
index 0c11b271c35..c910a5d6d7e 100644
--- a/tests/ui/self/elision/lt-ref-self-async.rs
+++ b/tests/ui/self/elision/lt-ref-self-async.rs
@@ -1,6 +1,6 @@
 //@ edition:2018
 //@ run-rustfix
-#![allow(non_snake_case, dead_code, elided_named_lifetimes)]
+#![allow(non_snake_case, dead_code, mismatched_lifetime_syntaxes)]
 
 use std::pin::Pin;
 
diff --git a/tests/ui/self/self_lifetime-async.rs b/tests/ui/self/self_lifetime-async.rs
index fd690207118..f839ab03a60 100644
--- a/tests/ui/self/self_lifetime-async.rs
+++ b/tests/ui/self/self_lifetime-async.rs
@@ -4,13 +4,13 @@
 struct Foo<'a>(&'a ());
 impl<'a> Foo<'a> {
     async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
-    //~^ WARNING elided lifetime has a name
+    //~^ WARNING lifetime flowing from input to output with different syntax
 }
 
 type Alias = Foo<'static>;
 impl Alias {
     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
-    //~^ WARNING elided lifetime has a name
+    //~^ WARNING lifetime flowing from input to output with different syntax
 }
 
 fn main() {}
diff --git a/tests/ui/self/self_lifetime-async.stderr b/tests/ui/self/self_lifetime-async.stderr
index 32de3fd18c9..a9c1be2e808 100644
--- a/tests/ui/self/self_lifetime-async.stderr
+++ b/tests/ui/self/self_lifetime-async.stderr
@@ -1,18 +1,29 @@
-warning: elided lifetime has a name
-  --> $DIR/self_lifetime-async.rs:6:44
+warning: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/self_lifetime-async.rs:6:29
    |
 LL |     async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
-   |                  --                        ^ this elided lifetime gets resolved as `'b`
-   |                  |
-   |                  lifetime `'b` declared here
+   |                             ^^             --- the lifetime gets resolved as `'b`
+   |                             |
+   |                             this lifetime flows to the output
    |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
+   = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
+help: one option is to consistently use `'b`
+   |
+LL |     async fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 }
+   |                                             ++
 
-warning: elided lifetime has a name
-  --> $DIR/self_lifetime-async.rs:12:52
+warning: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/self_lifetime-async.rs:12:42
    |
 LL |     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
-   |                  -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
+   |                                          ^^        --- the lifetime gets resolved as `'a`
+   |                                          |
+   |                                          this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL |     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg }
+   |                                                     ++
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/self/self_lifetime.rs b/tests/ui/self/self_lifetime.rs
index 0607c3b9317..aaa31f85ad5 100644
--- a/tests/ui/self/self_lifetime.rs
+++ b/tests/ui/self/self_lifetime.rs
@@ -5,13 +5,13 @@
 struct Foo<'a>(&'a ());
 impl<'a> Foo<'a> {
     fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
-    //~^ WARNING elided lifetime has a name
+    //~^ WARNING lifetime flowing from input to output with different syntax
 }
 
 type Alias = Foo<'static>;
 impl Alias {
     fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
-    //~^ WARNING elided lifetime has a name
+    //~^ WARNING lifetime flowing from input to output with different syntax
 }
 
 fn main() {}
diff --git a/tests/ui/self/self_lifetime.stderr b/tests/ui/self/self_lifetime.stderr
index cd8f4d8adf8..ec676e69cf6 100644
--- a/tests/ui/self/self_lifetime.stderr
+++ b/tests/ui/self/self_lifetime.stderr
@@ -1,18 +1,29 @@
-warning: elided lifetime has a name
-  --> $DIR/self_lifetime.rs:7:38
+warning: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/self_lifetime.rs:7:23
    |
 LL |     fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
-   |            --                        ^ this elided lifetime gets resolved as `'b`
-   |            |
-   |            lifetime `'b` declared here
+   |                       ^^             --- the lifetime gets resolved as `'b`
+   |                       |
+   |                       this lifetime flows to the output
    |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
+   = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
+help: one option is to consistently use `'b`
+   |
+LL |     fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 }
+   |                                       ++
 
-warning: elided lifetime has a name
-  --> $DIR/self_lifetime.rs:13:46
+warning: lifetime flowing from input to output with different syntax can be confusing
+  --> $DIR/self_lifetime.rs:13:36
    |
 LL |     fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
-   |            -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
+   |                                    ^^        --- the lifetime gets resolved as `'a`
+   |                                    |
+   |                                    this lifetime flows to the output
+   |
+help: one option is to consistently use `'a`
+   |
+LL |     fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg }
+   |                                               ++
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr
index 354ca78c7be..d097b809b56 100644
--- a/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr
+++ b/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr
@@ -13,7 +13,7 @@ error[E0080]: a cycle occurred during layout computation
   --> $DIR/stack-overflow-trait-infer-98842.rs:14:1
    |
 LL | const _: *const Foo = 0 as _;
-   | ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr
index 354ca78c7be..d097b809b56 100644
--- a/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr
+++ b/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr
@@ -13,7 +13,7 @@ error[E0080]: a cycle occurred during layout computation
   --> $DIR/stack-overflow-trait-infer-98842.rs:14:1
    |
 LL | const _: *const Foo = 0 as _;
-   | ^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/crashes/140571.rs b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs
index 97fa1d8432d..f4cde1d62b2 100644
--- a/tests/crashes/140571.rs
+++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs
@@ -1,14 +1,21 @@
-//@ known-bug: #140571
+// Regression test for #140571. The compiler used to ICE
+
+#![feature(associated_const_equality, specialization)]
+//~^ WARN the feature `specialization` is incomplete
+
 pub trait IsVoid {
     const IS_VOID: bool;
 }
 impl<T> IsVoid for T {
     default const IS_VOID: bool = false;
 }
-impl<T> Maybe<T> for () where T: NotVoid + ?Sized {}
 
 pub trait NotVoid {}
 impl<T> NotVoid for T where T: IsVoid<IS_VOID = false> + ?Sized {}
 
 pub trait Maybe<T> {}
 impl<T> Maybe<T> for T {}
+impl<T> Maybe<T> for () where T: NotVoid + ?Sized {}
+//~^ ERROR conflicting implementations of trait `Maybe<()>` for type `()`
+
+fn main() {}
diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr
new file mode 100644
index 00000000000..a26b30fbb63
--- /dev/null
+++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr
@@ -0,0 +1,21 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:39
+   |
+LL | #![feature(associated_const_equality, specialization)]
+   |                                       ^^^^^^^^^^^^^^
+   |
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0119]: conflicting implementations of trait `Maybe<()>` for type `()`
+  --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:18:1
+   |
+LL | impl<T> Maybe<T> for T {}
+   | ---------------------- first implementation here
+LL | impl<T> Maybe<T> for () where T: NotVoid + ?Sized {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/statics/issue-14227.stderr b/tests/ui/statics/issue-14227.stderr
index 372a06ae1ed..f5ab2314494 100644
--- a/tests/ui/statics/issue-14227.stderr
+++ b/tests/ui/statics/issue-14227.stderr
@@ -2,7 +2,7 @@ error[E0080]: cannot access extern static `symbol`
   --> $DIR/issue-14227.rs:4:21
    |
 LL | static CRASH: u32 = symbol;
-   |                     ^^^^^^ evaluation of static initializer failed here
+   |                     ^^^^^^ evaluation of `CRASH` failed here
 
 error[E0133]: use of extern static is unsafe and requires unsafe function or block
   --> $DIR/issue-14227.rs:4:21
diff --git a/tests/ui/statics/uninhabited-static.stderr b/tests/ui/statics/uninhabited-static.stderr
index 60268ad3562..f799a82f139 100644
--- a/tests/ui/statics/uninhabited-static.stderr
+++ b/tests/ui/statics/uninhabited-static.stderr
@@ -47,13 +47,13 @@ error[E0080]: constructing invalid value: encountered a value of uninhabited typ
   --> $DIR/uninhabited-static.rs:12:31
    |
 LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `VOID2` failed here
 
 error[E0080]: constructing invalid value: encountered a value of uninhabited type `Void`
   --> $DIR/uninhabited-static.rs:15:32
    |
 LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of static initializer failed here
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `NEVER2` failed here
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/structs/default-field-values/invalid-const.stderr b/tests/ui/structs/default-field-values/invalid-const.stderr
index f4a74ef9fdc..545783e6c74 100644
--- a/tests/ui/structs/default-field-values/invalid-const.stderr
+++ b/tests/ui/structs/default-field-values/invalid-const.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: asdf
   --> $DIR/invalid-const.rs:5:19
    |
 LL |     pub bax: u8 = panic!("asdf"),
-   |                   ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |                   ^^^^^^^^^^^^^^ evaluation of `Bat::bax::{constant#0}` failed here
 
 error[E0080]: attempt to compute `130_u8 + 130_u8`, which would overflow
   --> $DIR/invalid-const.rs:11:19
diff --git a/tests/ui/suggestions/abi-typo.fixed b/tests/ui/suggestions/abi-typo.fixed
index 44fa80f6338..ae507c3e48f 100644
--- a/tests/ui/suggestions/abi-typo.fixed
+++ b/tests/ui/suggestions/abi-typo.fixed
@@ -1,6 +1,6 @@
 //@ run-rustfix
-extern "cdecl" fn cdedl() {} //~ ERROR invalid ABI
+extern "system" fn systen() {} //~ ERROR invalid ABI
 
 fn main() {
-    cdedl();
+    systen();
 }
diff --git a/tests/ui/suggestions/abi-typo.rs b/tests/ui/suggestions/abi-typo.rs
index 3d5c23e0f23..c40bd803e53 100644
--- a/tests/ui/suggestions/abi-typo.rs
+++ b/tests/ui/suggestions/abi-typo.rs
@@ -1,6 +1,6 @@
 //@ run-rustfix
-extern "cdedl" fn cdedl() {} //~ ERROR invalid ABI
+extern "systen" fn systen() {} //~ ERROR invalid ABI
 
 fn main() {
-    cdedl();
+    systen();
 }
diff --git a/tests/ui/suggestions/abi-typo.stderr b/tests/ui/suggestions/abi-typo.stderr
index 4d89ac16570..a8b4d366705 100644
--- a/tests/ui/suggestions/abi-typo.stderr
+++ b/tests/ui/suggestions/abi-typo.stderr
@@ -1,14 +1,14 @@
-error[E0703]: invalid ABI: found `cdedl`
+error[E0703]: invalid ABI: found `systen`
   --> $DIR/abi-typo.rs:2:8
    |
-LL | extern "cdedl" fn cdedl() {}
-   |        ^^^^^^^ invalid ABI
+LL | extern "systen" fn systen() {}
+   |        ^^^^^^^^ invalid ABI
    |
    = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
-help: there's a similarly named valid ABI `cdecl`
+help: there's a similarly named valid ABI `system`
    |
-LL - extern "cdedl" fn cdedl() {}
-LL + extern "cdecl" fn cdedl() {}
+LL - extern "systen" fn systen() {}
+LL + extern "system" fn systen() {}
    |
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/suggestions/double-reference-ty-in-self-ty.rs b/tests/ui/suggestions/double-reference-ty-in-self-ty.rs
new file mode 100644
index 00000000000..4ac13f0f635
--- /dev/null
+++ b/tests/ui/suggestions/double-reference-ty-in-self-ty.rs
@@ -0,0 +1,12 @@
+// issue#135863
+
+struct A;
+
+impl A {
+    fn len(self: &&A) {}
+}
+
+fn main() {
+    A.len();
+    //~^ ERROR: no method named `len` found for struct `A` in the current scope
+}
diff --git a/tests/ui/suggestions/double-reference-ty-in-self-ty.stderr b/tests/ui/suggestions/double-reference-ty-in-self-ty.stderr
new file mode 100644
index 00000000000..a7182342410
--- /dev/null
+++ b/tests/ui/suggestions/double-reference-ty-in-self-ty.stderr
@@ -0,0 +1,19 @@
+error[E0599]: no method named `len` found for struct `A` in the current scope
+  --> $DIR/double-reference-ty-in-self-ty.rs:10:7
+   |
+LL | struct A;
+   | -------- method `len` not found for this struct
+...
+LL |     fn len(self: &&A) {}
+   |        --- the method is available for `&A` here
+...
+LL |     A.len();
+   |       ^^^ method not found in `A`
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following trait defines an item `len`, perhaps you need to implement it:
+           candidate #1: `ExactSizeIterator`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs
index f5c3da847c7..f176d52c087 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs
@@ -73,7 +73,6 @@ mod in_path {
 
 // This must not err, as the `&` actually resolves to `'a`.
 fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) {
-    //~^ WARNING elided lifetime has a name
     f("f");
 }
 
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
index 92996ca8467..f29107b297a 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
@@ -149,14 +149,6 @@ LL -     fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
 LL +     fn g(mut x: impl Foo<()>) -> Option<()> { x.next() }
    |
 
-warning: elided lifetime has a name
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:75:57
-   |
-LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) {
-   |                       -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
-   |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
-
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
   --> $DIR/impl-trait-missing-lifetime-gated.rs:6:35
    |
@@ -289,7 +281,7 @@ help: consider introducing a named lifetime parameter
 LL |     fn g<'a>(mut x: impl Foo<'a, ()>) -> Option<&()> { x.next() }
    |         ++++                 +++
 
-error: aborting due to 17 previous errors; 1 warning emitted
+error: aborting due to 17 previous errors
 
 Some errors have detailed explanations: E0106, E0658.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
index b61bea16e3b..b641f5941dc 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
@@ -100,7 +100,6 @@ where
 
 // This also works. The `'_` isn't necessary but it's where we arrive to following the suggestions:
 fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a
-//~^ WARNING elided lifetime has a name
 where
     G: Get<T>,
 {
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
index b92719e8033..41cb2ee46bb 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
@@ -6,14 +6,6 @@ LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
    |        |
    |        help: consider introducing lifetime `'a` here: `'a,`
 
-warning: elided lifetime has a name
-  --> $DIR/missing-lifetimes-in-signature.rs:102:64
-   |
-LL | fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a
-   |        -- lifetime `'a` declared here                          ^^ this elided lifetime gets resolved as `'a`
-   |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
-
 error[E0700]: hidden type for `impl FnOnce()` captures lifetime that does not appear in bounds
   --> $DIR/missing-lifetimes-in-signature.rs:19:5
    |
@@ -136,7 +128,7 @@ help: consider adding an explicit lifetime bound
 LL |     G: Get<T> + 'a,
    |               ++++
 
-error: aborting due to 8 previous errors; 1 warning emitted
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0261, E0309, E0311, E0621, E0700.
 For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/tag-variant-cast-non-nullary.stderr b/tests/ui/tag-variant-cast-non-nullary.stderr
index 2e1dde27d0f..8ec1c5f11ec 100644
--- a/tests/ui/tag-variant-cast-non-nullary.stderr
+++ b/tests/ui/tag-variant-cast-non-nullary.stderr
@@ -2,10 +2,14 @@ error[E0605]: non-primitive cast: `NonNullary` as `isize`
   --> $DIR/tag-variant-cast-non-nullary.rs:19:15
    |
 LL |     let val = v as isize;
-   |               ^^^^^^^^^^ help: consider using the `From` trait instead: `isize::from(v)`
+   |               ^^^^^^^^^^ an `as` expression can be used to convert enum types to numeric types only if the enum type is unit-only or field-less
    |
-   = note: an `as` expression can be used to convert enum types to numeric types only if the enum type is unit-only or field-less
    = note: see https://doc.rust-lang.org/reference/items/enumerations.html#casting for more information
+help: consider using the `From` trait instead
+   |
+LL -     let val = v as isize;
+LL +     let val = isize::from(v);
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/custom-test-frameworks-simple.rs b/tests/ui/test-attrs/custom_test_frameworks_simple.rs
index 3fb7de6b26b..54a4e4095a7 100644
--- a/tests/ui/custom-test-frameworks-simple.rs
+++ b/tests/ui/test-attrs/custom_test_frameworks_simple.rs
@@ -1,3 +1,5 @@
+//! Checks run with a custom test framework and indexed test functions.
+
 //@ compile-flags: --test
 //@ run-pass
 
diff --git a/tests/ui/track-diagnostics/track.stderr b/tests/ui/track-diagnostics/track.stderr
index d2908bb9177..527c0d1b898 100644
--- a/tests/ui/track-diagnostics/track.stderr
+++ b/tests/ui/track-diagnostics/track.stderr
@@ -10,7 +10,7 @@ error[E0268]: `break` outside of a loop or labeled block
    |
 LL |     break rust
    |     ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
--Ztrack-diagnostics: created at compiler/rustc_passes/src/loops.rs:LL:CC
+-Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/loops.rs:LL:CC
 
 error: internal compiler error: It looks like you're trying to break rust; would you like some ICE?
   --> $DIR/track.rs:LL:CC
diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
index a22d88b7c59..eedaae43f9a 100644
--- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
+++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
@@ -49,23 +49,6 @@ LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), Assoc = i32> {
    |                                                        +++++++
 
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:46
-   |
-LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
-   |                                              ^^^^^ expected 1 generic argument
-   |
-note: trait defined here, with 1 generic parameter: `T`
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:5:11
-   |
-LL | pub trait Trait<T> {
-   |           ^^^^^ -
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: replace the generic bound with the associated type
-   |
-LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), Assoc = i32> {
-   |                                                        +++++++
-
-error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:18
    |
 LL | struct Struct<T: Trait<u32, String>> {
@@ -127,6 +110,23 @@ note: struct defined here, with 1 generic parameter: `T`
 LL | struct Struct<T: Trait<u32, String>> {
    |        ^^^^^^ -
 
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:46
+   |
+LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
+   |                                              ^^^^^ expected 1 generic argument
+   |
+note: trait defined here, with 1 generic parameter: `T`
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:5:11
+   |
+LL | pub trait Trait<T> {
+   |           ^^^^^ -
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: replace the generic bound with the associated type
+   |
+LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), Assoc = i32> {
+   |                                                        +++++++
+
 error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0107, E0207.
diff --git a/tests/ui/builtin-clone-unwind.rs b/tests/ui/traits/clone-unwind-rc-cleanup.rs
index 507ea045b4f..cd02050ea27 100644
--- a/tests/ui/builtin-clone-unwind.rs
+++ b/tests/ui/traits/clone-unwind-rc-cleanup.rs
@@ -1,14 +1,13 @@
+//! Tests cleanup behavior of the built-in `Clone` impl for tuples during unwinding.
+
 //@ run-pass
 //@ needs-unwind
 
 #![allow(unused_variables)]
 #![allow(unused_imports)]
 
-// Test that builtin implementations of `Clone` cleanup everything
-// in case of unwinding.
-
-use std::thread;
 use std::rc::Rc;
+use std::thread;
 
 struct S(Rc<()>);
 
@@ -28,34 +27,20 @@ fn main() {
     // Unwinding with tuples...
     let ccounter = counter.clone();
     let result = std::panic::catch_unwind(move || {
-        let _ = (
-            S(ccounter.clone()),
-            S(ccounter.clone()),
-            S(ccounter.clone()),
-            S(ccounter)
-        ).clone();
+        let _ =
+            (S(ccounter.clone()), S(ccounter.clone()), S(ccounter.clone()), S(ccounter)).clone();
     });
 
     assert!(result.is_err());
-    assert_eq!(
-        1,
-        Rc::strong_count(&counter)
-    );
+    assert_eq!(1, Rc::strong_count(&counter));
 
     // ... and with arrays.
     let ccounter = counter.clone();
     let child = std::panic::catch_unwind(move || {
-        let _ = [
-            S(ccounter.clone()),
-            S(ccounter.clone()),
-            S(ccounter.clone()),
-            S(ccounter)
-        ].clone();
+        let _ =
+            [S(ccounter.clone()), S(ccounter.clone()), S(ccounter.clone()), S(ccounter)].clone();
     });
 
     assert!(child.is_err());
-    assert_eq!(
-        1,
-        Rc::strong_count(&counter)
-    );
+    assert_eq!(1, Rc::strong_count(&counter));
 }
diff --git a/tests/ui/traits/const-traits/const-impl-trait.stderr b/tests/ui/traits/const-traits/const-impl-trait.stderr
index 27d7957c001..6783cec3960 100644
--- a/tests/ui/traits/const-traits/const-impl-trait.stderr
+++ b/tests/ui/traits/const-traits/const-impl-trait.stderr
@@ -33,13 +33,14 @@ note: `PartialEq` can't be used with `~const` because it isn't annotated with `#
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:17:11
+  --> $DIR/const-impl-trait.rs:16:13
    |
-LL | ) -> impl ~const PartialEq + ~const Destruct {
-   |           ^^^^^^ can't be applied to `PartialEq`
+LL |     x: impl ~const PartialEq + ~const Destruct,
+   |             ^^^^^^ can't be applied to `PartialEq`
    |
 note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/const-impl-trait.rs:17:11
@@ -49,7 +50,6 @@ LL | ) -> impl ~const PartialEq + ~const Destruct {
    |
 note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/const-impl-trait.rs:17:11
@@ -62,32 +62,32 @@ note: `PartialEq` can't be used with `~const` because it isn't annotated with `#
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:16:13
+  --> $DIR/const-impl-trait.rs:23:22
    |
-LL |     x: impl ~const PartialEq + ~const Destruct,
-   |             ^^^^^^ can't be applied to `PartialEq`
+LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
+   |                      ^^^^^^ can't be applied to `PartialEq`
    |
 note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:23:22
+  --> $DIR/const-impl-trait.rs:27:22
    |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
+LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
    |                      ^^^^^^ can't be applied to `PartialEq`
    |
 note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/const-impl-trait.rs:27:22
+  --> $DIR/const-impl-trait.rs:17:11
    |
-LL |     fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
-   |                      ^^^^^^ can't be applied to `PartialEq`
+LL | ) -> impl ~const PartialEq + ~const Destruct {
+   |           ^^^^^^ can't be applied to `PartialEq`
    |
 note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/const-impl-trait.rs:27:22
diff --git a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs
index f90ff91aff4..b563b78f78a 100644
--- a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs
+++ b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs
@@ -6,6 +6,7 @@
 // Regression test for issue #125877.
 
 //@ compile-flags: -Znext-solver
+//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION"
 
 #![feature(const_trait_impl, effects)]
 //~^ ERROR feature has been removed
diff --git a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr
index d45c4cba1f8..a04f98e68a6 100644
--- a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr
+++ b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr
@@ -1,13 +1,14 @@
 error[E0557]: feature has been removed
-  --> $DIR/const-trait-impl-parameter-mismatch.rs:10:30
+  --> $DIR/const-trait-impl-parameter-mismatch.rs:11:30
    |
 LL | #![feature(const_trait_impl, effects)]
    |                              ^^^^^^^ feature has been removed
    |
+   = note: removed in 1.84.0 (you are using $RUSTC_VERSION); see <https://github.com/rust-lang/rust/pull/132479> for more information
    = note: removed, redundant with `#![feature(const_trait_impl)]`
 
 error[E0049]: associated function `compute` has 0 type parameters but its trait declaration has 1 type parameter
-  --> $DIR/const-trait-impl-parameter-mismatch.rs:19:16
+  --> $DIR/const-trait-impl-parameter-mismatch.rs:20:16
    |
 LL |     fn compute<T: ~const Aux>() -> u32;
    |                - expected 1 type parameter
diff --git a/tests/ui/can-copy-pod.rs b/tests/ui/traits/copy-trait-implicit-copy.rs
index ffb8a08fa98..e06385587b4 100644
--- a/tests/ui/can-copy-pod.rs
+++ b/tests/ui/traits/copy-trait-implicit-copy.rs
@@ -1,13 +1,13 @@
+//! Tests that type parameters with the `Copy` are implicitly copyable.
+
 //@ run-pass
 
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-// Tests that type parameters with the `Copy` are implicitly copyable.
-
 #![allow(dead_code)]
 
-fn can_copy_copy<T:Copy>(v: T) {
+fn can_copy_copy<T: Copy>(v: T) {
     let _a = v;
     let _b = v;
 }
diff --git a/tests/ui/default-method-simple.rs b/tests/ui/traits/default_method_simple.rs
index e5fbedfaece..96fad94f57a 100644
--- a/tests/ui/default-method-simple.rs
+++ b/tests/ui/traits/default_method_simple.rs
@@ -1,6 +1,6 @@
-//@ run-pass
+//! Checks basic default method functionality.
 
-#![allow(dead_code)]
+//@ run-pass
 
 trait Foo {
     fn f(&self) {
@@ -10,9 +10,7 @@ trait Foo {
     fn g(&self);
 }
 
-struct A {
-    x: isize
-}
+struct A;
 
 impl Foo for A {
     fn g(&self) {
@@ -21,6 +19,6 @@ impl Foo for A {
 }
 
 pub fn main() {
-    let a = A { x: 1 };
+    let a = A;
     a.f();
 }
diff --git a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr
index 57cba790b55..7d39c82d22f 100644
--- a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr
+++ b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr
@@ -1,13 +1,10 @@
-error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
+error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>>`
   --> $DIR/coherence-fulfill-overflow.rs:12:1
    |
 LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
    | ------------------------------------- first implementation here
 LL | impl<T: ?Sized + TwoW> Trait for T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
-   |
-   = note: overflow evaluating the requirement `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>: TwoW`
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`)
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>>`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/trait-impl-missing-method.rs b/tests/ui/traits/trait-impl-missing-method.rs
new file mode 100644
index 00000000000..1f03a332c4a
--- /dev/null
+++ b/tests/ui/traits/trait-impl-missing-method.rs
@@ -0,0 +1,13 @@
+//! Trait impls must define all required methods.
+
+trait MyTrait {
+    fn trait_method(&self);
+}
+
+struct ImplType;
+
+impl MyTrait for ImplType {} //~ ERROR not all trait items implemented, missing: `trait_method`
+
+fn main() {
+    let _ = ImplType;
+}
diff --git a/tests/ui/traits/trait-impl-missing-method.stderr b/tests/ui/traits/trait-impl-missing-method.stderr
new file mode 100644
index 00000000000..ae11c3665ee
--- /dev/null
+++ b/tests/ui/traits/trait-impl-missing-method.stderr
@@ -0,0 +1,12 @@
+error[E0046]: not all trait items implemented, missing: `trait_method`
+  --> $DIR/trait-impl-missing-method.rs:9:1
+   |
+LL |     fn trait_method(&self);
+   |     ----------------------- `trait_method` from trait
+...
+LL | impl MyTrait for ImplType {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `trait_method` in implementation
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/transmutability/uninhabited.stderr b/tests/ui/transmutability/uninhabited.stderr
index 79cd75ce279..4757daec997 100644
--- a/tests/ui/transmutability/uninhabited.stderr
+++ b/tests/ui/transmutability/uninhabited.stderr
@@ -44,7 +44,7 @@ error[E0080]: evaluation panicked: assertion failed: false
   --> $DIR/uninhabited.rs:41:9
    |
 LL |         assert!(false);
-   |         ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^ evaluation of `yawning_void_struct::_` failed here
 
 error[E0277]: `()` cannot be safely transmuted into `yawning_void_enum::Void`
   --> $DIR/uninhabited.rs:71:41
@@ -71,7 +71,7 @@ error[E0080]: evaluation panicked: assertion failed: false
   --> $DIR/uninhabited.rs:63:9
    |
 LL |         assert!(false);
-   |         ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^ evaluation of `yawning_void_enum::_` failed here
 
 error[E0277]: `u128` cannot be safely transmuted into `DistantVoid`
   --> $DIR/uninhabited.rs:92:43
@@ -98,7 +98,7 @@ error[E0080]: evaluation panicked: assertion failed: false
   --> $DIR/uninhabited.rs:87:9
    |
 LL |         assert!(false);
-   |         ^^^^^^^^^^^^^^ evaluation of constant value failed here
+   |         ^^^^^^^^^^^^^^ evaluation of `distant_void::_` failed here
 
 error[E0277]: `Src` cannot be safely transmuted into `issue_126267::Error`
   --> $DIR/uninhabited.rs:108:42
diff --git a/tests/ui/treat-err-as-bug/err.stderr b/tests/ui/treat-err-as-bug/err.stderr
index 3279392e1f4..0052dd75626 100644
--- a/tests/ui/treat-err-as-bug/err.stderr
+++ b/tests/ui/treat-err-as-bug/err.stderr
@@ -2,7 +2,7 @@ error: internal compiler error[E0080]: attempt to compute `0_u32 - 1_u32`, which
   --> $DIR/err.rs:9:21
    |
 LL | pub static C: u32 = 0 - 1;
-   |                     ^^^^^ evaluation of static initializer failed here
+   |                     ^^^^^ evaluation of `C` failed here
 
 
 error: the compiler unexpectedly panicked. this is a bug.
diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr
index 7c09ab6a91a..72a253c4be8 100644
--- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr
+++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr
@@ -2,7 +2,7 @@ error[E0283]: type annotations needed: cannot satisfy `Foo: Trait<Bar>`
   --> $DIR/constrain_in_projection2.rs:28:14
    |
 LL |     let x = <Foo as Trait<Bar>>::Assoc::default();
-   |              ^^^ help: use the fully qualified path to an implementation: `<Type as Trait>::Assoc`
+   |              ^^^
    |
 note: multiple `impl`s satisfying `Foo: Trait<Bar>` found
   --> $DIR/constrain_in_projection2.rs:18:1
@@ -13,6 +13,11 @@ LL | impl Trait<()> for Foo {
 LL | impl Trait<u32> for Foo {
    | ^^^^^^^^^^^^^^^^^^^^^^^
    = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+help: use the fully qualified path to an implementation
+   |
+LL -     let x = <Foo as Trait<Bar>>::Assoc::default();
+LL +     let x = <<Type as Trait>::Assoc as Trait<Bar>>::Assoc::default();
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
index d77efa39aeb..60d9521621f 100644
--- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
@@ -3,7 +3,7 @@
 type Opaque2<T> = impl Sized;
 type Opaque<'a, T> = Opaque2<T>;
 #[define_opaque(Opaque)]
-fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x } //~ WARNING elided lifetime has a name
+fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
 //~^ ERROR: hidden type for `Opaque2<T>` captures lifetime that does not appear in bounds
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
index 61eb76ffc5a..b73e6b8c101 100644
--- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
@@ -1,13 +1,3 @@
-warning: elided lifetime has a name
-  --> $DIR/missing_lifetime_bound.rs:6:41
-   |
-LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
-   |             --                          ^ this elided lifetime gets resolved as `'a`
-   |             |
-   |             lifetime `'a` declared here
-   |
-   = note: `#[warn(elided_named_lifetimes)]` on by default
-
 error[E0700]: hidden type for `Opaque2<T>` captures lifetime that does not appear in bounds
   --> $DIR/missing_lifetime_bound.rs:6:47
    |
@@ -19,6 +9,6 @@ LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
    |             |
    |             hidden type `&'a i32` captures the lifetime `'a` as defined here
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/type-id-higher-rank-2.rs b/tests/ui/type-id-higher-rank-2.rs
index 4a76b737e8c..7b0c7b53940 100644
--- a/tests/ui/type-id-higher-rank-2.rs
+++ b/tests/ui/type-id-higher-rank-2.rs
@@ -5,7 +5,7 @@ use std::any::Any;
 
 struct Foo<'a>(&'a str);
 
-fn good(s: &String) -> Foo { Foo(s) }
+fn good(s: &String) -> Foo<'_> { Foo(s) }
 
 fn bad1(s: String) -> Option<&'static str> {
     let a: Box<dyn Any> = Box::new(good as fn(&String) -> Foo);
diff --git a/tests/ui/type/pattern_types/literals.stderr b/tests/ui/type/pattern_types/literals.stderr
index 72c812ed3ba..7ab7b81ac23 100644
--- a/tests/ui/type/pattern_types/literals.stderr
+++ b/tests/ui/type/pattern_types/literals.stderr
@@ -2,31 +2,31 @@ error[E0080]: evaluation panicked: exclusive range end at minimum value of type
   --> $DIR/literals.rs:86:62
    |
 LL | fn empty_range_at_base_type_min() -> pattern_type!(u32 is 0..0) {
-   |                                                              ^ evaluation of constant value failed here
+   |                                                              ^ evaluation of `empty_range_at_base_type_min::{constant#1}` failed here
 
 error[E0080]: evaluation panicked: exclusive range end at minimum value of type
   --> $DIR/literals.rs:91:63
    |
 LL | fn empty_range_at_base_type_min2() -> pattern_type!(u32 is 0..0) {
-   |                                                               ^ evaluation of constant value failed here
+   |                                                               ^ evaluation of `empty_range_at_base_type_min2::{constant#1}` failed here
 
 error[E0080]: evaluation panicked: exclusive range end at minimum value of type
   --> $DIR/literals.rs:106:65
    |
 LL | fn wraparound_range_at_base_ty_end() -> pattern_type!(u32 is 1..0) {
-   |                                                                 ^ evaluation of constant value failed here
+   |                                                                 ^ evaluation of `wraparound_range_at_base_ty_end::{constant#1}` failed here
 
 error[E0080]: evaluation panicked: exclusive range end at minimum value of type
   --> $DIR/literals.rs:111:66
    |
 LL | fn wraparound_range_at_base_ty_end2() -> pattern_type!(u32 is 1..0) {
-   |                                                                  ^ evaluation of constant value failed here
+   |                                                                  ^ evaluation of `wraparound_range_at_base_ty_end2::{constant#1}` failed here
 
 error[E0080]: evaluation panicked: exclusive range end at minimum value of type
   --> $DIR/literals.rs:116:66
    |
 LL | fn wraparound_range_at_base_ty_end3() -> pattern_type!(u32 is 1..0) {
-   |                                                                  ^ evaluation of constant value failed here
+   |                                                                  ^ evaluation of `wraparound_range_at_base_ty_end3::{constant#1}` failed here
 
 error[E0308]: mismatched types
   --> $DIR/literals.rs:9:5
diff --git a/tests/ui/type/pattern_types/matching.rs b/tests/ui/type/pattern_types/matching.rs
index b8463a8e822..21f89b3b673 100644
--- a/tests/ui/type/pattern_types/matching.rs
+++ b/tests/ui/type/pattern_types/matching.rs
@@ -1,6 +1,7 @@
 #![feature(pattern_types, pattern_type_macro, structural_match)]
 
 //@ check-pass
+//@ compile-flags: -Zvalidate-mir
 
 use std::marker::StructuralPartialEq;
 use std::pat::pattern_type;
diff --git a/tests/ui/type/pattern_types/or_patterns.stderr b/tests/ui/type/pattern_types/or_patterns.stderr
index 58ca585f4a9..a417e502e35 100644
--- a/tests/ui/type/pattern_types/or_patterns.stderr
+++ b/tests/ui/type/pattern_types/or_patterns.stderr
@@ -41,9 +41,8 @@ LL |     let _: NonNegOneI8 = -128;
 
 error: layout_of((i8) is (i8::MIN..=-1 | 1..)) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -80,9 +79,8 @@ LL | type NonNullI8 = pattern_type!(i8 is ..0 | 1..);
 
 error: layout_of((i8) is (i8::MIN..=-2 | 0..)) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr
index bcb602a70dd..abd8b87fffc 100644
--- a/tests/ui/type/pattern_types/range_patterns.stderr
+++ b/tests/ui/type/pattern_types/range_patterns.stderr
@@ -1,8 +1,7 @@
 error: layout_of(NonZero<u32>) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -46,9 +45,8 @@ LL | type X = std::num::NonZeroU32;
 
 error: layout_of((u32) is 1..) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -85,9 +83,8 @@ LL | type Y = pattern_type!(u32 is 1..);
 
 error: layout_of(Option<(u32) is 1..>) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -125,9 +122,8 @@ error: layout_of(Option<(u32) is 1..>) = Layout {
                variants: [
                    Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -147,9 +143,8 @@ error: layout_of(Option<(u32) is 1..>) = Layout {
                    },
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Scalar(
                            Initialized {
@@ -199,9 +194,8 @@ LL | type Z = Option<pattern_type!(u32 is 1..)>;
 
 error: layout_of(Option<NonZero<u32>>) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -239,9 +233,8 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
                variants: [
                    Layout {
                        size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(1 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Memory {
                            sized: true,
@@ -261,9 +254,8 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
                    },
                    Layout {
                        size: Size(4 bytes),
-                       align: AbiAndPrefAlign {
+                       align: AbiAlign {
                            abi: Align(4 bytes),
-                           pref: $SOME_ALIGN,
                        },
                        backend_repr: Scalar(
                            Initialized {
@@ -313,9 +305,8 @@ LL | type A = Option<std::num::NonZeroU32>;
 
 error: layout_of(NonZeroU32New) = Layout {
            size: Size(4 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -369,7 +360,7 @@ error[E0080]: evaluation panicked: exclusive range end at minimum value of type
   --> $DIR/range_patterns.rs:25:37
    |
 LL | type WRAP = pattern_type!(u32 is 1..0);
-   |                                     ^ evaluation of constant value failed here
+   |                                     ^ evaluation of `WRAP::{constant#1}` failed here
 
 error: the type has an unknown layout
   --> $DIR/range_patterns.rs:25:1
@@ -387,9 +378,8 @@ LL | type WRAP2 = pattern_type!(u32 is 5..2);
 
 error: layout_of((i8) is -10..=10) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
@@ -426,9 +416,8 @@ LL | type SIGN = pattern_type!(i8 is -10..=10);
 
 error: layout_of((i8) is i8::MIN..=0) = Layout {
            size: Size(1 bytes),
-           align: AbiAndPrefAlign {
+           align: AbiAlign {
                abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
            },
            backend_repr: Scalar(
                Initialized {
diff --git a/tests/ui/type/pattern_types/reverse_range.stderr b/tests/ui/type/pattern_types/reverse_range.stderr
index 8f5b86c7db9..6e6e34409a3 100644
--- a/tests/ui/type/pattern_types/reverse_range.stderr
+++ b/tests/ui/type/pattern_types/reverse_range.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation panicked: exclusive range end at minimum value of type
   --> $DIR/reverse_range.rs:7:36
    |
 LL | const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) };
-   |                                    ^ evaluation of constant value failed here
+   |                                    ^ evaluation of `NONE::{constant#1}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type/pattern_types/validity.stderr b/tests/ui/type/pattern_types/validity.stderr
index 7ba73aacc24..4f4c16028f6 100644
--- a/tests/ui/type/pattern_types/validity.stderr
+++ b/tests/ui/type/pattern_types/validity.stderr
@@ -13,13 +13,13 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/validity.rs:13:1
    |
 LL | const BAD_UNINIT: pattern_type!(u32 is 1..) =
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_UNINIT` failed here
 
 error[E0080]: unable to turn pointer into integer
   --> $DIR/validity.rs:17:1
    |
 LL | const BAD_PTR: pattern_type!(usize is 1..) = unsafe { std::mem::transmute(&42) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_PTR` failed here
    |
    = 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
@@ -50,7 +50,7 @@ error[E0080]: using uninitialized data, but this operation requires initialized
   --> $DIR/validity.rs:29:1
    |
 LL | const CHAR_UNINIT: pattern_type!(char is 'A'..'Z') =
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of constant value failed here
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `CHAR_UNINIT` failed here
 
 error[E0080]: constructing invalid value: encountered 97, but expected something in the range 65..=89
   --> $DIR/validity.rs:33:1
diff --git a/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr b/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr
index de993df722c..872c506c7f1 100644
--- a/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr
+++ b/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr
@@ -1,4 +1,22 @@
 error[E0571]: `break` with value from a `while` loop
+  --> $DIR/issue-114529-illegal-break-with-value.rs:22:9
+   |
+LL |       while true {
+   |       ---------- you can't `break` with a value in a `while` loop
+LL | /         break (|| {
+LL | |             let local = 9;
+LL | |         });
+   | |__________^ can only break with a value inside `loop` or breakable block
+   |
+help: use `break` on its own without a value inside this `while` loop
+   |
+LL -         break (|| {
+LL -             let local = 9;
+LL -         });
+LL +         break;
+   |
+
+error[E0571]: `break` with value from a `while` loop
   --> $DIR/issue-114529-illegal-break-with-value.rs:9:13
    |
 LL |         while true {
@@ -26,24 +44,6 @@ LL -             break v;
 LL +             break;
    |
 
-error[E0571]: `break` with value from a `while` loop
-  --> $DIR/issue-114529-illegal-break-with-value.rs:22:9
-   |
-LL |       while true {
-   |       ---------- you can't `break` with a value in a `while` loop
-LL | /         break (|| {
-LL | |             let local = 9;
-LL | |         });
-   | |__________^ can only break with a value inside `loop` or breakable block
-   |
-help: use `break` on its own without a value inside this `while` loop
-   |
-LL -         break (|| {
-LL -             let local = 9;
-LL -         });
-LL +         break;
-   |
-
 error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0571`.
diff --git a/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs
new file mode 100644
index 00000000000..4a08bf28bf3
--- /dev/null
+++ b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs
@@ -0,0 +1,39 @@
+//! Test for issue <github.com/rust-lang/rust/issues/30904>
+//! Related to higher-ranked lifetime inference with unboxed closures and FnOnce.
+
+#![feature(fn_traits, unboxed_closures)]
+
+fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {}
+
+struct Compose<F, G>(F, G);
+
+impl<T, F, G> FnOnce<(T,)> for Compose<F, G>
+where
+    F: FnOnce<(T,)>,
+    G: FnOnce<(F::Output,)>,
+{
+    type Output = G::Output;
+    extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output {
+        (self.1)((self.0)(x))
+    }
+}
+
+struct Str<'a>(&'a str);
+
+fn mk_str<'a>(s: &'a str) -> Str<'a> {
+    Str(s)
+}
+
+fn main() {
+    let _: for<'a> fn(&'a str) -> Str<'a> = mk_str;
+    let _: for<'a> fn(&'a str) -> Str<'a> = Str;
+    //~^ ERROR: mismatched types
+
+    test(|_: &str| {});
+    test(mk_str);
+    test(Str);
+
+    test(Compose(|_: &str| {}, |_| {}));
+    test(Compose(mk_str, |_| {}));
+    test(Compose(Str, |_| {}));
+}
diff --git a/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr
new file mode 100644
index 00000000000..a31d99f45d5
--- /dev/null
+++ b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/fn-traits-hrtb-coercion.rs:29:45
+   |
+LL |     let _: for<'a> fn(&'a str) -> Str<'a> = Str;
+   |            ------------------------------   ^^^ one type is more general than the other
+   |            |
+   |            expected due to this
+   |
+   = note:      expected fn pointer `for<'a> fn(&'a _) -> Str<'a>`
+           found struct constructor `fn(&_) -> Str<'_> {Str::<'_>}`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/underscore-lifetimes.rs b/tests/ui/underscore-lifetimes.rs
index 6174f8ce036..a372851f9cf 100644
--- a/tests/ui/underscore-lifetimes.rs
+++ b/tests/ui/underscore-lifetimes.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 
-#![allow(dead_code)]
+#![allow(dead_code, mismatched_lifetime_syntaxes)]
 struct Foo<'a>(&'a u8);
 
 fn foo(x: &u8) -> Foo<'_> {
diff --git a/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr
index b7cbe1a5cf4..2f01331db9a 100644
--- a/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr
+++ b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr
@@ -1,10 +1,4 @@
 error[E0268]: `break` outside of a loop or labeled block
-  --> $DIR/break-inside-unsafe-block-issue-128604.rs:2:28
-   |
-LL |     let a = ["_"; unsafe { break; 1 + 2 }];
-   |                            ^^^^^ cannot `break` outside of a loop or labeled block
-
-error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/break-inside-unsafe-block-issue-128604.rs:14:9
    |
 LL |         break;
@@ -37,6 +31,12 @@ LL |         unsafe {
 LL ~             break 'block;
    |
 
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-unsafe-block-issue-128604.rs:2:28
+   |
+LL |     let a = ["_"; unsafe { break; 1 + 2 }];
+   |                            ^^^^^ cannot `break` outside of a loop or labeled block
+
 error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0268`.
diff --git a/triagebot.toml b/triagebot.toml
index db263a3768f..15c56f8861f 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1210,6 +1210,7 @@ compiler = [
     "@fee1-dead",
     "@fmease",
     "@jieyouxu",
+    "@jdonszelmann",
     "@lcnr",
     "@Nadrieril",
     "@nnethercote",