summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Cronjob Bot <miri@cron.bot>2025-07-10 05:05:40 +0000
committerThe Miri Cronjob Bot <miri@cron.bot>2025-07-10 05:05:40 +0000
commit1f721c651e0b1920c61560f9433363fee60c04f5 (patch)
treee13122fbfedbcc622b3d04c2214abd1ff2261b17
parente726c643e8319ee5eb2a8be45eb65f7600be2d5d (diff)
parentc629a450d650f478bde8fffca92a0da7b0701316 (diff)
downloadrust-1f721c651e0b1920c61560f9433363fee60c04f5.tar.gz
rust-1f721c651e0b1920c61560f9433363fee60c04f5.zip
Merge from rustc
-rw-r--r--Cargo.lock82
-rw-r--r--Cargo.toml1
-rw-r--r--compiler/rustc_attr_data_structures/src/attributes.rs15
-rw-r--r--compiler/rustc_attr_data_structures/src/encode_cross_crate.rs5
-rw-r--r--compiler/rustc_attr_parsing/messages.ftl4
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs4
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/deprecation.rs2
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/dummy.rs19
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/inline.rs4
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/link_attrs.rs38
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/mod.rs46
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/must_use.rs2
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/path.rs2
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs6
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/test_attrs.rs2
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/traits.rs2
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/transparency.rs2
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs11
-rw-r--r--compiler/rustc_borrowck/src/consumers.rs81
-rw-r--r--compiler/rustc_borrowck/src/lib.rs43
-rw-r--r--compiler/rustc_borrowck/src/nll.rs6
-rw-r--r--compiler/rustc_borrowck/src/root_cx.rs13
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs13
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs18
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs31
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs12
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs177
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs25
-rw-r--r--compiler/rustc_const_eval/messages.ftl2
-rw-r--r--compiler/rustc_const_eval/src/errors.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs76
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs21
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs30
-rw-r--r--compiler/rustc_const_eval/src/interpret/mod.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs23
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs64
-rw-r--r--compiler/rustc_errors/src/emitter.rs2
-rw-r--r--compiler/rustc_expand/messages.ftl26
-rw-r--r--compiler/rustc_expand/src/errors.rs44
-rw-r--r--compiler/rustc_expand/src/mbe/metavar_expr.rs98
-rw-r--r--compiler/rustc_hir/src/lang_items.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs9
-rw-r--r--compiler/rustc_lint/src/types.rs9
-rw-r--r--compiler/rustc_lint/src/unused.rs10
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs33
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs1
-rw-r--r--compiler/rustc_mir_build/src/builder/scope.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/drop_flag_effects.rs28
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs11
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/mod.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/initialized.rs88
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs2
-rw-r--r--compiler/rustc_mir_transform/src/remove_uninit_drops.rs1
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs1
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs29
-rw-r--r--compiler/rustc_passes/src/check_export.rs7
-rw-r--r--compiler/rustc_passes/src/reachable.rs1
-rw-r--r--compiler/rustc_pattern_analysis/src/checks.rs50
-rw-r--r--compiler/rustc_pattern_analysis/src/lib.rs15
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs83
-rw-r--r--compiler/rustc_pattern_analysis/src/usefulness.rs7
-rw-r--r--compiler/rustc_pattern_analysis/tests/common/mod.rs9
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs36
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs9
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs19
-rw-r--r--compiler/rustc_resolve/src/lib.rs26
-rw-r--r--compiler/rustc_resolve/src/macros.rs11
-rw-r--r--compiler/rustc_session/src/config.rs99
-rw-r--r--compiler/rustc_session/src/options.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/spec/mod.rs15
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs33
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs13
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs180
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs27
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs250
-rw-r--r--compiler/stable_mir/src/mir/alloc.rs3
-rw-r--r--compiler/stable_mir/src/unstable/convert/stable/mir.rs3
-rw-r--r--library/alloc/src/lib.rs2
-rw-r--r--library/alloc/src/string.rs3
-rw-r--r--library/alloc/src/vec/mod.rs3
-rw-r--r--library/compiler-builtins/.github/workflows/main.yaml20
-rw-r--r--library/compiler-builtins/builtins-test-intrinsics/build.rs1
-rw-r--r--library/compiler-builtins/builtins-test/benches/float_cmp.rs2
-rw-r--r--library/compiler-builtins/builtins-test/build.rs1
-rw-r--r--library/compiler-builtins/builtins-test/tests/conv.rs4
-rw-r--r--library/compiler-builtins/builtins-test/tests/div_rem.rs4
-rwxr-xr-xlibrary/compiler-builtins/ci/run.sh27
-rw-r--r--library/compiler-builtins/compiler-builtins/build.rs3
-rw-r--r--library/compiler-builtins/compiler-builtins/configure.rs88
-rw-r--r--library/compiler-builtins/compiler-builtins/src/aarch64.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/arm.rs31
-rw-r--r--library/compiler-builtins/compiler-builtins/src/int/udiv.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/lib.rs2
-rw-r--r--library/compiler-builtins/compiler-builtins/src/probestack.rs50
-rw-r--r--library/compiler-builtins/compiler-builtins/src/x86.rs10
-rw-r--r--library/compiler-builtins/compiler-builtins/src/x86_64.rs4
-rw-r--r--library/compiler-builtins/crates/josh-sync/Cargo.toml1
-rw-r--r--library/compiler-builtins/crates/josh-sync/src/sync.rs30
-rw-r--r--library/compiler-builtins/crates/libm-macros/src/lib.rs2
-rw-r--r--library/compiler-builtins/crates/symbol-check/src/main.rs144
-rw-r--r--library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json23
-rw-r--r--library/compiler-builtins/libm-test/benches/icount.rs18
-rw-r--r--library/compiler-builtins/libm-test/tests/u256.rs46
-rw-r--r--library/compiler-builtins/libm-test/tests/z_extensive/run.rs6
-rw-r--r--library/compiler-builtins/libm/configure.rs88
-rw-r--r--library/compiler-builtins/libm/src/math/support/big.rs133
-rw-r--r--library/compiler-builtins/libm/src/math/support/big/tests.rs63
-rw-r--r--library/compiler-builtins/libm/src/math/support/int_traits.rs23
-rw-r--r--library/compiler-builtins/thumbv6m-linux-eabi.json28
-rw-r--r--library/compiler-builtins/thumbv7em-linux-eabi.json27
-rw-r--r--library/compiler-builtins/thumbv7em-linux-eabihf.json28
-rw-r--r--library/compiler-builtins/thumbv7m-linux-eabi.json27
-rw-r--r--library/compiler-builtins/triagebot.toml21
-rw-r--r--library/core/Cargo.toml2
-rw-r--r--library/core/src/alloc/layout.rs4
-rw-r--r--library/core/src/any.rs84
-rw-r--r--library/core/src/cell.rs40
-rw-r--r--library/core/src/default.rs5
-rw-r--r--library/core/src/error.rs24
-rw-r--r--library/core/src/fmt/mod.rs14
-rw-r--r--library/core/src/intrinsics/mod.rs15
-rw-r--r--library/core/src/iter/sources/empty.rs3
-rw-r--r--library/core/src/marker.rs12
-rw-r--r--library/core/src/num/fmt.rs25
-rw-r--r--library/core/src/ops/drop.rs2
-rw-r--r--library/core/src/option.rs4
-rw-r--r--library/core/src/pin.rs16
-rw-r--r--library/core/src/ptr/alignment.rs3
-rw-r--r--library/core/src/slice/mod.rs38
-rw-r--r--library/core/src/str/mod.rs6
-rw-r--r--library/core/src/unicode/unicode_data.rs2
-rw-r--r--library/coretests/tests/any.rs8
-rw-r--r--library/coretests/tests/floats/f128.rs14
-rw-r--r--library/coretests/tests/floats/f16.rs14
-rw-r--r--library/coretests/tests/floats/f32.rs14
-rw-r--r--library/coretests/tests/floats/f64.rs14
-rw-r--r--library/coretests/tests/floats/mod.rs23
-rw-r--r--library/proc_macro/src/bridge/symbol.rs4
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/sys/fs/unix.rs1
-rw-r--r--library/std/src/sys/pal/unix/thread.rs2
-rw-r--r--library/sysroot/Cargo.toml1
-rwxr-xr-xsrc/bootstrap/configure.py26
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs16
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs20
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs42
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs15
-rw-r--r--src/bootstrap/src/core/builder/mod.rs2
-rw-r--r--src/bootstrap/src/core/builder/tests.rs54
-rw-r--r--src/bootstrap/src/core/config/flags.rs5
-rw-r--r--src/bootstrap/src/core/config/toml/rust.rs5
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/helpers.rs25
-rw-r--r--src/bootstrap/src/utils/tests/mod.rs2
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/codegen-options/index.md59
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/mips64-unknown-linux-muslabi64.md49
-rw-r--r--src/doc/rustc/src/platform-support/wasm32-wasip1.md49
-rw-r--r--src/doc/unstable-book/src/compiler-flags/codegen-options.md8
-rw-r--r--src/doc/unstable-book/src/compiler-flags/linker-features.md35
-rw-r--r--src/etc/completions/x.fish2
-rw-r--r--src/etc/completions/x.ps12
-rw-r--r--src/etc/completions/x.py.fish2
-rw-r--r--src/etc/completions/x.py.ps12
-rw-r--r--src/etc/completions/x.py.zsh2
-rw-r--r--src/etc/completions/x.zsh2
-rw-r--r--src/librustdoc/html/render/write_shared.rs4
-rw-r--r--src/librustdoc/json/conversions.rs15
m---------src/llvm-project0
-rw-r--r--src/tools/clippy/.github/workflows/feature_freeze.yml14
-rw-r--r--src/tools/clippy/.github/workflows/lintcheck.yml28
-rw-r--r--src/tools/clippy/.github/workflows/lintcheck_summary.yml106
-rw-r--r--src/tools/clippy/Cargo.toml12
-rw-r--r--src/tools/clippy/book/src/development/infrastructure/backport.md2
-rw-r--r--src/tools/clippy/book/src/development/infrastructure/changelog_update.md32
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md1
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs1
-rw-r--r--src/tools/clippy/clippy_dev/src/fmt.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs44
-rw-r--r--src/tools/clippy/clippy_lints/src/cognitive_complexity.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/missing_headers.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/exhaustive_items.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/exit.rs35
-rw-r--r--src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/empty_loop.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_let_else.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs168
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/return_and_then.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/swap_with_temporary.rs52
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_bool.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/neg_multiply.rs40
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/op_ref.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs109
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_async.rs2
-rw-r--r--src/tools/clippy/clippy_lints_internal/src/symbols.rs2
-rw-r--r--src/tools/clippy/clippy_test_deps/Cargo.toml17
-rw-r--r--src/tools/clippy/clippy_test_deps/src/main.rs (renamed from tests/run-make/rust-lld-by-default-beta-stable/main.rs)0
-rw-r--r--src/tools/clippy/clippy_utils/README.md2
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs82
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs64
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/mod.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs16
-rw-r--r--src/tools/clippy/lintcheck/src/config.rs3
-rw-r--r--src/tools/clippy/lintcheck/src/json.rs105
-rw-r--r--src/tools/clippy/lintcheck/src/main.rs7
-rw-r--r--src/tools/clippy/rust-toolchain.toml2
-rw-r--r--src/tools/clippy/tests/compile-test.rs76
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr10
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs11
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr.fixed6
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr.rs6
-rw-r--r--src/tools/clippy/tests/ui/cast_size.32bit.stderr10
-rw-r--r--src/tools/clippy/tests/ui/cast_size.64bit.stderr10
-rw-r--r--src/tools/clippy/tests/ui/cast_size.rs6
-rw-r--r--src/tools/clippy/tests/ui/coerce_container_to_any.fixed13
-rw-r--r--src/tools/clippy/tests/ui/coerce_container_to_any.rs13
-rw-r--r--src/tools/clippy/tests/ui/coerce_container_to_any.stderr14
-rw-r--r--src/tools/clippy/tests/ui/disallowed_script_idents.rs14
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.fixed6
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.rs2
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.stderr26
-rw-r--r--src/tools/clippy/tests/ui/empty_loop_intrinsic.rs13
-rw-r--r--src/tools/clippy/tests/ui/exit1_compile_flag_test.rs17
-rw-r--r--src/tools/clippy/tests/ui/exit1_compile_flag_test.stderr11
-rw-r--r--src/tools/clippy/tests/ui/exit2_compile_flag_test.rs15
-rw-r--r--src/tools/clippy/tests/ui/exit2_compile_flag_test.stderr11
-rw-r--r--src/tools/clippy/tests/ui/exit3_compile_flag_test.rs11
-rw-r--r--src/tools/clippy/tests/ui/exit4.rs8
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.fixed44
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.rs44
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.stderr32
-rw-r--r--src/tools/clippy/tests/ui/manual_is_variant_and.fixed112
-rw-r--r--src/tools/clippy/tests/ui/manual_is_variant_and.rs110
-rw-r--r--src/tools/clippy/tests/ui/manual_is_variant_and.stderr100
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.fixed45
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.rs73
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.stderr72
-rw-r--r--src/tools/clippy/tests/ui/missing_panics_doc.rs28
-rw-r--r--src/tools/clippy/tests/ui/missing_panics_doc.stderr38
-rw-r--r--src/tools/clippy/tests/ui/needless_bool_assign.fixed9
-rw-r--r--src/tools/clippy/tests/ui/needless_bool_assign.rs13
-rw-r--r--src/tools/clippy/tests/ui/needless_bool_assign.stderr13
-rw-r--r--src/tools/clippy/tests/ui/neg_multiply.fixed12
-rw-r--r--src/tools/clippy/tests/ui/neg_multiply.rs12
-rw-r--r--src/tools/clippy/tests/ui/neg_multiply.stderr8
-rw-r--r--src/tools/clippy/tests/ui/op_ref.fixed34
-rw-r--r--src/tools/clippy/tests/ui/op_ref.rs34
-rw-r--r--src/tools/clippy/tests/ui/op_ref.stderr22
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.fixed20
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.rs20
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.stderr14
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed14
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs12
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr28
-rw-r--r--src/tools/clippy/tests/ui/return_and_then.fixed131
-rw-r--r--src/tools/clippy/tests/ui/return_and_then.rs114
-rw-r--r--src/tools/clippy/tests/ui/return_and_then.stderr96
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.fixed7
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.rs7
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.stderr30
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core_unfixable.rs18
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core_unfixable.stderr30
-rw-r--r--src/tools/clippy/tests/ui/swap_with_temporary.fixed46
-rw-r--r--src/tools/clippy/tests/ui/swap_with_temporary.rs46
-rw-r--r--src/tools/clippy/tests/ui/swap_with_temporary.stderr38
-rw-r--r--src/tools/clippy/tests/ui/track-diagnostics-clippy.rs3
-rw-r--r--src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.fixed10
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.rs10
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.stderr26
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.fixed13
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.rs13
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr.fixed8
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr.rs8
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr.stderr8
-rw-r--r--src/tools/clippy/triagebot.toml7
-rw-r--r--src/tools/clippy/util/gh-pages/index_template.html40
-rw-r--r--src/tools/clippy/util/gh-pages/script.js6
-rw-r--r--src/tools/clippy/util/gh-pages/style.css26
-rw-r--r--src/tools/compiletest/src/runtest.rs6
-rw-r--r--src/tools/miri/src/machine.rs12
-rw-r--r--src/tools/opt-dist/src/tests.rs3
-rw-r--r--src/tools/run-make-support/CHANGELOG.md83
-rw-r--r--src/tools/run-make-support/Cargo.toml21
-rw-r--r--src/tools/run-make-support/src/artifact_names.rs6
-rw-r--r--src/tools/run-make-support/src/external_deps/c_build.rs23
-rw-r--r--src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs6
-rw-r--r--src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs6
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs4
-rw-r--r--src/tools/run-make-support/src/lib.rs108
-rw-r--r--src/tools/run-make-support/src/linker.rs4
-rw-r--r--src/tools/run-make-support/src/targets.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs8
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs2
-rw-r--r--src/tools/test-float-parse/src/lib.rs2
-rw-r--r--src/tools/tidy/src/ext_tool_checks.rs203
-rw-r--r--src/tools/tidy/src/lib.rs34
-rw-r--r--src/tools/tidy/src/main.rs10
-rw-r--r--src/tools/tidy/src/rustdoc_json.rs20
-rw-r--r--src/tools/unicode-table-generator/src/range_search.rs2
-rw-r--r--tests/codegen/enum/enum-aggregate.rs15
-rw-r--r--tests/codegen/enum/enum-match.rs2
-rw-r--r--tests/codegen/error-provide.rs6
-rw-r--r--tests/codegen/simd/aggregate-simd.rs106
-rw-r--r--tests/codegen/union-aggregate.rs23
-rw-r--r--tests/mir-opt/otherwise_drops.result_ok.ElaborateDrops.diff108
-rw-r--r--tests/mir-opt/otherwise_drops.rs13
-rw-r--r--tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff11
-rw-r--r--tests/run-make/archive-duplicate-names/rmake.rs8
-rw-r--r--tests/run-make/c-link-to-rust-dylib/rmake.rs6
-rw-r--r--tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs6
-rw-r--r--tests/run-make/cdylib-dylib-linkage/rmake.rs4
-rw-r--r--tests/run-make/cdylib/rmake.rs4
-rw-r--r--tests/run-make/compiler-rt-works-on-mingw/rmake.rs2
-rw-r--r--tests/run-make/compressed-debuginfo-zstd/rmake.rs2
-rw-r--r--tests/run-make/link-args-order/rmake.rs4
-rw-r--r--tests/run-make/link-dedup/rmake.rs4
-rw-r--r--tests/run-make/native-link-modifier-bundle/rmake.rs4
-rw-r--r--tests/run-make/native-link-modifier-whole-archive/rmake.rs6
-rw-r--r--tests/run-make/pointer-auth-link-with-c/rmake.rs6
-rw-r--r--tests/run-make/print-native-static-libs/rmake.rs6
-rw-r--r--tests/run-make/raw-dylib-alt-calling-convention/rmake.rs6
-rw-r--r--tests/run-make/raw-dylib-import-name-type/rmake.rs4
-rw-r--r--tests/run-make/raw-dylib-inline-cross-dylib/rmake.rs4
-rw-r--r--tests/run-make/raw-dylib-link-ordinal/rmake.rs4
-rw-r--r--tests/run-make/raw-dylib-stdcall-ordinal/rmake.rs4
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs/rmake.rs6
-rw-r--r--tests/run-make/rust-lld-by-default-beta-stable/rmake.rs14
-rw-r--r--tests/run-make/rust-lld-custom-target/rmake.rs3
-rw-r--r--tests/run-make/rust-lld-link-script-provide/rmake.rs2
-rw-r--r--tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/main.rs (renamed from tests/run-make/rust-lld-by-default-nightly/main.rs)0
-rw-r--r--tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs (renamed from tests/run-make/rust-lld-by-default-nightly/rmake.rs)13
-rw-r--r--tests/run-make/rust-lld-x86_64-unknown-linux-gnu/main.rs5
-rw-r--r--tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs20
-rw-r--r--tests/run-make/rust-lld/rmake.rs18
-rw-r--r--tests/run-make/split-debuginfo/rmake.rs6
-rw-r--r--tests/run-make/static-dylib-by-default/rmake.rs6
-rw-r--r--tests/run-make/staticlib-dylib-linkage/rmake.rs4
-rw-r--r--tests/run-make/symbol-visibility/rmake.rs6
-rw-r--r--tests/rustdoc-json/attrs/target_feature.rs23
-rw-r--r--tests/ui-fulldeps/auxiliary/obtain-borrowck-input.rs4
-rw-r--r--tests/ui-fulldeps/obtain-borrowck.rs20
-rw-r--r--tests/ui-fulldeps/obtain-borrowck.run.stdout2
-rw-r--r--tests/ui/async-await/issues/issue-54752-async-block.rs1
-rw-r--r--tests/ui/async-await/issues/issue-54752-async-block.stderr15
-rw-r--r--tests/ui/attributes/malformed-attrs.stderr45
-rw-r--r--tests/ui/codegen/output-slot-init-vs-noninit.rs (renamed from tests/ui/output-slot-variants.rs)54
-rw-r--r--tests/ui/codegen/remark-flag-functionality.rs (renamed from tests/ui/optimization-remark.rs)14
-rw-r--r--tests/ui/codegen/shift-right-operand-mutation.rs19
-rw-r--r--tests/ui/codegen/sret-aliasing-rules.rs28
-rw-r--r--tests/ui/const-generics/issues/issue-90318.rs3
-rw-r--r--tests/ui/const-generics/issues/issue-90318.stderr25
-rw-r--r--tests/ui/consts/const_cmp_type_id.rs3
-rw-r--r--tests/ui/consts/const_cmp_type_id.stderr20
-rw-r--r--tests/ui/consts/const_transmute_type_id.rs11
-rw-r--r--tests/ui/consts/const_transmute_type_id.stderr12
-rw-r--r--tests/ui/consts/const_transmute_type_id2.rs14
-rw-r--r--tests/ui/consts/const_transmute_type_id2.stderr15
-rw-r--r--tests/ui/consts/const_transmute_type_id3.rs16
-rw-r--r--tests/ui/consts/const_transmute_type_id3.stderr15
-rw-r--r--tests/ui/consts/const_transmute_type_id4.rs16
-rw-r--r--tests/ui/consts/const_transmute_type_id4.stderr15
-rw-r--r--tests/ui/consts/issue-73976-monomorphic.rs2
-rw-r--r--tests/ui/consts/issue-73976-monomorphic.stderr9
-rw-r--r--tests/ui/consts/rustc-impl-const-stability.rs8
-rw-r--r--tests/ui/consts/rustc-impl-const-stability.stderr6
-rw-r--r--tests/ui/error-codes/E0424.stderr2
-rw-r--r--tests/ui/float/conv-bits-runtime-const.rs43
-rw-r--r--tests/ui/imports/ambiguous-1.rs2
-rw-r--r--tests/ui/imports/ambiguous-1.stderr42
-rw-r--r--tests/ui/imports/ambiguous-10.rs3
-rw-r--r--tests/ui/imports/ambiguous-10.stderr36
-rw-r--r--tests/ui/imports/ambiguous-12.rs3
-rw-r--r--tests/ui/imports/ambiguous-12.stderr36
-rw-r--r--tests/ui/imports/ambiguous-13.rs3
-rw-r--r--tests/ui/imports/ambiguous-13.stderr36
-rw-r--r--tests/ui/imports/ambiguous-14.rs3
-rw-r--r--tests/ui/imports/ambiguous-14.stderr36
-rw-r--r--tests/ui/imports/ambiguous-15.rs3
-rw-r--r--tests/ui/imports/ambiguous-15.stderr36
-rw-r--r--tests/ui/imports/ambiguous-16.rs3
-rw-r--r--tests/ui/imports/ambiguous-16.stderr36
-rw-r--r--tests/ui/imports/ambiguous-17.rs3
-rw-r--r--tests/ui/imports/ambiguous-17.stderr38
-rw-r--r--tests/ui/imports/ambiguous-3.rs3
-rw-r--r--tests/ui/imports/ambiguous-3.stderr36
-rw-r--r--tests/ui/imports/ambiguous-4-extern.rs2
-rw-r--r--tests/ui/imports/ambiguous-4-extern.stderr42
-rw-r--r--tests/ui/imports/ambiguous-4.rs2
-rw-r--r--tests/ui/imports/ambiguous-5.rs3
-rw-r--r--tests/ui/imports/ambiguous-5.stderr36
-rw-r--r--tests/ui/imports/ambiguous-6.rs3
-rw-r--r--tests/ui/imports/ambiguous-6.stderr36
-rw-r--r--tests/ui/imports/ambiguous-9.rs5
-rw-r--r--tests/ui/imports/ambiguous-9.stderr72
-rw-r--r--tests/ui/imports/duplicate.rs2
-rw-r--r--tests/ui/imports/duplicate.stderr30
-rw-r--r--tests/ui/imports/unresolved-seg-after-ambiguous.rs2
-rw-r--r--tests/ui/imports/unresolved-seg-after-ambiguous.stderr30
-rw-r--r--tests/ui/linking/link-self-contained-consistency.rs1
-rw-r--r--tests/ui/linking/link-self-contained-linker-disallowed.rs18
-rw-r--r--tests/ui/linking/link-self-contained-linker-disallowed.unstable_positive.stderr2
-rw-r--r--tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_negative.stderr2
-rw-r--r--tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_positive.stderr2
-rw-r--r--tests/ui/linking/link-self-contained-unstable.crto.stderr2
-rw-r--r--tests/ui/linking/link-self-contained-unstable.libc.stderr2
-rw-r--r--tests/ui/linking/link-self-contained-unstable.mingw.stderr2
-rw-r--r--tests/ui/linking/link-self-contained-unstable.rs13
-rw-r--r--tests/ui/linking/link-self-contained-unstable.sanitizers.stderr2
-rw-r--r--tests/ui/linking/link-self-contained-unstable.unwind.stderr2
-rw-r--r--tests/ui/linking/linker-features-lld-disallowed.rs19
-rw-r--r--tests/ui/linking/linker-features-lld-disallowed.unstable_positive.stderr2
-rw-r--r--tests/ui/linking/linker-features-lld-disallowed.unstable_target_negative.stderr2
-rw-r--r--tests/ui/linking/linker-features-lld-disallowed.unstable_target_positive.stderr2
-rw-r--r--tests/ui/linking/linker-features-malformed.invalid_modifier.stderr2
-rw-r--r--tests/ui/linking/linker-features-malformed.invalid_separator.stderr2
-rw-r--r--tests/ui/linking/linker-features-malformed.no_value.stderr2
-rw-r--r--tests/ui/linking/linker-features-malformed.rs26
-rw-r--r--tests/ui/linking/linker-features-malformed.unknown_boolean.stderr2
-rw-r--r--tests/ui/linking/linker-features-malformed.unknown_modifier_value.stderr2
-rw-r--r--tests/ui/linking/linker-features-malformed.unknown_value.stderr2
-rw-r--r--tests/ui/linking/linker-features-unstable-cc.rs13
-rw-r--r--tests/ui/linking/linker-features-unstable-cc.stderr2
-rw-r--r--tests/ui/lint/dead-code/unused-struct-derive-default.rs4
-rw-r--r--tests/ui/lint/unused/closure-body-issue-136741.fixed36
-rw-r--r--tests/ui/lint/unused/closure-body-issue-136741.rs38
-rw-r--r--tests/ui/lint/unused/closure-body-issue-136741.stderr62
-rw-r--r--tests/ui/macros/macro-paren-span-diagnostic.rs (renamed from tests/ui/paren-span.rs)6
-rw-r--r--tests/ui/macros/macro-paren-span-diagnostic.stderr (renamed from tests/ui/paren-span.stderr)2
-rw-r--r--tests/ui/macros/metavar-expressions/syntax-errors.rs33
-rw-r--r--tests/ui/macros/metavar-expressions/syntax-errors.stderr192
-rw-r--r--tests/ui/mir/enum/convert_non_integer_break.rs (renamed from tests/ui/mir/enum/convert_non_enum_break.rs)7
-rw-r--r--tests/ui/mir/enum/convert_non_integer_niche_break.rs (renamed from tests/ui/mir/enum/convert_non_enum_niche_break.rs)0
-rw-r--r--tests/ui/mir/enum/convert_non_integer_niche_ok.rs (renamed from tests/ui/mir/enum/convert_non_enum_niche_ok.rs)0
-rw-r--r--tests/ui/mir/enum/convert_non_integer_ok.rs (renamed from tests/ui/mir/enum/convert_non_enum_ok.rs)7
-rw-r--r--tests/ui/mir/enum/niche_option_tuple_break.rs11
-rw-r--r--tests/ui/mir/enum/with_niche_int_break.rs4
-rw-r--r--tests/ui/out-pointer-aliasing.rs23
-rw-r--r--tests/ui/over-constrained-vregs.rs12
-rw-r--r--tests/ui/panic_implementation-closures.rs10
-rw-r--r--tests/ui/panics/panic-during-display-formatting.rs (renamed from tests/ui/panic-while-printing.rs)12
-rw-r--r--tests/ui/panics/panic-handler-closures.rs12
-rw-r--r--tests/ui/parser/ufcs-return-unused-parens.fixed20
-rw-r--r--tests/ui/parser/ufcs-return-unused-parens.rs20
-rw-r--r--tests/ui/parser/ufcs-return-unused-parens.stderr (renamed from tests/ui/path-lookahead.stderr)4
-rw-r--r--tests/ui/path-lookahead.fixed17
-rw-r--r--tests/ui/path-lookahead.rs17
-rw-r--r--tests/ui/pattern/box-pattern-constructor-mismatch.rs11
-rw-r--r--tests/ui/pattern/box-pattern-constructor-mismatch.stderr10
-rw-r--r--tests/ui/proc-macro/auxiliary/mixed-site-span.rs110
-rw-r--r--tests/ui/proc-macro/auxiliary/token-site-span.rs30
-rw-r--r--tests/ui/proc-macro/mixed-site-span.rs164
-rw-r--r--tests/ui/proc-macro/mixed-site-span.stderr600
-rw-r--r--tests/ui/resolve/false-self-in-macro-issue-143134.rs10
-rw-r--r--tests/ui/resolve/false-self-in-macro-issue-143134.stderr9
-rw-r--r--tests/ui/resolve/suggestions/auxiliary/suggest-constructor-cycle-error.rs (renamed from tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-builder-fn.rs (renamed from tests/ui/resolve/suggest-builder-fn.rs)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-builder-fn.stderr (renamed from tests/ui/resolve/suggest-builder-fn.stderr)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-constructor-cycle-error.rs (renamed from tests/ui/resolve/suggest-constructor-cycle-error.rs)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-constructor-cycle-error.stderr (renamed from tests/ui/resolve/suggest-constructor-cycle-error.stderr)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed (renamed from tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs (renamed from tests/ui/resolve/suggest-import-without-clobbering-attrs.rs)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.stderr (renamed from tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.rs (renamed from tests/ui/resolve/suggest-path-for-tuple-struct.rs)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.stderr (renamed from tests/ui/resolve/suggest-path-for-tuple-struct.stderr)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.rs (renamed from tests/ui/resolve/suggest-path-instead-of-mod-dot-item.rs)0
-rw-r--r--tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr (renamed from tests/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr)0
-rw-r--r--tests/ui/specialization/const_trait_impl.rs8
-rw-r--r--tests/ui/specialization/const_trait_impl.stderr60
-rw-r--r--tests/ui/suggestions/suggest-remove-refs-6.rs12
-rw-r--r--tests/ui/suggestions/suggest-remove-refs-6.stderr22
-rw-r--r--tests/ui/traits/const-traits/const-traits-alloc.rs9
-rw-r--r--tests/ui/traits/const-traits/const-traits-core.rs46
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-gate.rs5
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr21
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs8
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr18
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-use.rs2
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-use.stderr57
-rw-r--r--tests/ui/traits/const-traits/std-impl-gate.gated.stderr18
-rw-r--r--tests/ui/traits/const-traits/std-impl-gate.rs7
-rw-r--r--tests/ui/traits/const-traits/std-impl-gate.stock.stderr20
-rw-r--r--tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs18
-rw-r--r--tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr19
-rw-r--r--tests/ui/traits/partialeq-ref-mismatch-diagnostic.rs (renamed from tests/ui/partialeq_help.rs)4
-rw-r--r--tests/ui/traits/partialeq-ref-mismatch-diagnostic.stderr (renamed from tests/ui/partialeq_help.stderr)8
-rw-r--r--triagebot.toml16
521 files changed, 8448 insertions, 2968 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6d823c5b5a5..549818eecb0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -569,22 +569,16 @@ dependencies = [
  "color-print",
  "declare_clippy_lint",
  "filetime",
- "futures",
- "if_chain",
  "itertools",
- "parking_lot",
  "pulldown-cmark",
- "quote",
  "regex",
  "rustc_tools_util 0.4.2",
  "serde",
  "serde_json",
- "syn 2.0.104",
  "tempfile",
- "termize 0.1.1",
- "tokio",
+ "termize",
  "toml 0.7.8",
- "ui_test",
+ "ui_test 0.30.2",
  "walkdir",
 ]
 
@@ -643,6 +637,21 @@ dependencies = [
 ]
 
 [[package]]
+name = "clippy_test_deps"
+version = "0.1.0"
+dependencies = [
+ "futures",
+ "if_chain",
+ "itertools",
+ "parking_lot",
+ "quote",
+ "regex",
+ "serde",
+ "syn 2.0.104",
+ "tokio",
+]
+
+[[package]]
 name = "clippy_utils"
 version = "0.1.90"
 dependencies = [
@@ -2409,7 +2418,7 @@ dependencies = [
  "smallvec",
  "tempfile",
  "tikv-jemalloc-sys",
- "ui_test",
+ "ui_test 0.29.2",
 ]
 
 [[package]]
@@ -3214,7 +3223,7 @@ dependencies = [
 
 [[package]]
 name = "run_make_support"
-version = "0.2.0"
+version = "0.0.0"
 dependencies = [
  "bstr",
  "build_helper",
@@ -3773,7 +3782,7 @@ dependencies = [
  "serde",
  "serde_json",
  "termcolor",
- "termize 0.2.0",
+ "termize",
  "tracing",
  "windows 0.61.3",
 ]
@@ -4536,7 +4545,7 @@ dependencies = [
  "rustc_serialize",
  "rustc_span",
  "rustc_target",
- "termize 0.2.0",
+ "termize",
  "tracing",
  "windows 0.61.3",
 ]
@@ -5068,6 +5077,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "spanned"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c92d4b0c055fde758f086eb4a6e73410247df8a3837fd606d2caeeaf72aa566d"
+dependencies = [
+ "anyhow",
+ "bstr",
+ "color-eyre",
+]
+
+[[package]]
 name = "spdx-expression"
 version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5307,16 +5327,6 @@ dependencies = [
 
 [[package]]
 name = "termize"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1706be6b564323ce7092f5f7e6b118a14c8ef7ed0e69c8c5329c914a9f101295"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "termize"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6a8da106d1a19c5b9c53c03311936568a0439926a7607815bd3461139cbab1cc"
@@ -5726,7 +5736,33 @@ dependencies = [
  "rustfix",
  "serde",
  "serde_json",
- "spanned",
+ "spanned 0.3.0",
+]
+
+[[package]]
+name = "ui_test"
+version = "0.30.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b56a6897cc4bb6f8daf1939b0b39cd9645856997f46f4d0b3e3cb7122dfe9251"
+dependencies = [
+ "annotate-snippets 0.11.5",
+ "anyhow",
+ "bstr",
+ "cargo-platform",
+ "cargo_metadata 0.18.1",
+ "color-eyre",
+ "colored",
+ "comma",
+ "crossbeam-channel",
+ "indicatif",
+ "levenshtein",
+ "prettydiff",
+ "regex",
+ "rustc_version",
+ "rustfix",
+ "serde",
+ "serde_json",
+ "spanned 0.4.1",
 ]
 
 [[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 6d3425f4115..9890027d098 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,6 +13,7 @@ members = [
   "src/tools/cargotest",
   "src/tools/clippy",
   "src/tools/clippy/clippy_dev",
+  "src/tools/clippy/clippy_test_deps",
   "src/tools/collect-license-metadata",
   "src/tools/compiletest",
   "src/tools/coverage-dump",
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs
index 2cbb7270785..b656db32528 100644
--- a/compiler/rustc_attr_data_structures/src/attributes.rs
+++ b/compiler/rustc_attr_data_structures/src/attributes.rs
@@ -240,6 +240,9 @@ pub enum AttributeKind {
     /// 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_dummy]`.
+    Dummy,
+
     /// Represents [`#[export_name]`](https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute).
     ExportName {
         /// The name to export this item with.
@@ -248,6 +251,15 @@ pub enum AttributeKind {
         span: Span,
     },
 
+    /// Represents `#[export_stable]`.
+    ExportStable,
+
+    /// Represents `#[ffi_const]`.
+    FfiConst(Span),
+
+    /// Represents `#[ffi_pure]`.
+    FfiPure(Span),
+
     /// Represents `#[ignore]`
     Ignore {
         span: Span,
@@ -326,6 +338,9 @@ pub enum AttributeKind {
         span: Span,
     },
 
+    /// Represents `#[rustc_std_internal_symbol]`.
+    StdInternalSymbol(Span),
+
     /// Represents `#[target_feature(enable = "...")]`
     TargetFeature(ThinVec<(Symbol, Span)>, Span),
 
diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs
index a6ae49d2808..5414c7b103b 100644
--- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs
+++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs
@@ -25,7 +25,11 @@ impl AttributeKind {
             ConstStabilityIndirect => No,
             Deprecation { .. } => Yes,
             DocComment { .. } => Yes,
+            Dummy => No,
             ExportName { .. } => Yes,
+            ExportStable => No,
+            FfiConst(..) => No,
+            FfiPure(..) => No,
             Ignore { .. } => No,
             Inline(..) => No,
             LinkName { .. } => Yes,
@@ -48,6 +52,7 @@ impl AttributeKind {
             RustcObjectLifetimeDefault => No,
             SkipDuringMethodDispatch { .. } => No,
             Stability { .. } => Yes,
+            StdInternalSymbol(..) => No,
             TargetFeature(..) => No,
             TrackCaller(..) => Yes,
             Used { .. } => No,
diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl
index 8a709ea5d20..bec3a1e8a59 100644
--- a/compiler/rustc_attr_parsing/messages.ftl
+++ b/compiler/rustc_attr_parsing/messages.ftl
@@ -146,12 +146,12 @@ attr_parsing_unused_duplicate =
     unused attribute
     .suggestion = remove this attribute
     .note = attribute also specified here
-    .warn = {-passes_previously_accepted}
+    .warn = {-attr_parsing_previously_accepted}
 
 attr_parsing_unused_multiple =
     multiple `{$name}` attributes
     .suggestion = remove this attribute
     .note = attribute also specified here
 
--attr_parsing_perviously_accepted =
+-attr_parsing_previously_accepted =
     this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
index cb3956d46a0..fdec09edaa1 100644
--- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
@@ -15,7 +15,7 @@ pub(crate) struct OptimizeParser;
 
 impl<S: Stage> SingleAttributeParser<S> for OptimizeParser {
     const PATH: &[Symbol] = &[sym::optimize];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
     const TEMPLATE: AttributeTemplate = template!(List: "size|speed|none");
 
@@ -56,7 +56,7 @@ pub(crate) struct ExportNameParser;
 
 impl<S: Stage> SingleAttributeParser<S> for ExportNameParser {
     const PATH: &[rustc_span::Symbol] = &[sym::export_name];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
     const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
index 702ad66f578..08cf1ab5d19 100644
--- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
@@ -36,7 +36,7 @@ fn get<S: Stage>(
 
 impl<S: Stage> SingleAttributeParser<S> for DeprecationParser {
     const PATH: &[Symbol] = &[sym::deprecated];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
     const TEMPLATE: AttributeTemplate = template!(
         Word,
diff --git a/compiler/rustc_attr_parsing/src/attributes/dummy.rs b/compiler/rustc_attr_parsing/src/attributes/dummy.rs
new file mode 100644
index 00000000000..e5e1c3bb6b6
--- /dev/null
+++ b/compiler/rustc_attr_parsing/src/attributes/dummy.rs
@@ -0,0 +1,19 @@
+use rustc_attr_data_structures::AttributeKind;
+use rustc_feature::{AttributeTemplate, template};
+use rustc_span::{Symbol, sym};
+
+use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
+use crate::context::{AcceptContext, Stage};
+use crate::parser::ArgParser;
+
+pub(crate) struct DummyParser;
+impl<S: Stage> SingleAttributeParser<S> for DummyParser {
+    const PATH: &[Symbol] = &[sym::rustc_dummy];
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore;
+    const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really
+
+    fn convert(_: &mut AcceptContext<'_, '_, S>, _: &ArgParser<'_>) -> Option<AttributeKind> {
+        Some(AttributeKind::Dummy)
+    }
+}
diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs
index 11844f4cd95..fe812175218 100644
--- a/compiler/rustc_attr_parsing/src/attributes/inline.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs
@@ -16,7 +16,7 @@ pub(crate) struct InlineParser;
 
 impl<S: Stage> SingleAttributeParser<S> for InlineParser {
     const PATH: &'static [Symbol] = &[sym::inline];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
     const TEMPLATE: AttributeTemplate = template!(Word, List: "always|never");
 
@@ -57,7 +57,7 @@ pub(crate) struct RustcForceInlineParser;
 
 impl<S: Stage> SingleAttributeParser<S> for RustcForceInlineParser {
     const PATH: &'static [Symbol] = &[sym::rustc_force_inline];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
     const TEMPLATE: AttributeTemplate = template!(Word, List: "reason", NameValueStr: "reason");
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
index e298053ab76..23a8e96482d 100644
--- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
@@ -1,9 +1,11 @@
 use rustc_attr_data_structures::AttributeKind;
 use rustc_attr_data_structures::AttributeKind::{LinkName, LinkSection};
 use rustc_feature::{AttributeTemplate, template};
-use rustc_span::{Symbol, sym};
+use rustc_span::{Span, Symbol, sym};
 
-use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
+use crate::attributes::{
+    AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
+};
 use crate::context::{AcceptContext, Stage};
 use crate::parser::ArgParser;
 use crate::session_diagnostics::NullOnLinkSection;
@@ -12,7 +14,7 @@ pub(crate) struct LinkNameParser;
 
 impl<S: Stage> SingleAttributeParser<S> for LinkNameParser {
     const PATH: &[Symbol] = &[sym::link_name];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
     const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
 
@@ -34,7 +36,7 @@ pub(crate) struct LinkSectionParser;
 
 impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
     const PATH: &[Symbol] = &[sym::link_section];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
     const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
 
@@ -57,3 +59,31 @@ impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
         Some(LinkSection { name, span: cx.attr_span })
     }
 }
+
+pub(crate) struct ExportStableParser;
+impl<S: Stage> NoArgsAttributeParser<S> for ExportStableParser {
+    const PATH: &[Symbol] = &[sym::export_stable];
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
+    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable;
+}
+
+pub(crate) struct FfiConstParser;
+impl<S: Stage> NoArgsAttributeParser<S> for FfiConstParser {
+    const PATH: &[Symbol] = &[sym::ffi_const];
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiConst;
+}
+
+pub(crate) struct FfiPureParser;
+impl<S: Stage> NoArgsAttributeParser<S> for FfiPureParser {
+    const PATH: &[Symbol] = &[sym::ffi_pure];
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure;
+}
+
+pub(crate) struct StdInternalSymbolParser;
+impl<S: Stage> NoArgsAttributeParser<S> for StdInternalSymbolParser {
+    const PATH: &[Symbol] = &[sym::rustc_std_internal_symbol];
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::StdInternalSymbol;
+}
diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
index ba7572434df..68c716d1a99 100644
--- a/compiler/rustc_attr_parsing/src/attributes/mod.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
@@ -30,6 +30,7 @@ pub(crate) mod cfg;
 pub(crate) mod codegen_attrs;
 pub(crate) mod confusables;
 pub(crate) mod deprecation;
+pub(crate) mod dummy;
 pub(crate) mod inline;
 pub(crate) mod link_attrs;
 pub(crate) mod lint_helpers;
@@ -139,7 +140,7 @@ impl<T: SingleAttributeParser<S>, S: Stage> AttributeParser<S> for Single<T, S>
             if let Some(pa) = T::convert(cx, args) {
                 match T::ATTRIBUTE_ORDER {
                     // keep the first and report immediately. ignore this attribute
-                    AttributeOrder::KeepFirst => {
+                    AttributeOrder::KeepInnermost => {
                         if let Some((_, unused)) = group.1 {
                             T::ON_DUPLICATE.exec::<T>(cx, cx.attr_span, unused);
                             return;
@@ -147,7 +148,7 @@ impl<T: SingleAttributeParser<S>, S: Stage> AttributeParser<S> for Single<T, S>
                     }
                     // keep the new one and warn about the previous,
                     // then replace
-                    AttributeOrder::KeepLast => {
+                    AttributeOrder::KeepOutermost => {
                         if let Some((_, used)) = group.1 {
                             T::ON_DUPLICATE.exec::<T>(cx, used, cx.attr_span);
                         }
@@ -164,9 +165,6 @@ impl<T: SingleAttributeParser<S>, S: Stage> AttributeParser<S> for Single<T, S>
     }
 }
 
-// FIXME(jdonszelmann): logic is implemented but the attribute parsers needing
-// them will be merged in another PR
-#[allow(unused)]
 pub(crate) enum OnDuplicate<S: Stage> {
     /// Give a default warning
     Warn,
@@ -212,25 +210,29 @@ impl<S: Stage> OnDuplicate<S> {
         }
     }
 }
-//
-// FIXME(jdonszelmann): logic is implemented but the attribute parsers needing
-// them will be merged in another PR
-#[allow(unused)]
+
 pub(crate) enum AttributeOrder {
-    /// Duplicates after the first attribute will be an error.
+    /// Duplicates after the innermost instance of the attribute will be an error/warning.
+    /// Only keep the lowest attribute.
     ///
-    /// This should be used where duplicates would be ignored, but carry extra
-    /// meaning that could cause confusion. For example, `#[stable(since="1.0")]
-    /// #[stable(since="2.0")]`, which version should be used for `stable`?
-    KeepFirst,
-
-    /// Duplicates preceding the last instance of the attribute will be a
-    /// warning, with a note that this will be an error in the future.
+    /// Attributes are processed from bottom to top, so this raises a warning/error on all the attributes
+    /// further above the lowest one:
+    /// ```
+    /// #[stable(since="1.0")] //~ WARNING duplicated attribute
+    /// #[stable(since="2.0")]
+    /// ```
+    KeepInnermost,
+
+    /// Duplicates before the outermost instance of the attribute will be an error/warning.
+    /// Only keep the highest attribute.
     ///
-    /// This is the same as `FutureWarnFollowing`, except the last attribute is
-    /// the one that is "used". Ideally these can eventually migrate to
-    /// `ErrorPreceding`.
-    KeepLast,
+    /// Attributes are processed from bottom to top, so this raises a warning/error on all the attributes
+    /// below the highest one:
+    /// ```
+    /// #[path="foo.rs"]
+    /// #[path="bar.rs"] //~ WARNING duplicated attribute
+    /// ```
+    KeepOutermost,
 }
 
 /// An even simpler version of [`SingleAttributeParser`]:
@@ -256,7 +258,7 @@ impl<T: NoArgsAttributeParser<S>, S: Stage> Default for WithoutArgs<T, S> {
 
 impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for WithoutArgs<T, S> {
     const PATH: &[Symbol] = T::PATH;
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
     const ON_DUPLICATE: OnDuplicate<S> = T::ON_DUPLICATE;
     const TEMPLATE: AttributeTemplate = template!(Word);
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs
index b5eb85f68b4..e0a3e675509 100644
--- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs
@@ -12,7 +12,7 @@ pub(crate) struct MustUseParser;
 
 impl<S: Stage> SingleAttributeParser<S> for MustUseParser {
     const PATH: &[Symbol] = &[sym::must_use];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
     const TEMPLATE: AttributeTemplate = template!(Word, NameValueStr: "reason");
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/path.rs b/compiler/rustc_attr_parsing/src/attributes/path.rs
index 0dfbc9a9aa8..febb1b45a18 100644
--- a/compiler/rustc_attr_parsing/src/attributes/path.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/path.rs
@@ -10,7 +10,7 @@ pub(crate) struct PathParser;
 
 impl<S: Stage> SingleAttributeParser<S> for PathParser {
     const PATH: &[Symbol] = &[sym::path];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
     const TEMPLATE: AttributeTemplate = template!(NameValueStr: "file");
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
index e6b6a6fe3c9..ec821cb11ce 100644
--- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
@@ -11,7 +11,7 @@ pub(crate) struct RustcLayoutScalarValidRangeStart;
 
 impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStart {
     const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_start];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
     const TEMPLATE: AttributeTemplate = template!(List: "start");
 
@@ -25,7 +25,7 @@ pub(crate) struct RustcLayoutScalarValidRangeEnd;
 
 impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEnd {
     const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_end];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
     const TEMPLATE: AttributeTemplate = template!(List: "end");
 
@@ -62,7 +62,7 @@ pub(crate) struct RustcObjectLifetimeDefaultParser;
 
 impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {
     const PATH: &[rustc_span::Symbol] = &[sym::rustc_object_lifetime_default];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
     const TEMPLATE: AttributeTemplate = template!(Word);
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs
index cea3ee52ff4..ee81f64860f 100644
--- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs
@@ -11,7 +11,7 @@ pub(crate) struct IgnoreParser;
 
 impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
     const PATH: &[Symbol] = &[sym::ignore];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
     const TEMPLATE: AttributeTemplate = template!(Word, NameValueStr: "reason");
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs
index 83a98c53c7f..c29dbf4d1e9 100644
--- a/compiler/rustc_attr_parsing/src/attributes/traits.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs
@@ -12,7 +12,7 @@ pub(crate) struct SkipDuringMethodDispatchParser;
 
 impl<S: Stage> SingleAttributeParser<S> for SkipDuringMethodDispatchParser {
     const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
 
     const TEMPLATE: AttributeTemplate = template!(List: "array, boxed_slice");
diff --git a/compiler/rustc_attr_parsing/src/attributes/transparency.rs b/compiler/rustc_attr_parsing/src/attributes/transparency.rs
index ce5ceb9139a..c9fdc57cc06 100644
--- a/compiler/rustc_attr_parsing/src/attributes/transparency.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/transparency.rs
@@ -14,7 +14,7 @@ pub(crate) struct TransparencyParser;
 #[allow(rustc::diagnostic_outside_of_impl)]
 impl<S: Stage> SingleAttributeParser<S> for TransparencyParser {
     const PATH: &[Symbol] = &[sym::rustc_macro_transparency];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Custom(|cx, used, unused| {
         cx.dcx().span_err(vec![used, unused], "multiple macro transparency attributes");
     });
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index 939f4a6fde7..dbe1a5b2ad0 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -21,8 +21,12 @@ use crate::attributes::codegen_attrs::{
 };
 use crate::attributes::confusables::ConfusablesParser;
 use crate::attributes::deprecation::DeprecationParser;
+use crate::attributes::dummy::DummyParser;
 use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
-use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser};
+use crate::attributes::link_attrs::{
+    ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkSectionParser,
+    StdInternalSymbolParser,
+};
 use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser};
 use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
 use crate::attributes::must_use::MustUseParser;
@@ -127,6 +131,7 @@ attribute_parsers!(
 
         // tidy-alphabetical-start
         Single<DeprecationParser>,
+        Single<DummyParser>,
         Single<ExportNameParser>,
         Single<IgnoreParser>,
         Single<InlineParser>,
@@ -145,6 +150,9 @@ attribute_parsers!(
         Single<WithoutArgs<ColdParser>>,
         Single<WithoutArgs<ConstContinueParser>>,
         Single<WithoutArgs<ConstStabilityIndirectParser>>,
+        Single<WithoutArgs<ExportStableParser>>,
+        Single<WithoutArgs<FfiConstParser>>,
+        Single<WithoutArgs<FfiPureParser>>,
         Single<WithoutArgs<LoopMatchParser>>,
         Single<WithoutArgs<MayDangleParser>>,
         Single<WithoutArgs<NoImplicitPreludeParser>>,
@@ -152,6 +160,7 @@ attribute_parsers!(
         Single<WithoutArgs<NonExhaustiveParser>>,
         Single<WithoutArgs<PassByValueParser>>,
         Single<WithoutArgs<PubTransparentParser>>,
+        Single<WithoutArgs<StdInternalSymbolParser>>,
         Single<WithoutArgs<TrackCallerParser>>,
         // tidy-alphabetical-end
     ];
diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs
index 1f087b09234..1c4ff5a6779 100644
--- a/compiler/rustc_borrowck/src/consumers.rs
+++ b/compiler/rustc_borrowck/src/consumers.rs
@@ -1,7 +1,9 @@
 //! This file provides API for compiler consumers.
 
+use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::mir::{Body, Promoted};
 use rustc_middle::ty::TyCtxt;
 
@@ -17,7 +19,39 @@ pub use super::polonius::legacy::{
 pub use super::region_infer::RegionInferenceContext;
 use crate::{BorrowCheckRootCtxt, do_mir_borrowck};
 
-/// Options determining the output behavior of [`get_body_with_borrowck_facts`].
+/// Struct used during mir borrowck to collect bodies with facts for a typeck root and all
+/// its nested bodies.
+pub(crate) struct BorrowckConsumer<'tcx> {
+    options: ConsumerOptions,
+    bodies: FxHashMap<LocalDefId, BodyWithBorrowckFacts<'tcx>>,
+}
+
+impl<'tcx> BorrowckConsumer<'tcx> {
+    pub(crate) fn new(options: ConsumerOptions) -> Self {
+        Self { options, bodies: Default::default() }
+    }
+
+    pub(crate) fn insert_body(&mut self, def_id: LocalDefId, body: BodyWithBorrowckFacts<'tcx>) {
+        if self.bodies.insert(def_id, body).is_some() {
+            bug!("unexpected previous body for {def_id:?}");
+        }
+    }
+
+    /// Should the Polonius input facts be computed?
+    pub(crate) fn polonius_input(&self) -> bool {
+        matches!(
+            self.options,
+            ConsumerOptions::PoloniusInputFacts | ConsumerOptions::PoloniusOutputFacts
+        )
+    }
+
+    /// Should we run Polonius and collect the output facts?
+    pub(crate) fn polonius_output(&self) -> bool {
+        matches!(self.options, ConsumerOptions::PoloniusOutputFacts)
+    }
+}
+
+/// Options determining the output behavior of [`get_bodies_with_borrowck_facts`].
 ///
 /// If executing under `-Z polonius` the choice here has no effect, and everything as if
 /// [`PoloniusOutputFacts`](ConsumerOptions::PoloniusOutputFacts) had been selected
@@ -43,17 +77,6 @@ pub enum ConsumerOptions {
     PoloniusOutputFacts,
 }
 
-impl ConsumerOptions {
-    /// Should the Polonius input facts be computed?
-    pub(crate) fn polonius_input(&self) -> bool {
-        matches!(self, Self::PoloniusInputFacts | Self::PoloniusOutputFacts)
-    }
-    /// Should we run Polonius and collect the output facts?
-    pub(crate) fn polonius_output(&self) -> bool {
-        matches!(self, Self::PoloniusOutputFacts)
-    }
-}
-
 /// A `Body` with information computed by the borrow checker. This struct is
 /// intended to be consumed by compiler consumers.
 ///
@@ -82,25 +105,35 @@ pub struct BodyWithBorrowckFacts<'tcx> {
     pub output_facts: Option<Box<PoloniusOutput>>,
 }
 
-/// This function computes borrowck facts for the given body. The [`ConsumerOptions`]
-/// determine which facts are returned. This function makes a copy of the body because
-/// it needs to regenerate the region identifiers. It should never be invoked during a
-/// typical compilation session due to the unnecessary overhead of returning
-/// [`BodyWithBorrowckFacts`].
+/// This function computes borrowck facts for the given def id and all its nested bodies.
+/// It must be called with a typeck root which will then borrowck all nested bodies as well.
+/// The [`ConsumerOptions`] determine which facts are returned. This function makes a copy
+/// of the bodies because it needs to regenerate the region identifiers. It should never be
+/// invoked during a typical compilation session due to the unnecessary overhead of
+/// returning [`BodyWithBorrowckFacts`].
 ///
 /// Note:
-/// *   This function will panic if the required body was already stolen. This
+/// *   This function will panic if the required bodies were already stolen. This
 ///     can, for example, happen when requesting a body of a `const` function
 ///     because they are evaluated during typechecking. The panic can be avoided
 ///     by overriding the `mir_borrowck` query. You can find a complete example
-///     that shows how to do this at `tests/run-make/obtain-borrowck/`.
+///     that shows how to do this at `tests/ui-fulldeps/obtain-borrowck.rs`.
 ///
 /// *   Polonius is highly unstable, so expect regular changes in its signature or other details.
-pub fn get_body_with_borrowck_facts(
+pub fn get_bodies_with_borrowck_facts(
     tcx: TyCtxt<'_>,
-    def_id: LocalDefId,
+    root_def_id: LocalDefId,
     options: ConsumerOptions,
-) -> BodyWithBorrowckFacts<'_> {
-    let mut root_cx = BorrowCheckRootCtxt::new(tcx, def_id);
-    *do_mir_borrowck(&mut root_cx, def_id, Some(options)).1.unwrap()
+) -> FxHashMap<LocalDefId, BodyWithBorrowckFacts<'_>> {
+    let mut root_cx =
+        BorrowCheckRootCtxt::new(tcx, root_def_id, Some(BorrowckConsumer::new(options)));
+
+    // See comment in `rustc_borrowck::mir_borrowck`
+    let nested_bodies = tcx.nested_bodies_within(root_def_id);
+    for def_id in nested_bodies {
+        root_cx.get_or_insert_nested(def_id);
+    }
+
+    do_mir_borrowck(&mut root_cx, root_def_id);
+    root_cx.consumer.unwrap().bodies
 }
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 82b300dcb17..321b18c9b78 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -51,7 +51,7 @@ use smallvec::SmallVec;
 use tracing::{debug, instrument};
 
 use crate::borrow_set::{BorrowData, BorrowSet};
-use crate::consumers::{BodyWithBorrowckFacts, ConsumerOptions};
+use crate::consumers::BodyWithBorrowckFacts;
 use crate::dataflow::{BorrowIndex, Borrowck, BorrowckDomain, Borrows};
 use crate::diagnostics::{
     AccessKind, BorrowckDiagnosticsBuffer, IllegalMoveOriginKind, MoveError, RegionName,
@@ -124,7 +124,7 @@ fn mir_borrowck(
         let opaque_types = ConcreteOpaqueTypes(Default::default());
         Ok(tcx.arena.alloc(opaque_types))
     } else {
-        let mut root_cx = BorrowCheckRootCtxt::new(tcx, def);
+        let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None);
         // We need to manually borrowck all nested bodies from the HIR as
         // we do not generate MIR for dead code. Not doing so causes us to
         // never check closures in dead code.
@@ -134,7 +134,7 @@ fn mir_borrowck(
         }
 
         let PropagatedBorrowCheckResults { closure_requirements, used_mut_upvars } =
-            do_mir_borrowck(&mut root_cx, def, None).0;
+            do_mir_borrowck(&mut root_cx, def);
         debug_assert!(closure_requirements.is_none());
         debug_assert!(used_mut_upvars.is_empty());
         root_cx.finalize()
@@ -289,17 +289,12 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
 
 /// Perform the actual borrow checking.
 ///
-/// Use `consumer_options: None` for the default behavior of returning
-/// [`PropagatedBorrowCheckResults`] only. Otherwise, return [`BodyWithBorrowckFacts`]
-/// according to the given [`ConsumerOptions`].
-///
 /// For nested bodies this should only be called through `root_cx.get_or_insert_nested`.
 #[instrument(skip(root_cx), level = "debug")]
 fn do_mir_borrowck<'tcx>(
     root_cx: &mut BorrowCheckRootCtxt<'tcx>,
     def: LocalDefId,
-    consumer_options: Option<ConsumerOptions>,
-) -> (PropagatedBorrowCheckResults<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
+) -> PropagatedBorrowCheckResults<'tcx> {
     let tcx = root_cx.tcx;
     let infcx = BorrowckInferCtxt::new(tcx, def);
     let (input_body, promoted) = tcx.mir_promoted(def);
@@ -343,7 +338,6 @@ fn do_mir_borrowck<'tcx>(
         &location_table,
         &move_data,
         &borrow_set,
-        consumer_options,
     );
 
     // Dump MIR results into a file, if that is enabled. This lets us
@@ -483,23 +477,24 @@ fn do_mir_borrowck<'tcx>(
         used_mut_upvars: mbcx.used_mut_upvars,
     };
 
-    let body_with_facts = if consumer_options.is_some() {
-        Some(Box::new(BodyWithBorrowckFacts {
-            body: body_owned,
-            promoted,
-            borrow_set,
-            region_inference_context: regioncx,
-            location_table: polonius_input.as_ref().map(|_| location_table),
-            input_facts: polonius_input,
-            output_facts: polonius_output,
-        }))
-    } else {
-        None
-    };
+    if let Some(consumer) = &mut root_cx.consumer {
+        consumer.insert_body(
+            def,
+            BodyWithBorrowckFacts {
+                body: body_owned,
+                promoted,
+                borrow_set,
+                region_inference_context: regioncx,
+                location_table: polonius_input.as_ref().map(|_| location_table),
+                input_facts: polonius_input,
+                output_facts: polonius_output,
+            },
+        );
+    }
 
     debug!("do_mir_borrowck: result = {:#?}", result);
 
-    (result, body_with_facts)
+    result
 }
 
 fn get_flow_results<'a, 'tcx>(
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index af450507296..41f67e78930 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -18,7 +18,6 @@ use rustc_span::sym;
 use tracing::{debug, instrument};
 
 use crate::borrow_set::BorrowSet;
-use crate::consumers::ConsumerOptions;
 use crate::diagnostics::RegionErrors;
 use crate::handle_placeholders::compute_sccs_applying_placeholder_outlives_constraints;
 use crate::polonius::PoloniusDiagnosticsContext;
@@ -83,12 +82,11 @@ pub(crate) fn compute_regions<'tcx>(
     location_table: &PoloniusLocationTable,
     move_data: &MoveData<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
-    consumer_options: Option<ConsumerOptions>,
 ) -> NllOutput<'tcx> {
     let is_polonius_legacy_enabled = infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled();
-    let polonius_input = consumer_options.map(|c| c.polonius_input()).unwrap_or_default()
+    let polonius_input = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_input())
         || is_polonius_legacy_enabled;
-    let polonius_output = consumer_options.map(|c| c.polonius_output()).unwrap_or_default()
+    let polonius_output = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_output())
         || is_polonius_legacy_enabled;
     let mut polonius_facts =
         (polonius_input || PoloniusFacts::enabled(infcx.tcx)).then_some(PoloniusFacts::default());
diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs
index 66b526fa02a..9b1d12aede5 100644
--- a/compiler/rustc_borrowck/src/root_cx.rs
+++ b/compiler/rustc_borrowck/src/root_cx.rs
@@ -6,6 +6,7 @@ use rustc_middle::ty::{OpaqueHiddenType, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::ErrorGuaranteed;
 use smallvec::SmallVec;
 
+use crate::consumers::BorrowckConsumer;
 use crate::{ClosureRegionRequirements, ConcreteOpaqueTypes, PropagatedBorrowCheckResults};
 
 /// The shared context used by both the root as well as all its nested
@@ -16,16 +17,24 @@ pub(super) struct BorrowCheckRootCtxt<'tcx> {
     concrete_opaque_types: ConcreteOpaqueTypes<'tcx>,
     nested_bodies: FxHashMap<LocalDefId, PropagatedBorrowCheckResults<'tcx>>,
     tainted_by_errors: Option<ErrorGuaranteed>,
+    /// This should be `None` during normal compilation. See [`crate::consumers`] for more
+    /// information on how this is used.
+    pub(crate) consumer: Option<BorrowckConsumer<'tcx>>,
 }
 
 impl<'tcx> BorrowCheckRootCtxt<'tcx> {
-    pub(super) fn new(tcx: TyCtxt<'tcx>, root_def_id: LocalDefId) -> BorrowCheckRootCtxt<'tcx> {
+    pub(super) fn new(
+        tcx: TyCtxt<'tcx>,
+        root_def_id: LocalDefId,
+        consumer: Option<BorrowckConsumer<'tcx>>,
+    ) -> BorrowCheckRootCtxt<'tcx> {
         BorrowCheckRootCtxt {
             tcx,
             root_def_id,
             concrete_opaque_types: Default::default(),
             nested_bodies: Default::default(),
             tainted_by_errors: None,
+            consumer,
         }
     }
 
@@ -71,7 +80,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
             self.root_def_id.to_def_id()
         );
         if !self.nested_bodies.contains_key(&def_id) {
-            let result = super::do_mir_borrowck(self, def_id, None).0;
+            let result = super::do_mir_borrowck(self, def_id);
             if let Some(prev) = self.nested_bodies.insert(def_id, result) {
                 bug!("unexpected previous nested body: {prev:?}");
             }
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index ed06423b260..85adf0f3716 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -175,6 +175,13 @@ pub(crate) fn codegen_const_value<'tcx>(
                             fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
                         fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
                     }
+                    GlobalAlloc::TypeId { .. } => {
+                        return CValue::const_val(
+                            fx,
+                            layout,
+                            ScalarInt::try_from_target_usize(offset.bytes(), fx.tcx).unwrap(),
+                        );
+                    }
                     GlobalAlloc::Static(def_id) => {
                         assert!(fx.tcx.is_static(def_id));
                         let data_id = data_id_for_static(
@@ -360,6 +367,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
                     GlobalAlloc::Memory(alloc) => alloc,
                     GlobalAlloc::Function { .. }
                     | GlobalAlloc::Static(_)
+                    | GlobalAlloc::TypeId { .. }
                     | GlobalAlloc::VTable(..) => {
                         unreachable!()
                     }
@@ -471,6 +479,11 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
                         .principal()
                         .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
                 ),
+                GlobalAlloc::TypeId { .. } => {
+                    // Nothing to do, the bytes/offset of this pointer have already been written together with all other bytes,
+                    // so we just need to drop this provenance.
+                    continue;
+                }
                 GlobalAlloc::Static(def_id) => {
                     if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
                     {
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index 32713eb56c6..28848ca6184 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -1,7 +1,6 @@
 use gccjit::{LValue, RValue, ToRValue, Type};
-use rustc_abi as abi;
-use rustc_abi::HasDataLayout;
 use rustc_abi::Primitive::Pointer;
+use rustc_abi::{self as abi, HasDataLayout};
 use rustc_codegen_ssa::traits::{
     BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods,
 };
@@ -282,6 +281,13 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
                         let init = self.const_data_from_alloc(alloc);
                         self.static_addr_of(init, alloc.inner().align, None)
                     }
+                    GlobalAlloc::TypeId { .. } => {
+                        let val = self.const_usize(offset.bytes());
+                        // This is still a variable of pointer type, even though we only use the provenance
+                        // of that pointer in CTFE and Miri. But to make LLVM's type system happy,
+                        // we need an int-to-ptr cast here (it doesn't matter at all which provenance that picks).
+                        return self.context.new_cast(None, val, ty);
+                    }
                     GlobalAlloc::Static(def_id) => {
                         assert!(self.tcx.is_static(def_id));
                         self.get_static(def_id).get_address(None)
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index 92f38565eef..b9b5c776d86 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -3,9 +3,8 @@
 use std::borrow::Borrow;
 
 use libc::{c_char, c_uint};
-use rustc_abi as abi;
-use rustc_abi::HasDataLayout;
 use rustc_abi::Primitive::Pointer;
+use rustc_abi::{self as abi, HasDataLayout as _};
 use rustc_ast::Mutability;
 use rustc_codegen_ssa::common::TypeKind;
 use rustc_codegen_ssa::traits::*;
@@ -284,7 +283,8 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
                                 self.const_bitcast(llval, llty)
                             };
                         } else {
-                            let init = const_alloc_to_llvm(self, alloc, /*static*/ false);
+                            let init =
+                                const_alloc_to_llvm(self, alloc.inner(), /*static*/ false);
                             let alloc = alloc.inner();
                             let value = match alloc.mutability {
                                 Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None),
@@ -316,15 +316,19 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
                                 }),
                             )))
                             .unwrap_memory();
-                        let init = const_alloc_to_llvm(self, alloc, /*static*/ false);
-                        let value = self.static_addr_of_impl(init, alloc.inner().align, None);
-                        value
+                        let init = const_alloc_to_llvm(self, alloc.inner(), /*static*/ false);
+                        self.static_addr_of_impl(init, alloc.inner().align, None)
                     }
                     GlobalAlloc::Static(def_id) => {
                         assert!(self.tcx.is_static(def_id));
                         assert!(!self.tcx.is_thread_local_static(def_id));
                         self.get_static(def_id)
                     }
+                    GlobalAlloc::TypeId { .. } => {
+                        // Drop the provenance, the offset contains the bytes of the hash
+                        let llval = self.const_usize(offset.bytes());
+                        return unsafe { llvm::LLVMConstIntToPtr(llval, llty) };
+                    }
                 };
                 let base_addr_space = global_alloc.address_space(self);
                 let llval = unsafe {
@@ -346,7 +350,7 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
     }
 
     fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value {
-        const_alloc_to_llvm(self, alloc, /*static*/ false)
+        const_alloc_to_llvm(self, alloc.inner(), /*static*/ false)
     }
 
     fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value {
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 28f5282c6b0..21524fd2eb8 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -27,10 +27,9 @@ use crate::{base, debuginfo};
 
 pub(crate) fn const_alloc_to_llvm<'ll>(
     cx: &CodegenCx<'ll, '_>,
-    alloc: ConstAllocation<'_>,
+    alloc: &Allocation,
     is_static: bool,
 ) -> &'ll Value {
-    let alloc = alloc.inner();
     // We expect that callers of const_alloc_to_llvm will instead directly codegen a pointer or
     // integer for any &ZST where the ZST is a constant (i.e. not a static). We should never be
     // producing empty LLVM allocations as they're just adding noise to binaries and forcing less
@@ -141,7 +140,7 @@ fn codegen_static_initializer<'ll, 'tcx>(
     def_id: DefId,
 ) -> Result<(&'ll Value, ConstAllocation<'tcx>), ErrorHandled> {
     let alloc = cx.tcx.eval_static_initializer(def_id)?;
-    Ok((const_alloc_to_llvm(cx, alloc, /*static*/ true), alloc))
+    Ok((const_alloc_to_llvm(cx, alloc.inner(), /*static*/ true), alloc))
 }
 
 fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: Align) {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 343cb0eeca9..b46773396fc 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1379,7 +1379,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
         }
     }
 
-    let features = sess.opts.unstable_opts.linker_features;
+    let features = sess.opts.cg.linker_features;
 
     // linker and linker flavor specified via command line have precedence over what the target
     // specification specifies
@@ -3327,35 +3327,6 @@ fn add_lld_args(
     // this, `wasm-component-ld`, which is overridden if this option is passed.
     if !sess.target.is_like_wasm {
         cmd.cc_arg("-fuse-ld=lld");
-
-        // On ELF platforms like at least x64 linux, GNU ld and LLD have opposite defaults on some
-        // section garbage-collection features. For example, the somewhat popular `linkme` crate and
-        // its dependents rely in practice on this difference: when using lld, they need `-z
-        // nostart-stop-gc` to prevent encapsulation symbols and sections from being
-        // garbage-collected.
-        //
-        // More information about all this can be found in:
-        // - https://maskray.me/blog/2021-01-31-metadata-sections-comdat-and-shf-link-order
-        // - https://lld.llvm.org/ELF/start-stop-gc
-        //
-        // So when using lld, we restore, for now, the traditional behavior to help migration, but
-        // will remove it in the future.
-        // Since this only disables an optimization, it shouldn't create issues, but is in theory
-        // slightly suboptimal. However, it:
-        // - doesn't have any visible impact on our benchmarks
-        // - reduces the need to disable lld for the crates that depend on this
-        //
-        // Note that lld can detect some cases where this difference is relied on, and emits a
-        // dedicated error to add this link arg. We could make use of this error to emit an FCW. As
-        // of writing this, we don't do it, because lld is already enabled by default on nightly
-        // without this mitigation: no working project would see the FCW, so we do this to help
-        // stabilization.
-        //
-        // FIXME: emit an FCW if linking fails due its absence, and then remove this link-arg in the
-        // future.
-        if sess.target.llvm_target == "x86_64-unknown-linux-gnu" {
-            cmd.link_arg("-znostart-stop-gc");
-        }
     }
 
     if !flavor.is_gnu() {
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index ff454427871..85d01d4f938 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -203,6 +203,13 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                     UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER,
                     UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER,
                 },
+                AttributeKind::FfiConst(_) => {
+                    codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST
+                }
+                AttributeKind::FfiPure(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE,
+                AttributeKind::StdInternalSymbol(_) => {
+                    codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
+                }
                 _ => {}
             }
         }
@@ -213,17 +220,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
 
         match name {
             sym::rustc_allocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR,
-            sym::ffi_pure => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE,
-            sym::ffi_const => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST,
             sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND,
             sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR,
             sym::rustc_deallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR,
             sym::rustc_allocator_zeroed => {
                 codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
             }
-            sym::rustc_std_internal_symbol => {
-                codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
-            }
             sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL,
             sym::linkage => {
                 if let Some(val) = attr.value_str() {
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 99f35b79208..6d6465dd798 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -171,8 +171,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer
         if let Some(local) = place.as_local() {
             self.define(local, DefLocation::Assignment(location));
             if self.locals[local] != LocalKind::Memory {
-                let decl_span = self.fx.mir.local_decls[local].source_info.span;
-                if !self.fx.rvalue_creates_operand(rvalue, decl_span) {
+                if !self.fx.rvalue_creates_operand(rvalue) {
                     self.locals[local] = LocalKind::Memory;
                 }
             }
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 2896dfd5463..bc83e41b278 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -186,7 +186,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
         offset: Size,
     ) -> Self {
         let alloc_align = alloc.inner().align;
-        assert!(alloc_align >= layout.align.abi);
+        assert!(alloc_align >= layout.align.abi, "{alloc_align:?} < {:?}", layout.align.abi);
 
         let read_scalar = |start, size, s: abi::Scalar, ty| {
             match alloc.0.read_scalar(
@@ -565,118 +565,167 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
             }
         }
     }
+}
 
-    /// Creates an incomplete operand containing the [`abi::Scalar`]s expected based
-    /// on the `layout` passed. This is for use with [`OperandRef::insert_field`]
-    /// later to set the necessary immediate(s), one-by-one converting all the `Right` to `Left`.
-    ///
-    /// Returns `None` for `layout`s which cannot be built this way.
-    pub(crate) fn builder(
-        layout: TyAndLayout<'tcx>,
-    ) -> Option<OperandRef<'tcx, Either<V, abi::Scalar>>> {
-        // Uninhabited types are weird, because for example `Result<!, !>`
-        // shows up as `FieldsShape::Primitive` and we need to be able to write
-        // a field into `(u32, !)`. We'll do that in an `alloca` instead.
-        if layout.uninhabited {
-            return None;
-        }
+/// Each of these variants starts out as `Either::Right` when it's uninitialized,
+/// then setting the field changes that to `Either::Left` with the backend value.
+#[derive(Debug, Copy, Clone)]
+enum OperandValueBuilder<V> {
+    ZeroSized,
+    Immediate(Either<V, abi::Scalar>),
+    Pair(Either<V, abi::Scalar>, Either<V, abi::Scalar>),
+    /// `repr(simd)` types need special handling because they each have a non-empty
+    /// array field (which uses [`OperandValue::Ref`]) despite the SIMD type itself
+    /// using [`OperandValue::Immediate`] which for any other kind of type would
+    /// mean that its one non-ZST field would also be [`OperandValue::Immediate`].
+    Vector(Either<V, ()>),
+}
+
+/// Allows building up an `OperandRef` by setting fields one at a time.
+#[derive(Debug, Copy, Clone)]
+pub(super) struct OperandRefBuilder<'tcx, V> {
+    val: OperandValueBuilder<V>,
+    layout: TyAndLayout<'tcx>,
+}
 
+impl<'a, 'tcx, V: CodegenObject> OperandRefBuilder<'tcx, V> {
+    /// Creates an uninitialized builder for an instance of the `layout`.
+    ///
+    /// ICEs for [`BackendRepr::Memory`] types (other than ZSTs), which should
+    /// be built up inside a [`PlaceRef`] instead as they need an allocated place
+    /// into which to write the values of the fields.
+    pub(super) fn new(layout: TyAndLayout<'tcx>) -> Self {
         let val = match layout.backend_repr {
-            BackendRepr::Memory { .. } if layout.is_zst() => OperandValue::ZeroSized,
-            BackendRepr::Scalar(s) => OperandValue::Immediate(Either::Right(s)),
-            BackendRepr::ScalarPair(a, b) => OperandValue::Pair(Either::Right(a), Either::Right(b)),
-            BackendRepr::Memory { .. } | BackendRepr::SimdVector { .. } => return None,
+            BackendRepr::Memory { .. } if layout.is_zst() => OperandValueBuilder::ZeroSized,
+            BackendRepr::Scalar(s) => OperandValueBuilder::Immediate(Either::Right(s)),
+            BackendRepr::ScalarPair(a, b) => {
+                OperandValueBuilder::Pair(Either::Right(a), Either::Right(b))
+            }
+            BackendRepr::SimdVector { .. } => OperandValueBuilder::Vector(Either::Right(())),
+            BackendRepr::Memory { .. } => {
+                bug!("Cannot use non-ZST Memory-ABI type in operand builder: {layout:?}");
+            }
         };
-        Some(OperandRef { val, layout })
+        OperandRefBuilder { val, layout }
     }
-}
 
-impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, Either<V, abi::Scalar>> {
-    pub(crate) fn insert_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
+    pub(super) fn insert_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         &mut self,
         bx: &mut Bx,
-        v: VariantIdx,
-        f: FieldIdx,
-        operand: OperandRef<'tcx, V>,
+        variant: VariantIdx,
+        field: FieldIdx,
+        field_operand: OperandRef<'tcx, V>,
     ) {
-        let (expect_zst, is_zero_offset) = if let abi::FieldsShape::Primitive = self.layout.fields {
+        if let OperandValue::ZeroSized = field_operand.val {
+            // A ZST never adds any state, so just ignore it.
+            // This special-casing is worth it because of things like
+            // `Result<!, !>` where `Ok(never)` is legal to write,
+            // but the type shows as FieldShape::Primitive so we can't
+            // actually look at the layout for the field being set.
+            return;
+        }
+
+        let is_zero_offset = if let abi::FieldsShape::Primitive = self.layout.fields {
             // The other branch looking at field layouts ICEs for primitives,
             // so we need to handle them separately.
-            // Multiple fields is possible for cases such as aggregating
-            // a thin pointer, where the second field is the unit.
+            // Because we handled ZSTs above (like the metadata in a thin pointer),
+            // the only possibility is that we're setting the one-and-only field.
             assert!(!self.layout.is_zst());
-            assert_eq!(v, FIRST_VARIANT);
-            let first_field = f == FieldIdx::ZERO;
-            (!first_field, first_field)
+            assert_eq!(variant, FIRST_VARIANT);
+            assert_eq!(field, FieldIdx::ZERO);
+            true
         } else {
-            let variant_layout = self.layout.for_variant(bx.cx(), v);
-            let field_layout = variant_layout.field(bx.cx(), f.as_usize());
-            let field_offset = variant_layout.fields.offset(f.as_usize());
-            (field_layout.is_zst(), field_offset == Size::ZERO)
+            let variant_layout = self.layout.for_variant(bx.cx(), variant);
+            let field_offset = variant_layout.fields.offset(field.as_usize());
+            field_offset == Size::ZERO
         };
 
         let mut update = |tgt: &mut Either<V, abi::Scalar>, src, from_scalar| {
             let to_scalar = tgt.unwrap_right();
+            // We transmute here (rather than just `from_immediate`) because in
+            // `Result<usize, *const ()>` the field of the `Ok` is an integer,
+            // but the corresponding scalar in the enum is a pointer.
             let imm = transmute_scalar(bx, src, from_scalar, to_scalar);
             *tgt = Either::Left(imm);
         };
 
-        match (operand.val, operand.layout.backend_repr) {
-            (OperandValue::ZeroSized, _) if expect_zst => {}
+        match (field_operand.val, field_operand.layout.backend_repr) {
+            (OperandValue::ZeroSized, _) => unreachable!("Handled above"),
             (OperandValue::Immediate(v), BackendRepr::Scalar(from_scalar)) => match &mut self.val {
-                OperandValue::Immediate(val @ Either::Right(_)) if is_zero_offset => {
+                OperandValueBuilder::Immediate(val @ Either::Right(_)) if is_zero_offset => {
                     update(val, v, from_scalar);
                 }
-                OperandValue::Pair(fst @ Either::Right(_), _) if is_zero_offset => {
+                OperandValueBuilder::Pair(fst @ Either::Right(_), _) if is_zero_offset => {
                     update(fst, v, from_scalar);
                 }
-                OperandValue::Pair(_, snd @ Either::Right(_)) if !is_zero_offset => {
+                OperandValueBuilder::Pair(_, snd @ Either::Right(_)) if !is_zero_offset => {
                     update(snd, v, from_scalar);
                 }
-                _ => bug!("Tried to insert {operand:?} into {v:?}.{f:?} of {self:?}"),
+                _ => {
+                    bug!("Tried to insert {field_operand:?} into {variant:?}.{field:?} of {self:?}")
+                }
+            },
+            (OperandValue::Immediate(v), BackendRepr::SimdVector { .. }) => match &mut self.val {
+                OperandValueBuilder::Vector(val @ Either::Right(())) if is_zero_offset => {
+                    *val = Either::Left(v);
+                }
+                _ => {
+                    bug!("Tried to insert {field_operand:?} into {variant:?}.{field:?} of {self:?}")
+                }
             },
             (OperandValue::Pair(a, b), BackendRepr::ScalarPair(from_sa, from_sb)) => {
                 match &mut self.val {
-                    OperandValue::Pair(fst @ Either::Right(_), snd @ Either::Right(_)) => {
+                    OperandValueBuilder::Pair(fst @ Either::Right(_), snd @ Either::Right(_)) => {
                         update(fst, a, from_sa);
                         update(snd, b, from_sb);
                     }
-                    _ => bug!("Tried to insert {operand:?} into {v:?}.{f:?} of {self:?}"),
+                    _ => bug!(
+                        "Tried to insert {field_operand:?} into {variant:?}.{field:?} of {self:?}"
+                    ),
                 }
             }
-            _ => bug!("Unsupported operand {operand:?} inserting into {v:?}.{f:?} of {self:?}"),
+            (OperandValue::Ref(place), BackendRepr::Memory { .. }) => match &mut self.val {
+                OperandValueBuilder::Vector(val @ Either::Right(())) => {
+                    let ibty = bx.cx().immediate_backend_type(self.layout);
+                    let simd = bx.load_from_place(ibty, place);
+                    *val = Either::Left(simd);
+                }
+                _ => {
+                    bug!("Tried to insert {field_operand:?} into {variant:?}.{field:?} of {self:?}")
+                }
+            },
+            _ => bug!("Operand cannot be used with `insert_field`: {field_operand:?}"),
         }
     }
 
     /// Insert the immediate value `imm` for field `f` in the *type itself*,
     /// rather than into one of the variants.
     ///
-    /// Most things want [`OperandRef::insert_field`] instead, but this one is
+    /// Most things want [`Self::insert_field`] instead, but this one is
     /// necessary for writing things like enum tags that aren't in any variant.
     pub(super) fn insert_imm(&mut self, f: FieldIdx, imm: V) {
         let field_offset = self.layout.fields.offset(f.as_usize());
         let is_zero_offset = field_offset == Size::ZERO;
         match &mut self.val {
-            OperandValue::Immediate(val @ Either::Right(_)) if is_zero_offset => {
+            OperandValueBuilder::Immediate(val @ Either::Right(_)) if is_zero_offset => {
                 *val = Either::Left(imm);
             }
-            OperandValue::Pair(fst @ Either::Right(_), _) if is_zero_offset => {
+            OperandValueBuilder::Pair(fst @ Either::Right(_), _) if is_zero_offset => {
                 *fst = Either::Left(imm);
             }
-            OperandValue::Pair(_, snd @ Either::Right(_)) if !is_zero_offset => {
+            OperandValueBuilder::Pair(_, snd @ Either::Right(_)) if !is_zero_offset => {
                 *snd = Either::Left(imm);
             }
             _ => bug!("Tried to insert {imm:?} into field {f:?} of {self:?}"),
         }
     }
 
-    /// After having set all necessary fields, this converts the
-    /// `OperandValue<Either<V, _>>` (as obtained from [`OperandRef::builder`])
-    /// to the normal `OperandValue<V>`.
+    /// After having set all necessary fields, this converts the builder back
+    /// to the normal `OperandRef`.
     ///
     /// ICEs if any required fields were not set.
-    pub fn build(&self, cx: &impl CodegenMethods<'tcx, Value = V>) -> OperandRef<'tcx, V> {
-        let OperandRef { val, layout } = *self;
+    pub(super) fn build(&self, cx: &impl CodegenMethods<'tcx, Value = V>) -> OperandRef<'tcx, V> {
+        let OperandRefBuilder { val, layout } = *self;
 
         // For something like `Option::<u32>::None`, it's expected that the
         // payload scalar will not actually have been set, so this converts
@@ -692,10 +741,22 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, Either<V, abi::Scalar>> {
         };
 
         let val = match val {
-            OperandValue::ZeroSized => OperandValue::ZeroSized,
-            OperandValue::Immediate(v) => OperandValue::Immediate(unwrap(v)),
-            OperandValue::Pair(a, b) => OperandValue::Pair(unwrap(a), unwrap(b)),
-            OperandValue::Ref(_) => bug!(),
+            OperandValueBuilder::ZeroSized => OperandValue::ZeroSized,
+            OperandValueBuilder::Immediate(v) => OperandValue::Immediate(unwrap(v)),
+            OperandValueBuilder::Pair(a, b) => OperandValue::Pair(unwrap(a), unwrap(b)),
+            OperandValueBuilder::Vector(v) => match v {
+                Either::Left(v) => OperandValue::Immediate(v),
+                Either::Right(())
+                    if let BackendRepr::SimdVector { element, .. } = layout.backend_repr
+                        && element.is_uninit_valid() =>
+                {
+                    let bty = cx.immediate_backend_type(layout);
+                    OperandValue::Immediate(cx.const_undef(bty))
+                }
+                Either::Right(()) => {
+                    bug!("OperandRef::build called while fields are missing {self:?}")
+                }
+            },
         };
         OperandRef { val, layout }
     }
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 4af4e1e6a61..cbbb0196890 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -4,10 +4,9 @@ use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use rustc_middle::{bug, mir};
 use rustc_session::config::OptLevel;
-use rustc_span::{DUMMY_SP, Span};
 use tracing::{debug, instrument};
 
-use super::operand::{OperandRef, OperandValue};
+use super::operand::{OperandRef, OperandRefBuilder, OperandValue};
 use super::place::{PlaceRef, codegen_tag_value};
 use super::{FunctionCx, LocalRef};
 use crate::common::{IntPredicate, TypeKind};
@@ -181,7 +180,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
 
             _ => {
-                assert!(self.rvalue_creates_operand(rvalue, DUMMY_SP));
+                assert!(self.rvalue_creates_operand(rvalue));
                 let temp = self.codegen_rvalue_operand(bx, rvalue);
                 temp.val.store(bx, dest);
             }
@@ -354,10 +353,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         bx: &mut Bx,
         rvalue: &mir::Rvalue<'tcx>,
     ) -> OperandRef<'tcx, Bx::Value> {
-        assert!(
-            self.rvalue_creates_operand(rvalue, DUMMY_SP),
-            "cannot codegen {rvalue:?} to operand",
-        );
+        assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {rvalue:?} to operand",);
 
         match *rvalue {
             mir::Rvalue::Cast(ref kind, ref source, mir_cast_ty) => {
@@ -668,9 +664,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
                 // `rvalue_creates_operand` has arranged that we only get here if
                 // we can build the aggregate immediate from the field immediates.
-                let Some(mut builder) = OperandRef::builder(layout) else {
-                    bug!("Cannot use type in operand builder: {layout:?}")
-                };
+                let mut builder = OperandRefBuilder::new(layout);
                 for (field_idx, field) in fields.iter_enumerated() {
                     let op = self.codegen_operand(bx, field);
                     let fi = active_field_index.unwrap_or(field_idx);
@@ -980,7 +974,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     /// will not actually take the operand path because the result type is such
     /// that it always gets an `alloca`, but where it's not worth re-checking the
     /// layout in this code when the right thing will happen anyway.
-    pub(crate) fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool {
+    pub(crate) fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>) -> bool {
         match *rvalue {
             mir::Rvalue::Cast(mir::CastKind::Transmute, ref operand, cast_ty) => {
                 let operand_ty = operand.ty(self.mir, self.cx.tcx());
@@ -1025,18 +1019,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::Rvalue::NullaryOp(..) |
             mir::Rvalue::ThreadLocalRef(_) |
             mir::Rvalue::Use(..) |
+            mir::Rvalue::Aggregate(..) | // (*)
             mir::Rvalue::WrapUnsafeBinder(..) => // (*)
                 true,
             // Arrays are always aggregates, so it's not worth checking anything here.
             // (If it's really `[(); N]` or `[T; 0]` and we use the place path, fine.)
             mir::Rvalue::Repeat(..) => false,
-            mir::Rvalue::Aggregate(..) => {
-                    let ty = rvalue.ty(self.mir, self.cx.tcx());
-                    let ty = self.monomorphize(ty);
-                    let layout = self.cx.spanned_layout_of(ty, span);
-                    OperandRef::<Bx::Value>::builder(layout).is_some()
-                }
-            }
+        }
 
         // (*) this is only true if the type is suitable
     }
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 22a1894ee72..b767ca9a3c2 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -78,6 +78,8 @@ const_eval_dealloc_kind_mismatch =
 
 const_eval_deref_function_pointer =
     accessing {$allocation} which contains a function
+const_eval_deref_typeid_pointer =
+    accessing {$allocation} which contains a `TypeId`
 const_eval_deref_vtable_pointer =
     accessing {$allocation} which contains a vtable
 const_eval_division_by_zero =
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 9133a5fc8ef..49cd7138748 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -475,6 +475,7 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
             WriteToReadOnly(_) => const_eval_write_to_read_only,
             DerefFunctionPointer(_) => const_eval_deref_function_pointer,
             DerefVTablePointer(_) => const_eval_deref_vtable_pointer,
+            DerefTypeIdPointer(_) => const_eval_deref_typeid_pointer,
             InvalidBool(_) => const_eval_invalid_bool,
             InvalidChar(_) => const_eval_invalid_char,
             InvalidTag(_) => const_eval_invalid_tag,
@@ -588,7 +589,10 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
                 diag.arg("has", has.bytes());
                 diag.arg("msg", format!("{msg:?}"));
             }
-            WriteToReadOnly(alloc) | DerefFunctionPointer(alloc) | DerefVTablePointer(alloc) => {
+            WriteToReadOnly(alloc)
+            | DerefFunctionPointer(alloc)
+            | DerefVTablePointer(alloc)
+            | DerefTypeIdPointer(alloc) => {
                 diag.arg("allocation", alloc);
             }
             InvalidBool(b) => {
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 068d6369f87..41fc8d47cd3 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -96,7 +96,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     /// This inherent method takes priority over the trait method with the same name in LayoutOf,
     /// and allows wrapping the actual [LayoutOf::layout_of] with a tracing span.
     /// See [LayoutOf::layout_of] for the original documentation.
-    #[inline]
+    #[inline(always)]
     pub fn layout_of(
         &self,
         ty: Ty<'tcx>,
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 378ed6d0e10..1eba1f2f03c 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -4,7 +4,7 @@
 
 use std::assert_matches::assert_matches;
 
-use rustc_abi::Size;
+use rustc_abi::{FieldIdx, Size};
 use rustc_apfloat::ieee::{Double, Half, Quad, Single};
 use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
 use rustc_middle::ty::layout::TyAndLayout;
@@ -28,8 +28,35 @@ pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAll
     let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes(), ());
     tcx.mk_const_alloc(alloc)
 }
-
 impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
+    /// Generates a value of `TypeId` for `ty` in-place.
+    pub(crate) fn write_type_id(
+        &mut self,
+        ty: Ty<'tcx>,
+        dest: &PlaceTy<'tcx, M::Provenance>,
+    ) -> InterpResult<'tcx, ()> {
+        let tcx = self.tcx;
+        let type_id_hash = tcx.type_id_hash(ty).as_u128();
+        let op = self.const_val_to_op(
+            ConstValue::Scalar(Scalar::from_u128(type_id_hash)),
+            tcx.types.u128,
+            None,
+        )?;
+        self.copy_op_allow_transmute(&op, dest)?;
+
+        // Give the first pointer-size bytes provenance that knows about the type id.
+        // Here we rely on `TypeId` being a newtype around an array of pointers, so we
+        // first project to its only field and then the first array element.
+        let alloc_id = tcx.reserve_and_set_type_id_alloc(ty);
+        let first = self.project_field(dest, FieldIdx::ZERO)?;
+        let first = self.project_index(&first, 0)?;
+        let offset = self.read_scalar(&first)?.to_target_usize(&tcx)?;
+        let ptr = Pointer::new(alloc_id.into(), Size::from_bytes(offset));
+        let ptr = self.global_root_pointer(ptr)?;
+        let val = Scalar::from_pointer(ptr, &tcx);
+        self.write_scalar(val, &first)
+    }
+
     /// Returns `true` if emulation happened.
     /// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
     /// intrinsic handling.
@@ -63,9 +90,48 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             sym::type_id => {
                 let tp_ty = instance.args.type_at(0);
                 ensure_monomorphic_enough(tcx, tp_ty)?;
-                let val = ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128());
-                let val = self.const_val_to_op(val, dest.layout.ty, Some(dest.layout))?;
-                self.copy_op(&val, dest)?;
+                self.write_type_id(tp_ty, dest)?;
+            }
+            sym::type_id_eq => {
+                // Both operands are `TypeId`, which is a newtype around an array of pointers.
+                // Project until we have the array elements.
+                let a_fields = self.project_field(&args[0], FieldIdx::ZERO)?;
+                let b_fields = self.project_field(&args[1], FieldIdx::ZERO)?;
+
+                let mut a_fields = self.project_array_fields(&a_fields)?;
+                let mut b_fields = self.project_array_fields(&b_fields)?;
+
+                let (_idx, a) = a_fields
+                    .next(self)?
+                    .expect("we know the layout of TypeId has at least 2 array elements");
+                let a = self.deref_pointer(&a)?;
+                let (a, offset_a) = self.get_ptr_type_id(a.ptr())?;
+
+                let (_idx, b) = b_fields
+                    .next(self)?
+                    .expect("we know the layout of TypeId has at least 2 array elements");
+                let b = self.deref_pointer(&b)?;
+                let (b, offset_b) = self.get_ptr_type_id(b.ptr())?;
+
+                let provenance_matches = a == b;
+
+                let mut eq_id = offset_a == offset_b;
+
+                while let Some((_, a)) = a_fields.next(self)? {
+                    let (_, b) = b_fields.next(self)?.unwrap();
+
+                    let a = self.read_target_usize(&a)?;
+                    let b = self.read_target_usize(&b)?;
+                    eq_id &= a == b;
+                }
+
+                if !eq_id && provenance_matches {
+                    throw_ub_format!(
+                        "type_id_eq: one of the TypeId arguments is invalid, the hash does not match the type it represents"
+                    )
+                }
+
+                self.write_scalar(Scalar::from_bool(provenance_matches), dest)?;
             }
             sym::variant_count => {
                 let tp_ty = instance.args.type_at(0);
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 844c19fea2d..d150ed69250 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -18,8 +18,8 @@ use rustc_target::callconv::FnAbi;
 
 use super::{
     AllocBytes, AllocId, AllocKind, AllocRange, Allocation, CTFE_ALLOC_SALT, ConstAllocation,
-    CtfeProvenance, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, MemoryKind,
-    Misalignment, OpTy, PlaceTy, Pointer, Provenance, RangeSet, interp_ok, throw_unsup,
+    CtfeProvenance, EnteredTraceSpan, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy,
+    MemoryKind, Misalignment, OpTy, PlaceTy, Pointer, Provenance, RangeSet, interp_ok, throw_unsup,
 };
 
 /// Data returned by [`Machine::after_stack_pop`], and consumed by
@@ -147,12 +147,6 @@ pub trait Machine<'tcx>: Sized {
     /// already been checked before.
     const ALL_CONSTS_ARE_PRECHECKED: bool = true;
 
-    /// Determines whether rustc_const_eval functions that make use of the [Machine] should make
-    /// tracing calls (to the `tracing` library). By default this is `false`, meaning the tracing
-    /// calls will supposedly be optimized out. This flag is set to `true` inside Miri, to allow
-    /// tracing the interpretation steps, among other things.
-    const TRACING_ENABLED: bool = false;
-
     /// Whether memory accesses should be alignment-checked.
     fn enforce_alignment(ecx: &InterpCx<'tcx, Self>) -> bool;
 
@@ -634,6 +628,17 @@ pub trait Machine<'tcx>: Sized {
     /// Compute the value passed to the constructors of the `AllocBytes` type for
     /// abstract machine allocations.
     fn get_default_alloc_params(&self) -> <Self::Bytes as AllocBytes>::AllocParams;
+
+    /// Allows enabling/disabling tracing calls from within `rustc_const_eval` at compile time, by
+    /// delegating the entering of [tracing::Span]s to implementors of the [Machine] trait. The
+    /// default implementation corresponds to tracing being disabled, meaning the tracing calls will
+    /// supposedly be optimized out completely. To enable tracing, override this trait method and
+    /// return `span.entered()`. Also see [crate::enter_trace_span].
+    #[must_use]
+    #[inline(always)]
+    fn enter_trace_span(_span: impl FnOnce() -> tracing::Span) -> impl EnteredTraceSpan {
+        ()
+    }
 }
 
 /// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 524023b8104..bb301600135 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -15,9 +15,9 @@ use std::{fmt, ptr};
 use rustc_abi::{Align, HasDataLayout, Size};
 use rustc_ast::Mutability;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
-use rustc_middle::bug;
 use rustc_middle::mir::display_allocation;
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
+use rustc_middle::{bug, throw_ub_format};
 use tracing::{debug, instrument, trace};
 
 use super::{
@@ -346,6 +346,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                         kind = "vtable",
                     )
                 }
+                Some(GlobalAlloc::TypeId { .. }) => {
+                    err_ub_custom!(
+                        fluent::const_eval_invalid_dealloc,
+                        alloc_id = alloc_id,
+                        kind = "typeid",
+                    )
+                }
                 Some(GlobalAlloc::Static(..) | GlobalAlloc::Memory(..)) => {
                     err_ub_custom!(
                         fluent::const_eval_invalid_dealloc,
@@ -615,6 +622,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             }
             Some(GlobalAlloc::Function { .. }) => throw_ub!(DerefFunctionPointer(id)),
             Some(GlobalAlloc::VTable(..)) => throw_ub!(DerefVTablePointer(id)),
+            Some(GlobalAlloc::TypeId { .. }) => throw_ub!(DerefTypeIdPointer(id)),
             None => throw_ub!(PointerUseAfterFree(id, CheckInAllocMsg::MemoryAccess)),
             Some(GlobalAlloc::Static(def_id)) => {
                 assert!(self.tcx.is_static(def_id));
@@ -896,7 +904,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env);
             let mutbl = global_alloc.mutability(*self.tcx, self.typing_env);
             let kind = match global_alloc {
-                GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData,
+                GlobalAlloc::TypeId { .. }
+                | GlobalAlloc::Static { .. }
+                | GlobalAlloc::Memory { .. } => AllocKind::LiveData,
                 GlobalAlloc::Function { .. } => bug!("We already checked function pointers above"),
                 GlobalAlloc::VTable { .. } => AllocKind::VTable,
             };
@@ -936,6 +946,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         }
     }
 
+    /// Takes a pointer that is the first chunk of a `TypeId` and return the type that its
+    /// provenance refers to, as well as the segment of the hash that this pointer covers.
+    pub fn get_ptr_type_id(
+        &self,
+        ptr: Pointer<Option<M::Provenance>>,
+    ) -> InterpResult<'tcx, (Ty<'tcx>, Size)> {
+        let (alloc_id, offset, _meta) = self.ptr_get_alloc_id(ptr, 0)?;
+        let GlobalAlloc::TypeId { ty } = self.tcx.global_alloc(alloc_id) else {
+            throw_ub_format!("type_id_eq: `TypeId` provenance is not a type id")
+        };
+        interp_ok((ty, offset))
+    }
+
     pub fn get_ptr_fn(
         &self,
         ptr: Pointer<Option<M::Provenance>>,
@@ -1197,6 +1220,9 @@ impl<'a, 'tcx, M: Machine<'tcx>> std::fmt::Debug for DumpAllocs<'a, 'tcx, M> {
                         Some(GlobalAlloc::VTable(ty, dyn_ty)) => {
                             write!(fmt, " (vtable: impl {dyn_ty} for {ty})")?;
                         }
+                        Some(GlobalAlloc::TypeId { ty }) => {
+                            write!(fmt, " (typeid for {ty})")?;
+                        }
                         Some(GlobalAlloc::Static(did)) => {
                             write!(fmt, " (static: {})", self.ecx.tcx.def_path_str(did))?;
                         }
diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs
index 8303f891f98..2fc372dd019 100644
--- a/compiler/rustc_const_eval/src/interpret/mod.rs
+++ b/compiler/rustc_const_eval/src/interpret/mod.rs
@@ -37,6 +37,7 @@ pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable};
 use self::place::{MemPlace, Place};
 pub use self::projection::{OffsetMode, Projectable};
 pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation, StackPopInfo};
+pub use self::util::EnteredTraceSpan;
 pub(crate) use self::util::create_static_alloc;
 pub use self::validity::{CtfeValidationMode, RangeSet, RefTracking};
 pub use self::visitor::ValueVisitor;
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index 306697d4ec9..f72c4418081 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -296,7 +296,11 @@ where
         base: &'a P,
     ) -> InterpResult<'tcx, ArrayIterator<'a, 'tcx, M::Provenance, P>> {
         let abi::FieldsShape::Array { stride, .. } = base.layout().fields else {
-            span_bug!(self.cur_span(), "project_array_fields: expected an array layout");
+            span_bug!(
+                self.cur_span(),
+                "project_array_fields: expected an array layout, got {:#?}",
+                base.layout()
+            );
         };
         let len = base.len(self)?;
         let field_layout = base.layout().field(self, 0);
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index 99add01f95c..72650d545c3 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -46,21 +46,20 @@ pub(crate) fn create_static_alloc<'tcx>(
     interp_ok(ecx.ptr_to_mplace(Pointer::from(alloc_id).into(), layout))
 }
 
-/// This struct is needed to enforce `#[must_use]` on [tracing::span::EnteredSpan]
-/// while wrapping them in an `Option`.
-#[must_use]
-pub enum MaybeEnteredSpan {
-    Some(tracing::span::EnteredSpan),
-    None,
-}
+/// A marker trait returned by [crate::interpret::Machine::enter_trace_span], identifying either a
+/// real [tracing::span::EnteredSpan] in case tracing is enabled, or the dummy type `()` when
+/// tracing is disabled.
+pub trait EnteredTraceSpan {}
+impl EnteredTraceSpan for () {}
+impl EnteredTraceSpan for tracing::span::EnteredSpan {}
 
+/// Shortand for calling [crate::interpret::Machine::enter_trace_span] on a [tracing::info_span].
+/// This is supposed to be compiled out when [crate::interpret::Machine::enter_trace_span] has the
+/// default implementation (i.e. when it does not actually enter the span but instead returns `()`).
+/// Note: the result of this macro **must be used** because the span is exited when it's dropped.
 #[macro_export]
 macro_rules! enter_trace_span {
     ($machine:ident, $($tt:tt)*) => {
-        if $machine::TRACING_ENABLED {
-            $crate::interpret::util::MaybeEnteredSpan::Some(tracing::info_span!($($tt)*).entered())
-        } else {
-            $crate::interpret::util::MaybeEnteredSpan::None
-        }
+        $machine::enter_trace_span(|| tracing::info_span!($($tt)*))
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index fc4d13af8c4..fc44490c96d 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -571,40 +571,42 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
                     let alloc_actual_mutbl =
                         global_alloc.mutability(*self.ecx.tcx, self.ecx.typing_env);
 
-                    if let GlobalAlloc::Static(did) = global_alloc {
-                        let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else {
-                            bug!()
-                        };
-                        // Special handling for pointers to statics (irrespective of their type).
-                        assert!(!self.ecx.tcx.is_thread_local_static(did));
-                        assert!(self.ecx.tcx.is_static(did));
-                        // Mode-specific checks
-                        match ctfe_mode {
-                            CtfeValidationMode::Static { .. }
-                            | CtfeValidationMode::Promoted { .. } => {
-                                // We skip recursively checking other statics. These statics must be sound by
-                                // themselves, and the only way to get broken statics here is by using
-                                // unsafe code.
-                                // The reasons we don't check other statics is twofold. For one, in all
-                                // sound cases, the static was already validated on its own, and second, we
-                                // trigger cycle errors if we try to compute the value of the other static
-                                // and that static refers back to us (potentially through a promoted).
-                                // This could miss some UB, but that's fine.
-                                // We still walk nested allocations, as they are fundamentally part of this validation run.
-                                // This means we will also recurse into nested statics of *other*
-                                // statics, even though we do not recurse into other statics directly.
-                                // That's somewhat inconsistent but harmless.
-                                skip_recursive_check = !nested;
-                            }
-                            CtfeValidationMode::Const { .. } => {
-                                // If this is mutable memory or an `extern static`, there's no point in checking it -- we'd
-                                // just get errors trying to read the value.
-                                if alloc_actual_mutbl.is_mut() || self.ecx.tcx.is_foreign_item(did)
-                                {
-                                    skip_recursive_check = true;
+                    match global_alloc {
+                        GlobalAlloc::Static(did) => {
+                            let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else {
+                                bug!()
+                            };
+                            assert!(!self.ecx.tcx.is_thread_local_static(did));
+                            assert!(self.ecx.tcx.is_static(did));
+                            match ctfe_mode {
+                                CtfeValidationMode::Static { .. }
+                                | CtfeValidationMode::Promoted { .. } => {
+                                    // We skip recursively checking other statics. These statics must be sound by
+                                    // themselves, and the only way to get broken statics here is by using
+                                    // unsafe code.
+                                    // The reasons we don't check other statics is twofold. For one, in all
+                                    // sound cases, the static was already validated on its own, and second, we
+                                    // trigger cycle errors if we try to compute the value of the other static
+                                    // and that static refers back to us (potentially through a promoted).
+                                    // This could miss some UB, but that's fine.
+                                    // We still walk nested allocations, as they are fundamentally part of this validation run.
+                                    // This means we will also recurse into nested statics of *other*
+                                    // statics, even though we do not recurse into other statics directly.
+                                    // That's somewhat inconsistent but harmless.
+                                    skip_recursive_check = !nested;
+                                }
+                                CtfeValidationMode::Const { .. } => {
+                                    // If this is mutable memory or an `extern static`, there's no point in checking it -- we'd
+                                    // just get errors trying to read the value.
+                                    if alloc_actual_mutbl.is_mut()
+                                        || self.ecx.tcx.is_foreign_item(did)
+                                    {
+                                        skip_recursive_check = true;
+                                    }
                                 }
                             }
                         }
+                        _ => (),
                     }
 
                     // If this allocation has size zero, there is no actual mutability here.
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 2f398cea926..510f37f37e2 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -3526,7 +3526,7 @@ pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
     // All the chars that differ in capitalization are confusable (above):
     let confusable = iter::zip(found.chars(), suggested.chars())
         .filter(|(f, s)| f != s)
-        .all(|(f, s)| (ascii_confusables.contains(&f) || ascii_confusables.contains(&s)));
+        .all(|(f, s)| ascii_confusables.contains(&f) || ascii_confusables.contains(&s));
     confusable && found.to_lowercase() == suggested.to_lowercase()
             // FIXME: We sometimes suggest the same thing we already have, which is a
             //        bug, but be defensive against that here.
diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl
index 3fc0fa06191..89d6e62834d 100644
--- a/compiler/rustc_expand/messages.ftl
+++ b/compiler/rustc_expand/messages.ftl
@@ -133,6 +133,32 @@ expand_module_multiple_candidates =
 expand_must_repeat_once =
     this must repeat at least once
 
+expand_mve_extra_tokens =
+    unexpected trailing tokens
+    .label = for this metavariable expression
+    .range = the `{$name}` metavariable expression takes between {$min_or_exact_args} and {$max_args} arguments
+    .exact = the `{$name}` metavariable expression takes {$min_or_exact_args ->
+        [zero] no arguments
+        [one] a single argument
+        *[other] {$min_or_exact_args} arguments
+    }
+    .suggestion = try removing {$extra_count ->
+        [one] this token
+        *[other] these tokens
+    }
+
+expand_mve_missing_paren =
+    expected `(`
+    .label = for this this metavariable expression
+    .unexpected = unexpected token
+    .note = metavariable expressions use function-like parentheses syntax
+    .suggestion = try adding parentheses
+
+expand_mve_unrecognized_expr =
+    unrecognized metavariable expression
+    .label = not a valid metavariable expression
+    .note = valid metavariable expressions are {$valid_expr_list}
+
 expand_mve_unrecognized_var =
     variable `{$key}` is not recognized in meta-variable expression
 
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index fdbc65aff68..3ac5d213053 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -496,6 +496,50 @@ pub(crate) use metavar_exprs::*;
 mod metavar_exprs {
     use super::*;
 
+    #[derive(Diagnostic, Default)]
+    #[diag(expand_mve_extra_tokens)]
+    pub(crate) struct MveExtraTokens {
+        #[primary_span]
+        #[suggestion(code = "", applicability = "machine-applicable")]
+        pub span: Span,
+        #[label]
+        pub ident_span: Span,
+        pub extra_count: usize,
+
+        // The rest is only used for specific diagnostics and can be default if neither
+        // `note` is `Some`.
+        #[note(expand_exact)]
+        pub exact_args_note: Option<()>,
+        #[note(expand_range)]
+        pub range_args_note: Option<()>,
+        pub min_or_exact_args: usize,
+        pub max_args: usize,
+        pub name: String,
+    }
+
+    #[derive(Diagnostic)]
+    #[note]
+    #[diag(expand_mve_missing_paren)]
+    pub(crate) struct MveMissingParen {
+        #[primary_span]
+        #[label]
+        pub ident_span: Span,
+        #[label(expand_unexpected)]
+        pub unexpected_span: Option<Span>,
+        #[suggestion(code = "( /* ... */ )", applicability = "has-placeholders")]
+        pub insert_span: Option<Span>,
+    }
+
+    #[derive(Diagnostic)]
+    #[note]
+    #[diag(expand_mve_unrecognized_expr)]
+    pub(crate) struct MveUnrecognizedExpr {
+        #[primary_span]
+        #[label]
+        pub span: Span,
+        pub valid_expr_list: &'static str,
+    }
+
     #[derive(Diagnostic)]
     #[diag(expand_mve_unrecognized_var)]
     pub(crate) struct MveUnrecognizedVar {
diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs
index ffd3548019a..d2b275ad20a 100644
--- a/compiler/rustc_expand/src/mbe/metavar_expr.rs
+++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs
@@ -7,6 +7,8 @@ use rustc_macros::{Decodable, Encodable};
 use rustc_session::parse::ParseSess;
 use rustc_span::{Ident, Span, Symbol};
 
+use crate::errors;
+
 pub(crate) const RAW_IDENT_ERR: &str = "`${concat(..)}` currently does not support raw identifiers";
 pub(crate) const UNSUPPORTED_CONCAT_ELEM_ERR: &str = "expected identifier or string literal";
 
@@ -40,11 +42,32 @@ impl MetaVarExpr {
     ) -> PResult<'psess, MetaVarExpr> {
         let mut iter = input.iter();
         let ident = parse_ident(&mut iter, psess, outer_span)?;
-        let Some(TokenTree::Delimited(.., Delimiter::Parenthesis, args)) = iter.next() else {
-            let msg = "meta-variable expression parameter must be wrapped in parentheses";
-            return Err(psess.dcx().struct_span_err(ident.span, msg));
+        let next = iter.next();
+        let Some(TokenTree::Delimited(.., Delimiter::Parenthesis, args)) = next else {
+            // No `()`; wrong or no delimiters. Point at a problematic span or a place to
+            // add parens if it makes sense.
+            let (unexpected_span, insert_span) = match next {
+                Some(TokenTree::Delimited(..)) => (None, None),
+                Some(tt) => (Some(tt.span()), None),
+                None => (None, Some(ident.span.shrink_to_hi())),
+            };
+            let err =
+                errors::MveMissingParen { ident_span: ident.span, unexpected_span, insert_span };
+            return Err(psess.dcx().create_err(err));
         };
-        check_trailing_token(&mut iter, psess)?;
+
+        // Ensure there are no trailing tokens in the braces, e.g. `${foo() extra}`
+        if iter.peek().is_some() {
+            let span = iter_span(&iter).expect("checked is_some above");
+            let err = errors::MveExtraTokens {
+                span,
+                ident_span: ident.span,
+                extra_count: iter.count(),
+                ..Default::default()
+            };
+            return Err(psess.dcx().create_err(err));
+        }
+
         let mut iter = args.iter();
         let rslt = match ident.as_str() {
             "concat" => parse_concat(&mut iter, psess, outer_span, ident.span)?,
@@ -56,18 +79,14 @@ impl MetaVarExpr {
             "index" => MetaVarExpr::Index(parse_depth(&mut iter, psess, ident.span)?),
             "len" => MetaVarExpr::Len(parse_depth(&mut iter, psess, ident.span)?),
             _ => {
-                let err_msg = "unrecognized meta-variable expression";
-                let mut err = psess.dcx().struct_span_err(ident.span, err_msg);
-                err.span_suggestion(
-                    ident.span,
-                    "supported expressions are count, ignore, index and len",
-                    "",
-                    Applicability::MachineApplicable,
-                );
-                return Err(err);
+                let err = errors::MveUnrecognizedExpr {
+                    span: ident.span,
+                    valid_expr_list: "`count`, `ignore`, `index`, `len`, and `concat`",
+                };
+                return Err(psess.dcx().create_err(err));
             }
         };
-        check_trailing_token(&mut iter, psess)?;
+        check_trailing_tokens(&mut iter, psess, ident)?;
         Ok(rslt)
     }
 
@@ -87,20 +106,51 @@ impl MetaVarExpr {
     }
 }
 
-// Checks if there are any remaining tokens. For example, `${ignore(ident ... a b c ...)}`
-fn check_trailing_token<'psess>(
+/// Checks if there are any remaining tokens (for example, `${ignore($valid, extra)}`) and create
+/// a diag with the correct arg count if so.
+fn check_trailing_tokens<'psess>(
     iter: &mut TokenStreamIter<'_>,
     psess: &'psess ParseSess,
+    ident: Ident,
 ) -> PResult<'psess, ()> {
-    if let Some(tt) = iter.next() {
-        let mut diag = psess
-            .dcx()
-            .struct_span_err(tt.span(), format!("unexpected token: {}", pprust::tt_to_string(tt)));
-        diag.span_note(tt.span(), "meta-variable expression must not have trailing tokens");
-        Err(diag)
-    } else {
-        Ok(())
+    if iter.peek().is_none() {
+        // All tokens consumed, as expected
+        return Ok(());
     }
+
+    // `None` for max indicates the arg count must be exact, `Some` indicates a range is accepted.
+    let (min_or_exact_args, max_args) = match ident.as_str() {
+        "concat" => panic!("concat takes unlimited tokens but didn't eat them all"),
+        "ignore" => (1, None),
+        // 1 or 2 args
+        "count" => (1, Some(2)),
+        // 0 or 1 arg
+        "index" => (0, Some(1)),
+        "len" => (0, Some(1)),
+        other => unreachable!("unknown MVEs should be rejected earlier (got `{other}`)"),
+    };
+
+    let err = errors::MveExtraTokens {
+        span: iter_span(iter).expect("checked is_none above"),
+        ident_span: ident.span,
+        extra_count: iter.count(),
+
+        exact_args_note: if max_args.is_some() { None } else { Some(()) },
+        range_args_note: if max_args.is_some() { Some(()) } else { None },
+        min_or_exact_args,
+        max_args: max_args.unwrap_or_default(),
+        name: ident.to_string(),
+    };
+    Err(psess.dcx().create_err(err))
+}
+
+/// Returns a span encompassing all tokens in the iterator if there is at least one item.
+fn iter_span(iter: &TokenStreamIter<'_>) -> Option<Span> {
+    let mut iter = iter.clone(); // cloning is cheap
+    let first_sp = iter.next()?.span();
+    let last_sp = iter.last().map(TokenTree::span).unwrap_or(first_sp);
+    let span = first_sp.with_hi(last_sp.hi());
+    Some(span)
 }
 
 /// Indicates what is placed in a `concat` parameter. For example, literals
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index c11db63ba11..6347f1bfa71 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -274,6 +274,8 @@ language_item_table! {
     PartialOrd,              sym::partial_ord,         partial_ord_trait,          Target::Trait,          GenericRequirement::Exact(1);
     CVoid,                   sym::c_void,              c_void,                     Target::Enum,           GenericRequirement::None;
 
+    TypeId,                  sym::type_id,             type_id,                    Target::Struct,         GenericRequirement::None;
+
     // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and
     // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays.
     //
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index cebf7d1b532..e3532ade32f 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -93,6 +93,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
         | sym::three_way_compare
         | sym::discriminant_value
         | sym::type_id
+        | sym::type_id_eq
         | sym::select_unpredictable
         | sym::cold_path
         | sym::ptr_guaranteed_cmp
@@ -220,7 +221,13 @@ pub(crate) fn check_intrinsic_type(
         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::type_id => {
+            (1, 0, vec![], tcx.type_of(tcx.lang_items().type_id().unwrap()).instantiate_identity())
+        }
+        sym::type_id_eq => {
+            let type_id = tcx.type_of(tcx.lang_items().type_id().unwrap()).instantiate_identity();
+            (0, 0, vec![type_id, type_id], tcx.types.bool)
+        }
         sym::offset => (2, 0, vec![param(0), param(1)], param(0)),
         sym::arith_offset => (
             1,
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index e41bc8f852e..fc9d795cb23 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -59,8 +59,7 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `overflowing_literals` lint detects literal out of range for its
-    /// type.
+    /// The `overflowing_literals` lint detects literals out of range for their type.
     ///
     /// ### Example
     ///
@@ -72,9 +71,9 @@ declare_lint! {
     ///
     /// ### Explanation
     ///
-    /// It is usually a mistake to use a literal that overflows the type where
-    /// it is used. Either use a literal that is within range, or change the
-    /// type to be within the range of the literal.
+    /// It is usually a mistake to use a literal that overflows its type
+    /// Change either the literal or its type such that the literal is
+    /// within the range of its type.
     OVERFLOWING_LITERALS,
     Deny,
     "literal out of range for its type"
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index d3942a1c816..a9eb1739f7f 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -1,7 +1,7 @@
 use std::iter;
 
 use rustc_ast::util::{classify, parser};
-use rustc_ast::{self as ast, ExprKind, HasAttrs as _, StmtKind};
+use rustc_ast::{self as ast, ExprKind, FnRetTy, HasAttrs as _, StmtKind};
 use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{MultiSpan, pluralize};
@@ -599,6 +599,7 @@ enum UnusedDelimsCtx {
     AnonConst,
     MatchArmExpr,
     IndexExpr,
+    ClosureBody,
 }
 
 impl From<UnusedDelimsCtx> for &'static str {
@@ -620,6 +621,7 @@ impl From<UnusedDelimsCtx> for &'static str {
             UnusedDelimsCtx::ArrayLenExpr | UnusedDelimsCtx::AnonConst => "const expression",
             UnusedDelimsCtx::MatchArmExpr => "match arm expression",
             UnusedDelimsCtx::IndexExpr => "index expression",
+            UnusedDelimsCtx::ClosureBody => "closure body",
         }
     }
 }
@@ -919,6 +921,11 @@ trait UnusedDelimLint {
                 let (args_to_check, ctx) = match *call_or_other {
                     Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg),
                     MethodCall(ref call) => (&call.args[..], UnusedDelimsCtx::MethodArg),
+                    Closure(ref closure)
+                        if matches!(closure.fn_decl.output, FnRetTy::Default(_)) =>
+                    {
+                        (&[closure.body.clone()][..], UnusedDelimsCtx::ClosureBody)
+                    }
                     // actual catch-all arm
                     _ => {
                         return;
@@ -1508,6 +1515,7 @@ impl UnusedDelimLint for UnusedBraces {
                             && (ctx != UnusedDelimsCtx::AnonConst
                                 || (matches!(expr.kind, ast::ExprKind::Lit(_))
                                     && !expr.span.from_expansion()))
+                            && ctx != UnusedDelimsCtx::ClosureBody
                             && !cx.sess().source_map().is_multiline(value.span)
                             && value.attrs.is_empty()
                             && !value.span.from_expansion()
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index b37548b281c..15f0bad226d 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4343,11 +4343,12 @@ declare_lint! {
     ///
     /// [future-incompatible]: ../index.md#future-incompatible-lints
     pub AMBIGUOUS_GLOB_IMPORTS,
-    Warn,
+    Deny,
     "detects certain glob imports that require reporting an ambiguity error",
     @future_incompatible = FutureIncompatibleInfo {
         reason: FutureIncompatibilityReason::FutureReleaseError,
         reference: "issue #114095 <https://github.com/rust-lang/rust/issues/114095>",
+        report_in_deps: true,
     };
 }
 
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 8acb8fa9f80..71e0c943fbb 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -392,6 +392,8 @@ pub enum UndefinedBehaviorInfo<'tcx> {
     DerefFunctionPointer(AllocId),
     /// Trying to access the data behind a vtable pointer.
     DerefVTablePointer(AllocId),
+    /// Trying to access the actual type id.
+    DerefTypeIdPointer(AllocId),
     /// Using a non-boolean `u8` as bool.
     InvalidBool(u8),
     /// Using a non-character `u32` as character.
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 0b2645013ba..bed99a4ff2a 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -103,6 +103,7 @@ enum AllocDiscriminant {
     Fn,
     VTable,
     Static,
+    Type,
 }
 
 pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder<'tcx>>(
@@ -127,6 +128,11 @@ pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder<'tcx>>(
             ty.encode(encoder);
             poly_trait_ref.encode(encoder);
         }
+        GlobalAlloc::TypeId { ty } => {
+            trace!("encoding {alloc_id:?} with {ty:#?}");
+            AllocDiscriminant::Type.encode(encoder);
+            ty.encode(encoder);
+        }
         GlobalAlloc::Static(did) => {
             assert!(!tcx.is_thread_local_static(did));
             // References to statics doesn't need to know about their allocations,
@@ -228,6 +234,12 @@ impl<'s> AllocDecodingSession<'s> {
                 trace!("decoded vtable alloc instance: {ty:?}, {poly_trait_ref:?}");
                 decoder.interner().reserve_and_set_vtable_alloc(ty, poly_trait_ref, CTFE_ALLOC_SALT)
             }
+            AllocDiscriminant::Type => {
+                trace!("creating typeid alloc ID");
+                let ty = Decodable::decode(decoder);
+                trace!("decoded typid: {ty:?}");
+                decoder.interner().reserve_and_set_type_id_alloc(ty)
+            }
             AllocDiscriminant::Static => {
                 trace!("creating extern static alloc ID");
                 let did = <DefId as Decodable<D>>::decode(decoder);
@@ -258,6 +270,9 @@ pub enum GlobalAlloc<'tcx> {
     Static(DefId),
     /// The alloc ID points to memory.
     Memory(ConstAllocation<'tcx>),
+    /// The first pointer-sized segment of a type id. On 64 bit systems, the 128 bit type id
+    /// is split into two segments, on 32 bit systems there are 4 segments, and so on.
+    TypeId { ty: Ty<'tcx> },
 }
 
 impl<'tcx> GlobalAlloc<'tcx> {
@@ -296,9 +311,10 @@ impl<'tcx> GlobalAlloc<'tcx> {
     pub fn address_space(&self, cx: &impl HasDataLayout) -> AddressSpace {
         match self {
             GlobalAlloc::Function { .. } => cx.data_layout().instruction_address_space,
-            GlobalAlloc::Static(..) | GlobalAlloc::Memory(..) | GlobalAlloc::VTable(..) => {
-                AddressSpace::ZERO
-            }
+            GlobalAlloc::TypeId { .. }
+            | GlobalAlloc::Static(..)
+            | GlobalAlloc::Memory(..)
+            | GlobalAlloc::VTable(..) => AddressSpace::ZERO,
         }
     }
 
@@ -334,7 +350,7 @@ impl<'tcx> GlobalAlloc<'tcx> {
                 }
             }
             GlobalAlloc::Memory(alloc) => alloc.inner().mutability,
-            GlobalAlloc::Function { .. } | GlobalAlloc::VTable(..) => {
+            GlobalAlloc::TypeId { .. } | GlobalAlloc::Function { .. } | GlobalAlloc::VTable(..) => {
                 // These are immutable.
                 Mutability::Not
             }
@@ -380,8 +396,10 @@ impl<'tcx> GlobalAlloc<'tcx> {
             GlobalAlloc::Function { .. } => (Size::ZERO, Align::ONE),
             GlobalAlloc::VTable(..) => {
                 // No data to be accessed here. But vtables are pointer-aligned.
-                return (Size::ZERO, tcx.data_layout.pointer_align().abi);
+                (Size::ZERO, tcx.data_layout.pointer_align().abi)
             }
+            // Fake allocation, there's nothing to access here
+            GlobalAlloc::TypeId { .. } => (Size::ZERO, Align::ONE),
         }
     }
 }
@@ -487,6 +505,11 @@ impl<'tcx> TyCtxt<'tcx> {
         self.reserve_and_set_dedup(GlobalAlloc::VTable(ty, dyn_ty), salt)
     }
 
+    /// Generates an [AllocId] for a [core::any::TypeId]. Will get deduplicated.
+    pub fn reserve_and_set_type_id_alloc(self, ty: Ty<'tcx>) -> AllocId {
+        self.reserve_and_set_dedup(GlobalAlloc::TypeId { ty }, 0)
+    }
+
     /// Interns the `Allocation` and return a new `AllocId`, even if there's already an identical
     /// `Allocation` with a different `AllocId`.
     /// Statics with identical content will still point to the same `Allocation`, i.e.,
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index e9f3fb6ac8d..8e403dfddae 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1621,6 +1621,7 @@ pub fn write_allocations<'tcx>(
             Some(GlobalAlloc::VTable(ty, dyn_ty)) => {
                 write!(w, " (vtable: impl {dyn_ty} for {ty})")?
             }
+            Some(GlobalAlloc::TypeId { ty }) => write!(w, " (typeid for {ty})")?,
             Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => {
                 write!(w, " (static: {}", tcx.def_path_str(did))?;
                 if body.phase <= MirPhase::Runtime(RuntimePhase::PostCleanup)
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 4e078847815..7c48a4b0885 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1773,6 +1773,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                         }
                         Some(GlobalAlloc::Function { .. }) => p!("<function>"),
                         Some(GlobalAlloc::VTable(..)) => p!("<vtable>"),
+                        Some(GlobalAlloc::TypeId { .. }) => p!("<typeid>"),
                         None => p!("<dangling pointer>"),
                     }
                     return Ok(());
diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs
index 5a5456aedc2..12a56d7c5ea 100644
--- a/compiler/rustc_mir_build/src/builder/scope.rs
+++ b/compiler/rustc_mir_build/src/builder/scope.rs
@@ -927,6 +927,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             scrut_span: rustc_span::Span::default(),
             refutable: true,
             known_valid_scrutinee: true,
+            internal_state: Default::default(),
         };
 
         let valtree = match self.eval_unevaluated_mir_constant_to_valtree(constant) {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index b7b160c738d..a49bfc1b8f4 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -406,6 +406,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
             scrut_span,
             refutable,
             known_valid_scrutinee,
+            internal_state: Default::default(),
         }
     }
 
diff --git a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs
index 496a342cf4c..c9c7fddae5a 100644
--- a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs
+++ b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs
@@ -1,5 +1,6 @@
 use rustc_abi::VariantIdx;
 use rustc_middle::mir::{self, Body, Location, Terminator, TerminatorKind};
+use smallvec::SmallVec;
 use tracing::debug;
 
 use super::move_paths::{InitKind, LookupResult, MoveData, MovePathIndex};
@@ -155,15 +156,28 @@ where
     }
 }
 
-/// Calls `handle_inactive_variant` for each descendant move path of `enum_place` that contains a
-/// `Downcast` to a variant besides the `active_variant`.
-///
-/// NOTE: If there are no move paths corresponding to an inactive variant,
-/// `handle_inactive_variant` will not be called for that variant.
+/// Indicates which variants are inactive at a `SwitchInt` edge by listing their `VariantIdx`s or
+/// specifying the single active variant's `VariantIdx`.
+pub(crate) enum InactiveVariants {
+    Inactives(SmallVec<[VariantIdx; 4]>),
+    Active(VariantIdx),
+}
+
+impl InactiveVariants {
+    fn contains(&self, variant_idx: VariantIdx) -> bool {
+        match self {
+            InactiveVariants::Inactives(inactives) => inactives.contains(&variant_idx),
+            InactiveVariants::Active(active) => variant_idx != *active,
+        }
+    }
+}
+
+/// Calls `handle_inactive_variant` for each child move path of `enum_place` corresponding to an
+/// inactive variant at a particular `SwitchInt` edge.
 pub(crate) fn on_all_inactive_variants<'tcx>(
     move_data: &MoveData<'tcx>,
     enum_place: mir::Place<'tcx>,
-    active_variant: VariantIdx,
+    inactive_variants: &InactiveVariants,
     mut handle_inactive_variant: impl FnMut(MovePathIndex),
 ) {
     let LookupResult::Exact(enum_mpi) = move_data.rev_lookup.find(enum_place.as_ref()) else {
@@ -182,7 +196,7 @@ pub(crate) fn on_all_inactive_variants<'tcx>(
             unreachable!();
         };
 
-        if variant_idx != active_variant {
+        if inactive_variants.contains(variant_idx) {
             on_all_children_bits(move_data, variant_mpi, |mpi| handle_inactive_variant(mpi));
         }
     }
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index e955e38ad10..cb647476db8 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -112,12 +112,13 @@ impl Direction for Backward {
                     propagate(pred, &tmp);
                 }
 
-                mir::TerminatorKind::SwitchInt { targets: _, ref discr } => {
+                mir::TerminatorKind::SwitchInt { ref targets, ref discr } => {
                     if let Some(mut data) = analysis.get_switch_int_data(block, discr) {
                         let mut tmp = analysis.bottom_value(body);
                         for &value in &body.basic_blocks.switch_sources()[&(block, pred)] {
                             tmp.clone_from(exit_state);
-                            analysis.apply_switch_int_edge_effect(&mut data, &mut tmp, value);
+                            analysis
+                                .apply_switch_int_edge_effect(&mut data, &mut tmp, value, targets);
                             propagate(pred, &tmp);
                         }
                     } else {
@@ -290,20 +291,20 @@ impl Direction for Forward {
                     for (value, target) in targets.iter() {
                         tmp.clone_from(exit_state);
                         let value = SwitchTargetValue::Normal(value);
-                        analysis.apply_switch_int_edge_effect(&mut data, &mut tmp, value);
+                        analysis.apply_switch_int_edge_effect(&mut data, &mut tmp, value, targets);
                         propagate(target, &tmp);
                     }
 
                     // Once we get to the final, "otherwise" branch, there is no need to preserve
                     // `exit_state`, so pass it directly to `apply_switch_int_edge_effect` to save
                     // a clone of the dataflow state.
-                    let otherwise = targets.otherwise();
                     analysis.apply_switch_int_edge_effect(
                         &mut data,
                         exit_state,
                         SwitchTargetValue::Otherwise,
+                        targets,
                     );
-                    propagate(otherwise, exit_state);
+                    propagate(targets.otherwise(), exit_state);
                 } else {
                     for target in targets.all_targets() {
                         propagate(*target, exit_state);
diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs
index 9cadec100b5..b6a56036019 100644
--- a/compiler/rustc_mir_dataflow/src/framework/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs
@@ -224,6 +224,7 @@ pub trait Analysis<'tcx> {
         _data: &mut Self::SwitchIntData,
         _state: &mut Self::Domain,
         _value: SwitchTargetValue,
+        _targets: &mir::SwitchTargets,
     ) {
         unreachable!();
     }
diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
index 18165b0b9bd..085757f0fb6 100644
--- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
@@ -9,9 +9,10 @@ use rustc_middle::mir::{
 };
 use rustc_middle::ty::util::Discr;
 use rustc_middle::ty::{self, TyCtxt};
+use smallvec::SmallVec;
 use tracing::{debug, instrument};
 
-use crate::drop_flag_effects::DropFlagState;
+use crate::drop_flag_effects::{DropFlagState, InactiveVariants};
 use crate::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData, MovePathIndex};
 use crate::{
     Analysis, GenKill, MaybeReachable, drop_flag_effects, drop_flag_effects_for_function_entry,
@@ -26,6 +27,12 @@ pub struct MaybePlacesSwitchIntData<'tcx> {
 }
 
 impl<'tcx> MaybePlacesSwitchIntData<'tcx> {
+    /// Creates a `SmallVec` mapping each target in `targets` to its `VariantIdx`.
+    fn variants(&mut self, targets: &mir::SwitchTargets) -> SmallVec<[VariantIdx; 4]> {
+        self.index = 0;
+        targets.all_values().iter().map(|value| self.next_discr(value.get())).collect()
+    }
+
     // The discriminant order in the `SwitchInt` targets should match the order yielded by
     // `AdtDef::discriminants`. We rely on this to match each discriminant in the targets to its
     // corresponding variant in linear time.
@@ -131,12 +138,26 @@ pub struct MaybeInitializedPlaces<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     body: &'a Body<'tcx>,
     move_data: &'a MoveData<'tcx>,
+    exclude_inactive_in_otherwise: bool,
     skip_unreachable_unwind: bool,
 }
 
 impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
     pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
-        MaybeInitializedPlaces { tcx, body, move_data, skip_unreachable_unwind: false }
+        MaybeInitializedPlaces {
+            tcx,
+            body,
+            move_data,
+            exclude_inactive_in_otherwise: false,
+            skip_unreachable_unwind: false,
+        }
+    }
+
+    /// Ensures definitely inactive variants are excluded from the set of initialized places for
+    /// blocks reached through an `otherwise` edge.
+    pub fn exclude_inactive_in_otherwise(mut self) -> Self {
+        self.exclude_inactive_in_otherwise = true;
+        self
     }
 
     pub fn skipping_unreachable_unwind(mut self) -> Self {
@@ -208,6 +229,7 @@ pub struct MaybeUninitializedPlaces<'a, 'tcx> {
     move_data: &'a MoveData<'tcx>,
 
     mark_inactive_variants_as_uninit: bool,
+    include_inactive_in_otherwise: bool,
     skip_unreachable_unwind: DenseBitSet<mir::BasicBlock>,
 }
 
@@ -218,6 +240,7 @@ impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
             body,
             move_data,
             mark_inactive_variants_as_uninit: false,
+            include_inactive_in_otherwise: false,
             skip_unreachable_unwind: DenseBitSet::new_empty(body.basic_blocks.len()),
         }
     }
@@ -232,6 +255,13 @@ impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
         self
     }
 
+    /// Ensures definitely inactive variants are included in the set of uninitialized places for
+    /// blocks reached through an `otherwise` edge.
+    pub fn include_inactive_in_otherwise(mut self) -> Self {
+        self.include_inactive_in_otherwise = true;
+        self
+    }
+
     pub fn skipping_unreachable_unwind(
         mut self,
         unreachable_unwind: DenseBitSet<mir::BasicBlock>,
@@ -431,17 +461,24 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
         data: &mut Self::SwitchIntData,
         state: &mut Self::Domain,
         value: SwitchTargetValue,
+        targets: &mir::SwitchTargets,
     ) {
-        if let SwitchTargetValue::Normal(value) = value {
-            // Kill all move paths that correspond to variants we know to be inactive along this
-            // particular outgoing edge of a `SwitchInt`.
-            drop_flag_effects::on_all_inactive_variants(
-                self.move_data,
-                data.enum_place,
-                data.next_discr(value),
-                |mpi| state.kill(mpi),
-            );
-        }
+        let inactive_variants = match value {
+            SwitchTargetValue::Normal(value) => InactiveVariants::Active(data.next_discr(value)),
+            SwitchTargetValue::Otherwise if self.exclude_inactive_in_otherwise => {
+                InactiveVariants::Inactives(data.variants(targets))
+            }
+            _ => return,
+        };
+
+        // Kill all move paths that correspond to variants we know to be inactive along this
+        // particular outgoing edge of a `SwitchInt`.
+        drop_flag_effects::on_all_inactive_variants(
+            self.move_data,
+            data.enum_place,
+            &inactive_variants,
+            |mpi| state.kill(mpi),
+        );
     }
 }
 
@@ -544,17 +581,24 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
         data: &mut Self::SwitchIntData,
         state: &mut Self::Domain,
         value: SwitchTargetValue,
+        targets: &mir::SwitchTargets,
     ) {
-        if let SwitchTargetValue::Normal(value) = value {
-            // Mark all move paths that correspond to variants other than this one as maybe
-            // uninitialized (in reality, they are *definitely* uninitialized).
-            drop_flag_effects::on_all_inactive_variants(
-                self.move_data,
-                data.enum_place,
-                data.next_discr(value),
-                |mpi| state.gen_(mpi),
-            );
-        }
+        let inactive_variants = match value {
+            SwitchTargetValue::Normal(value) => InactiveVariants::Active(data.next_discr(value)),
+            SwitchTargetValue::Otherwise if self.include_inactive_in_otherwise => {
+                InactiveVariants::Inactives(data.variants(targets))
+            }
+            _ => return,
+        };
+
+        // Mark all move paths that correspond to variants other than this one as maybe
+        // uninitialized (in reality, they are *definitely* uninitialized).
+        drop_flag_effects::on_all_inactive_variants(
+            self.move_data,
+            data.enum_place,
+            &inactive_variants,
+            |mpi| state.gen_(mpi),
+        );
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index 42c8cb0b906..b4fa2be1d00 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -62,12 +62,14 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
             let env = MoveDataTypingEnv { move_data, typing_env };
 
             let mut inits = MaybeInitializedPlaces::new(tcx, body, &env.move_data)
+                .exclude_inactive_in_otherwise()
                 .skipping_unreachable_unwind()
                 .iterate_to_fixpoint(tcx, body, Some("elaborate_drops"))
                 .into_results_cursor(body);
             let dead_unwinds = compute_dead_unwinds(body, &mut inits);
 
             let uninits = MaybeUninitializedPlaces::new(tcx, body, &env.move_data)
+                .include_inactive_in_otherwise()
                 .mark_inactive_variants_as_uninit()
                 .skipping_unreachable_unwind(dead_unwinds)
                 .iterate_to_fixpoint(tcx, body, Some("elaborate_drops"))
diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
index 9044a88295c..25d6fa1bab9 100644
--- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
+++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
@@ -22,6 +22,7 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops {
         let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, typing_env));
 
         let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
+            .exclude_inactive_in_otherwise()
             .iterate_to_fixpoint(tcx, body, Some("remove_uninit_drops"))
             .into_results_cursor(body);
 
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 131064f9832..91c8e64ce9a 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1219,6 +1219,7 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt
             ));
             collect_alloc(tcx, alloc_id, output)
         }
+        GlobalAlloc::TypeId { .. } => {}
     }
 }
 
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 9ed7124a11c..d6cc98d505c 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2206,7 +2206,7 @@ impl<'a> Parser<'a> {
 
             if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
                 return IsMacroRulesItem::Yes { has_bang: true };
-            } else if self.look_ahead(1, |t| (t.is_ident())) {
+            } else if self.look_ahead(1, |t| t.is_ident()) {
                 // macro_rules foo
                 self.dcx().emit_err(errors::MacroRulesMissingBang {
                     span: macro_rules_span,
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 67b68e77d2b..11424ec3724 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -271,6 +271,10 @@ pub fn check_builtin_meta_item(
         if matches!(
             name,
             sym::inline
+                | sym::export_stable
+                | sym::ffi_const
+                | sym::ffi_pure
+                | sym::rustc_std_internal_symbol
                 | sym::may_dangle
                 | sym::rustc_as_ptr
                 | sym::rustc_pub_transparent
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 9e4e78c1db6..0aa6a2b41cf 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -204,10 +204,20 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     AttributeKind::RustcLayoutScalarValidRangeStart(_num, attr_span)
                     | AttributeKind::RustcLayoutScalarValidRangeEnd(_num, attr_span),
                 ) => self.check_rustc_layout_scalar_valid_range(*attr_span, span, target),
+                Attribute::Parsed(AttributeKind::ExportStable) => {
+                    // handled in `check_export`
+                }
+                &Attribute::Parsed(AttributeKind::FfiConst(attr_span)) => {
+                    self.check_ffi_const(attr_span, target)
+                }
+                &Attribute::Parsed(AttributeKind::FfiPure(attr_span)) => {
+                    self.check_ffi_pure(attr_span, attrs, target)
+                }
                 Attribute::Parsed(
                     AttributeKind::BodyStability { .. }
                     | AttributeKind::ConstStabilityIndirect
-                    | AttributeKind::MacroTransparency(_),
+                    | AttributeKind::MacroTransparency(_)
+                    | AttributeKind::Dummy,
                 ) => { /* do nothing  */ }
                 Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
                     self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
@@ -233,6 +243,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 &Attribute::Parsed(AttributeKind::PassByValue(attr_span)) => {
                     self.check_pass_by_value(attr_span, span, target)
                 }
+                &Attribute::Parsed(AttributeKind::StdInternalSymbol(attr_span)) => {
+                    self.check_rustc_std_internal_symbol(attr_span, span, target)
+                }
                 Attribute::Unparsed(attr_item) => {
                     style = Some(attr_item.style);
                     match attr.path().as_slice() {
@@ -258,9 +271,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         ),
                         [sym::no_link, ..] => self.check_no_link(hir_id, attr, span, target),
                         [sym::debugger_visualizer, ..] => self.check_debugger_visualizer(attr, target),
-                        [sym::rustc_std_internal_symbol, ..] => {
-                            self.check_rustc_std_internal_symbol(attr, span, target)
-                        }
                         [sym::rustc_no_implicit_autorefs, ..] => {
                             self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
                         }
@@ -300,8 +310,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         [sym::rustc_has_incoherent_inherent_impls, ..] => {
                             self.check_has_incoherent_inherent_impls(attr, span, target)
                         }
-                        [sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target),
-                        [sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target),
                         [sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target),
                         [sym::link, ..] => self.check_link(hir_id, attr, span, target),
                         [sym::macro_use, ..] | [sym::macro_escape, ..] => {
@@ -346,7 +354,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             | sym::cfg_attr
                             | sym::cfg_trace
                             | sym::cfg_attr_trace
-                            | sym::export_stable // handled in `check_export`
                             // need to be fixed
                             | sym::cfi_encoding // FIXME(cfi_encoding)
                             | sym::pointee // FIXME(derive_coerce_pointee)
@@ -1507,7 +1514,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             self.dcx().emit_err(errors::FfiPureInvalidTarget { attr_span });
             return;
         }
-        if attrs.iter().any(|a| a.has_name(sym::ffi_const)) {
+        if find_attr!(attrs, AttributeKind::FfiConst(_)) {
             // `#[ffi_const]` functions cannot be `#[ffi_pure]`
             self.dcx().emit_err(errors::BothFfiConstAndPure { attr_span });
         }
@@ -2214,13 +2221,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_rustc_std_internal_symbol(&self, attr: &Attribute, span: Span, target: Target) {
+    fn check_rustc_std_internal_symbol(&self, attr_span: Span, span: Span, target: Target) {
         match target {
             Target::Fn | Target::Static | Target::ForeignFn | Target::ForeignStatic => {}
             _ => {
-                self.tcx
-                    .dcx()
-                    .emit_err(errors::RustcStdInternalSymbol { attr_span: attr.span(), span });
+                self.tcx.dcx().emit_err(errors::RustcStdInternalSymbol { attr_span, span });
             }
         }
     }
diff --git a/compiler/rustc_passes/src/check_export.rs b/compiler/rustc_passes/src/check_export.rs
index f8f489d7d06..b1f4584c2a8 100644
--- a/compiler/rustc_passes/src/check_export.rs
+++ b/compiler/rustc_passes/src/check_export.rs
@@ -2,6 +2,7 @@ use std::iter;
 use std::ops::ControlFlow;
 
 use rustc_abi::ExternAbi;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
@@ -14,7 +15,7 @@ use rustc_middle::ty::{
     self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Visibility,
 };
 use rustc_session::config::CrateType;
-use rustc_span::{Span, sym};
+use rustc_span::Span;
 
 use crate::errors::UnexportableItem;
 
@@ -44,7 +45,7 @@ impl<'tcx> ExportableItemCollector<'tcx> {
     }
 
     fn item_is_exportable(&self, def_id: LocalDefId) -> bool {
-        let has_attr = self.tcx.has_attr(def_id, sym::export_stable);
+        let has_attr = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable);
         if !self.in_exportable_mod && !has_attr {
             return false;
         }
@@ -80,7 +81,7 @@ impl<'tcx> ExportableItemCollector<'tcx> {
     fn walk_item_with_mod(&mut self, item: &'tcx hir::Item<'tcx>) {
         let def_id = item.hir_id().owner.def_id;
         let old_exportable_mod = self.in_exportable_mod;
-        if self.tcx.get_attr(def_id, sym::export_stable).is_some() {
+        if find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable) {
             self.in_exportable_mod = true;
         }
         let old_seen_exportable_in_mod = std::mem::replace(&mut self.seen_exportable_in_mod, false);
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 7e15267a953..b49e8118fe3 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -325,6 +325,7 @@ impl<'tcx> ReachableContext<'tcx> {
                         self.visit(args);
                     }
                 }
+                GlobalAlloc::TypeId { ty, .. } => self.visit(ty),
                 GlobalAlloc::Memory(alloc) => self.propagate_from_alloc(alloc),
             }
         }
diff --git a/compiler/rustc_pattern_analysis/src/checks.rs b/compiler/rustc_pattern_analysis/src/checks.rs
new file mode 100644
index 00000000000..88ccaa1e0e5
--- /dev/null
+++ b/compiler/rustc_pattern_analysis/src/checks.rs
@@ -0,0 +1,50 @@
+//! Contains checks that must be run to validate matches before performing usefulness analysis.
+
+use crate::constructor::Constructor::*;
+use crate::pat_column::PatternColumn;
+use crate::{MatchArm, PatCx};
+
+/// Validate that deref patterns and normal constructors aren't used to match on the same place.
+pub(crate) fn detect_mixed_deref_pat_ctors<'p, Cx: PatCx>(
+    cx: &Cx,
+    arms: &[MatchArm<'p, Cx>],
+) -> Result<(), Cx::Error> {
+    let pat_column = PatternColumn::new(arms);
+    detect_mixed_deref_pat_ctors_inner(cx, &pat_column)
+}
+
+fn detect_mixed_deref_pat_ctors_inner<'p, Cx: PatCx>(
+    cx: &Cx,
+    column: &PatternColumn<'p, Cx>,
+) -> Result<(), Cx::Error> {
+    let Some(ty) = column.head_ty() else {
+        return Ok(());
+    };
+
+    // Check for a mix of deref patterns and normal constructors.
+    let mut deref_pat = None;
+    let mut normal_pat = None;
+    for pat in column.iter() {
+        match pat.ctor() {
+            // The analysis can handle mixing deref patterns with wildcards and opaque patterns.
+            Wildcard | Opaque(_) => {}
+            DerefPattern(_) => deref_pat = Some(pat),
+            // Nothing else can be compared to deref patterns in `Constructor::is_covered_by`.
+            _ => normal_pat = Some(pat),
+        }
+    }
+    if let Some(deref_pat) = deref_pat
+        && let Some(normal_pat) = normal_pat
+    {
+        return Err(cx.report_mixed_deref_pat_ctors(deref_pat, normal_pat));
+    }
+
+    // Specialize and recurse into the patterns' fields.
+    let set = column.analyze_ctors(cx, &ty)?;
+    for ctor in set.present {
+        for specialized_column in column.specialize(cx, &ty, &ctor).iter() {
+            detect_mixed_deref_pat_ctors_inner(cx, specialized_column)?;
+        }
+    }
+    Ok(())
+}
diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs
index 2b85d7b26ce..66df35f9ee4 100644
--- a/compiler/rustc_pattern_analysis/src/lib.rs
+++ b/compiler/rustc_pattern_analysis/src/lib.rs
@@ -8,6 +8,7 @@
 #![allow(unused_crate_dependencies)]
 // tidy-alphabetical-end
 
+pub(crate) mod checks;
 pub mod constructor;
 #[cfg(feature = "rustc")]
 pub mod errors;
@@ -107,6 +108,20 @@ pub trait PatCx: Sized + fmt::Debug {
         _gapped_with: &[&DeconstructedPat<Self>],
     ) {
     }
+
+    /// Check if we may need to perform additional deref-pattern-specific validation.
+    fn match_may_contain_deref_pats(&self) -> bool {
+        true
+    }
+
+    /// The current implementation of deref patterns requires that they can't match on the same
+    /// place as a normal constructor. Since this isn't caught by type-checking, we check it in the
+    /// `PatCx` before running the analysis. This reports an error if the check fails.
+    fn report_mixed_deref_pat_ctors(
+        &self,
+        deref_pat: &DeconstructedPat<Self>,
+        normal_pat: &DeconstructedPat<Self>,
+    ) -> Self::Error;
 }
 
 /// The arm of a match expression.
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index e53cebc59ba..ee72b676b38 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -1,3 +1,4 @@
+use std::cell::Cell;
 use std::fmt;
 use std::iter::once;
 
@@ -99,6 +100,16 @@ pub struct RustcPatCtxt<'p, 'tcx: 'p> {
     /// Whether the data at the scrutinee is known to be valid. This is false if the scrutinee comes
     /// from a union field, a pointer deref, or a reference deref (pending opsem decisions).
     pub known_valid_scrutinee: bool,
+    pub internal_state: RustcPatCtxtState,
+}
+
+/// Private fields of [`RustcPatCtxt`], separated out to permit record initialization syntax.
+#[derive(Clone, Default)]
+pub struct RustcPatCtxtState {
+    /// Has a deref pattern been lowered? This is initialized to `false` and is updated by
+    /// [`RustcPatCtxt::lower_pat`] in order to avoid performing deref-pattern-specific validation
+    /// for everything containing patterns.
+    has_lowered_deref_pat: Cell<bool>,
 }
 
 impl<'p, 'tcx: 'p> fmt::Debug for RustcPatCtxt<'p, 'tcx> {
@@ -474,6 +485,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                 fields = vec![self.lower_pat(subpattern).at_index(0)];
                 arity = 1;
                 ctor = DerefPattern(cx.reveal_opaque_ty(subpattern.ty));
+                self.internal_state.has_lowered_deref_pat.set(true);
             }
             PatKind::Leaf { subpatterns } | PatKind::Variant { subpatterns, .. } => {
                 match ty.kind() {
@@ -1027,6 +1039,25 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
             );
         }
     }
+
+    fn match_may_contain_deref_pats(&self) -> bool {
+        self.internal_state.has_lowered_deref_pat.get()
+    }
+
+    fn report_mixed_deref_pat_ctors(
+        &self,
+        deref_pat: &crate::pat::DeconstructedPat<Self>,
+        normal_pat: &crate::pat::DeconstructedPat<Self>,
+    ) -> Self::Error {
+        let deref_pattern_label = deref_pat.data().span;
+        let normal_constructor_label = normal_pat.data().span;
+        self.tcx.dcx().emit_err(errors::MixedDerefPatternConstructors {
+            spans: vec![deref_pattern_label, normal_constructor_label],
+            smart_pointer_ty: deref_pat.ty().inner(),
+            deref_pattern_label,
+            normal_constructor_label,
+        })
+    }
 }
 
 /// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
@@ -1055,13 +1086,6 @@ pub fn analyze_match<'p, 'tcx>(
 ) -> Result<UsefulnessReport<'p, 'tcx>, ErrorGuaranteed> {
     let scrut_ty = tycx.reveal_opaque_ty(scrut_ty);
 
-    // The analysis doesn't support deref patterns mixed with normal constructors; error if present.
-    // FIXME(deref_patterns): This only needs to run when a deref pattern was found during lowering.
-    if tycx.tcx.features().deref_patterns() {
-        let pat_column = PatternColumn::new(arms);
-        detect_mixed_deref_pat_ctors(tycx, &pat_column)?;
-    }
-
     let scrut_validity = PlaceValidity::from_bool(tycx.known_valid_scrutinee);
     let report = compute_match_usefulness(
         tycx,
@@ -1080,48 +1104,3 @@ pub fn analyze_match<'p, 'tcx>(
 
     Ok(report)
 }
-
-// FIXME(deref_patterns): Currently it's the responsibility of the frontend (rustc or rust-analyzer)
-// to ensure that deref patterns don't appear in the same column as normal constructors. Deref
-// patterns aren't currently implemented in rust-analyzer, but should they be, the columnwise check
-// here could be made generic and shared between frontends.
-fn detect_mixed_deref_pat_ctors<'p, 'tcx>(
-    cx: &RustcPatCtxt<'p, 'tcx>,
-    column: &PatternColumn<'p, RustcPatCtxt<'p, 'tcx>>,
-) -> Result<(), ErrorGuaranteed> {
-    let Some(&ty) = column.head_ty() else {
-        return Ok(());
-    };
-
-    // Check for a mix of deref patterns and normal constructors.
-    let mut normal_ctor_span = None;
-    let mut deref_pat_span = None;
-    for pat in column.iter() {
-        match pat.ctor() {
-            // The analysis can handle mixing deref patterns with wildcards and opaque patterns.
-            Wildcard | Opaque(_) => {}
-            DerefPattern(_) => deref_pat_span = Some(pat.data().span),
-            // Nothing else can be compared to deref patterns in `Constructor::is_covered_by`.
-            _ => normal_ctor_span = Some(pat.data().span),
-        }
-    }
-    if let Some(normal_constructor_label) = normal_ctor_span
-        && let Some(deref_pattern_label) = deref_pat_span
-    {
-        return Err(cx.tcx.dcx().emit_err(errors::MixedDerefPatternConstructors {
-            spans: vec![deref_pattern_label, normal_constructor_label],
-            smart_pointer_ty: ty.inner(),
-            deref_pattern_label,
-            normal_constructor_label,
-        }));
-    }
-
-    // Specialize and recurse into the patterns' fields.
-    let set = column.analyze_ctors(cx, &ty)?;
-    for ctor in set.present {
-        for specialized_column in column.specialize(cx, &ty, &ctor).iter() {
-            detect_mixed_deref_pat_ctors(cx, specialized_column)?;
-        }
-    }
-    Ok(())
-}
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index c348cd508f9..b1c646e9884 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -720,7 +720,7 @@ use tracing::{debug, instrument};
 use self::PlaceValidity::*;
 use crate::constructor::{Constructor, ConstructorSet, IntRange};
 use crate::pat::{DeconstructedPat, PatId, PatOrWild, WitnessPat};
-use crate::{MatchArm, PatCx, PrivateUninhabitedField};
+use crate::{MatchArm, PatCx, PrivateUninhabitedField, checks};
 #[cfg(not(feature = "rustc"))]
 pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
     f()
@@ -1836,6 +1836,11 @@ pub fn compute_match_usefulness<'p, Cx: PatCx>(
     scrut_validity: PlaceValidity,
     complexity_limit: usize,
 ) -> Result<UsefulnessReport<'p, Cx>, Cx::Error> {
+    // The analysis doesn't support deref patterns mixed with normal constructors; error if present.
+    if tycx.match_may_contain_deref_pats() {
+        checks::detect_mixed_deref_pat_ctors(tycx, arms)?;
+    }
+
     let mut cx = UsefulnessCtxt {
         tycx,
         branch_usefulness: FxHashMap::default(),
diff --git a/compiler/rustc_pattern_analysis/tests/common/mod.rs b/compiler/rustc_pattern_analysis/tests/common/mod.rs
index 8980b644f59..0b939ef7816 100644
--- a/compiler/rustc_pattern_analysis/tests/common/mod.rs
+++ b/compiler/rustc_pattern_analysis/tests/common/mod.rs
@@ -1,6 +1,7 @@
 use rustc_pattern_analysis::constructor::{
     Constructor, ConstructorSet, IntRange, MaybeInfiniteInt, RangeEnd, VariantVisibility,
 };
+use rustc_pattern_analysis::pat::DeconstructedPat;
 use rustc_pattern_analysis::usefulness::{PlaceValidity, UsefulnessReport};
 use rustc_pattern_analysis::{MatchArm, PatCx, PrivateUninhabitedField};
 
@@ -184,6 +185,14 @@ impl PatCx for Cx {
     fn complexity_exceeded(&self) -> Result<(), Self::Error> {
         Err(())
     }
+
+    fn report_mixed_deref_pat_ctors(
+        &self,
+        _deref_pat: &DeconstructedPat<Self>,
+        _normal_pat: &DeconstructedPat<Self>,
+    ) -> Self::Error {
+        panic!("`rustc_pattern_analysis::tests` currently doesn't test deref pattern errors")
+    }
 }
 
 /// Construct a single pattern; see `pats!()`.
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index f775cac149e..ef122deba4e 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -162,28 +162,30 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         }
     }
 
-    pub(crate) fn get_macro(&mut self, res: Res) -> Option<&MacroData> {
+    pub(crate) fn get_macro(&self, res: Res) -> Option<&'ra MacroData> {
         match res {
             Res::Def(DefKind::Macro(..), def_id) => Some(self.get_macro_by_def_id(def_id)),
-            Res::NonMacroAttr(_) => Some(&self.non_macro_attr),
+            Res::NonMacroAttr(_) => Some(self.non_macro_attr),
             _ => None,
         }
     }
 
-    pub(crate) fn get_macro_by_def_id(&mut self, def_id: DefId) -> &MacroData {
-        if self.macro_map.contains_key(&def_id) {
-            return &self.macro_map[&def_id];
-        }
-
-        let loaded_macro = self.cstore().load_macro_untracked(def_id, self.tcx);
-        let macro_data = match loaded_macro {
-            LoadedMacro::MacroDef { def, ident, attrs, span, edition } => {
-                self.compile_macro(&def, ident, &attrs, span, ast::DUMMY_NODE_ID, edition)
-            }
-            LoadedMacro::ProcMacro(ext) => MacroData::new(Arc::new(ext)),
-        };
+    pub(crate) fn get_macro_by_def_id(&self, def_id: DefId) -> &'ra MacroData {
+        // Local macros are always compiled.
+        match def_id.as_local() {
+            Some(local_def_id) => self.local_macro_map[&local_def_id],
+            None => *self.extern_macro_map.borrow_mut().entry(def_id).or_insert_with(|| {
+                let loaded_macro = self.cstore().load_macro_untracked(def_id, self.tcx);
+                let macro_data = match loaded_macro {
+                    LoadedMacro::MacroDef { def, ident, attrs, span, edition } => {
+                        self.compile_macro(&def, ident, &attrs, span, ast::DUMMY_NODE_ID, edition)
+                    }
+                    LoadedMacro::ProcMacro(ext) => MacroData::new(Arc::new(ext)),
+                };
 
-        self.macro_map.entry(def_id).or_insert(macro_data)
+                self.arenas.alloc_macro(macro_data)
+            }),
+        }
     }
 
     pub(crate) fn build_reduced_graph(
@@ -1203,7 +1205,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
     fn insert_unused_macro(&mut self, ident: Ident, def_id: LocalDefId, node_id: NodeId) {
         if !ident.as_str().starts_with('_') {
             self.r.unused_macros.insert(def_id, (node_id, ident));
-            let nrules = self.r.macro_map[&def_id.to_def_id()].nrules;
+            let nrules = self.r.local_macro_map[&def_id].nrules;
             self.r.unused_macro_rules.insert(node_id, DenseBitSet::new_filled(nrules));
         }
     }
@@ -1222,7 +1224,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                     Some((macro_kind, ident, span)) => {
                         let res = Res::Def(DefKind::Macro(macro_kind), def_id.to_def_id());
                         let macro_data = MacroData::new(self.r.dummy_ext(macro_kind));
-                        self.r.macro_map.insert(def_id.to_def_id(), macro_data);
+                        self.r.new_local_macro(def_id, macro_data);
                         self.r.proc_macro_stubs.insert(def_id);
                         (res, ident, span, false)
                     }
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 1e345b11c14..e2caf632dd2 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -165,7 +165,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
             self.create_def(i.id, i.kind.ident().map(|ident| ident.name), def_kind, i.span);
 
         if let Some(macro_data) = opt_macro_data {
-            self.resolver.macro_map.insert(def_id.to_def_id(), macro_data);
+            self.resolver.new_local_macro(def_id, macro_data);
         }
 
         self.with_parent(def_id, |this| {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index c99bc747fd2..c4ff5770e76 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1669,9 +1669,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         let mut all_attrs: UnordMap<Symbol, Vec<_>> = UnordMap::default();
         // We're collecting these in a hashmap, and handle ordering the output further down.
         #[allow(rustc::potential_query_instability)]
-        for (def_id, data) in &self.macro_map {
+        for (def_id, data) in self
+            .local_macro_map
+            .iter()
+            .map(|(local_id, data)| (local_id.to_def_id(), data))
+            .chain(self.extern_macro_map.borrow().iter().map(|(id, d)| (*id, d)))
+        {
             for helper_attr in &data.ext.helper_attrs {
-                let item_name = self.tcx.item_name(*def_id);
+                let item_name = self.tcx.item_name(def_id);
                 all_attrs.entry(*helper_attr).or_default().push(item_name);
                 if helper_attr == &ident.name {
                     derives.push(item_name);
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index fa04c8bc604..8114021510e 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -328,8 +328,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 let module_did = mod_prefix.as_ref().and_then(Res::mod_def_id);
 
                 let mod_prefix =
-                    mod_prefix.map_or_else(String::new, |res| (format!("{} ", res.descr())));
-
+                    mod_prefix.map_or_else(String::new, |res| format!("{} ", res.descr()));
                 (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path)), module_did, None)
             };
 
@@ -1183,15 +1182,23 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 _ => "`self` value is a keyword only available in methods with a `self` parameter",
             },
         );
+
+        // using `let self` is wrong even if we're not in an associated method or if we're in a macro expansion.
+        // So, we should return early if we're in a pattern, see issue #143134.
+        if matches!(source, PathSource::Pat) {
+            return true;
+        }
+
         let is_assoc_fn = self.self_type_is_available();
         let self_from_macro = "a `self` parameter, but a macro invocation can only \
                                access identifiers it receives from parameters";
-        if let Some((fn_kind, span)) = &self.diag_metadata.current_function {
+        if let Some((fn_kind, fn_span)) = &self.diag_metadata.current_function {
             // The current function has a `self` parameter, but we were unable to resolve
             // a reference to `self`. This can only happen if the `self` identifier we
-            // are resolving came from a different hygiene context.
+            // are resolving came from a different hygiene context or a variable binding.
+            // But variable binding error is returned early above.
             if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) {
-                err.span_label(*span, format!("this function has {self_from_macro}"));
+                err.span_label(*fn_span, format!("this function has {self_from_macro}"));
             } else {
                 let doesnt = if is_assoc_fn {
                     let (span, sugg) = fn_kind
@@ -1204,7 +1211,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                             // This avoids placing the suggestion into the visibility specifier.
                             let span = fn_kind
                                 .ident()
-                                .map_or(*span, |ident| span.with_lo(ident.span.hi()));
+                                .map_or(*fn_span, |ident| fn_span.with_lo(ident.span.hi()));
                             (
                                 self.r
                                     .tcx
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index f8ca20c568f..6e4c5ef1909 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1128,10 +1128,12 @@ pub struct Resolver<'ra, 'tcx> {
     builtin_macros: FxHashMap<Symbol, SyntaxExtensionKind>,
     registered_tools: &'tcx RegisteredTools,
     macro_use_prelude: FxIndexMap<Symbol, NameBinding<'ra>>,
-    macro_map: FxHashMap<DefId, MacroData>,
+    local_macro_map: FxHashMap<LocalDefId, &'ra MacroData>,
+    /// Lazily populated cache of macros loaded from external crates.
+    extern_macro_map: RefCell<FxHashMap<DefId, &'ra MacroData>>,
     dummy_ext_bang: Arc<SyntaxExtension>,
     dummy_ext_derive: Arc<SyntaxExtension>,
-    non_macro_attr: MacroData,
+    non_macro_attr: &'ra MacroData,
     local_macro_def_scopes: FxHashMap<LocalDefId, Module<'ra>>,
     ast_transform_scopes: FxHashMap<LocalExpnId, Module<'ra>>,
     unused_macros: FxIndexMap<LocalDefId, (NodeId, Ident)>,
@@ -1241,6 +1243,7 @@ pub struct ResolverArenas<'ra> {
     imports: TypedArena<ImportData<'ra>>,
     name_resolutions: TypedArena<RefCell<NameResolution<'ra>>>,
     ast_paths: TypedArena<ast::Path>,
+    macros: TypedArena<MacroData>,
     dropless: DroplessArena,
 }
 
@@ -1287,7 +1290,7 @@ impl<'ra> ResolverArenas<'ra> {
         self.name_resolutions.alloc(Default::default())
     }
     fn alloc_macro_rules_scope(&'ra self, scope: MacroRulesScope<'ra>) -> MacroRulesScopeRef<'ra> {
-        Interned::new_unchecked(self.dropless.alloc(Cell::new(scope)))
+        self.dropless.alloc(Cell::new(scope))
     }
     fn alloc_macro_rules_binding(
         &'ra self,
@@ -1298,6 +1301,9 @@ impl<'ra> ResolverArenas<'ra> {
     fn alloc_ast_paths(&'ra self, paths: &[ast::Path]) -> &'ra [ast::Path] {
         self.ast_paths.alloc_from_iter(paths.iter().cloned())
     }
+    fn alloc_macro(&'ra self, macro_data: MacroData) -> &'ra MacroData {
+        self.macros.alloc(macro_data)
+    }
     fn alloc_pattern_spans(&'ra self, spans: impl Iterator<Item = Span>) -> &'ra [Span] {
         self.dropless.alloc_from_iter(spans)
     }
@@ -1540,10 +1546,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             builtin_macros: Default::default(),
             registered_tools,
             macro_use_prelude: Default::default(),
-            macro_map: FxHashMap::default(),
+            local_macro_map: Default::default(),
+            extern_macro_map: Default::default(),
             dummy_ext_bang: Arc::new(SyntaxExtension::dummy_bang(edition)),
             dummy_ext_derive: Arc::new(SyntaxExtension::dummy_derive(edition)),
-            non_macro_attr: MacroData::new(Arc::new(SyntaxExtension::non_macro_attr(edition))),
+            non_macro_attr: arenas
+                .alloc_macro(MacroData::new(Arc::new(SyntaxExtension::non_macro_attr(edition)))),
             invocation_parent_scopes: Default::default(),
             output_macro_rules_scopes: Default::default(),
             macro_rules_scopes: Default::default(),
@@ -1616,6 +1624,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         )
     }
 
+    fn new_local_macro(&mut self, def_id: LocalDefId, macro_data: MacroData) -> &'ra MacroData {
+        let mac = self.arenas.alloc_macro(macro_data);
+        self.local_macro_map.insert(def_id, mac);
+        mac
+    }
+
     fn next_node_id(&mut self) -> NodeId {
         let start = self.next_node_id;
         let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
@@ -1734,7 +1748,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         f(self, MacroNS);
     }
 
-    fn is_builtin_macro(&mut self, res: Res) -> bool {
+    fn is_builtin_macro(&self, res: Res) -> bool {
         self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some())
     }
 
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index acbefe53422..89bbe8dad98 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -9,7 +9,6 @@ use rustc_ast::expand::StrippedCfgItem;
 use rustc_ast::{self as ast, Crate, NodeId, attr};
 use rustc_ast_pretty::pprust;
 use rustc_attr_data_structures::StabilityLevel;
-use rustc_data_structures::intern::Interned;
 use rustc_errors::{Applicability, DiagCtxtHandle, StashKey};
 use rustc_expand::base::{
     Annotatable, DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension,
@@ -80,7 +79,7 @@ pub(crate) enum MacroRulesScope<'ra> {
 /// This helps to avoid uncontrollable growth of `macro_rules!` scope chains,
 /// which usually grow linearly with the number of macro invocations
 /// in a module (including derives) and hurt performance.
-pub(crate) type MacroRulesScopeRef<'ra> = Interned<'ra, Cell<MacroRulesScope<'ra>>>;
+pub(crate) type MacroRulesScopeRef<'ra> = &'ra Cell<MacroRulesScope<'ra>>;
 
 /// Macro namespace is separated into two sub-namespaces, one for bang macros and
 /// one for attribute-like macros (attributes, derives).
@@ -354,8 +353,8 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
             if unused_arms.is_empty() {
                 continue;
             }
-            let def_id = self.local_def_id(node_id).to_def_id();
-            let m = &self.macro_map[&def_id];
+            let def_id = self.local_def_id(node_id);
+            let m = &self.local_macro_map[&def_id];
             let SyntaxExtensionKind::LegacyBang(ref ext) = m.ext.kind else {
                 continue;
             };
@@ -1132,7 +1131,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         }
     }
 
-    pub(crate) fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
+    pub(crate) fn check_reserved_macro_name(&self, ident: Ident, res: Res) {
         // Reserve some names that are not quite covered by the general check
         // performed on `Resolver::builtin_attrs`.
         if ident.name == sym::cfg || ident.name == sym::cfg_attr {
@@ -1148,7 +1147,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     ///
     /// Possibly replace its expander to a pre-defined one for built-in macros.
     pub(crate) fn compile_macro(
-        &mut self,
+        &self,
         macro_def: &ast::MacroDef,
         ident: Ident,
         attrs: &[rustc_hir::Attribute],
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 4627c2978fc..a91e2140fd4 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -370,12 +370,34 @@ impl LinkSelfContained {
     }
 
     /// To help checking CLI usage while some of the values are unstable: returns whether one of the
-    /// components was set individually. This would also require the `-Zunstable-options` flag, to
-    /// be allowed.
-    fn are_unstable_variants_set(&self) -> bool {
-        let any_component_set =
-            !self.enabled_components.is_empty() || !self.disabled_components.is_empty();
-        self.explicitly_set.is_none() && any_component_set
+    /// unstable components was set individually, for the given `TargetTuple`. This would also
+    /// require the `-Zunstable-options` flag, to be allowed.
+    fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
+        if self.explicitly_set.is_some() {
+            return Ok(());
+        }
+
+        // `-C link-self-contained=-linker` is only stable on x64 linux.
+        let has_minus_linker = self.disabled_components.is_linker_enabled();
+        if has_minus_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
+            return Err(format!(
+                "`-C link-self-contained=-linker` is unstable on the `{target_tuple}` \
+                    target. The `-Z unstable-options` flag must also be passed to use it on this target",
+            ));
+        }
+
+        // Any `+linker` or other component used is unstable, and that's an error.
+        let unstable_enabled = self.enabled_components;
+        let unstable_disabled = self.disabled_components - LinkSelfContainedComponents::LINKER;
+        if !unstable_enabled.union(unstable_disabled).is_empty() {
+            return Err(String::from(
+                "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` \
+                are stable, the `-Z unstable-options` flag must also be passed to use \
+                the unstable values",
+            ));
+        }
+
+        Ok(())
     }
 
     /// Returns whether the self-contained linker component was enabled on the CLI, using the
@@ -402,7 +424,7 @@ impl LinkSelfContained {
     }
 }
 
-/// The different values that `-Z linker-features` can take on the CLI: a list of individually
+/// The different values that `-C linker-features` can take on the CLI: a list of individually
 /// enabled or disabled features used during linking.
 ///
 /// There is no need to enable or disable them in bulk. Each feature is fine-grained, and can be
@@ -442,6 +464,39 @@ impl LinkerFeaturesCli {
             _ => None,
         }
     }
+
+    /// When *not* using `-Z unstable-options` on the CLI, ensure only stable linker features are
+    /// used, for the given `TargetTuple`. Returns `Ok` if no unstable variants are used.
+    /// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()`
+    /// returns false.
+    pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
+        // `-C linker-features=-lld` is only stable on x64 linux.
+        let has_minus_lld = self.disabled.is_lld_enabled();
+        if has_minus_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
+            return Err(format!(
+                "`-C linker-features=-lld` is unstable on the `{target_tuple}` \
+                    target. The `-Z unstable-options` flag must also be passed to use it on this target",
+            ));
+        }
+
+        // Any `+lld` or non-lld feature used is unstable, and that's an error.
+        let unstable_enabled = self.enabled;
+        let unstable_disabled = self.disabled - LinkerFeatures::LLD;
+        if !unstable_enabled.union(unstable_disabled).is_empty() {
+            let unstable_features: Vec<_> = unstable_enabled
+                .iter()
+                .map(|f| format!("+{}", f.as_str().unwrap()))
+                .chain(unstable_disabled.iter().map(|f| format!("-{}", f.as_str().unwrap())))
+                .collect();
+            return Err(format!(
+                "`-C linker-features={}` is unstable, and also requires the \
+                `-Z unstable-options` flag to be used",
+                unstable_features.join(","),
+            ));
+        }
+
+        Ok(())
+    }
 }
 
 /// Used with `-Z assert-incr-state`.
@@ -2638,26 +2693,21 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
         }
     }
 
-    if !nightly_options::is_unstable_enabled(matches)
-        && cg.force_frame_pointers == FramePointer::NonLeaf
-    {
+    let unstable_options_enabled = nightly_options::is_unstable_enabled(matches);
+    if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf {
         early_dcx.early_fatal(
             "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
                 and a nightly compiler",
         )
     }
 
-    // For testing purposes, until we have more feedback about these options: ensure `-Z
-    // unstable-options` is required when using the unstable `-C link-self-contained` and `-C
-    // linker-flavor` options.
-    if !nightly_options::is_unstable_enabled(matches) {
-        let uses_unstable_self_contained_option =
-            cg.link_self_contained.are_unstable_variants_set();
-        if uses_unstable_self_contained_option {
-            early_dcx.early_fatal(
-                "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off` are stable, \
-                the `-Z unstable-options` flag must also be passed to use the unstable values",
-            );
+    let target_triple = parse_target_triple(early_dcx, matches);
+
+    // Ensure `-Z unstable-options` is required when using the unstable `-C link-self-contained` and
+    // `-C linker-flavor` options.
+    if !unstable_options_enabled {
+        if let Err(error) = cg.link_self_contained.check_unstable_variants(&target_triple) {
+            early_dcx.early_fatal(error);
         }
 
         if let Some(flavor) = cg.linker_flavor {
@@ -2697,7 +2747,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
 
     let cg = cg;
 
-    let target_triple = parse_target_triple(early_dcx, matches);
     let opt_level = parse_opt_level(early_dcx, matches, &cg);
     // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
     // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
@@ -2706,6 +2755,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
     let debuginfo = select_debuginfo(matches, &cg);
     let debuginfo_compression = unstable_opts.debuginfo_compression;
 
+    if !unstable_options_enabled {
+        if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) {
+            early_dcx.early_fatal(error);
+        }
+    }
+
     let crate_name = matches.opt_str("crate-name");
     let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
     // Parse any `-l` flags, which link to native libraries.
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index ecd82c0cc01..626262c8442 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -2015,6 +2015,8 @@ options! {
         on a C toolchain or linker installed in the system"),
     linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
         "system linker to link outputs with"),
+    linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED],
+        "a comma-separated list of linker features to enable (+) or disable (-): `lld`"),
     linker_flavor: Option<LinkerFlavorCli> = (None, parse_linker_flavor, [UNTRACKED],
         "linker flavor"),
     linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
@@ -2307,8 +2309,6 @@ options! {
         "link native libraries in the linker invocation (default: yes)"),
     link_only: bool = (false, parse_bool, [TRACKED],
         "link the `.rlink` file generated by `-Z no-link` (default: no)"),
-    linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED],
-        "a comma-separated list of linker features to enable (+) or disable (-): `lld`"),
     lint_llvm_ir: bool = (false, parse_bool, [TRACKED],
         "lint LLVM IR (default: no)"),
     lint_mir: bool = (false, parse_bool, [UNTRACKED],
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 09f01d8704e..4df91cc3429 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -2194,6 +2194,7 @@ symbols! {
         type_changing_struct_update,
         type_const,
         type_id,
+        type_id_eq,
         type_ir,
         type_ir_infer_ctxt_like,
         type_ir_inherent,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 5346b206a17..4bc0d88a910 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -725,7 +725,7 @@ impl ToJson for LinkSelfContainedComponents {
 }
 
 bitflags::bitflags! {
-    /// The `-Z linker-features` components that can individually be enabled or disabled.
+    /// The `-C linker-features` components that can individually be enabled or disabled.
     ///
     /// They are feature flags intended to be a more flexible mechanism than linker flavors, and
     /// also to prevent a combinatorial explosion of flavors whenever a new linker feature is
@@ -756,7 +756,7 @@ bitflags::bitflags! {
 rustc_data_structures::external_bitflags_debug! { LinkerFeatures }
 
 impl LinkerFeatures {
-    /// Parses a single `-Z linker-features` well-known feature, not a set of flags.
+    /// Parses a single `-C linker-features` well-known feature, not a set of flags.
     pub fn from_str(s: &str) -> Option<LinkerFeatures> {
         Some(match s {
             "cc" => LinkerFeatures::CC,
@@ -765,6 +765,17 @@ impl LinkerFeatures {
         })
     }
 
+    /// Return the linker feature name, as would be passed on the CLI.
+    ///
+    /// Returns `None` if the bitflags aren't a singular component (but a mix of multiple flags).
+    pub fn as_str(self) -> Option<&'static str> {
+        Some(match self {
+            LinkerFeatures::CC => "cc",
+            LinkerFeatures::LLD => "lld",
+            _ => return None,
+        })
+    }
+
     /// Returns whether the `lld` linker feature is enabled.
     pub fn is_lld_enabled(self) -> bool {
         self.contains(LinkerFeatures::LLD)
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
index 39f115ce0cd..a8ba1baf6b9 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
@@ -4,7 +4,7 @@ use rustc_errors::{Applicability, Diag, E0283, E0284, E0790, MultiSpan, struct_s
 use rustc_hir as hir;
 use rustc_hir::LangItem;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
 use rustc_hir::intravisit::Visitor as _;
 use rustc_infer::infer::{BoundRegionConversionTime, InferCtxt};
 use rustc_infer::traits::util::elaborate;
@@ -128,19 +128,26 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>(
         },
     );
 
-    let predicates =
-        tcx.predicates_of(obligation.cause.body_id.to_def_id()).instantiate_identity(tcx);
-    for (pred, span) in elaborate(tcx, predicates.into_iter()) {
-        let kind = pred.kind();
-        if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder()
-            && param_env_candidate_may_apply(kind.rebind(trait_pred))
-        {
-            if kind.rebind(trait_pred.trait_ref)
-                == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id()))
+    // If our `body_id` has been set (and isn't just from a dummy obligation cause),
+    // then try to look for a param-env clause that would apply. The way we compute
+    // this is somewhat manual, since we need the spans, so we elaborate this directly
+    // from `predicates_of` rather than actually looking at the param-env which
+    // otherwise would be more appropriate.
+    let body_id = obligation.cause.body_id;
+    if body_id != CRATE_DEF_ID {
+        let predicates = tcx.predicates_of(body_id.to_def_id()).instantiate_identity(tcx);
+        for (pred, span) in elaborate(tcx, predicates.into_iter()) {
+            let kind = pred.kind();
+            if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder()
+                && param_env_candidate_may_apply(kind.rebind(trait_pred))
             {
-                ambiguities.push(CandidateSource::ParamEnv(tcx.def_span(trait_pred.def_id())))
-            } else {
-                ambiguities.push(CandidateSource::ParamEnv(span))
+                if kind.rebind(trait_pred.trait_ref)
+                    == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id()))
+                {
+                    ambiguities.push(CandidateSource::ParamEnv(tcx.def_span(trait_pred.def_id())))
+                } else {
+                    ambiguities.push(CandidateSource::ParamEnv(span))
+                }
             }
         }
     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 28d572b303a..cd3e6c4bc54 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1933,7 +1933,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     StringPart::highlighted("multiple different versions".to_string()),
                     StringPart::normal(" of crate `".to_string()),
                     StringPart::highlighted(format!("{crate_name}")),
-                    StringPart::normal("` in the dependency graph\n".to_string()),
+                    StringPart::normal("` in the dependency graph".to_string()),
                 ],
             );
             if points_at_type {
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 e801ec358fa..3e64573aa03 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -1581,12 +1581,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         'outer: loop {
             while let hir::ExprKind::AddrOf(_, _, borrowed) = expr.kind {
                 count += 1;
-                let span = if expr.span.eq_ctxt(borrowed.span) {
-                    expr.span.until(borrowed.span)
-                } else {
-                    expr.span.with_hi(expr.span.lo() + BytePos(1))
-                };
+                let span =
+                    if let Some(borrowed_span) = borrowed.span.find_ancestor_inside(expr.span) {
+                        expr.span.until(borrowed_span)
+                    } else {
+                        break 'outer;
+                    };
 
+                // Double check that the span we extracted actually corresponds to a borrow,
+                // rather than some macro garbage.
                 match self.tcx.sess.source_map().span_to_snippet(span) {
                     Ok(snippet) if snippet.starts_with("&") => {}
                     _ => break 'outer,
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 9af85f5e3f0..cc188a280aa 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -19,7 +19,7 @@ use rustc_middle::{bug, span_bug};
 use tracing::{debug, instrument, trace};
 
 use super::SelectionCandidate::*;
-use super::{BuiltinImplConditions, SelectionCandidateSet, SelectionContext, TraitObligationStack};
+use super::{SelectionCandidateSet, SelectionContext, TraitObligationStack};
 use crate::traits::util;
 
 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
@@ -75,8 +75,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     self.assemble_candidates_from_impls(obligation, &mut candidates);
 
                     // For other types, we'll use the builtin rules.
-                    let copy_conditions = self.copy_clone_conditions(obligation);
-                    self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
+                    self.assemble_builtin_copy_clone_candidate(
+                        obligation.predicate.self_ty().skip_binder(),
+                        &mut candidates,
+                    );
                 }
                 Some(LangItem::DiscriminantKind) => {
                     // `DiscriminantKind` is automatically implemented for every type.
@@ -88,14 +90,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
                 Some(LangItem::Sized) => {
                     self.assemble_builtin_sized_candidate(
-                        obligation,
+                        obligation.predicate.self_ty().skip_binder(),
                         &mut candidates,
                         SizedTraitKind::Sized,
                     );
                 }
                 Some(LangItem::MetaSized) => {
                     self.assemble_builtin_sized_candidate(
-                        obligation,
+                        obligation.predicate.self_ty().skip_binder(),
                         &mut candidates,
                         SizedTraitKind::MetaSized,
                     );
@@ -357,14 +359,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         obligation: &PolyTraitObligation<'tcx>,
         candidates: &mut SelectionCandidateSet<'tcx>,
     ) {
-        let self_ty = obligation.self_ty().skip_binder();
-        // gen constructs get lowered to a special kind of coroutine that
-        // should directly `impl FusedIterator`.
-        if let ty::Coroutine(did, ..) = self_ty.kind()
-            && self.tcx().coroutine_is_gen(*did)
-        {
-            debug!(?self_ty, ?obligation, "assemble_fused_iterator_candidates",);
-
+        if self.coroutine_is_gen(obligation.self_ty().skip_binder()) {
             candidates.vec.push(BuiltinCandidate);
         }
     }
@@ -1113,41 +1108,164 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         }
     }
 
-    /// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself.
+    /// Assembles `Copy` and `Clone` candidates for built-in types with no libcore-defined
+    /// `Copy` or `Clone` impls.
     #[instrument(level = "debug", skip(self, candidates))]
-    fn assemble_builtin_sized_candidate(
+    fn assemble_builtin_copy_clone_candidate(
         &mut self,
-        obligation: &PolyTraitObligation<'tcx>,
+        self_ty: Ty<'tcx>,
         candidates: &mut SelectionCandidateSet<'tcx>,
-        sizedness: SizedTraitKind,
     ) {
-        match self.sizedness_conditions(obligation, sizedness) {
-            BuiltinImplConditions::Where(_nested) => {
-                candidates.vec.push(SizedCandidate);
+        match *self_ty.kind() {
+            // These impls are built-in because we cannot express sufficiently
+            // generic impls in libcore.
+            ty::FnDef(..)
+            | ty::FnPtr(..)
+            | ty::Error(_)
+            | ty::Tuple(..)
+            | ty::CoroutineWitness(..)
+            | ty::Pat(..) => {
+                candidates.vec.push(BuiltinCandidate);
+            }
+
+            // Implementations provided in libcore.
+            ty::Uint(_)
+            | ty::Int(_)
+            | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
+            | ty::Bool
+            | ty::Float(_)
+            | ty::Char
+            | ty::RawPtr(..)
+            | ty::Never
+            | ty::Ref(_, _, hir::Mutability::Not)
+            | ty::Array(..) => {}
+
+            // FIXME(unsafe_binder): Should we conditionally
+            // (i.e. universally) implement copy/clone?
+            ty::UnsafeBinder(_) => {}
+
+            // Not `Sized`, which is a supertrait of `Copy`/`Clone`.
+            ty::Dynamic(..) | ty::Str | ty::Slice(..) | ty::Foreign(..) => {}
+
+            // Not `Copy` or `Clone` by design.
+            ty::Ref(_, _, hir::Mutability::Mut) => {}
+
+            ty::Coroutine(coroutine_def_id, args) => {
+                match self.tcx().coroutine_movability(coroutine_def_id) {
+                    hir::Movability::Static => {}
+                    hir::Movability::Movable => {
+                        if self.tcx().features().coroutine_clone() {
+                            let resolved_upvars =
+                                self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
+                            let resolved_witness =
+                                self.infcx.shallow_resolve(args.as_coroutine().witness());
+                            if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
+                                // Not yet resolved.
+                                candidates.ambiguous = true;
+                            } else {
+                                candidates.vec.push(BuiltinCandidate);
+                            }
+                        }
+                    }
+                }
             }
-            BuiltinImplConditions::None => {}
-            BuiltinImplConditions::Ambiguous => {
+
+            ty::Closure(_, args) => {
+                let resolved_upvars =
+                    self.infcx.shallow_resolve(args.as_closure().tupled_upvars_ty());
+                if resolved_upvars.is_ty_var() {
+                    // Not yet resolved.
+                    candidates.ambiguous = true;
+                } else {
+                    candidates.vec.push(BuiltinCandidate);
+                }
+            }
+
+            ty::CoroutineClosure(_, args) => {
+                let resolved_upvars =
+                    self.infcx.shallow_resolve(args.as_coroutine_closure().tupled_upvars_ty());
+                if resolved_upvars.is_ty_var() {
+                    // Not yet resolved.
+                    candidates.ambiguous = true;
+                } else {
+                    candidates.vec.push(BuiltinCandidate);
+                }
+            }
+
+            // Fallback to whatever user-defined impls or param-env clauses exist in this case.
+            ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {}
+
+            ty::Infer(ty::TyVar(_)) => {
                 candidates.ambiguous = true;
             }
+
+            // Only appears when assembling higher-ranked `for<T> T: Clone`.
+            ty::Bound(..) => {}
+
+            ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
+                bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty);
+            }
         }
     }
 
-    /// Assembles the trait which are built-in to the language itself:
-    /// e.g. `Copy` and `Clone`.
+    /// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself.
     #[instrument(level = "debug", skip(self, candidates))]
-    fn assemble_builtin_bound_candidates(
+    fn assemble_builtin_sized_candidate(
         &mut self,
-        conditions: BuiltinImplConditions<'tcx>,
+        self_ty: Ty<'tcx>,
         candidates: &mut SelectionCandidateSet<'tcx>,
+        sizedness: SizedTraitKind,
     ) {
-        match conditions {
-            BuiltinImplConditions::Where(_) => {
-                candidates.vec.push(BuiltinCandidate);
+        match *self_ty.kind() {
+            // Always sized.
+            ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
+            | ty::Uint(_)
+            | ty::Int(_)
+            | ty::Bool
+            | ty::Float(_)
+            | ty::FnDef(..)
+            | ty::FnPtr(..)
+            | ty::RawPtr(..)
+            | ty::Char
+            | ty::Ref(..)
+            | ty::Coroutine(..)
+            | ty::CoroutineWitness(..)
+            | ty::Array(..)
+            | ty::Closure(..)
+            | ty::CoroutineClosure(..)
+            | ty::Never
+            | ty::Error(_) => {
+                candidates.vec.push(SizedCandidate);
+            }
+
+            // Conditionally `Sized`.
+            ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => {
+                candidates.vec.push(SizedCandidate);
             }
-            BuiltinImplConditions::None => {}
-            BuiltinImplConditions::Ambiguous => {
+
+            // `MetaSized` but not `Sized`.
+            ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness {
+                SizedTraitKind::Sized => {}
+                SizedTraitKind::MetaSized => {
+                    candidates.vec.push(SizedCandidate);
+                }
+            },
+
+            // Not `MetaSized` or `Sized`.
+            ty::Foreign(..) => {}
+
+            ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => {}
+
+            ty::Infer(ty::TyVar(_)) => {
                 candidates.ambiguous = true;
             }
+
+            // Only appears when assembling higher-ranked `for<T> T: Sized`.
+            ty::Bound(..) => {}
+
+            ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
+                bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty);
+            }
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 545531f927a..ee8cef20279 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -21,7 +21,7 @@ use thin_vec::thin_vec;
 use tracing::{debug, instrument};
 
 use super::SelectionCandidate::{self, *};
-use super::{BuiltinImplConditions, PredicateObligations, SelectionContext};
+use super::{PredicateObligations, SelectionContext};
 use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
 use crate::traits::util::{self, closure_trait_ref_and_return_type};
 use crate::traits::{
@@ -257,16 +257,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         debug!(?obligation, "confirm_builtin_candidate");
         let tcx = self.tcx();
         let trait_def = obligation.predicate.def_id();
-        let conditions = match tcx.as_lang_item(trait_def) {
-            Some(LangItem::Sized) => self.sizedness_conditions(obligation, SizedTraitKind::Sized),
+        let self_ty = self.infcx.shallow_resolve(
+            self.infcx.enter_forall_and_leak_universe(obligation.predicate.self_ty()),
+        );
+        let types = match tcx.as_lang_item(trait_def) {
+            Some(LangItem::Sized) => self.sizedness_conditions(self_ty, SizedTraitKind::Sized),
             Some(LangItem::MetaSized) => {
-                self.sizedness_conditions(obligation, SizedTraitKind::MetaSized)
+                self.sizedness_conditions(self_ty, SizedTraitKind::MetaSized)
             }
             Some(LangItem::PointeeSized) => {
                 bug!("`PointeeSized` is removing during lowering");
             }
-            Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation),
-            Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation),
+            Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(self_ty),
+            Some(LangItem::FusedIterator) => {
+                if self.coroutine_is_gen(self_ty) {
+                    ty::Binder::dummy(vec![])
+                } else {
+                    unreachable!("tried to assemble `FusedIterator` for non-gen coroutine");
+                }
+            }
             Some(
                 LangItem::Destruct
                 | LangItem::DiscriminantKind
@@ -274,12 +283,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 | LangItem::PointeeTrait
                 | LangItem::Tuple
                 | LangItem::Unpin,
-            ) => BuiltinImplConditions::Where(ty::Binder::dummy(vec![])),
+            ) => ty::Binder::dummy(vec![]),
             other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"),
         };
-        let BuiltinImplConditions::Where(types) = conditions else {
-            bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);
-        };
         let types = self.infcx.enter_forall_and_leak_universe(types);
 
         let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
@@ -403,6 +409,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             let self_ty =
                 obligation.predicate.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty));
+            let self_ty = self.infcx.enter_forall_and_leak_universe(self_ty);
 
             let types = self.constituent_types_for_ty(self_ty)?;
             let types = self.infcx.enter_forall_and_leak_universe(types);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index c9930c69b32..2e65750db25 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -188,18 +188,6 @@ struct EvaluatedCandidate<'tcx> {
     evaluation: EvaluationResult,
 }
 
-/// When does the builtin impl for `T: Trait` apply?
-#[derive(Debug)]
-enum BuiltinImplConditions<'tcx> {
-    /// The impl is conditional on `T1, T2, ...: Trait`.
-    Where(ty::Binder<'tcx, Vec<Ty<'tcx>>>),
-    /// There is no built-in impl. There may be some other
-    /// candidate (a where-clause or user-defined impl).
-    None,
-    /// It is unknown whether there is an impl.
-    Ambiguous,
-}
-
 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     pub fn new(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> {
         SelectionContext {
@@ -2104,14 +2092,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
 impl<'tcx> SelectionContext<'_, 'tcx> {
     fn sizedness_conditions(
         &mut self,
-        obligation: &PolyTraitObligation<'tcx>,
+        self_ty: Ty<'tcx>,
         sizedness: SizedTraitKind,
-    ) -> BuiltinImplConditions<'tcx> {
-        use self::BuiltinImplConditions::{Ambiguous, None, Where};
-
-        // NOTE: binder moved to (*)
-        let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
-
+    ) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
         match self_ty.kind() {
             ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
             | ty::Uint(_)
@@ -2129,59 +2112,44 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             | ty::Closure(..)
             | ty::CoroutineClosure(..)
             | ty::Never
-            | ty::Error(_) => {
-                // safe for everything
-                Where(ty::Binder::dummy(Vec::new()))
-            }
+            | ty::Error(_) => ty::Binder::dummy(vec![]),
 
             ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness {
-                SizedTraitKind::Sized => None,
-                SizedTraitKind::MetaSized => Where(ty::Binder::dummy(Vec::new())),
+                SizedTraitKind::Sized => unreachable!("tried to assemble `Sized` for unsized type"),
+                SizedTraitKind::MetaSized => ty::Binder::dummy(vec![]),
             },
 
-            ty::Foreign(..) => None,
+            ty::Foreign(..) => unreachable!("tried to assemble `Sized` for unsized type"),
 
-            ty::Tuple(tys) => Where(
-                obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])),
-            ),
+            ty::Tuple(tys) => {
+                ty::Binder::dummy(tys.last().map_or_else(Vec::new, |&last| vec![last]))
+            }
 
-            ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])),
+            ty::Pat(ty, _) => ty::Binder::dummy(vec![*ty]),
 
             ty::Adt(def, args) => {
                 if let Some(crit) = def.sizedness_constraint(self.tcx(), sizedness) {
-                    // (*) binder moved here
-                    Where(obligation.predicate.rebind(vec![crit.instantiate(self.tcx(), args)]))
+                    ty::Binder::dummy(vec![crit.instantiate(self.tcx(), args)])
                 } else {
-                    Where(ty::Binder::dummy(Vec::new()))
+                    ty::Binder::dummy(vec![])
                 }
             }
 
-            // FIXME(unsafe_binders): This binder needs to be squashed
-            ty::UnsafeBinder(binder_ty) => Where(binder_ty.map_bound(|ty| vec![ty])),
-
-            ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None,
-            ty::Infer(ty::TyVar(_)) => Ambiguous,
-
-            // We can make this an ICE if/once we actually instantiate the trait obligation eagerly.
-            ty::Bound(..) => None,
+            ty::UnsafeBinder(binder_ty) => binder_ty.map_bound(|ty| vec![ty]),
 
-            ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
-                bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty);
+            ty::Alias(..)
+            | ty::Param(_)
+            | ty::Placeholder(..)
+            | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
+            | ty::Bound(..) => {
+                bug!("asked to assemble `Sized` of unexpected type: {:?}", self_ty);
             }
         }
     }
 
-    fn copy_clone_conditions(
-        &mut self,
-        obligation: &PolyTraitObligation<'tcx>,
-    ) -> BuiltinImplConditions<'tcx> {
-        // NOTE: binder moved to (*)
-        let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
-
-        use self::BuiltinImplConditions::{Ambiguous, None, Where};
-
+    fn copy_clone_conditions(&mut self, self_ty: Ty<'tcx>) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
         match *self_ty.kind() {
-            ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) => Where(ty::Binder::dummy(Vec::new())),
+            ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) => ty::Binder::dummy(vec![]),
 
             ty::Uint(_)
             | ty::Int(_)
@@ -2193,127 +2161,78 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             | ty::Never
             | ty::Ref(_, _, hir::Mutability::Not)
             | ty::Array(..) => {
-                // Implementations provided in libcore
-                None
+                unreachable!("tried to assemble `Sized` for type with libcore-provided impl")
             }
 
             // FIXME(unsafe_binder): Should we conditionally
             // (i.e. universally) implement copy/clone?
-            ty::UnsafeBinder(_) => None,
-
-            ty::Dynamic(..)
-            | ty::Str
-            | ty::Slice(..)
-            | ty::Foreign(..)
-            | ty::Ref(_, _, hir::Mutability::Mut) => None,
+            ty::UnsafeBinder(_) => unreachable!("tried to assemble `Sized` for unsafe binder"),
 
             ty::Tuple(tys) => {
                 // (*) binder moved here
-                Where(obligation.predicate.rebind(tys.iter().collect()))
+                ty::Binder::dummy(tys.iter().collect())
             }
 
             ty::Pat(ty, _) => {
                 // (*) binder moved here
-                Where(obligation.predicate.rebind(vec![ty]))
+                ty::Binder::dummy(vec![ty])
             }
 
             ty::Coroutine(coroutine_def_id, args) => {
                 match self.tcx().coroutine_movability(coroutine_def_id) {
-                    hir::Movability::Static => None,
+                    hir::Movability::Static => {
+                        unreachable!("tried to assemble `Sized` for static coroutine")
+                    }
                     hir::Movability::Movable => {
                         if self.tcx().features().coroutine_clone() {
-                            let resolved_upvars =
-                                self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
-                            let resolved_witness =
-                                self.infcx.shallow_resolve(args.as_coroutine().witness());
-                            if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
-                                // Not yet resolved.
-                                Ambiguous
-                            } else {
-                                let all = args
-                                    .as_coroutine()
+                            ty::Binder::dummy(
+                                args.as_coroutine()
                                     .upvar_tys()
                                     .iter()
                                     .chain([args.as_coroutine().witness()])
-                                    .collect::<Vec<_>>();
-                                Where(obligation.predicate.rebind(all))
-                            }
+                                    .collect::<Vec<_>>(),
+                            )
                         } else {
-                            None
+                            unreachable!(
+                                "tried to assemble `Sized` for coroutine without enabled feature"
+                            )
                         }
                     }
                 }
             }
 
-            ty::CoroutineWitness(def_id, args) => {
-                let hidden_types = rebind_coroutine_witness_types(
-                    self.infcx.tcx,
-                    def_id,
-                    args,
-                    obligation.predicate.bound_vars(),
-                );
-                Where(hidden_types)
-            }
+            ty::CoroutineWitness(def_id, args) => self
+                .infcx
+                .tcx
+                .coroutine_hidden_types(def_id)
+                .instantiate(self.infcx.tcx, args)
+                .map_bound(|witness| witness.types.to_vec()),
 
-            ty::Closure(_, args) => {
-                // (*) binder moved here
-                let ty = self.infcx.shallow_resolve(args.as_closure().tupled_upvars_ty());
-                if let ty::Infer(ty::TyVar(_)) = ty.kind() {
-                    // Not yet resolved.
-                    Ambiguous
-                } else {
-                    Where(obligation.predicate.rebind(args.as_closure().upvar_tys().to_vec()))
-                }
-            }
+            ty::Closure(_, args) => ty::Binder::dummy(args.as_closure().upvar_tys().to_vec()),
 
             ty::CoroutineClosure(_, args) => {
-                // (*) binder moved here
-                let ty = self.infcx.shallow_resolve(args.as_coroutine_closure().tupled_upvars_ty());
-                if let ty::Infer(ty::TyVar(_)) = ty.kind() {
-                    // Not yet resolved.
-                    Ambiguous
-                } else {
-                    Where(
-                        obligation
-                            .predicate
-                            .rebind(args.as_coroutine_closure().upvar_tys().to_vec()),
-                    )
-                }
+                ty::Binder::dummy(args.as_coroutine_closure().upvar_tys().to_vec())
             }
 
-            ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {
-                // Fallback to whatever user-defined impls exist in this case.
-                None
-            }
-
-            ty::Infer(ty::TyVar(_)) => {
-                // Unbound type variable. Might or might not have
-                // applicable impls and so forth, depending on what
-                // those type variables wind up being bound to.
-                Ambiguous
-            }
-
-            // We can make this an ICE if/once we actually instantiate the trait obligation eagerly.
-            ty::Bound(..) => None,
-
-            ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
+            ty::Foreign(..)
+            | ty::Str
+            | ty::Slice(_)
+            | ty::Dynamic(..)
+            | ty::Adt(..)
+            | ty::Alias(..)
+            | ty::Param(..)
+            | ty::Placeholder(..)
+            | ty::Bound(..)
+            | ty::Ref(_, _, ty::Mutability::Mut)
+            | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
                 bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty);
             }
         }
     }
 
-    fn fused_iterator_conditions(
-        &mut self,
-        obligation: &PolyTraitObligation<'tcx>,
-    ) -> BuiltinImplConditions<'tcx> {
-        let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
-        if let ty::Coroutine(did, ..) = *self_ty.kind()
-            && self.tcx().coroutine_is_gen(did)
-        {
-            BuiltinImplConditions::Where(ty::Binder::dummy(Vec::new()))
-        } else {
-            BuiltinImplConditions::None
-        }
+    fn coroutine_is_gen(&mut self, self_ty: Ty<'tcx>) -> bool {
+        matches!(*self_ty.kind(), ty::Coroutine(did, ..)
+            if self.tcx().coroutine_is_gen(did))
     }
 
     /// For default impls, we need to break apart a type into its
@@ -2330,9 +2249,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
     #[instrument(level = "debug", skip(self), ret)]
     fn constituent_types_for_ty(
         &self,
-        t: ty::Binder<'tcx, Ty<'tcx>>,
+        t: Ty<'tcx>,
     ) -> Result<ty::Binder<'tcx, Vec<Ty<'tcx>>>, SelectionError<'tcx>> {
-        Ok(match *t.skip_binder().kind() {
+        Ok(match *t.kind() {
             ty::Uint(_)
             | ty::Int(_)
             | ty::Bool
@@ -2349,8 +2268,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             // `assemble_candidates_from_auto_impls`.
             ty::Foreign(..) => ty::Binder::dummy(Vec::new()),
 
-            // FIXME(unsafe_binders): Squash the double binder for now, I guess.
-            ty::UnsafeBinder(_) => return Err(SelectionError::Unimplemented),
+            ty::UnsafeBinder(ty) => ty.map_bound(|ty| vec![ty]),
 
             // Treat this like `struct str([u8]);`
             ty::Str => ty::Binder::dummy(vec![Ty::new_slice(self.tcx(), self.tcx().types.u8)]),
@@ -2364,40 +2282,47 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 bug!("asked to assemble constituent types of unexpected type: {:?}", t);
             }
 
-            ty::RawPtr(element_ty, _) | ty::Ref(_, element_ty, _) => t.rebind(vec![element_ty]),
+            ty::RawPtr(element_ty, _) | ty::Ref(_, element_ty, _) => {
+                ty::Binder::dummy(vec![element_ty])
+            }
 
-            ty::Pat(ty, _) | ty::Array(ty, _) | ty::Slice(ty) => t.rebind(vec![ty]),
+            ty::Pat(ty, _) | ty::Array(ty, _) | ty::Slice(ty) => ty::Binder::dummy(vec![ty]),
 
             ty::Tuple(tys) => {
                 // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
-                t.rebind(tys.iter().collect())
+                ty::Binder::dummy(tys.iter().collect())
             }
 
             ty::Closure(_, args) => {
                 let ty = self.infcx.shallow_resolve(args.as_closure().tupled_upvars_ty());
-                t.rebind(vec![ty])
+                ty::Binder::dummy(vec![ty])
             }
 
             ty::CoroutineClosure(_, args) => {
                 let ty = self.infcx.shallow_resolve(args.as_coroutine_closure().tupled_upvars_ty());
-                t.rebind(vec![ty])
+                ty::Binder::dummy(vec![ty])
             }
 
             ty::Coroutine(_, args) => {
                 let ty = self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
                 let witness = args.as_coroutine().witness();
-                t.rebind([ty].into_iter().chain(iter::once(witness)).collect())
+                ty::Binder::dummy([ty].into_iter().chain(iter::once(witness)).collect())
             }
 
-            ty::CoroutineWitness(def_id, args) => {
-                rebind_coroutine_witness_types(self.infcx.tcx, def_id, args, t.bound_vars())
-            }
+            ty::CoroutineWitness(def_id, args) => self
+                .infcx
+                .tcx
+                .coroutine_hidden_types(def_id)
+                .instantiate(self.infcx.tcx, args)
+                .map_bound(|witness| witness.types.to_vec()),
 
             // For `PhantomData<T>`, we pass `T`.
-            ty::Adt(def, args) if def.is_phantom_data() => t.rebind(args.types().collect()),
+            ty::Adt(def, args) if def.is_phantom_data() => {
+                ty::Binder::dummy(args.types().collect())
+            }
 
             ty::Adt(def, args) => {
-                t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), args)).collect())
+                ty::Binder::dummy(def.all_fields().map(|f| f.ty(self.tcx(), args)).collect())
             }
 
             ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
@@ -2408,7 +2333,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                     // which enforces a DAG between the functions requiring
                     // the auto trait bounds in question.
                     match self.tcx().type_of_opaque(def_id) {
-                        Ok(ty) => t.rebind(vec![ty.instantiate(self.tcx(), args)]),
+                        Ok(ty) => ty::Binder::dummy(vec![ty.instantiate(self.tcx(), args)]),
                         Err(_) => {
                             return Err(SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id));
                         }
@@ -2880,23 +2805,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
     }
 }
 
-fn rebind_coroutine_witness_types<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    def_id: DefId,
-    args: ty::GenericArgsRef<'tcx>,
-    bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
-) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
-    let bound_coroutine_types = tcx.coroutine_hidden_types(def_id).skip_binder();
-    let shifted_coroutine_types =
-        tcx.shift_bound_var_indices(bound_vars.len(), bound_coroutine_types.skip_binder());
-    ty::Binder::bind_with_vars(
-        ty::EarlyBinder::bind(shifted_coroutine_types.types.to_vec()).instantiate(tcx, args),
-        tcx.mk_bound_variable_kinds_from_iter(
-            bound_vars.iter().chain(bound_coroutine_types.bound_vars()),
-        ),
-    )
-}
-
 impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {
     fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> {
         TraitObligationStackList::with(self)
diff --git a/compiler/stable_mir/src/mir/alloc.rs b/compiler/stable_mir/src/mir/alloc.rs
index 0d45e59885c..9a94551f3ec 100644
--- a/compiler/stable_mir/src/mir/alloc.rs
+++ b/compiler/stable_mir/src/mir/alloc.rs
@@ -23,6 +23,9 @@ pub enum GlobalAlloc {
     Static(StaticDef),
     /// The alloc ID points to memory.
     Memory(Allocation),
+    /// The first pointer-sized segment of a type id. On 64 bit systems, the 128 bit type id
+    /// is split into two segments, on 32 bit systems there are 4 segments, and so on.
+    TypeId { ty: Ty },
 }
 
 impl From<AllocId> for GlobalAlloc {
diff --git a/compiler/stable_mir/src/unstable/convert/stable/mir.rs b/compiler/stable_mir/src/unstable/convert/stable/mir.rs
index f6f4706e40b..ad39fc37600 100644
--- a/compiler/stable_mir/src/unstable/convert/stable/mir.rs
+++ b/compiler/stable_mir/src/unstable/convert/stable/mir.rs
@@ -864,6 +864,9 @@ impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
             mir::interpret::GlobalAlloc::Memory(alloc) => {
                 GlobalAlloc::Memory(alloc.stable(tables, cx))
             }
+            mir::interpret::GlobalAlloc::TypeId { ty } => {
+                GlobalAlloc::TypeId { ty: ty.stable(tables, cx) }
+            }
         }
     }
 }
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 4290bb7a8a9..4ad65e678c3 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -107,8 +107,10 @@
 #![feature(char_max_len)]
 #![feature(clone_to_uninit)]
 #![feature(coerce_unsized)]
+#![feature(const_default)]
 #![feature(const_eval_select)]
 #![feature(const_heap)]
+#![feature(const_trait_impl)]
 #![feature(core_intrinsics)]
 #![feature(deprecated_suggestion)]
 #![feature(deref_pure_trait)]
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 187d1ca71d9..58baa07bc17 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -2611,7 +2611,8 @@ impl_eq! { Cow<'a, str>, &'b str }
 impl_eq! { Cow<'a, str>, String }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Default for String {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl const Default for String {
     /// Creates an empty `String`.
     #[inline]
     fn default() -> String {
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index c8341750f4d..9dac58bac4f 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -3895,7 +3895,8 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for Vec<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl<T> const Default for Vec<T> {
     /// Creates an empty `Vec<T>`.
     ///
     /// The vector will not allocate until elements are pushed onto it.
diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml
index 95b0962b082..541c99c828d 100644
--- a/library/compiler-builtins/.github/workflows/main.yaml
+++ b/library/compiler-builtins/.github/workflows/main.yaml
@@ -195,6 +195,25 @@ jobs:
       run: ./ci/update-musl.sh
     - run: cargo clippy --workspace --all-targets
 
+  build-custom:
+    name: Build custom target
+    runs-on: ubuntu-24.04
+    timeout-minutes: 10
+    steps:
+    - uses: actions/checkout@v4
+    - name: Install Rust
+      run: |
+        rustup update nightly --no-self-update
+        rustup default nightly
+        rustup component add rust-src
+    - uses: Swatinem/rust-cache@v2
+    - run: |
+        # Ensure we can build with custom target.json files (these can interact
+        # poorly with build scripts)
+        cargo build -p compiler_builtins -p libm \
+          --target etc/thumbv7em-none-eabi-renamed.json \
+          -Zbuild-std=core
+
   benchmarks:
     name: Benchmarks
     timeout-minutes: 20
@@ -331,6 +350,7 @@ jobs:
   success:
     needs:
       - benchmarks
+      - build-custom
       - clippy
       - extensive
       - miri
diff --git a/library/compiler-builtins/builtins-test-intrinsics/build.rs b/library/compiler-builtins/builtins-test-intrinsics/build.rs
index 89b126ff2b2..b82581262f7 100644
--- a/library/compiler-builtins/builtins-test-intrinsics/build.rs
+++ b/library/compiler-builtins/builtins-test-intrinsics/build.rs
@@ -6,6 +6,5 @@ fn main() {
     println!("cargo::rerun-if-changed=../configure.rs");
 
     let target = builtins_configure::Target::from_env();
-    builtins_configure::configure_f16_f128(&target);
     builtins_configure::configure_aliases(&target);
 }
diff --git a/library/compiler-builtins/builtins-test/benches/float_cmp.rs b/library/compiler-builtins/builtins-test/benches/float_cmp.rs
index 87a89efb5a4..da29b5d3132 100644
--- a/library/compiler-builtins/builtins-test/benches/float_cmp.rs
+++ b/library/compiler-builtins/builtins-test/benches/float_cmp.rs
@@ -177,6 +177,7 @@ float_bench! {
     ],
 }
 
+#[cfg(f128_enabled)]
 float_bench! {
     name: cmp_f128_gt,
     sig: (a: f128, b: f128) -> CmpResult,
@@ -189,6 +190,7 @@ float_bench! {
     asm: []
 }
 
+#[cfg(f128_enabled)]
 float_bench! {
     name: cmp_f128_unord,
     sig: (a: f128, b: f128) -> CmpResult,
diff --git a/library/compiler-builtins/builtins-test/build.rs b/library/compiler-builtins/builtins-test/build.rs
index e8f4eb4dd22..5b2dcd12ef8 100644
--- a/library/compiler-builtins/builtins-test/build.rs
+++ b/library/compiler-builtins/builtins-test/build.rs
@@ -116,5 +116,4 @@ fn main() {
     }
 
     builtins_configure::configure_aliases(&target);
-    builtins_configure::configure_f16_f128(&target);
 }
diff --git a/library/compiler-builtins/builtins-test/tests/conv.rs b/library/compiler-builtins/builtins-test/tests/conv.rs
index 491915d9bb1..7d729364fae 100644
--- a/library/compiler-builtins/builtins-test/tests/conv.rs
+++ b/library/compiler-builtins/builtins-test/tests/conv.rs
@@ -118,7 +118,7 @@ mod i_to_f {
         i128, __floattidf;
     }
 
-    #[cfg(not(feature = "no-f16-f128"))]
+    #[cfg(f128_enabled)]
     #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
     i_to_f! { f128, Quad, not(feature = "no-sys-f128-int-convert"),
         u32, __floatunsitf;
@@ -129,7 +129,7 @@ mod i_to_f {
         i128, __floattitf;
     }
 
-    #[cfg(not(feature = "no-f16-f128"))]
+    #[cfg(f128_enabled)]
     #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
     i_to_f! { f128, Quad, not(feature = "no-sys-f128-int-convert"),
         u32, __floatunsikf;
diff --git a/library/compiler-builtins/builtins-test/tests/div_rem.rs b/library/compiler-builtins/builtins-test/tests/div_rem.rs
index 5ae653cc90c..e8327f9b4b8 100644
--- a/library/compiler-builtins/builtins-test/tests/div_rem.rs
+++ b/library/compiler-builtins/builtins-test/tests/div_rem.rs
@@ -147,7 +147,7 @@ mod float_div {
         f64, __divdf3, Double, all();
     }
 
-    #[cfg(not(feature = "no-f16-f128"))]
+    #[cfg(f128_enabled)]
     #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
     float! {
         f128, __divtf3, Quad,
@@ -156,7 +156,7 @@ mod float_div {
         not(any(feature = "no-sys-f128", all(target_arch = "aarch64", target_os = "linux")));
     }
 
-    #[cfg(not(feature = "no-f16-f128"))]
+    #[cfg(f128_enabled)]
     #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
     float! {
         f128, __divkf3, Quad, not(feature = "no-sys-f128");
diff --git a/library/compiler-builtins/ci/run.sh b/library/compiler-builtins/ci/run.sh
index 27b9686eac6..8b7965bb205 100755
--- a/library/compiler-builtins/ci/run.sh
+++ b/library/compiler-builtins/ci/run.sh
@@ -54,29 +54,26 @@ 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
+"${symcheck[@]}" "$target" -- -p compiler_builtins
+"${symcheck[@]}" "$target" -- -p compiler_builtins --release
+"${symcheck[@]}" "$target" -- -p compiler_builtins --features c
+"${symcheck[@]}" "$target" -- -p compiler_builtins --features c --release
+"${symcheck[@]}" "$target" -- -p compiler_builtins --features no-asm
+"${symcheck[@]}" "$target" -- -p compiler_builtins --features no-asm --release
+"${symcheck[@]}" "$target" -- -p compiler_builtins --features no-f16-f128
+"${symcheck[@]}" "$target" -- -p compiler_builtins --features no-f16-f128 --release
 
 run_intrinsics_test() {
-    args=(
-        --target "$target" --verbose \
-        --manifest-path builtins-test-intrinsics/Cargo.toml
-    )
-    args+=( "$@" )
+    build_args=(--verbose --manifest-path builtins-test-intrinsics/Cargo.toml)
+    build_args+=("$@")
 
     # symcheck also checks the results of builtins-test-intrinsics
-    "${symcheck[@]}" "${args[@]}"
+    "${symcheck[@]}" "$target" -- "${build_args[@]}"
 
     # FIXME: we get access violations on Windows, our entrypoint may need to
     # be tweaked.
     if [ "${BUILD_ONLY:-}" != "1" ] && ! [[ "$target" = *"windows"* ]]; then
-        cargo run "${args[@]}"
+        cargo run --target "$target" "${build_args[@]}"
     fi
 }
 
diff --git a/library/compiler-builtins/compiler-builtins/build.rs b/library/compiler-builtins/compiler-builtins/build.rs
index 018899faf1d..8f51c12b535 100644
--- a/library/compiler-builtins/compiler-builtins/build.rs
+++ b/library/compiler-builtins/compiler-builtins/build.rs
@@ -2,7 +2,7 @@ mod configure;
 
 use std::env;
 
-use configure::{Target, configure_aliases, configure_f16_f128};
+use configure::{Target, configure_aliases};
 
 fn main() {
     println!("cargo::rerun-if-changed=build.rs");
@@ -12,7 +12,6 @@ fn main() {
     let cwd = env::current_dir().unwrap();
 
     configure_check_cfg();
-    configure_f16_f128(&target);
     configure_aliases(&target);
 
     configure_libm(&target);
diff --git a/library/compiler-builtins/compiler-builtins/configure.rs b/library/compiler-builtins/compiler-builtins/configure.rs
index d825f35a9aa..9721ddf090c 100644
--- a/library/compiler-builtins/compiler-builtins/configure.rs
+++ b/library/compiler-builtins/compiler-builtins/configure.rs
@@ -1,6 +1,7 @@
 // Configuration that is shared between `compiler_builtins` and `builtins_test`.
 
-use std::env;
+use std::process::{Command, Stdio};
+use std::{env, str};
 
 #[derive(Debug)]
 #[allow(dead_code)]
@@ -16,6 +17,8 @@ pub struct Target {
     pub pointer_width: u8,
     pub little_endian: bool,
     pub features: Vec<String>,
+    pub reliable_f128: bool,
+    pub reliable_f16: bool,
 }
 
 impl Target {
@@ -32,6 +35,26 @@ impl Target {
             .map(|s| s.to_lowercase().replace("_", "-"))
             .collect();
 
+        // Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
+        // to get consistent output regardless of channel (`f16`/`f128` config options are hidden
+        // on stable otherwise).
+        let mut cmd = Command::new(env::var("RUSTC").unwrap());
+        cmd.args(["--print=cfg", "--target", &triple])
+            .env("RUSTC_BOOTSTRAP", "1")
+            .stderr(Stdio::inherit());
+        let out = cmd
+            .output()
+            .unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
+        let rustc_cfg = str::from_utf8(&out.stdout).unwrap();
+
+        // If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
+        // choice and leave `f16` and `f128` disabled.
+        let rustc_output_ok = out.status.success();
+        let reliable_f128 =
+            rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
+        let reliable_f16 =
+            rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");
+
         Self {
             triple,
             triple_split,
@@ -51,6 +74,8 @@ impl Target {
                 .split(",")
                 .map(ToOwned::to_owned)
                 .collect(),
+            reliable_f128,
+            reliable_f16,
         }
     }
 
@@ -74,63 +99,24 @@ pub fn configure_aliases(target: &Target) {
     if target.triple_split[0] == "thumbv6m" || target.triple_split[0] == "thumbv8m.base" {
         println!("cargo:rustc-cfg=thumb_1")
     }
-}
-
-/// Configure whether or not `f16` and `f128` support should be enabled.
-pub fn configure_f16_f128(target: &Target) {
-    // Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
-    // that the backend will not crash when using these types and generates code that can be called
-    // without crashing (no infinite recursion). This does not mean that the platform doesn't have
-    // ABI or other bugs.
-    //
-    // We do this here rather than in `rust-lang/rust` because configuring via cargo features is
-    // not straightforward.
-    //
-    // Original source of this list:
-    // <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
-    let f16_enabled = match target.arch.as_str() {
-        // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
-        "arm64ec" => false,
-        // Selection failure <https://github.com/llvm/llvm-project/issues/50374>
-        "s390x" => false,
-        // Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
-        "csky" => false,
-        "hexagon" => false,
-        "powerpc" | "powerpc64" => false,
-        "sparc" | "sparc64" => false,
-        "wasm32" | "wasm64" => false,
-        // Most everything else works as of LLVM 19
-        _ => true,
-    };
 
-    let f128_enabled = match target.arch.as_str() {
-        // Unsupported (libcall is not supported) <https://github.com/llvm/llvm-project/issues/121122>
-        "amdgpu" => false,
-        // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
-        "arm64ec" => false,
-        // FIXME(llvm20): fixed by <https://github.com/llvm/llvm-project/pull/117525>
-        "mips64" | "mips64r6" => false,
-        // Selection failure <https://github.com/llvm/llvm-project/issues/95471>
-        "nvptx64" => false,
-        // Selection failure <https://github.com/llvm/llvm-project/issues/101545>
-        "powerpc64" if &target.os == "aix" => false,
-        // Selection failure <https://github.com/llvm/llvm-project/issues/41838>
-        "sparc" => false,
-        // Most everything else works as of LLVM 19
-        _ => true,
-    };
+    /* Not all backends support `f16` and `f128` to the same level on all architectures, so we
+     * need to disable things if the compiler may crash. See configuration at:
+     * * https://github.com/rust-lang/rust/blob/c65dccabacdfd6c8a7f7439eba13422fdd89b91e/compiler/rustc_codegen_llvm/src/llvm_util.rs#L367-L432
+     * * https://github.com/rust-lang/rustc_codegen_gcc/blob/4b5c44b14166083eef8d71f15f5ea1f53fc976a0/src/lib.rs#L496-L507
+     * * https://github.com/rust-lang/rustc_codegen_cranelift/blob/c713ffab3c6e28ab4b4dd4e392330f786ea657ad/src/lib.rs#L196-L226
+     */
 
-    // If the feature is set, disable these types.
-    let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some();
+    // If the feature is set, disable both of these types.
+    let no_f16_f128 = target.cargo_features.iter().any(|s| s == "no-f16-f128");
 
     println!("cargo::rustc-check-cfg=cfg(f16_enabled)");
-    println!("cargo::rustc-check-cfg=cfg(f128_enabled)");
-
-    if f16_enabled && !disable_both {
+    if target.reliable_f16 && !no_f16_f128 {
         println!("cargo::rustc-cfg=f16_enabled");
     }
 
-    if f128_enabled && !disable_both {
+    println!("cargo::rustc-check-cfg=cfg(f128_enabled)");
+    if target.reliable_f128 && !no_f16_f128 {
         println!("cargo::rustc-cfg=f128_enabled");
     }
 }
diff --git a/library/compiler-builtins/compiler-builtins/src/aarch64.rs b/library/compiler-builtins/compiler-builtins/src/aarch64.rs
index 80392187c89..a72b30d29f0 100644
--- a/library/compiler-builtins/compiler-builtins/src/aarch64.rs
+++ b/library/compiler-builtins/compiler-builtins/src/aarch64.rs
@@ -5,7 +5,7 @@ use core::intrinsics;
 intrinsics! {
     #[unsafe(naked)]
     #[cfg(all(target_os = "uefi", not(feature = "no-asm")))]
-    pub unsafe extern "C" fn __chkstk() {
+    pub unsafe extern "custom" fn __chkstk() {
         core::arch::naked_asm!(
             ".p2align 2",
             "lsl    x16, x15, #4",
diff --git a/library/compiler-builtins/compiler-builtins/src/arm.rs b/library/compiler-builtins/compiler-builtins/src/arm.rs
index a7d84e49b34..fbec93ca431 100644
--- a/library/compiler-builtins/compiler-builtins/src/arm.rs
+++ b/library/compiler-builtins/compiler-builtins/src/arm.rs
@@ -9,11 +9,10 @@ unsafe extern "C" {
 }
 
 // SAFETY: these are defined in compiler-builtins
-// FIXME(extern_custom), this isn't always the correct ABI
-unsafe extern "aapcs" {
+unsafe extern "custom" {
     // 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;
+    fn __aeabi_idiv();
 }
 
 intrinsics! {
@@ -21,7 +20,7 @@ intrinsics! {
     // custom calling convention which can't be implemented using a normal Rust function.
     #[unsafe(naked)]
     #[cfg(not(target_env = "msvc"))]
-    pub unsafe extern "C" fn __aeabi_uidivmod() {
+    pub unsafe extern "custom" fn __aeabi_uidivmod() {
         core::arch::naked_asm!(
             "push {{lr}}",
             "sub sp, sp, #4",
@@ -35,7 +34,7 @@ intrinsics! {
     }
 
     #[unsafe(naked)]
-    pub unsafe extern "C" fn __aeabi_uldivmod() {
+    pub unsafe extern "custom" fn __aeabi_uldivmod() {
         core::arch::naked_asm!(
             "push {{r4, lr}}",
             "sub sp, sp, #16",
@@ -51,7 +50,7 @@ intrinsics! {
     }
 
     #[unsafe(naked)]
-    pub unsafe extern "C" fn __aeabi_idivmod() {
+    pub unsafe extern "custom" fn __aeabi_idivmod() {
         core::arch::naked_asm!(
             "push {{r0, r1, r4, lr}}",
             "bl {trampoline}",
@@ -64,7 +63,7 @@ intrinsics! {
     }
 
     #[unsafe(naked)]
-    pub unsafe extern "C" fn __aeabi_ldivmod() {
+    pub unsafe extern "custom" fn __aeabi_ldivmod() {
         core::arch::naked_asm!(
             "push {{r4, lr}}",
             "sub sp, sp, #16",
@@ -135,8 +134,8 @@ intrinsics! {
     /// eight bytes.
     #[cfg(not(target_vendor = "apple"))]
     pub unsafe extern "aapcs" fn __aeabi_memcpy8(dst: *mut u8, src: *const u8, n: usize) {
-        debug_assert!(dst.addr() & 7 == 0);
-        debug_assert!(src.addr() & 7 == 0);
+        debug_assert!(dst.addr().is_multiple_of(8));
+        debug_assert!(src.addr().is_multiple_of(8));
 
         // SAFETY: memcpy preconditions apply, less strict alignment.
         unsafe { __aeabi_memcpy4(dst, src, n) };
@@ -161,8 +160,8 @@ intrinsics! {
     /// four bytes.
     #[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
     pub unsafe extern "aapcs" fn __aeabi_memmove4(dst: *mut u8, src: *const u8, n: usize) {
-        debug_assert!(dst.addr() & 3 == 0);
-        debug_assert!(src.addr() & 3 == 0);
+        debug_assert!(dst.addr().is_multiple_of(4));
+        debug_assert!(src.addr().is_multiple_of(4));
 
         // SAFETY: same preconditions, less strict aligment.
         unsafe { __aeabi_memmove(dst, src, n) };
@@ -176,8 +175,8 @@ intrinsics! {
     /// eight bytes.
     #[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
     pub unsafe extern "aapcs" fn __aeabi_memmove8(dst: *mut u8, src: *const u8, n: usize) {
-        debug_assert!(dst.addr() & 7 == 0);
-        debug_assert!(src.addr() & 7 == 0);
+        debug_assert!(dst.addr().is_multiple_of(8));
+        debug_assert!(src.addr().is_multiple_of(8));
 
         // SAFETY: memmove preconditions apply, less strict alignment.
         unsafe { __aeabi_memmove(dst, src, n) };
@@ -236,7 +235,7 @@ intrinsics! {
     /// eight bytes.
     #[cfg(not(target_vendor = "apple"))]
     pub unsafe extern "aapcs" fn __aeabi_memset8(dst: *mut u8, n: usize, c: i32) {
-        debug_assert!(dst.addr() & 7 == 0);
+        debug_assert!(dst.addr().is_multiple_of(8));
 
         // SAFETY: memset preconditions apply, less strict alignment.
         unsafe { __aeabi_memset4(dst, n, c) };
@@ -261,7 +260,7 @@ intrinsics! {
     /// four bytes.
     #[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
     pub unsafe extern "aapcs" fn __aeabi_memclr4(dst: *mut u8, n: usize) {
-        debug_assert!(dst.addr() & 3 == 0);
+        debug_assert!(dst.addr().is_multiple_of(4));
 
         // SAFETY: memclr preconditions apply, less strict alignment.
         unsafe { __aeabi_memset4(dst, n, 0) };
@@ -275,7 +274,7 @@ intrinsics! {
     /// eight bytes.
     #[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
     pub unsafe extern "aapcs" fn __aeabi_memclr8(dst: *mut u8, n: usize) {
-        debug_assert!(dst.addr() & 7 == 0);
+        debug_assert!(dst.addr().is_multiple_of(8));
 
         // SAFETY: memclr preconditions apply, less strict alignment.
         unsafe { __aeabi_memset4(dst, n, 0) };
diff --git a/library/compiler-builtins/compiler-builtins/src/int/udiv.rs b/library/compiler-builtins/compiler-builtins/src/int/udiv.rs
index b9dee63c4cc..017a81ac914 100644
--- a/library/compiler-builtins/compiler-builtins/src/int/udiv.rs
+++ b/library/compiler-builtins/compiler-builtins/src/int/udiv.rs
@@ -44,7 +44,7 @@ intrinsics! {
     }
 
     #[unsafe(naked)]
-    pub unsafe extern "C" fn __udivmodqi4() {
+    pub unsafe extern "custom" fn __udivmodqi4() {
         // compute unsigned 8-bit `n / d` and `n % d`.
         //
         // Note: GCC implements a [non-standard calling convention](https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention) for this function.
diff --git a/library/compiler-builtins/compiler-builtins/src/lib.rs b/library/compiler-builtins/compiler-builtins/src/lib.rs
index 1cec39d8b41..fe0ad81dd3a 100644
--- a/library/compiler-builtins/compiler-builtins/src/lib.rs
+++ b/library/compiler-builtins/compiler-builtins/src/lib.rs
@@ -1,11 +1,13 @@
 #![cfg_attr(feature = "compiler-builtins", compiler_builtins)]
 #![cfg_attr(all(target_family = "wasm"), feature(wasm_numeric_instr))]
+#![feature(abi_custom)]
 #![feature(abi_unadjusted)]
 #![feature(asm_experimental_arch)]
 #![feature(cfg_target_has_atomic)]
 #![feature(compiler_builtins)]
 #![feature(core_intrinsics)]
 #![feature(linkage)]
+#![feature(asm_cfg)]
 #![feature(naked_functions)]
 #![feature(repr_simd)]
 #![feature(macro_metavar_expr_concat)]
diff --git a/library/compiler-builtins/compiler-builtins/src/probestack.rs b/library/compiler-builtins/compiler-builtins/src/probestack.rs
index 1441fd73b8d..f4105dde57e 100644
--- a/library/compiler-builtins/compiler-builtins/src/probestack.rs
+++ b/library/compiler-builtins/compiler-builtins/src/probestack.rs
@@ -52,36 +52,12 @@
 // 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`.
 #[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
-            "
-        };
-    }
-
+pub unsafe extern "custom" fn __rust_probestack() {
     core::arch::naked_asm!(
         "
             .cfi_startproc
@@ -131,8 +107,18 @@ pub unsafe extern "C" fn __rust_probestack() {
             .cfi_def_cfa_register %rsp
             .cfi_adjust_cfa_offset -8
     ",
-        ret!(),
-        "
+    #[cfg(not(all(target_env = "sgx", target_vendor = "fortanix")))]
+    "       ret",
+    #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))]
+    "
+            // 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
+    ",
+    "
             .cfi_endproc
     ",
         options(att_syntax)
@@ -144,13 +130,10 @@ pub unsafe extern "C" fn __rust_probestack() {
 // 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.
 #[unsafe(naked)]
 #[rustc_std_internal_symbol]
-pub unsafe extern "C" fn __rust_probestack() {
+pub unsafe extern "custom" fn __rust_probestack() {
     core::arch::naked_asm!(
         "
             .cfi_startproc
@@ -192,9 +175,6 @@ pub unsafe extern "C" fn __rust_probestack() {
 // 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:
@@ -203,7 +183,7 @@ pub unsafe extern "C" fn __rust_probestack() {
 //   themselves.
 #[unsafe(naked)]
 #[rustc_std_internal_symbol]
-pub unsafe extern "C" fn __rust_probestack() {
+pub unsafe extern "custom" fn __rust_probestack() {
     core::arch::naked_asm!(
         "
             .cfi_startproc
diff --git a/library/compiler-builtins/compiler-builtins/src/x86.rs b/library/compiler-builtins/compiler-builtins/src/x86.rs
index 01152d9c798..16e50922a94 100644
--- a/library/compiler-builtins/compiler-builtins/src/x86.rs
+++ b/library/compiler-builtins/compiler-builtins/src/x86.rs
@@ -2,7 +2,7 @@
 
 use core::intrinsics;
 
-// NOTE These functions are implemented using assembly because they using a custom
+// NOTE These functions are implemented using assembly because they use a custom
 // calling convention which can't be implemented using a normal Rust function
 
 // NOTE These functions are never mangled as they are not tested against compiler-rt
@@ -13,10 +13,10 @@ intrinsics! {
         any(all(windows, target_env = "gnu"), target_os = "uefi"),
         not(feature = "no-asm")
     ))]
-    pub unsafe extern "C" fn __chkstk() {
+    pub unsafe extern "custom" fn __chkstk() {
         core::arch::naked_asm!(
-            "jmp __alloca", // Jump to __alloca since fallthrough may be unreliable"
-            options(att_syntax)
+            "jmp {}", // Jump to __alloca since fallthrough may be unreliable"
+            sym crate::x86::_alloca::_alloca,
         );
     }
 
@@ -25,7 +25,7 @@ intrinsics! {
         any(all(windows, target_env = "gnu"), target_os = "uefi"),
         not(feature = "no-asm")
     ))]
-    pub unsafe extern "C" fn _alloca() {
+    pub unsafe extern "custom" fn _alloca() {
         // __chkstk and _alloca are the same function
         core::arch::naked_asm!(
             "push   %ecx",
diff --git a/library/compiler-builtins/compiler-builtins/src/x86_64.rs b/library/compiler-builtins/compiler-builtins/src/x86_64.rs
index fc1190f79b2..9b7133b482e 100644
--- a/library/compiler-builtins/compiler-builtins/src/x86_64.rs
+++ b/library/compiler-builtins/compiler-builtins/src/x86_64.rs
@@ -2,7 +2,7 @@
 
 use core::intrinsics;
 
-// NOTE These functions are implemented using assembly because they using a custom
+// NOTE These functions are implemented using assembly because they use a custom
 // calling convention which can't be implemented using a normal Rust function
 
 // NOTE These functions are never mangled as they are not tested against compiler-rt
@@ -17,7 +17,7 @@ intrinsics! {
         ),
         not(feature = "no-asm")
     ))]
-    pub unsafe extern "C" fn ___chkstk_ms() {
+    pub unsafe extern "custom" fn ___chkstk_ms() {
         core::arch::naked_asm!(
             "push   %rcx",
             "push   %rax",
diff --git a/library/compiler-builtins/crates/josh-sync/Cargo.toml b/library/compiler-builtins/crates/josh-sync/Cargo.toml
index 1f3bb376d6d..8e2e891db54 100644
--- a/library/compiler-builtins/crates/josh-sync/Cargo.toml
+++ b/library/compiler-builtins/crates/josh-sync/Cargo.toml
@@ -5,3 +5,4 @@ publish = false
 
 [dependencies]
 directories = "6.0.0"
+regex-lite = "0.1.6"
diff --git a/library/compiler-builtins/crates/josh-sync/src/sync.rs b/library/compiler-builtins/crates/josh-sync/src/sync.rs
index 003cf187d83..2d89d2d1cea 100644
--- a/library/compiler-builtins/crates/josh-sync/src/sync.rs
+++ b/library/compiler-builtins/crates/josh-sync/src/sync.rs
@@ -1,8 +1,11 @@
+use std::borrow::Cow;
 use std::net::{SocketAddr, TcpStream};
 use std::process::{Command, Stdio, exit};
 use std::time::Duration;
 use std::{env, fs, process, thread};
 
+use regex_lite::Regex;
+
 const JOSH_PORT: u16 = 42042;
 const DEFAULT_PR_BRANCH: &str = "update-builtins";
 
@@ -77,6 +80,7 @@ impl GitSync {
             "--depth=1",
         ]);
         let new_summary = check_output(["git", "log", "-1", "--format=%h %s", &new_upstream_base]);
+        let new_summary = replace_references(&new_summary, &self.upstream_repo);
 
         // 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.
@@ -297,6 +301,13 @@ fn check_output_cfg(prog: &str, f: impl FnOnce(&mut Command) -> &mut Command) ->
     String::from_utf8(out.stdout.trim_ascii().to_vec()).expect("non-UTF8 output")
 }
 
+/// Replace `#1234`-style issue/PR references with `repo#1234` to ensure links work across
+/// repositories.
+fn replace_references<'a>(s: &'a str, repo: &str) -> Cow<'a, str> {
+    let re = Regex::new(r"\B(?P<id>#\d+)\b").unwrap();
+    re.replace(s, &format!("{repo}$id"))
+}
+
 /// Create a wrapper that stops Josh on drop.
 pub struct Josh(process::Child);
 
@@ -369,3 +380,22 @@ impl Drop for Josh {
         self.0.kill().expect("failed to SIGKILL josh-proxy");
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_replace() {
+        assert_eq!(replace_references("#1234", "r-l/rust"), "r-l/rust#1234");
+        assert_eq!(replace_references("#1234x", "r-l/rust"), "#1234x");
+        assert_eq!(
+            replace_references("merge #1234", "r-l/rust"),
+            "merge r-l/rust#1234"
+        );
+        assert_eq!(
+            replace_references("foo/bar#1234", "r-l/rust"),
+            "foo/bar#1234"
+        );
+    }
+}
diff --git a/library/compiler-builtins/crates/libm-macros/src/lib.rs b/library/compiler-builtins/crates/libm-macros/src/lib.rs
index 482da974ca8..7efa1488f57 100644
--- a/library/compiler-builtins/crates/libm-macros/src/lib.rs
+++ b/library/compiler-builtins/crates/libm-macros/src/lib.rs
@@ -1,5 +1,3 @@
-#![feature(let_chains)]
-
 mod enums;
 mod parse;
 mod shared;
diff --git a/library/compiler-builtins/crates/symbol-check/src/main.rs b/library/compiler-builtins/crates/symbol-check/src/main.rs
index d83cd318d6a..1312a717970 100644
--- a/library/compiler-builtins/crates/symbol-check/src/main.rs
+++ b/library/compiler-builtins/crates/symbol-check/src/main.rs
@@ -8,7 +8,9 @@ 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 object::{
+    File as ObjFile, Object, ObjectSymbol, Symbol, SymbolKind, SymbolScope, SymbolSection,
+};
 use serde_json::Value;
 
 const CHECK_LIBRARIES: &[&str] = &["compiler_builtins", "builtins_test_intrinsics"];
@@ -16,10 +18,12 @@ const CHECK_EXTENSIONS: &[Option<&str>] = &[Some("rlib"), Some("a"), Some("exe")
 
 const USAGE: &str = "Usage:
 
-    symbol-check build-and-check CARGO_ARGS ...
+    symbol-check build-and-check [TARGET] -- CARGO_BUILD_ARGS ...
 
-Cargo will get invoked with `CARGO_ARGS` and all output
+Cargo will get invoked with `CARGO_ARGS` and the specified target. All output
 `compiler_builtins*.rlib` files will be checked.
+
+If TARGET is not specified, the host target is used.
 ";
 
 fn main() {
@@ -28,13 +32,13 @@ fn main() {
     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);
-            }
+        ["build-and-check", target, "--", args @ ..] if !args.is_empty() => {
+            check_cargo_args(args);
+            run_build_and_check(target, args);
+        }
+        ["build-and-check", "--", args @ ..] if !args.is_empty() => {
+            check_cargo_args(args);
+            run_build_and_check(&host_target(), args);
         }
         _ => {
             println!("{USAGE}");
@@ -43,14 +47,54 @@ fn main() {
     }
 }
 
+/// Make sure `--target` isn't passed to avoid confusion (since it should be proivded only once,
+/// positionally).
+fn check_cargo_args(args: &[&str]) {
+    for arg in args {
+        assert!(
+            !arg.contains("--target"),
+            "target must be passed positionally. {USAGE}"
+        );
+    }
+}
+
+fn run_build_and_check(target: &str, args: &[&str]) {
+    let paths = exec_cargo_with_args(target, args);
+    for path in paths {
+        println!("Checking {}", path.display());
+        let archive = Archive::from_path(&path);
+
+        verify_no_duplicates(&archive);
+        verify_core_symbols(&archive);
+    }
+}
+
+fn host_target() -> String {
+    let out = Command::new("rustc")
+        .arg("--version")
+        .arg("--verbose")
+        .output()
+        .unwrap();
+    assert!(out.status.success());
+    let out = String::from_utf8(out.stdout).unwrap();
+    out.lines()
+        .find_map(|s| s.strip_prefix("host: "))
+        .unwrap()
+        .to_owned()
+}
+
 /// Run `cargo build` with the provided additional arguments, collecting the list of created
 /// libraries.
-fn exec_cargo_with_args(args: &[&str]) -> Vec<PathBuf> {
+fn exec_cargo_with_args(target: &str, args: &[&str]) -> Vec<PathBuf> {
     let mut cmd = Command::new("cargo");
-    cmd.arg("build")
-        .arg("--message-format=json")
-        .args(args)
-        .stdout(Stdio::piped());
+    cmd.args([
+        "build",
+        "--target",
+        target,
+        "--message-format=json-diagnostic-rendered-ansi",
+    ])
+    .args(args)
+    .stdout(Stdio::piped());
 
     println!("running: {cmd:?}");
     let mut child = cmd.spawn().expect("failed to launch Cargo");
@@ -61,11 +105,21 @@ fn exec_cargo_with_args(args: &[&str]) -> Vec<PathBuf> {
 
     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" {
+        let reason = &j["reason"];
+
+        // Forward output that is meant to be user-facing
+        if reason == "compiler-message" {
+            println!("{}", j["message"]["rendered"].as_str().unwrap());
+        } else if reason == "build-finished" {
+            println!("build finshed. success: {}", j["success"]);
+        } else if reason == "build-script-executed" {
+            let pretty = serde_json::to_string_pretty(&j).unwrap();
+            println!("build script output: {pretty}",);
+        }
+
+        // Only interested in the artifact list now
+        if reason != "compiler-artifact" {
             continue;
         }
 
@@ -133,12 +187,12 @@ impl SymInfo {
 /// 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) {
+fn verify_no_duplicates(archive: &Archive) {
     let mut syms = BTreeMap::<String, SymInfo>::new();
     let mut dups = Vec::new();
     let mut found_any = false;
 
-    for_each_symbol(path, |symbol, member| {
+    archive.for_each_symbol(|symbol, member| {
         // Only check defined globals
         if !symbol.is_global() || symbol.is_undefined() {
             return;
@@ -185,12 +239,12 @@ fn verify_no_duplicates(path: &Path) {
 }
 
 /// Ensure that there are no references to symbols from `core` that aren't also (somehow) defined.
-fn verify_core_symbols(path: &Path) {
+fn verify_core_symbols(archive: &Archive) {
     let mut defined = BTreeSet::new();
     let mut undefined = Vec::new();
     let mut has_symbols = false;
 
-    for_each_symbol(path, |symbol, member| {
+    archive.for_each_symbol(|symbol, member| {
         has_symbols = true;
 
         // Find only symbols from `core`
@@ -219,14 +273,40 @@ fn verify_core_symbols(path: &Path) {
     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));
+/// Thin wrapper for owning data used by `object`.
+struct Archive {
+    data: Vec<u8>,
+}
+
+impl Archive {
+    fn from_path(path: &Path) -> Self {
+        Self {
+            data: fs::read(path).expect("reading file failed"),
+        }
+    }
+
+    fn file(&self) -> ArchiveFile<'_> {
+        ArchiveFile::parse(self.data.as_slice()).expect("archive parse failed")
+    }
+
+    /// For a given archive, do something with each object file.
+    fn for_each_object(&self, mut f: impl FnMut(ObjFile, &ArchiveMember)) {
+        let archive = self.file();
+
+        for member in archive.members() {
+            let member = member.expect("failed to access member");
+            let obj_data = member
+                .data(self.data.as_slice())
+                .expect("failed to access object");
+            let obj = ObjFile::parse(obj_data).expect("failed to parse object");
+            f(obj, &member);
+        }
+    }
+
+    /// For a given archive, do something with each symbol.
+    fn for_each_symbol(&self, mut f: impl FnMut(Symbol, &ArchiveMember)) {
+        self.for_each_object(|obj, member| {
+            obj.symbols().for_each(|sym| f(sym, member));
+        });
     }
 }
diff --git a/library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json b/library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json
new file mode 100644
index 00000000000..81273d44e49
--- /dev/null
+++ b/library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json
@@ -0,0 +1,23 @@
+{
+  "abi": "eabi",
+  "arch": "arm",
+  "c-enum-min-bits": 8,
+  "crt-objects-fallback": "false",
+  "data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
+  "emit-debug-gdb-scripts": false,
+  "frame-pointer": "always",
+  "linker": "rust-lld",
+  "linker-flavor": "gnu-lld",
+  "llvm-floatabi": "soft",
+  "llvm-target": "thumbv7em-none-eabi",
+  "max-atomic-width": 32,
+  "metadata": {
+    "description": "Bare ARMv7E-M",
+    "host_tools": false,
+    "std": false,
+    "tier": 2
+  },
+  "panic-strategy": "abort",
+  "relocation-model": "static",
+  "target-pointer-width": "32"
+}
diff --git a/library/compiler-builtins/libm-test/benches/icount.rs b/library/compiler-builtins/libm-test/benches/icount.rs
index a0928a29f99..02ee13f804f 100644
--- a/library/compiler-builtins/libm-test/benches/icount.rs
+++ b/library/compiler-builtins/libm-test/benches/icount.rs
@@ -120,6 +120,22 @@ fn icount_bench_u256_add(cases: Vec<(u256, u256)>) {
 }
 
 #[library_benchmark]
+#[bench::linspace(setup_u256_add())]
+fn icount_bench_u256_sub(cases: Vec<(u256, u256)>) {
+    for (x, y) in cases.iter().copied() {
+        black_box(black_box(x) - black_box(y));
+    }
+}
+
+#[library_benchmark]
+#[bench::linspace(setup_u256_shift())]
+fn icount_bench_u256_shl(cases: Vec<(u256, u32)>) {
+    for (x, y) in cases.iter().copied() {
+        black_box(black_box(x) << black_box(y));
+    }
+}
+
+#[library_benchmark]
 #[bench::linspace(setup_u256_shift())]
 fn icount_bench_u256_shr(cases: Vec<(u256, u32)>) {
     for (x, y) in cases.iter().copied() {
@@ -129,7 +145,7 @@ fn icount_bench_u256_shr(cases: Vec<(u256, u32)>) {
 
 library_benchmark_group!(
     name = icount_bench_u128_group;
-    benchmarks = icount_bench_u128_widen_mul, icount_bench_u256_add, icount_bench_u256_shr
+    benchmarks = icount_bench_u128_widen_mul, icount_bench_u256_add, icount_bench_u256_sub, icount_bench_u256_shl, icount_bench_u256_shr
 );
 
 #[library_benchmark]
diff --git a/library/compiler-builtins/libm-test/tests/u256.rs b/library/compiler-builtins/libm-test/tests/u256.rs
index 8cbb3ad226f..d1c5cfbcc58 100644
--- a/library/compiler-builtins/libm-test/tests/u256.rs
+++ b/library/compiler-builtins/libm-test/tests/u256.rs
@@ -111,20 +111,62 @@ fn mp_u256_add() {
         let y = random_u256(&mut rng);
         assign_bigint(&mut bx, x);
         assign_bigint(&mut by, y);
-        let actual = x + y;
+        let actual = if u256::MAX - x >= y {
+            x + y
+        } else {
+            // otherwise (u256::MAX - x) < y, so the wrapped result is
+            // (x + y) - (u256::MAX + 1) == y - (u256::MAX - x) - 1
+            y - (u256::MAX - x) - 1_u128.widen()
+        };
         bx += &by;
         check_one(|| hexu(x), || Some(hexu(y)), actual, &mut bx);
     }
 }
 
 #[test]
+fn mp_u256_sub() {
+    let mut rng = ChaCha8Rng::from_seed(*SEED);
+    let mut bx = BigInt::new();
+    let mut by = BigInt::new();
+
+    for _ in 0..bigint_fuzz_iteration_count() {
+        let x = random_u256(&mut rng);
+        let y = random_u256(&mut rng);
+        assign_bigint(&mut bx, x);
+        assign_bigint(&mut by, y);
+
+        // since the operators (may) panic on overflow,
+        // we should test something that doesn't
+        let actual = if x >= y { x - y } else { y - x };
+        bx -= &by;
+        bx.abs_mut();
+        check_one(|| hexu(x), || Some(hexu(y)), actual, &mut bx);
+    }
+}
+
+#[test]
+fn mp_u256_shl() {
+    let mut rng = ChaCha8Rng::from_seed(*SEED);
+    let mut bx = BigInt::new();
+
+    for _ in 0..bigint_fuzz_iteration_count() {
+        let x = random_u256(&mut rng);
+        let shift: u32 = rng.random_range(0..256);
+        assign_bigint(&mut bx, x);
+        let actual = x << shift;
+        bx <<= shift;
+        check_one(|| hexu(x), || Some(shift.to_string()), actual, &mut bx);
+    }
+}
+
+#[test]
 fn mp_u256_shr() {
     let mut rng = ChaCha8Rng::from_seed(*SEED);
     let mut bx = BigInt::new();
 
     for _ in 0..bigint_fuzz_iteration_count() {
         let x = random_u256(&mut rng);
-        let shift: u32 = rng.random_range(0..255);
+        let shift: u32 = rng.random_range(0..256);
         assign_bigint(&mut bx, x);
         let actual = x >> shift;
         bx >>= shift;
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 f2ba6a4a0e3..e04e00c6d74 100644
--- a/library/compiler-builtins/libm-test/tests/z_extensive/run.rs
+++ b/library/compiler-builtins/libm-test/tests/z_extensive/run.rs
@@ -197,15 +197,15 @@ impl Progress {
 
     fn update(&self, completed: u64, input: impl fmt::Debug) {
         // Infrequently update the progress bar.
-        if completed % 20_000 == 0 {
+        if completed.is_multiple_of(20_000) {
             self.pb.set_position(completed);
         }
 
-        if completed % 500_000 == 0 {
+        if completed.is_multiple_of(500_000) {
             self.pb.set_message(format!("input: {input:<24?}"));
         }
 
-        if !self.is_tty && completed % 5_000_000 == 0 {
+        if !self.is_tty && completed.is_multiple_of(5_000_000) {
             let len = self.pb.length().unwrap_or_default();
             eprintln!(
                 "[{elapsed:3?}s {percent:3.0}%] {name} \
diff --git a/library/compiler-builtins/libm/configure.rs b/library/compiler-builtins/libm/configure.rs
index 2a497c7b117..f9100d2d58b 100644
--- a/library/compiler-builtins/libm/configure.rs
+++ b/library/compiler-builtins/libm/configure.rs
@@ -1,7 +1,8 @@
 // Configuration shared with both libm and libm-test
 
-use std::env;
 use std::path::PathBuf;
+use std::process::{Command, Stdio};
+use std::{env, str};
 
 #[allow(dead_code)]
 pub struct Config {
@@ -9,6 +10,7 @@ pub struct Config {
     pub out_dir: PathBuf,
     pub opt_level: String,
     pub cargo_features: Vec<String>,
+    pub target_triple: String,
     pub target_arch: String,
     pub target_env: String,
     pub target_family: Option<String>,
@@ -16,10 +18,13 @@ pub struct Config {
     pub target_string: String,
     pub target_vendor: String,
     pub target_features: Vec<String>,
+    pub reliable_f128: bool,
+    pub reliable_f16: bool,
 }
 
 impl Config {
     pub fn from_env() -> Self {
+        let target_triple = env::var("TARGET").unwrap();
         let target_features = env::var("CARGO_CFG_TARGET_FEATURE")
             .map(|feats| feats.split(',').map(ToOwned::to_owned).collect())
             .unwrap_or_default();
@@ -28,7 +33,28 @@ impl Config {
             .map(|s| s.to_lowercase().replace("_", "-"))
             .collect();
 
+        // Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
+        // to get consistent output regardless of channel (`f16`/`f128` config options are hidden
+        // on stable otherwise).
+        let mut cmd = Command::new(env::var("RUSTC").unwrap());
+        cmd.args(["--print=cfg", "--target", &target_triple])
+            .env("RUSTC_BOOTSTRAP", "1")
+            .stderr(Stdio::inherit());
+        let out = cmd
+            .output()
+            .unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
+        let rustc_cfg = str::from_utf8(&out.stdout).unwrap();
+
+        // If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
+        // choice and leave `f16` and `f128` disabled.
+        let rustc_output_ok = out.status.success();
+        let reliable_f128 =
+            rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
+        let reliable_f16 =
+            rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");
+
         Self {
+            target_triple,
             manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
             out_dir: PathBuf::from(env::var("OUT_DIR").unwrap()),
             opt_level: env::var("OPT_LEVEL").unwrap(),
@@ -40,6 +66,8 @@ impl Config {
             target_string: env::var("TARGET").unwrap(),
             target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
             target_features,
+            reliable_f128,
+            reliable_f16,
         }
     }
 }
@@ -128,62 +156,18 @@ fn emit_f16_f128_cfg(cfg: &Config) {
         return;
     }
 
-    // Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
-    // that the backend will not crash when using these types and generates code that can be called
-    // without crashing (no infinite recursion). This does not mean that the platform doesn't have
-    // ABI or other bugs.
-    //
-    // We do this here rather than in `rust-lang/rust` because configuring via cargo features is
-    // not straightforward.
-    //
-    // Original source of this list:
-    // <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
-    let f16_enabled = match cfg.target_arch.as_str() {
-        // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
-        "arm64ec" => false,
-        // Selection failure <https://github.com/llvm/llvm-project/issues/50374>
-        "s390x" => false,
-        // Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
-        // FIXME(llvm): loongarch fixed by <https://github.com/llvm/llvm-project/pull/107791>
-        "csky" => false,
-        "hexagon" => false,
-        "loongarch64" => false,
-        "mips" | "mips64" | "mips32r6" | "mips64r6" => false,
-        "powerpc" | "powerpc64" => false,
-        "sparc" | "sparc64" => false,
-        "wasm32" | "wasm64" => false,
-        // Most everything else works as of LLVM 19
-        _ => true,
-    };
-
-    let f128_enabled = match cfg.target_arch.as_str() {
-        // Unsupported (libcall is not supported) <https://github.com/llvm/llvm-project/issues/121122>
-        "amdgpu" => false,
-        // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
-        "arm64ec" => false,
-        // Selection failure <https://github.com/llvm/llvm-project/issues/96432>
-        "mips64" | "mips64r6" => false,
-        // Selection failure <https://github.com/llvm/llvm-project/issues/95471>
-        "nvptx64" => false,
-        // Selection failure <https://github.com/llvm/llvm-project/issues/101545>
-        "powerpc64" if &cfg.target_os == "aix" => false,
-        // Selection failure <https://github.com/llvm/llvm-project/issues/41838>
-        "sparc" => false,
-        // Most everything else works as of LLVM 19
-        _ => true,
-    };
-
-    // If the feature is set, disable these types.
-    let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some();
+    /* See the compiler-builtins configure file for info about the meaning of these options */
 
-    println!("cargo:rustc-check-cfg=cfg(f16_enabled)");
-    println!("cargo:rustc-check-cfg=cfg(f128_enabled)");
+    // If the feature is set, disable both of these types.
+    let no_f16_f128 = cfg.cargo_features.iter().any(|s| s == "no-f16-f128");
 
-    if f16_enabled && !disable_both {
+    println!("cargo:rustc-check-cfg=cfg(f16_enabled)");
+    if cfg.reliable_f16 && !no_f16_f128 {
         println!("cargo:rustc-cfg=f16_enabled");
     }
 
-    if f128_enabled && !disable_both {
+    println!("cargo:rustc-check-cfg=cfg(f128_enabled)");
+    if cfg.reliable_f128 && !no_f16_f128 {
         println!("cargo:rustc-cfg=f128_enabled");
     }
 }
diff --git a/library/compiler-builtins/libm/src/math/support/big.rs b/library/compiler-builtins/libm/src/math/support/big.rs
index 8a52d86cc98..b7f12854249 100644
--- a/library/compiler-builtins/libm/src/math/support/big.rs
+++ b/library/compiler-builtins/libm/src/math/support/big.rs
@@ -11,10 +11,10 @@ const U128_LO_MASK: u128 = u64::MAX as u128;
 
 /// A 256-bit unsigned integer represented as two 128-bit native-endian limbs.
 #[allow(non_camel_case_types)]
-#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
+#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
 pub struct u256 {
-    pub lo: u128,
     pub hi: u128,
+    pub lo: u128,
 }
 
 impl u256 {
@@ -28,17 +28,17 @@ impl u256 {
     pub fn signed(self) -> i256 {
         i256 {
             lo: self.lo,
-            hi: self.hi,
+            hi: self.hi as i128,
         }
     }
 }
 
 /// A 256-bit signed integer represented as two 128-bit native-endian limbs.
 #[allow(non_camel_case_types)]
-#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
+#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
 pub struct i256 {
+    pub hi: i128,
     pub lo: u128,
-    pub hi: u128,
 }
 
 impl i256 {
@@ -47,7 +47,7 @@ impl i256 {
     pub fn unsigned(self) -> u256 {
         u256 {
             lo: self.lo,
-            hi: self.hi,
+            hi: self.hi as u128,
         }
     }
 }
@@ -73,17 +73,17 @@ impl MinInt for i256 {
 
     type Unsigned = u256;
 
-    const SIGNED: bool = false;
+    const SIGNED: bool = true;
     const BITS: u32 = 256;
     const ZERO: Self = Self { lo: 0, hi: 0 };
     const ONE: Self = Self { lo: 1, hi: 0 };
     const MIN: Self = Self {
-        lo: 0,
-        hi: 1 << 127,
+        lo: u128::MIN,
+        hi: i128::MIN,
     };
     const MAX: Self = Self {
         lo: u128::MAX,
-        hi: u128::MAX >> 1,
+        hi: i128::MAX,
     };
 }
 
@@ -109,60 +109,86 @@ macro_rules! impl_common {
             }
         }
 
-        impl ops::Shl<u32> for $ty {
+        impl ops::Add<Self> for $ty {
             type Output = Self;
 
-            fn shl(self, _rhs: u32) -> Self::Output {
-                unimplemented!("only used to meet trait bounds")
+            fn add(self, rhs: Self) -> Self::Output {
+                let (lo, carry) = self.lo.overflowing_add(rhs.lo);
+                let (hi, of) = Int::carrying_add(self.hi, rhs.hi, carry);
+                debug_assert!(!of, "attempt to add with overflow");
+                Self { lo, hi }
             }
         }
-    };
-}
 
-impl_common!(i256);
-impl_common!(u256);
+        impl ops::Sub<Self> for $ty {
+            type Output = Self;
 
-impl ops::Add<Self> for u256 {
-    type Output = Self;
+            fn sub(self, rhs: Self) -> Self::Output {
+                let (lo, borrow) = self.lo.overflowing_sub(rhs.lo);
+                let (hi, of) = Int::borrowing_sub(self.hi, rhs.hi, borrow);
+                debug_assert!(!of, "attempt to subtract with overflow");
+                Self { lo, hi }
+            }
+        }
 
-    fn add(self, rhs: Self) -> Self::Output {
-        let (lo, carry) = self.lo.overflowing_add(rhs.lo);
-        let hi = self.hi.wrapping_add(carry as u128).wrapping_add(rhs.hi);
+        impl ops::Shl<u32> for $ty {
+            type Output = Self;
 
-        Self { lo, hi }
-    }
-}
+            fn shl(mut self, rhs: u32) -> Self::Output {
+                debug_assert!(rhs < Self::BITS, "attempt to shift left with overflow");
 
-impl ops::Shr<u32> for u256 {
-    type Output = Self;
+                let half_bits = Self::BITS / 2;
+                let low_mask = half_bits - 1;
+                let s = rhs & low_mask;
 
-    fn shr(mut self, rhs: u32) -> Self::Output {
-        debug_assert!(rhs < Self::BITS, "attempted to shift right with overflow");
-        if rhs >= Self::BITS {
-            return Self::ZERO;
-        }
+                let lo = self.lo;
+                let hi = self.hi;
 
-        if rhs == 0 {
-            return self;
-        }
+                self.lo = lo << s;
 
-        if rhs < 128 {
-            self.lo >>= rhs;
-            self.lo |= self.hi << (128 - rhs);
-        } else {
-            self.lo = self.hi >> (rhs - 128);
+                if rhs & half_bits == 0 {
+                    self.hi = (lo >> (low_mask ^ s) >> 1) as _;
+                    self.hi |= hi << s;
+                } else {
+                    self.hi = self.lo as _;
+                    self.lo = 0;
+                }
+                self
+            }
         }
 
-        if rhs < 128 {
-            self.hi >>= rhs;
-        } else {
-            self.hi = 0;
-        }
+        impl ops::Shr<u32> for $ty {
+            type Output = Self;
 
-        self
-    }
+            fn shr(mut self, rhs: u32) -> Self::Output {
+                debug_assert!(rhs < Self::BITS, "attempt to shift right with overflow");
+
+                let half_bits = Self::BITS / 2;
+                let low_mask = half_bits - 1;
+                let s = rhs & low_mask;
+
+                let lo = self.lo;
+                let hi = self.hi;
+
+                self.hi = hi >> s;
+
+                #[allow(unused_comparisons)]
+                if rhs & half_bits == 0 {
+                    self.lo = (hi << (low_mask ^ s) << 1) as _;
+                    self.lo |= lo >> s;
+                } else {
+                    self.lo = self.hi as _;
+                    self.hi = if hi < 0 { !0 } else { 0 };
+                }
+                self
+            }
+        }
+    };
 }
 
+impl_common!(i256);
+impl_common!(u256);
+
 impl HInt for u128 {
     type D = u256;
 
@@ -200,7 +226,7 @@ impl HInt for u128 {
     }
 
     fn widen_hi(self) -> Self::D {
-        self.widen() << <Self as MinInt>::BITS
+        u256 { lo: 0, hi: self }
     }
 }
 
@@ -208,11 +234,10 @@ impl HInt for i128 {
     type D = i256;
 
     fn widen(self) -> Self::D {
-        let mut ret = self.unsigned().zero_widen().signed();
-        if self.is_negative() {
-            ret.hi = u128::MAX;
+        i256 {
+            lo: self as u128,
+            hi: if self < 0 { -1 } else { 0 },
         }
-        ret
     }
 
     fn zero_widen(self) -> Self::D {
@@ -228,7 +253,7 @@ impl HInt for i128 {
     }
 
     fn widen_hi(self) -> Self::D {
-        self.widen() << <Self as MinInt>::BITS
+        i256 { lo: 0, hi: self }
     }
 }
 
@@ -252,6 +277,6 @@ impl DInt for i256 {
     }
 
     fn hi(self) -> Self::H {
-        self.hi as i128
+        self.hi
     }
 }
diff --git a/library/compiler-builtins/libm/src/math/support/big/tests.rs b/library/compiler-builtins/libm/src/math/support/big/tests.rs
index d2010f0216e..d54706c7260 100644
--- a/library/compiler-builtins/libm/src/math/support/big/tests.rs
+++ b/library/compiler-builtins/libm/src/math/support/big/tests.rs
@@ -36,7 +36,7 @@ fn widen_i128() {
         (LOHI_SPLIT as i128).widen(),
         i256 {
             lo: LOHI_SPLIT,
-            hi: u128::MAX
+            hi: -1,
         }
     );
     assert_eq!((-1i128).zero_widen().unsigned(), (u128::MAX).widen());
@@ -275,3 +275,64 @@ fn shr_u256_overflow() {
     assert_eq!(u256::MAX >> 257, u256::ZERO);
     assert_eq!(u256::MAX >> u32::MAX, u256::ZERO);
 }
+
+#[test]
+fn u256_ord() {
+    let _1 = u256::ONE;
+    let _2 = _1 + _1;
+    for x in u8::MIN..u8::MAX {
+        let y = x + 1;
+        let wx = (x as u128).widen_hi();
+        let wy = (y as u128).widen_hi();
+        assert!([wx, wx + _1, wx + _2, wy, wy + _1, wy + _2].is_sorted());
+    }
+}
+#[test]
+fn i256_ord() {
+    let _1 = i256::ONE;
+    let _2 = _1 + _1;
+    for x in i8::MIN..i8::MAX {
+        let y = x + 1;
+        let wx = (x as i128).widen_hi();
+        let wy = (y as i128).widen_hi();
+        assert!([wx, wx + _1, wx + _2, wy - _2, wy - _1, wy].is_sorted());
+    }
+}
+
+#[test]
+fn u256_shifts() {
+    let _1 = u256::ONE;
+    for k in 0..255 {
+        let x = _1 << k;
+        let x2 = _1 << (k + 1);
+        assert!(x < x2);
+        assert_eq!(x << 1, x2);
+        assert_eq!(x + x, x2);
+        assert_eq!(x >> k, _1);
+        assert_eq!(x2 >> (k + 1), _1);
+    }
+}
+#[test]
+fn i256_shifts() {
+    let _1 = i256::ONE;
+    for k in 0..254 {
+        let x = _1 << k;
+        let x2 = _1 << (k + 1);
+        assert!(x < x2);
+        assert_eq!(x << 1, x2);
+        assert_eq!(x + x, x2);
+        assert_eq!(x >> k, _1);
+        assert_eq!(x2 >> (k + 1), _1);
+    }
+
+    let min = _1 << 255;
+    assert_eq!(min, i256::MIN);
+    let mut x = min;
+    for k in 0..255 {
+        assert_eq!(x, min >> k);
+        let y = x >> 1;
+        assert_eq!(y + y, x);
+        assert!(x < y);
+        x = y;
+    }
+}
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 9b29e2f4561..9d8826dfed3 100644
--- a/library/compiler-builtins/libm/src/math/support/int_traits.rs
+++ b/library/compiler-builtins/libm/src/math/support/int_traits.rs
@@ -37,8 +37,6 @@ pub trait Int:
     + fmt::Display
     + fmt::Binary
     + fmt::LowerHex
-    + PartialEq
-    + PartialOrd
     + ops::AddAssign
     + ops::SubAssign
     + ops::MulAssign
@@ -102,7 +100,10 @@ pub trait Int:
     fn rotate_left(self, other: u32) -> Self;
     fn overflowing_add(self, other: Self) -> (Self, bool);
     fn overflowing_sub(self, other: Self) -> (Self, bool);
+    fn carrying_add(self, other: Self, carry: bool) -> (Self, bool);
+    fn borrowing_sub(self, other: Self, borrow: bool) -> (Self, bool);
     fn leading_zeros(self) -> u32;
+    fn trailing_zeros(self) -> u32;
     fn ilog2(self) -> u32;
 }
 
@@ -168,12 +169,30 @@ macro_rules! int_impl_common {
             <Self>::leading_zeros(self)
         }
 
+        fn trailing_zeros(self) -> u32 {
+            <Self>::trailing_zeros(self)
+        }
+
         fn ilog2(self) -> u32 {
             // On our older MSRV, this resolves to the trait method. Which won't actually work,
             // but this is only called behind other gates.
             #[allow(clippy::incompatible_msrv)]
             <Self>::ilog2(self)
         }
+
+        fn carrying_add(self, other: Self, carry: bool) -> (Self, bool) {
+            let (ab, of1) = self.overflowing_add(other);
+            let (abc, of2) = ab.overflowing_add(Self::from_bool(carry));
+            // `of1 && of2` is possible with signed integers if a negative sum
+            // overflows to `MAX` and adding the carry overflows again back to `MIN`
+            (abc, of1 ^ of2)
+        }
+
+        fn borrowing_sub(self, other: Self, borrow: bool) -> (Self, bool) {
+            let (ab, of1) = self.overflowing_sub(other);
+            let (abc, of2) = ab.overflowing_sub(Self::from_bool(borrow));
+            (abc, of1 ^ of2)
+        }
     };
 }
 
diff --git a/library/compiler-builtins/thumbv6m-linux-eabi.json b/library/compiler-builtins/thumbv6m-linux-eabi.json
deleted file mode 100644
index ac736eae686..00000000000
--- a/library/compiler-builtins/thumbv6m-linux-eabi.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-    "abi-blacklist": [
-        "stdcall",
-        "fastcall",
-        "vectorcall",
-        "win64",
-        "sysv64"
-    ],
-    "arch": "arm",
-    "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
-    "env": "",
-    "executables": true,
-    "features": "+strict-align",
-    "linker": "arm-none-eabi-gcc",
-    "linker-flavor": "gcc",
-    "llvm-target": "thumbv6m-none-eabi",
-    "max-atomic-width": 0,
-    "os": "linux",
-    "panic-strategy": "abort",
-    "pre-link-args": {
-        "gcc": ["-nostartfiles"]
-    },
-    "relocation-model": "static",
-    "target-endian": "little",
-    "target-pointer-width": "32",
-    "target-c-int-width": "32",
-    "vendor": ""
-}
diff --git a/library/compiler-builtins/thumbv7em-linux-eabi.json b/library/compiler-builtins/thumbv7em-linux-eabi.json
deleted file mode 100644
index b6d4a6bda7b..00000000000
--- a/library/compiler-builtins/thumbv7em-linux-eabi.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-    "abi-blacklist": [
-        "stdcall",
-        "fastcall",
-        "vectorcall",
-        "win64",
-        "sysv64"
-    ],
-    "arch": "arm",
-    "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
-    "env": "",
-    "executables": true,
-    "linker": "arm-none-eabi-gcc",
-    "linker-flavor": "gcc",
-    "llvm-target": "thumbv7em-none-eabi",
-    "max-atomic-width": 32,
-    "os": "linux",
-    "panic-strategy": "abort",
-    "pre-link-args": {
-        "gcc": ["-nostartfiles"]
-    },
-    "relocation-model": "static",
-    "target-endian": "little",
-    "target-pointer-width": "32",
-    "target-c-int-width": "32",
-    "vendor": ""
-}
diff --git a/library/compiler-builtins/thumbv7em-linux-eabihf.json b/library/compiler-builtins/thumbv7em-linux-eabihf.json
deleted file mode 100644
index 81cfcd48d56..00000000000
--- a/library/compiler-builtins/thumbv7em-linux-eabihf.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-    "abi-blacklist": [
-        "stdcall",
-        "fastcall",
-        "vectorcall",
-        "win64",
-        "sysv64"
-    ],
-    "arch": "arm",
-    "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
-    "env": "",
-    "executables": true,
-    "features": "+vfp4,+d16,+fp-only-sp",
-    "linker": "arm-none-eabi-gcc",
-    "linker-flavor": "gcc",
-    "llvm-target": "thumbv7em-none-eabihf",
-    "max-atomic-width": 32,
-    "os": "linux",
-    "panic-strategy": "abort",
-    "pre-link-args": {
-        "gcc": ["-nostartfiles"]
-    },
-    "relocation-model": "static",
-    "target-endian": "little",
-    "target-pointer-width": "32",
-    "target-c-int-width": "32",
-    "vendor": ""
-}
diff --git a/library/compiler-builtins/thumbv7m-linux-eabi.json b/library/compiler-builtins/thumbv7m-linux-eabi.json
deleted file mode 100644
index abe037c5bef..00000000000
--- a/library/compiler-builtins/thumbv7m-linux-eabi.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-    "abi-blacklist": [
-        "stdcall",
-        "fastcall",
-        "vectorcall",
-        "win64",
-        "sysv64"
-    ],
-    "arch": "arm",
-    "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
-    "env": "",
-    "executables": true,
-    "linker": "arm-none-eabi-gcc",
-    "linker-flavor": "gcc",
-    "llvm-target": "thumbv7m-none-eabi",
-    "max-atomic-width": 32,
-    "os": "linux",
-    "panic-strategy": "abort",
-    "pre-link-args": {
-        "gcc": ["-nostartfiles"]
-    },
-    "relocation-model": "static",
-    "target-endian": "little",
-    "target-pointer-width": "32",
-    "target-c-int-width": "32",
-    "vendor": ""
-}
diff --git a/library/compiler-builtins/triagebot.toml b/library/compiler-builtins/triagebot.toml
new file mode 100644
index 00000000000..ecc05da0195
--- /dev/null
+++ b/library/compiler-builtins/triagebot.toml
@@ -0,0 +1,21 @@
+## See <https://forge.rust-lang.org/triagebot/index.html> for documentation
+## of these features.
+
+# Warns when a PR contains merge commits
+# Documentation at: https://forge.rust-lang.org/triagebot/no-merge.html
+[no-merges]
+exclude_titles = ["Update from"]
+
+# Canonicalize issue numbers to avoid closing the wrong issue
+# when commits are included in subtrees, as well as warning links in commits.
+# Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html
+[issue-links]
+check-commits = false
+
+# Prevents mentions in commits to avoid users being spammed
+# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html
+[no-mentions]
+
+# Enable issue transfers within the org
+# Documentation at: https://forge.rust-lang.org/triagebot/transfer.html
+[transfer]
diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml
index f88661ee001..3e34e03a61e 100644
--- a/library/core/Cargo.toml
+++ b/library/core/Cargo.toml
@@ -23,8 +23,6 @@ optimize_for_size = []
 # Make `RefCell` store additional debugging information, which is printed out when
 # a borrow error occurs
 debug_refcell = []
-# Make `TypeId` store a reference to the name of the type, so that it can print that name.
-debug_typeid = []
 
 [lints.rust.unexpected_cfgs]
 level = "warn"
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index 380f67f91f9..49275975f04 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -61,8 +61,8 @@ impl Layout {
     /// * `align` must be a power of two,
     ///
     /// * `size`, when rounded up to the nearest multiple of `align`,
-    ///    must not overflow `isize` (i.e., the rounded value must be
-    ///    less than or equal to `isize::MAX`).
+    ///   must not overflow `isize` (i.e., the rounded value must be
+    ///   less than or equal to `isize::MAX`).
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
     #[inline]
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index 01dce114592..39cdf6efda0 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -707,19 +707,52 @@ impl dyn Any + Send + Sync {
 /// ```
 #[derive(Clone, Copy, Eq, PartialOrd, Ord)]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[lang = "type_id"]
 pub struct TypeId {
-    // We avoid using `u128` because that imposes higher alignment requirements on many platforms.
-    // See issue #115620 for more information.
-    t: (u64, u64),
-    #[cfg(feature = "debug_typeid")]
-    name: &'static str,
+    /// This needs to be an array of pointers, since there is provenance
+    /// in the first array field. This provenance knows exactly which type
+    /// the TypeId actually is, allowing CTFE and miri to operate based off it.
+    /// At runtime all the pointers in the array contain bits of the hash, making
+    /// the entire `TypeId` actually just be a `u128` hash of the type.
+    pub(crate) data: [*const (); 16 / size_of::<*const ()>()],
 }
 
+// SAFETY: the raw pointer is always an integer
 #[stable(feature = "rust1", since = "1.0.0")]
-impl PartialEq for TypeId {
+unsafe impl Send for TypeId {}
+// SAFETY: the raw pointer is always an integer
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl Sync for TypeId {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
+impl const PartialEq for TypeId {
     #[inline]
     fn eq(&self, other: &Self) -> bool {
-        self.t == other.t
+        #[cfg(miri)]
+        return crate::intrinsics::type_id_eq(*self, *other);
+        #[cfg(not(miri))]
+        {
+            let this = self;
+            crate::intrinsics::const_eval_select!(
+                @capture { this: &TypeId, other: &TypeId } -> bool:
+                if const {
+                    crate::intrinsics::type_id_eq(*this, *other)
+                } else {
+                    // Ideally we would just invoke `type_id_eq` unconditionally here,
+                    // but since we do not MIR inline intrinsics, because backends
+                    // may want to override them (and miri does!), MIR opts do not
+                    // clean up this call sufficiently for LLVM to turn repeated calls
+                    // of `TypeId` comparisons against one specific `TypeId` into
+                    // a lookup table.
+                    // SAFETY: We know that at runtime none of the bits have provenance and all bits
+                    // are initialized. So we can just convert the whole thing to a `u128` and compare that.
+                    unsafe {
+                        crate::mem::transmute::<_, u128>(*this) == crate::mem::transmute::<_, u128>(*other)
+                    }
+                }
+            )
+        }
     }
 }
 
@@ -742,19 +775,19 @@ impl TypeId {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
     pub const fn of<T: ?Sized + 'static>() -> TypeId {
-        let t: u128 = const { intrinsics::type_id::<T>() };
-        let t1 = (t >> 64) as u64;
-        let t2 = t as u64;
-
-        TypeId {
-            t: (t1, t2),
-            #[cfg(feature = "debug_typeid")]
-            name: type_name::<T>(),
-        }
+        const { intrinsics::type_id::<T>() }
     }
 
     fn as_u128(self) -> u128 {
-        u128::from(self.t.0) << 64 | u128::from(self.t.1)
+        let mut bytes = [0; 16];
+
+        // This is a provenance-stripping memcpy.
+        for (i, chunk) in self.data.iter().copied().enumerate() {
+            let chunk = chunk.expose_provenance().to_ne_bytes();
+            let start = i * chunk.len();
+            bytes[start..(start + chunk.len())].copy_from_slice(&chunk);
+        }
+        u128::from_ne_bytes(bytes)
     }
 }
 
@@ -774,22 +807,19 @@ impl hash::Hash for TypeId {
         // - It is correct to do so -- only hashing a subset of `self` is still
         //   compatible with an `Eq` implementation that considers the entire
         //   value, as ours does.
-        self.t.1.hash(state);
+        let data =
+        // SAFETY: The `offset` stays in-bounds, it just moves the pointer to the 2nd half of the `TypeId`.
+        // Only the first ptr-sized chunk ever has provenance, so that second half is always
+        // fine to read at integer type.
+            unsafe { crate::ptr::read_unaligned(self.data.as_ptr().cast::<u64>().offset(1)) };
+        data.hash(state);
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for TypeId {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
-        #[cfg(feature = "debug_typeid")]
-        {
-            write!(f, "TypeId({:#034x} = {})", self.as_u128(), self.name)?;
-        }
-        #[cfg(not(feature = "debug_typeid"))]
-        {
-            write!(f, "TypeId({:#034x})", self.as_u128())?;
-        }
-        Ok(())
+        write!(f, "TypeId({:#034x})", self.as_u128())
     }
 }
 
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index dfed8a00b7d..c53a2b2beb4 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -333,7 +333,8 @@ impl<T: Copy> Clone for Cell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Default> Default for Cell<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl<T: ~const Default> const Default for Cell<T> {
     /// Creates a `Cell<T>`, with the `Default` value for T.
     #[inline]
     fn default() -> Cell<T> {
@@ -1323,7 +1324,8 @@ impl<T: Clone> Clone for RefCell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Default> Default for RefCell<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl<T: ~const Default> const Default for RefCell<T> {
     /// Creates a `RefCell<T>`, with the `Default` value for T.
     #[inline]
     fn default() -> RefCell<T> {
@@ -1938,21 +1940,21 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// 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
-/// you must not access the data in any way that contradicts that reference for the remainder of
-/// `'a`. For example, this means that if you take the `*mut T` from an `UnsafeCell<T>` and cast it
-/// to an `&T`, then the data in `T` must remain immutable (modulo any `UnsafeCell` data found
-/// within `T`, of course) until that reference's lifetime expires. Similarly, if you create a `&mut
-/// T` reference that is released to safe code, then you must not access the data within the
-/// `UnsafeCell` until that reference expires.
+///   you must not access the data in any way that contradicts that reference for the remainder of
+///   `'a`. For example, this means that if you take the `*mut T` from an `UnsafeCell<T>` and cast it
+///   to an `&T`, then the data in `T` must remain immutable (modulo any `UnsafeCell` data found
+///   within `T`, of course) until that reference's lifetime expires. Similarly, if you create a
+///   `&mut T` reference that is released to safe code, then you must not access the data within the
+///   `UnsafeCell` until that reference expires.
 ///
 /// - For both `&T` without `UnsafeCell<_>` and `&mut T`, you must also not deallocate the data
-/// until the reference expires. As a special exception, given an `&T`, any part of it that is
-/// inside an `UnsafeCell<_>` may be deallocated during the lifetime of the reference, after the
-/// last time the reference is used (dereferenced or reborrowed). Since you cannot deallocate a part
-/// of what a reference points to, this means the memory an `&T` points to can be deallocated only if
-/// *every part of it* (including padding) is inside an `UnsafeCell`.
+///   until the reference expires. As a special exception, given an `&T`, any part of it that is
+///   inside an `UnsafeCell<_>` may be deallocated during the lifetime of the reference, after the
+///   last time the reference is used (dereferenced or reborrowed). Since you cannot deallocate a part
+///   of what a reference points to, this means the memory an `&T` points to can be deallocated only if
+///   *every part of it* (including padding) is inside an `UnsafeCell`.
 ///
-///     However, whenever a `&UnsafeCell<T>` is constructed or dereferenced, it must still point to
+/// However, whenever a `&UnsafeCell<T>` is constructed or dereferenced, it must still point to
 /// live memory and the compiler is allowed to insert spurious reads if it can prove that this
 /// memory has not yet been deallocated.
 ///
@@ -1960,10 +1962,10 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// for single-threaded code:
 ///
 /// 1. A `&T` reference can be released to safe code and there it can co-exist with other `&T`
-/// references, but not with a `&mut T`
+///    references, but not with a `&mut T`
 ///
 /// 2. A `&mut T` reference may be released to safe code provided neither other `&mut T` nor `&T`
-/// co-exist with it. A `&mut T` must always be unique.
+///    co-exist with it. A `&mut T` must always be unique.
 ///
 /// Note that whilst mutating the contents of an `&UnsafeCell<T>` (even while other
 /// `&UnsafeCell<T>` references alias the cell) is
@@ -2330,7 +2332,8 @@ impl<T: ?Sized> UnsafeCell<T> {
 }
 
 #[stable(feature = "unsafe_cell_default", since = "1.10.0")]
-impl<T: Default> Default for UnsafeCell<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl<T: ~const Default> const Default for UnsafeCell<T> {
     /// Creates an `UnsafeCell`, with the `Default` value for T.
     fn default() -> UnsafeCell<T> {
         UnsafeCell::new(Default::default())
@@ -2434,7 +2437,8 @@ impl<T: ?Sized> SyncUnsafeCell<T> {
 }
 
 #[unstable(feature = "sync_unsafe_cell", issue = "95439")]
-impl<T: Default> Default for SyncUnsafeCell<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl<T: ~const Default> const Default for SyncUnsafeCell<T> {
     /// Creates an `SyncUnsafeCell`, with the `Default` value for T.
     fn default() -> SyncUnsafeCell<T> {
         SyncUnsafeCell::new(Default::default())
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index 0a15cedfb55..4d108b0c18e 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -103,6 +103,8 @@ use crate::ascii::Char as AsciiChar;
 /// ```
 #[rustc_diagnostic_item = "Default"]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
 pub trait Default: Sized {
     /// Returns the "default value" for a type.
     ///
@@ -149,7 +151,8 @@ pub macro Default($item:item) {
 macro_rules! default_impl {
     ($t:ty, $v:expr, $doc:tt) => {
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl Default for $t {
+        #[rustc_const_unstable(feature = "const_default", issue = "67792")]
+        impl const Default for $t {
             #[inline(always)]
             #[doc = $doc]
             fn default() -> $t {
diff --git a/library/core/src/error.rs b/library/core/src/error.rs
index 7f5c6ac42bc..88e633c9eef 100644
--- a/library/core/src/error.rs
+++ b/library/core/src/error.rs
@@ -447,28 +447,28 @@ where
 /// separated by API boundaries:
 ///
 /// * Consumer - the consumer requests objects using a Request instance; eg a crate that offers
-/// fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`.
+///   fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`.
 ///
 /// * Producer - the producer provides objects when requested via Request; eg. a library with an
-/// an `Error` implementation that automatically captures backtraces at the time instances are
-/// created.
+///   an `Error` implementation that automatically captures backtraces at the time instances are
+///   created.
 ///
 /// The consumer only needs to know where to submit their request and are expected to handle the
 /// request not being fulfilled by the use of `Option<T>` in the responses offered by the producer.
 ///
 /// * A Producer initializes the value of one of its fields of a specific type. (or is otherwise
-/// prepared to generate a value requested). eg, `backtrace::Backtrace` or
-/// `std::backtrace::Backtrace`
+///   prepared to generate a value requested). eg, `backtrace::Backtrace` or
+///   `std::backtrace::Backtrace`
 /// * A Consumer requests an object of a specific type (say `std::backtrace::Backtrace`). In the
-/// case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and
-/// `request_value` to simplify obtaining an `Option<T>` for a given type.
+///   case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and
+///   `request_value` to simplify obtaining an `Option<T>` for a given type.
 /// * The Producer, when requested, populates the given Request object which is given as a mutable
-/// reference.
+///   reference.
 /// * The Consumer extracts a value or reference to the requested type from the `Request` object
-/// wrapped in an `Option<T>`; in the case of `dyn Error` the aforementioned `request_ref` and `
-/// request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at
-/// all (but `Error` implementors do). The `None` case of the `Option` suggests only that the
-/// Producer cannot currently offer an instance of the requested type, not it can't or never will.
+///   wrapped in an `Option<T>`; in the case of `dyn Error` the aforementioned `request_ref` and `
+///   request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at
+///   all (but `Error` implementors do). The `None` case of the `Option` suggests only that the
+///   Producer cannot currently offer an instance of the requested type, not it can't or never will.
 ///
 /// # Examples
 ///
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 5e50eacec6e..228a331e1da 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -353,10 +353,10 @@ impl FormattingOptions {
     /// Sets or removes the sign (the `+` or the `-` flag).
     ///
     /// - `+`: This is intended for numeric types and indicates that the sign
-    /// should always be printed. By default only the negative sign of signed
-    /// values is printed, and the sign of positive or unsigned values is
-    /// omitted. This flag indicates that the correct sign (+ or -) should
-    /// always be printed.
+    ///   should always be printed. By default only the negative sign of signed
+    ///   values is printed, and the sign of positive or unsigned values is
+    ///   omitted. This flag indicates that the correct sign (+ or -) should
+    ///   always be printed.
     /// - `-`: Currently not used
     #[unstable(feature = "formatting_options", issue = "118117")]
     pub fn sign(&mut self, sign: Option<Sign>) -> &mut Self {
@@ -443,9 +443,9 @@ impl FormattingOptions {
     /// Sets or removes the precision.
     ///
     /// - For non-numeric types, this can be considered a “maximum width”. If
-    /// the resulting string is longer than this width, then it is truncated
-    /// down to this many characters and that truncated value is emitted with
-    /// proper fill, alignment and width if those parameters are set.
+    ///   the resulting string is longer than this width, then it is truncated
+    ///   down to this many characters and that truncated value is emitted with
+    ///   proper fill, alignment and width if those parameters are set.
     /// - For integral types, this is ignored.
     /// - For floating-point types, this indicates how many digits after the
     /// decimal point should be printed.
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 1ac0c7ff89b..c2e4b751c65 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -2724,7 +2724,20 @@ pub const fn type_name<T: ?Sized>() -> &'static str;
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic]
-pub const fn type_id<T: ?Sized + 'static>() -> u128;
+pub const fn type_id<T: ?Sized + 'static>() -> crate::any::TypeId;
+
+/// Tests (at compile-time) if two [`crate::any::TypeId`] instances identify the
+/// same type. This is necessary because at const-eval time the actual discriminating
+/// data is opaque and cannot be inspected directly.
+///
+/// The stabilized version of this intrinsic is the [PartialEq] impl for [`core::any::TypeId`].
+#[rustc_nounwind]
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[rustc_intrinsic]
+#[rustc_do_not_const_check]
+pub const fn type_id_eq(a: crate::any::TypeId, b: crate::any::TypeId) -> bool {
+    a.data == b.data
+}
 
 /// Lowers in MIR to `Rvalue::Aggregate` with `AggregateKind::RawPtr`.
 ///
diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs
index 3c3acceded8..309962ab70c 100644
--- a/library/core/src/iter/sources/empty.rs
+++ b/library/core/src/iter/sources/empty.rs
@@ -81,7 +81,8 @@ impl<T> Clone for Empty<T> {
 // not #[derive] because that adds a Default bound on T,
 // which isn't necessary.
 #[stable(feature = "iter_empty", since = "1.2.0")]
-impl<T> Default for Empty<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl<T> const Default for Empty<T> {
     fn default() -> Empty<T> {
         Empty(marker::PhantomData)
     }
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index ccbd2b00cfd..6531d3ec766 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -210,9 +210,14 @@ pub trait PointeeSized {
 ///   - `Trait` is dyn-compatible[^1].
 ///   - The type is sized.
 ///   - The type outlives `'a`.
+/// - Trait objects `dyn TraitA + AutoA... + 'a` implement `Unsize<dyn TraitB + AutoB... + 'b>`
+///    if all of these conditions are met:
+///   - `TraitB` is a supertrait of `TraitA`.
+///   - `AutoB...` is a subset of `AutoA...`.
+///   - `'a` outlives `'b`.
 /// - Structs `Foo<..., T1, ..., Tn, ...>` implement `Unsize<Foo<..., U1, ..., Un, ...>>`
-/// where any number of (type and const) parameters may be changed if all of these conditions
-/// are met:
+///   where any number of (type and const) parameters may be changed if all of these conditions
+///   are met:
 ///   - Only the last field of `Foo` has a type involving the parameters `T1`, ..., `Tn`.
 ///   - All other parameters of the struct are equal.
 ///   - `Field<T1, ..., Tn>: Unsize<Field<U1, ..., Un>>`, where `Field<...>` stands for the actual
@@ -858,7 +863,8 @@ impl<T: PointeeSized> Clone for PhantomData<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: PointeeSized> Default for PhantomData<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl<T: PointeeSized> const Default for PhantomData<T> {
     fn default() -> Self {
         Self
     }
diff --git a/library/core/src/num/fmt.rs b/library/core/src/num/fmt.rs
index ed61197157b..0e4b2844d81 100644
--- a/library/core/src/num/fmt.rs
+++ b/library/core/src/num/fmt.rs
@@ -22,19 +22,7 @@ impl<'a> Part<'a> {
     pub fn len(&self) -> usize {
         match *self {
             Part::Zero(nzeroes) => nzeroes,
-            Part::Num(v) => {
-                if v < 1_000 {
-                    if v < 10 {
-                        1
-                    } else if v < 100 {
-                        2
-                    } else {
-                        3
-                    }
-                } else {
-                    if v < 10_000 { 4 } else { 5 }
-                }
-            }
+            Part::Num(v) => v.checked_ilog10().unwrap_or_default() as usize + 1,
             Part::Copy(buf) => buf.len(),
         }
     }
@@ -82,21 +70,14 @@ pub struct Formatted<'a> {
 impl<'a> Formatted<'a> {
     /// Returns the exact byte length of combined formatted result.
     pub fn len(&self) -> usize {
-        let mut len = self.sign.len();
-        for part in self.parts {
-            len += part.len();
-        }
-        len
+        self.sign.len() + self.parts.iter().map(|part| part.len()).sum::<usize>()
     }
 
     /// Writes all formatted parts into the supplied buffer.
     /// Returns the number of written bytes, or `None` if the buffer is not enough.
     /// (It may still leave partially written bytes in the buffer; do not rely on that.)
     pub fn write(&self, out: &mut [u8]) -> Option<usize> {
-        if out.len() < self.sign.len() {
-            return None;
-        }
-        out[..self.sign.len()].copy_from_slice(self.sign.as_bytes());
+        out.get_mut(..self.sign.len())?.copy_from_slice(self.sign.as_bytes());
 
         let mut written = self.sign.len();
         for part in self.parts {
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
index 5d040804a8d..bbef7023207 100644
--- a/library/core/src/ops/drop.rs
+++ b/library/core/src/ops/drop.rs
@@ -11,7 +11,7 @@
 /// This destructor consists of two components:
 /// - A call to `Drop::drop` for that value, if this special `Drop` trait is implemented for its type.
 /// - The automatically generated "drop glue" which recursively calls the destructors
-///     of all the fields of this value.
+///   of all the fields of this value.
 ///
 /// As Rust automatically calls the destructors of all contained fields,
 /// you don't have to implement `Drop` in most cases. But there are some cases where
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index f2a1e901188..4ede273feda 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -125,6 +125,7 @@
 //!   `Option::<T>::None`
 //! - `transmute::<_, [u8; size_of::<T>()]>(Option::<T>::None)` is sound and produces
 //!   `[0u8; size_of::<T>()]`
+//!
 //! These cases are identified by the second column:
 //!
 //! | `T`                                                                 | Transmuting between `[0u8; size_of::<T>()]` and `Option::<T>::None` sound? |
@@ -2111,7 +2112,8 @@ where
 impl<T> crate::clone::UseCloned for Option<T> where T: crate::clone::UseCloned {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for Option<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl<T> const Default for Option<T> {
     /// Returns [`None`][Option::None].
     ///
     /// # Examples
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 3ca6feb679b..14bf7ba9015 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -137,10 +137,10 @@
 //! 2. An operation causes the value to depend on its own address not changing
 //!     * e.g. calling [`poll`] for the first time on the produced [`Future`]
 //! 3. Further pieces of the safe interface of the type use internal [`unsafe`] operations which
-//! assume that the address of the value is stable
+//!    assume that the address of the value is stable
 //!     * e.g. subsequent calls to [`poll`]
 //! 4. Before the value is invalidated (e.g. deallocated), it is *dropped*, giving it a chance to
-//! notify anything with pointers to itself that those pointers will be invalidated
+//!    notify anything with pointers to itself that those pointers will be invalidated
 //!     * e.g. [`drop`]ping the [`Future`] [^pin-drop-future]
 //!
 //! There are two possible ways to ensure the invariants required for 2. and 3. above (which
@@ -148,8 +148,8 @@
 //!
 //! 1. Have the value detect when it is moved and update all the pointers that point to itself.
 //! 2. Guarantee that the address of the value does not change (and that memory is not re-used
-//! for anything else) during the time that the pointers to it are expected to be valid to
-//! dereference.
+//!    for anything else) during the time that the pointers to it are expected to be valid to
+//!    dereference.
 //!
 //! Since, as we discussed, Rust can move values without notifying them that they have moved, the
 //! first option is ruled out.
@@ -160,11 +160,11 @@
 //! be able to enforce this invariant in Rust:
 //!
 //! 1. Offer a wholly `unsafe` API to interact with the object, thus requiring every caller to
-//! uphold the invariant themselves
+//!    uphold the invariant themselves
 //! 2. Store the value that must not be moved behind a carefully managed pointer internal to
-//! the object
+//!    the object
 //! 3. Leverage the type system to encode and enforce this invariant by presenting a restricted
-//! API surface to interact with *any* object that requires these invariants
+//!    API surface to interact with *any* object that requires these invariants
 //!
 //! The first option is quite obviously undesirable, as the [`unsafe`]ty of the interface will
 //! become viral throughout all code that interacts with the object.
@@ -530,7 +530,7 @@
 //! but it also implies that,
 //!
 //! 2. The memory location that stores the value must not get invalidated or otherwise repurposed
-//! during the lifespan of the pinned value until its [`drop`] returns or panics
+//!    during the lifespan of the pinned value until its [`drop`] returns or panics
 //!
 //! This point is subtle but required for intrusive data structures to be implemented soundly.
 //!
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs
index 3e66e271f03..304cde05af9 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -230,7 +230,8 @@ impl hash::Hash for Alignment {
 
 /// Returns [`Alignment::MIN`], which is valid for any type.
 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
-impl Default for Alignment {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl const Default for Alignment {
     fn default() -> Alignment {
         Alignment::MIN
     }
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index dc09ba8d788..db31bd2bbfb 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -1120,6 +1120,9 @@ impl<T> [T] {
     /// `chunk_size` elements, and [`rchunks`] for the same iterator but starting at the end of the
     /// slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_chunks`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1137,6 +1140,7 @@ impl<T> [T] {
     ///
     /// [`chunks_exact`]: slice::chunks_exact
     /// [`rchunks`]: slice::rchunks
+    /// [`as_chunks`]: slice::as_chunks
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1156,6 +1160,9 @@ impl<T> [T] {
     /// exactly `chunk_size` elements, and [`rchunks_mut`] for the same iterator but starting at
     /// the end of the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_chunks_mut`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1177,6 +1184,7 @@ impl<T> [T] {
     ///
     /// [`chunks_exact_mut`]: slice::chunks_exact_mut
     /// [`rchunks_mut`]: slice::rchunks_mut
+    /// [`as_chunks_mut`]: slice::as_chunks_mut
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1199,6 +1207,9 @@ impl<T> [T] {
     /// See [`chunks`] for a variant of this iterator that also returns the remainder as a smaller
     /// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_chunks`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1216,6 +1227,7 @@ impl<T> [T] {
     ///
     /// [`chunks`]: slice::chunks
     /// [`rchunks_exact`]: slice::rchunks_exact
+    /// [`as_chunks`]: slice::chunks
     #[stable(feature = "chunks_exact", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1239,6 +1251,9 @@ impl<T> [T] {
     /// smaller chunk, and [`rchunks_exact_mut`] for the same iterator but starting at the end of
     /// the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_chunks_mut`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1260,6 +1275,7 @@ impl<T> [T] {
     ///
     /// [`chunks_mut`]: slice::chunks_mut
     /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
+    /// [`as_chunks_mut`]: slice::as_chunks_mut
     #[stable(feature = "chunks_exact", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1707,6 +1723,9 @@ impl<T> [T] {
     /// `chunk_size` elements, and [`chunks`] for the same iterator but starting at the beginning
     /// of the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_rchunks`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1724,6 +1743,7 @@ impl<T> [T] {
     ///
     /// [`rchunks_exact`]: slice::rchunks_exact
     /// [`chunks`]: slice::chunks
+    /// [`as_rchunks`]: slice::as_rchunks
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1743,6 +1763,9 @@ impl<T> [T] {
     /// exactly `chunk_size` elements, and [`chunks_mut`] for the same iterator but starting at the
     /// beginning of the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_rchunks_mut`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1764,6 +1787,7 @@ impl<T> [T] {
     ///
     /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
     /// [`chunks_mut`]: slice::chunks_mut
+    /// [`as_rchunks_mut`]: slice::as_rchunks_mut
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1787,6 +1811,9 @@ impl<T> [T] {
     /// chunk, and [`chunks_exact`] for the same iterator but starting at the beginning of the
     /// slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_rchunks`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1805,6 +1832,7 @@ impl<T> [T] {
     /// [`chunks`]: slice::chunks
     /// [`rchunks`]: slice::rchunks
     /// [`chunks_exact`]: slice::chunks_exact
+    /// [`as_rchunks`]: slice::as_rchunks
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1828,6 +1856,9 @@ impl<T> [T] {
     /// smaller chunk, and [`chunks_exact_mut`] for the same iterator but starting at the beginning
     /// of the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_rchunks_mut`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1850,6 +1881,7 @@ impl<T> [T] {
     /// [`chunks_mut`]: slice::chunks_mut
     /// [`rchunks_mut`]: slice::rchunks_mut
     /// [`chunks_exact_mut`]: slice::chunks_exact_mut
+    /// [`as_rchunks_mut`]: slice::as_rchunks_mut
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -5158,7 +5190,8 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for &[T] {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl<T> const Default for &[T] {
     /// Creates an empty slice.
     fn default() -> Self {
         &[]
@@ -5166,7 +5199,8 @@ impl<T> Default for &[T] {
 }
 
 #[stable(feature = "mut_slice_default", since = "1.5.0")]
-impl<T> Default for &mut [T] {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl<T> const Default for &mut [T] {
     /// Creates a mutable empty slice.
     fn default() -> Self {
         &mut []
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index fe64132ff22..32a22988175 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -3072,7 +3072,8 @@ impl AsRef<[u8]> for str {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Default for &str {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl const Default for &str {
     /// Creates an empty str
     #[inline]
     fn default() -> Self {
@@ -3081,7 +3082,8 @@ impl Default for &str {
 }
 
 #[stable(feature = "default_mut_str", since = "1.28.0")]
-impl Default for &mut str {
+#[rustc_const_unstable(feature = "const_default", issue = "67792")]
+impl const Default for &mut str {
     /// Creates an empty mutable str
     #[inline]
     fn default() -> Self {
diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs
index 25b9c6e0e0e..b57234bbee9 100644
--- a/library/core/src/unicode/unicode_data.rs
+++ b/library/core/src/unicode/unicode_data.rs
@@ -82,7 +82,7 @@ unsafe fn skip_search<const SOR: usize, const OFFSETS: usize>(
     let needle = needle as u32;
 
     let last_idx =
-        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| (header.0 << 11)) {
+        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header.0 << 11) {
             Ok(idx) => idx + 1,
             Err(idx) => idx,
         };
diff --git a/library/coretests/tests/any.rs b/library/coretests/tests/any.rs
index 117ef004238..25002617d0b 100644
--- a/library/coretests/tests/any.rs
+++ b/library/coretests/tests/any.rs
@@ -118,14 +118,6 @@ fn any_unsized() {
     is_any::<[i32]>();
 }
 
-#[cfg(feature = "debug_typeid")]
-#[test]
-fn debug_typeid_includes_name() {
-    let type_id = TypeId::of::<[usize; 2]>();
-    let debug_str = format!("{type_id:?}");
-    assert!(debug_str.ends_with("= [usize; 2])"), "{debug_str:?} did not match");
-}
-
 #[test]
 fn distinct_type_names() {
     // https://github.com/rust-lang/rust/issues/84666
diff --git a/library/coretests/tests/floats/f128.rs b/library/coretests/tests/floats/f128.rs
index cf78e8796a0..38df09a91c1 100644
--- a/library/coretests/tests/floats/f128.rs
+++ b/library/coretests/tests/floats/f128.rs
@@ -56,20 +56,6 @@ fn test_num_f128() {
 // the intrinsics.
 
 #[test]
-fn test_nan() {
-    let nan: f128 = f128::NAN;
-    assert!(nan.is_nan());
-    assert!(!nan.is_infinite());
-    assert!(!nan.is_finite());
-    assert!(nan.is_sign_positive());
-    assert!(!nan.is_sign_negative());
-    assert!(!nan.is_normal());
-    assert_eq!(Fp::Nan, nan.classify());
-    // Ensure the quiet bit is set.
-    assert!(nan.to_bits() & (1 << (f128::MANTISSA_DIGITS - 2)) != 0);
-}
-
-#[test]
 fn test_infinity() {
     let inf: f128 = f128::INFINITY;
     assert!(inf.is_infinite());
diff --git a/library/coretests/tests/floats/f16.rs b/library/coretests/tests/floats/f16.rs
index 9e91b654304..f6749d796cc 100644
--- a/library/coretests/tests/floats/f16.rs
+++ b/library/coretests/tests/floats/f16.rs
@@ -52,20 +52,6 @@ fn test_num_f16() {
 // the intrinsics.
 
 #[test]
-fn test_nan() {
-    let nan: f16 = f16::NAN;
-    assert!(nan.is_nan());
-    assert!(!nan.is_infinite());
-    assert!(!nan.is_finite());
-    assert!(nan.is_sign_positive());
-    assert!(!nan.is_sign_negative());
-    assert!(!nan.is_normal());
-    assert_eq!(Fp::Nan, nan.classify());
-    // Ensure the quiet bit is set.
-    assert!(nan.to_bits() & (1 << (f16::MANTISSA_DIGITS - 2)) != 0);
-}
-
-#[test]
 fn test_infinity() {
     let inf: f16 = f16::INFINITY;
     assert!(inf.is_infinite());
diff --git a/library/coretests/tests/floats/f32.rs b/library/coretests/tests/floats/f32.rs
index d2724d12e39..f5d5723fea4 100644
--- a/library/coretests/tests/floats/f32.rs
+++ b/library/coretests/tests/floats/f32.rs
@@ -36,20 +36,6 @@ fn test_num_f32() {
 }
 
 #[test]
-fn test_nan() {
-    let nan: f32 = f32::NAN;
-    assert!(nan.is_nan());
-    assert!(!nan.is_infinite());
-    assert!(!nan.is_finite());
-    assert!(!nan.is_normal());
-    assert!(nan.is_sign_positive());
-    assert!(!nan.is_sign_negative());
-    assert_eq!(Fp::Nan, nan.classify());
-    // Ensure the quiet bit is set.
-    assert!(nan.to_bits() & (1 << (f32::MANTISSA_DIGITS - 2)) != 0);
-}
-
-#[test]
 fn test_infinity() {
     let inf: f32 = f32::INFINITY;
     assert!(inf.is_infinite());
diff --git a/library/coretests/tests/floats/f64.rs b/library/coretests/tests/floats/f64.rs
index b2b2393a527..34af87c241e 100644
--- a/library/coretests/tests/floats/f64.rs
+++ b/library/coretests/tests/floats/f64.rs
@@ -31,20 +31,6 @@ fn test_num_f64() {
 }
 
 #[test]
-fn test_nan() {
-    let nan: f64 = f64::NAN;
-    assert!(nan.is_nan());
-    assert!(!nan.is_infinite());
-    assert!(!nan.is_finite());
-    assert!(!nan.is_normal());
-    assert!(nan.is_sign_positive());
-    assert!(!nan.is_sign_negative());
-    assert_eq!(Fp::Nan, nan.classify());
-    // Ensure the quiet bit is set.
-    assert!(nan.to_bits() & (1 << (f64::MANTISSA_DIGITS - 2)) != 0);
-}
-
-#[test]
 fn test_infinity() {
     let inf: f64 = f64::INFINITY;
     assert!(inf.is_infinite());
diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs
index 6b4f586fa9b..36743a7d6df 100644
--- a/library/coretests/tests/floats/mod.rs
+++ b/library/coretests/tests/floats/mod.rs
@@ -1,4 +1,5 @@
 use std::fmt;
+use std::num::FpCategory as Fp;
 use std::ops::{Add, Div, Mul, Rem, Sub};
 
 /// Set the default tolerance for float comparison based on the type.
@@ -187,6 +188,8 @@ macro_rules! float_test {
             mod const_ {
                 #[allow(unused)]
                 use super::Approx;
+                #[allow(unused)]
+                use std::num::FpCategory as Fp;
                 // Shadow the runtime versions of the macro with const-compatible versions.
                 #[allow(unused)]
                 use $crate::floats::{
@@ -251,6 +254,26 @@ mod f32;
 mod f64;
 
 float_test! {
+    name: nan,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16))],
+        f128: #[cfg(any(miri, target_has_reliable_f128))],
+    },
+    test<Float> {
+        let nan: Float = Float::NAN;
+        assert!(nan.is_nan());
+        assert!(!nan.is_infinite());
+        assert!(!nan.is_finite());
+        assert!(!nan.is_normal());
+        assert!(nan.is_sign_positive());
+        assert!(!nan.is_sign_negative());
+        assert!(matches!(nan.classify(), Fp::Nan));
+        // Ensure the quiet bit is set.
+        assert!(nan.to_bits() & (1 << (Float::MANTISSA_DIGITS - 2)) != 0);
+    }
+}
+
+float_test! {
     name: min,
     attrs: {
         f16: #[cfg(any(miri, target_has_reliable_f16_math))],
diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs
index 6a1cecd69fb..57ca7db9fcd 100644
--- a/library/proc_macro/src/bridge/symbol.rs
+++ b/library/proc_macro/src/bridge/symbol.rs
@@ -33,7 +33,7 @@ impl Symbol {
     /// Validates and normalizes before converting it to a symbol.
     pub(crate) fn new_ident(string: &str, is_raw: bool) -> Self {
         // Fast-path: check if this is a valid ASCII identifier
-        if Self::is_valid_ascii_ident(string.as_bytes()) {
+        if Self::is_valid_ascii_ident(string.as_bytes()) || string == "$crate" {
             if is_raw && !Self::can_be_raw(string) {
                 panic!("`{}` cannot be a raw identifier", string);
             }
@@ -79,7 +79,7 @@ impl Symbol {
     // Mimics the behavior of `Symbol::can_be_raw` from `rustc_span`
     fn can_be_raw(string: &str) -> bool {
         match string {
-            "_" | "super" | "self" | "Self" | "crate" => false,
+            "_" | "super" | "self" | "Self" | "crate" | "$crate" => false,
             _ => true,
         }
     }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 3a75d316871..62ece4b6961 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -113,8 +113,6 @@ optimize_for_size = ["core/optimize_for_size", "alloc/optimize_for_size"]
 # Make `RefCell` store additional debugging information, which is printed out when
 # a borrow error occurs
 debug_refcell = ["core/debug_refcell"]
-# Make `TypeId` store a reference to the name of the type, so that it can print that name.
-debug_typeid = ["core/debug_typeid"]
 
 
 # Enable std_detect default features for stdarch/crates/std_detect:
diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs
index dc278274f00..b310db2dac4 100644
--- a/library/std/src/sys/fs/unix.rs
+++ b/library/std/src/sys/fs/unix.rs
@@ -1491,7 +1491,6 @@ impl File {
             target_os = "redox",
             target_os = "espidf",
             target_os = "horizon",
-            target_os = "vxworks",
             target_os = "nuttx",
         )))]
         let to_timespec = |time: Option<SystemTime>| match time {
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 53f0d1eeda5..e4f5520d8a3 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -222,7 +222,7 @@ impl Thread {
 
     #[cfg(target_os = "vxworks")]
     pub fn set_name(name: &CStr) {
-        let mut name = truncate_cstr::<{ libc::VX_TASK_RENAME_LENGTH - 1 }>(name);
+        let mut name = truncate_cstr::<{ (libc::VX_TASK_RENAME_LENGTH - 1) as usize }>(name);
         let res = unsafe { libc::taskNameSet(libc::taskIdSelf(), name.as_mut_ptr()) };
         debug_assert_eq!(res, libc::OK);
     }
diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml
index 3adc0224971..c4937c36d4c 100644
--- a/library/sysroot/Cargo.toml
+++ b/library/sysroot/Cargo.toml
@@ -22,7 +22,6 @@ compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"]
 compiler-builtins-no-f16-f128 = ["std/compiler-builtins-no-f16-f128"]
 compiler-builtins-mangled-names = ["std/compiler-builtins-mangled-names"]
 debug_refcell = ["std/debug_refcell"]
-debug_typeid = ["std/debug_typeid"]
 llvm-libunwind = ["std/llvm-libunwind"]
 system-llvm-libunwind = ["std/system-llvm-libunwind"]
 optimize_for_size = ["std/optimize_for_size"]
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index c077555b906..b05a5cc8b81 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -739,19 +739,29 @@ def configure_file(sections, top_level_keys, targets, config):
 
 
 def write_uncommented(target, f):
+    """Writes each block in 'target' that is not composed entirely of comments to 'f'.
+
+    A block is a sequence of non-empty lines separated by empty lines.
+    """
     block = []
-    is_comment = True
+
+    def flush(last):
+        # If the block is entirely made of comments, ignore it
+        entire_block_comments = all(ln.startswith("#") or ln == "" for ln in block)
+        if not entire_block_comments and len(block) > 0:
+            for line in block:
+                f.write(line + "\n")
+            # Required to output a newline before the start of a new section
+            if last:
+                f.write("\n")
+        block.clear()
 
     for line in target:
         block.append(line)
         if len(line) == 0:
-            if not is_comment:
-                for ln in block:
-                    f.write(ln + "\n")
-            block = []
-            is_comment = True
-            continue
-        is_comment = is_comment and line.startswith("#")
+            flush(last=False)
+
+    flush(last=True)
     return f
 
 
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 3e2bdc2d6b5..0587d21ecc2 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1369,9 +1369,7 @@ pub fn rustc_cargo_env(
     }
 
     // Enable rustc's env var for `rust-lld` when requested.
-    if builder.config.lld_enabled
-        && (builder.config.channel == "dev" || builder.config.channel == "nightly")
-    {
+    if builder.config.lld_enabled {
         cargo.env("CFG_USE_SELF_CONTAINED_LINKER", "1");
     }
 
@@ -2059,14 +2057,20 @@ impl Step for Assemble {
                 trace!("llvm-bitcode-linker enabled, installing");
                 let llvm_bitcode_linker =
                     builder.ensure(crate::core::build_steps::tool::LlvmBitcodeLinker {
-                        compiler,
+                        build_compiler: compiler,
                         target: target_compiler.host,
-                        extra_features: vec![],
                     });
+
+                // Copy the llvm-bitcode-linker to the self-contained binary directory
+                let bindir_self_contained = builder
+                    .sysroot(compiler)
+                    .join(format!("lib/rustlib/{}/bin/self-contained", compiler.host));
                 let tool_exe = exe("llvm-bitcode-linker", target_compiler.host);
+
+                t!(fs::create_dir_all(&bindir_self_contained));
                 builder.copy_link(
                     &llvm_bitcode_linker.tool_path,
-                    &libdir_bin.join(tool_exe),
+                    &bindir_self_contained.join(tool_exe),
                     FileType::Executable,
                 );
             }
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 25b7e5a1b5d..8b2d65ace50 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -2375,7 +2375,7 @@ impl Step for LlvmBitcodeLinker {
         builder.ensure(compile::Rustc::new(compiler, target));
 
         let llbc_linker =
-            builder.ensure(tool::LlvmBitcodeLinker { compiler, target, extra_features: vec![] });
+            builder.ensure(tool::LlvmBitcodeLinker { build_compiler: compiler, target });
 
         let self_contained_bin_dir = format!("lib/rustlib/{}/bin/self-contained", target.triple);
 
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index a5b7b22aba8..716bef3f38c 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -262,7 +262,13 @@ impl Step for Cargotest {
             .args(builder.config.test_args())
             .env("RUSTC", builder.rustc(compiler))
             .env("RUSTDOC", builder.rustdoc(compiler));
-        add_rustdoc_cargo_linker_args(&mut cmd, builder, compiler.host, LldThreads::No);
+        add_rustdoc_cargo_linker_args(
+            &mut cmd,
+            builder,
+            compiler.host,
+            LldThreads::No,
+            compiler.stage,
+        );
         cmd.delay_failure().run(builder);
     }
 }
@@ -857,7 +863,7 @@ impl Step for RustdocTheme {
             .env("CFG_RELEASE_CHANNEL", &builder.config.channel)
             .env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
             .env("RUSTC_BOOTSTRAP", "1");
-        cmd.args(linker_args(builder, self.compiler.host, LldThreads::No));
+        cmd.args(linker_args(builder, self.compiler.host, LldThreads::No, self.compiler.stage));
 
         cmd.delay_failure().run(builder);
     }
@@ -1033,7 +1039,13 @@ impl Step for RustdocGUI {
         cmd.env("RUSTDOC", builder.rustdoc(self.compiler))
             .env("RUSTC", builder.rustc(self.compiler));
 
-        add_rustdoc_cargo_linker_args(&mut cmd, builder, self.compiler.host, LldThreads::No);
+        add_rustdoc_cargo_linker_args(
+            &mut cmd,
+            builder,
+            self.compiler.host,
+            LldThreads::No,
+            self.compiler.stage,
+        );
 
         for path in &builder.paths {
             if let Some(p) = helpers::is_valid_test_suite_arg(path, "tests/rustdoc-gui", builder) {
@@ -1812,7 +1824,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         }
 
         let mut hostflags = flags.clone();
-        hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No));
+        hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No, compiler.stage));
 
         let mut targetflags = flags;
 
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index b05b34b9b22..5de1b472d79 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -910,6 +910,13 @@ impl Step for LldWrapper {
 
         tool_result
     }
+
+    fn metadata(&self) -> Option<StepMetadata> {
+        Some(
+            StepMetadata::build("LldWrapper", self.target_compiler.host)
+                .built_by(self.build_compiler),
+        )
+    }
 }
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
@@ -1014,9 +1021,8 @@ impl Step for RustAnalyzerProcMacroSrv {
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct LlvmBitcodeLinker {
-    pub compiler: Compiler,
+    pub build_compiler: Compiler,
     pub target: TargetSelection,
-    pub extra_features: Vec<String>,
 }
 
 impl Step for LlvmBitcodeLinker {
@@ -1032,8 +1038,9 @@ impl Step for LlvmBitcodeLinker {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(LlvmBitcodeLinker {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
-            extra_features: Vec::new(),
+            build_compiler: run
+                .builder
+                .compiler(run.builder.top_stage, run.builder.config.host_target),
             target: run.target,
         });
     }
@@ -1043,35 +1050,22 @@ impl Step for LlvmBitcodeLinker {
         instrument(level = "debug", name = "LlvmBitcodeLinker::run", skip_all)
     )]
     fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
-        let tool_result = builder.ensure(ToolBuild {
-            compiler: self.compiler,
+        builder.ensure(ToolBuild {
+            compiler: self.build_compiler,
             target: self.target,
             tool: "llvm-bitcode-linker",
             mode: Mode::ToolRustc,
             path: "src/tools/llvm-bitcode-linker",
             source_type: SourceType::InTree,
-            extra_features: self.extra_features,
+            extra_features: vec![],
             allow_features: "",
             cargo_args: Vec::new(),
             artifact_kind: ToolArtifactKind::Binary,
-        });
+        })
+    }
 
-        if tool_result.target_compiler.stage > 0 {
-            let bindir_self_contained = builder
-                .sysroot(tool_result.target_compiler)
-                .join(format!("lib/rustlib/{}/bin/self-contained", self.target.triple));
-            t!(fs::create_dir_all(&bindir_self_contained));
-            let bin_destination = bindir_self_contained
-                .join(exe("llvm-bitcode-linker", tool_result.target_compiler.host));
-            builder.copy_link(&tool_result.tool_path, &bin_destination, FileType::Executable);
-            ToolBuildResult {
-                tool_path: bin_destination,
-                build_compiler: tool_result.build_compiler,
-                target_compiler: tool_result.target_compiler,
-            }
-        } else {
-            tool_result
-        }
+    fn metadata(&self) -> Option<StepMetadata> {
+        Some(StepMetadata::build("LlvmBitcodeLinker", self.target).built_by(self.build_compiler))
     }
 }
 
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index deb7106f185..065d7e45e0f 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -115,7 +115,7 @@ impl Cargo {
             // No need to configure the target linker for these command types.
             Kind::Clean | Kind::Check | Kind::Suggest | Kind::Format | Kind::Setup => {}
             _ => {
-                cargo.configure_linker(builder);
+                cargo.configure_linker(builder, mode);
             }
         }
 
@@ -209,7 +209,7 @@ impl Cargo {
 
     // FIXME(onur-ozkan): Add coverage to make sure modifications to this function
     // doesn't cause cache invalidations (e.g., #130108).
-    fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo {
+    fn configure_linker(&mut self, builder: &Builder<'_>, mode: Mode) -> &mut Cargo {
         let target = self.target;
         let compiler = self.compiler;
 
@@ -264,7 +264,12 @@ impl Cargo {
             }
         }
 
-        for arg in linker_args(builder, compiler.host, LldThreads::Yes) {
+        // We use the snapshot compiler when building host code (build scripts/proc macros) of
+        // `Mode::Std` tools, so we need to determine the current stage here to pass the proper
+        // linker args (e.g. -C vs -Z).
+        // This should stay synchronized with the [cargo] function.
+        let host_stage = if mode == Mode::Std { 0 } else { compiler.stage };
+        for arg in linker_args(builder, compiler.host, LldThreads::Yes, host_stage) {
             self.hostflags.arg(&arg);
         }
 
@@ -274,10 +279,10 @@ impl Cargo {
         }
         // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
         // `linker_args` here.
-        for flag in linker_flags(builder, target, LldThreads::Yes) {
+        for flag in linker_flags(builder, target, LldThreads::Yes, compiler.stage) {
             self.rustflags.arg(&flag);
         }
-        for arg in linker_args(builder, target, LldThreads::Yes) {
+        for arg in linker_args(builder, target, LldThreads::Yes, compiler.stage) {
             self.rustdocflags.arg(&arg);
         }
 
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index b96a988cde3..7464327fde9 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -1599,7 +1599,7 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
             cmd.arg("-Dwarnings");
         }
         cmd.arg("-Znormalize-docs");
-        cmd.args(linker_args(self, compiler.host, LldThreads::Yes));
+        cmd.args(linker_args(self, compiler.host, LldThreads::Yes, compiler.stage));
         cmd
     }
 
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 1d5690a8197..bbcb58fca14 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -758,6 +758,58 @@ mod snapshot {
     }
 
     #[test]
+    fn build_compiler_tools() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx
+                .config("build")
+                .stage(2)
+                .args(&["--set", "rust.lld=true", "--set", "rust.llvm-bitcode-linker=true"])
+                .render_steps(), @r"
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 0 <host> -> LldWrapper 1 <host>
+        [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustc 1 <host> -> rustc 2 <host>
+        [build] rustc 1 <host> -> LldWrapper 2 <host>
+        [build] rustc 2 <host> -> LlvmBitcodeLinker 3 <host>
+        [build] rustc 2 <host> -> std 2 <host>
+        [build] rustdoc 1 <host>
+        "
+        );
+    }
+
+    #[test]
+    fn build_compiler_tools_cross() {
+        let ctx = TestCtx::new();
+        insta::assert_snapshot!(
+            ctx
+                .config("build")
+                .stage(2)
+                .args(&["--set", "rust.lld=true", "--set", "rust.llvm-bitcode-linker=true"])
+                .hosts(&[TEST_TRIPLE_1])
+                .render_steps(), @r"
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 0 <host> -> LldWrapper 1 <host>
+        [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustc 1 <host> -> rustc 2 <host>
+        [build] rustc 1 <host> -> LldWrapper 2 <host>
+        [build] rustc 2 <host> -> LlvmBitcodeLinker 3 <host>
+        [build] rustc 1 <host> -> std 1 <target1>
+        [build] rustc 2 <host> -> std 2 <target1>
+        [build] llvm <target1>
+        [build] rustc 1 <host> -> rustc 2 <target1>
+        [build] rustc 1 <host> -> LldWrapper 2 <target1>
+        [build] rustc 2 <target1> -> LlvmBitcodeLinker 3 <target1>
+        [build] rustdoc 1 <target1>
+        "
+        );
+    }
+
+    #[test]
     fn build_library_no_explicit_stage() {
         let ctx = TestCtx::new();
         insta::assert_snapshot!(
@@ -1040,6 +1092,7 @@ mod snapshot {
         [build] rustc 0 <host> -> cargo-clippy 1 <host>
         [build] rustc 0 <host> -> miri 1 <host>
         [build] rustc 0 <host> -> cargo-miri 1 <host>
+        [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <host>
         ");
     }
 
@@ -1230,6 +1283,7 @@ mod snapshot {
         [build] rustc 0 <host> -> cargo-clippy 1 <target1>
         [build] rustc 0 <host> -> miri 1 <target1>
         [build] rustc 0 <host> -> cargo-miri 1 <target1>
+        [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <target1>
         ");
     }
 
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index bfc06f90d4f..19e0d3413bb 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -383,7 +383,10 @@ pub enum Subcommand {
         bless: bool,
         #[arg(long)]
         /// comma-separated list of other files types to check (accepts py, py:lint,
-        /// py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)
+        /// py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)
+        ///
+        /// Any argument can be prefixed with "auto:" to only run if
+        /// relevant files are modified (eg. "auto:py").
         extra_checks: Option<String>,
         #[arg(long)]
         /// rerun tests even if the inputs are unchanged
diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs
index ac5eaea3bcb..0fae235bb93 100644
--- a/src/bootstrap/src/core/config/toml/rust.rs
+++ b/src/bootstrap/src/core/config/toml/rust.rs
@@ -619,7 +619,6 @@ impl Config {
         // 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
@@ -628,9 +627,7 @@ impl Config {
         //   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.host_target.triple == "x86_64-unknown-linux-gnu"
-            && self.hosts == [self.host_target]
-            && (self.channel == "dev" || self.channel == "nightly")
+        if self.host_target.triple == "x86_64-unknown-linux-gnu" && self.hosts == [self.host_target]
         {
             let no_llvm_config = self
                 .target_config
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 424f211c7d4..29591edc9cc 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -461,4 +461,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Warning,
         summary: "`download-rustc` has been temporarily disabled for the library profile due to implementation bugs (see #142505).",
     },
+    ChangeInfo {
+        change_id: 143398,
+        severity: ChangeSeverity::Info,
+        summary: "The --extra-checks flag now supports prefixing any check with `auto:` to only run it if relevant files are modified",
+    },
 ];
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 3c5f612daa7..eb00ed566c2 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -404,8 +404,9 @@ pub fn linker_args(
     builder: &Builder<'_>,
     target: TargetSelection,
     lld_threads: LldThreads,
+    stage: u32,
 ) -> Vec<String> {
-    let mut args = linker_flags(builder, target, lld_threads);
+    let mut args = linker_flags(builder, target, lld_threads, stage);
 
     if let Some(linker) = builder.linker(target) {
         args.push(format!("-Clinker={}", linker.display()));
@@ -420,19 +421,30 @@ pub fn linker_flags(
     builder: &Builder<'_>,
     target: TargetSelection,
     lld_threads: LldThreads,
+    stage: u32,
 ) -> Vec<String> {
     let mut args = vec![];
     if !builder.is_lld_direct_linker(target) && builder.config.lld_mode.is_used() {
         match builder.config.lld_mode {
             LldMode::External => {
-                args.push("-Zlinker-features=+lld".to_string());
-                // FIXME(kobzol): remove this flag once MCP510 gets stabilized
+                // cfg(bootstrap) - remove the stage 0 check after updating the bootstrap compiler:
+                // `-Clinker-features` has been stabilized.
+                if stage == 0 {
+                    args.push("-Zlinker-features=+lld".to_string());
+                } else {
+                    args.push("-Clinker-features=+lld".to_string());
+                }
                 args.push("-Zunstable-options".to_string());
             }
             LldMode::SelfContained => {
-                args.push("-Zlinker-features=+lld".to_string());
+                // cfg(bootstrap) - remove the stage 0 check after updating the bootstrap compiler:
+                // `-Clinker-features` has been stabilized.
+                if stage == 0 {
+                    args.push("-Zlinker-features=+lld".to_string());
+                } else {
+                    args.push("-Clinker-features=+lld".to_string());
+                }
                 args.push("-Clink-self-contained=+linker".to_string());
-                // FIXME(kobzol): remove this flag once MCP510 gets stabilized
                 args.push("-Zunstable-options".to_string());
             }
             LldMode::Unused => unreachable!(),
@@ -453,8 +465,9 @@ pub fn add_rustdoc_cargo_linker_args(
     builder: &Builder<'_>,
     target: TargetSelection,
     lld_threads: LldThreads,
+    stage: u32,
 ) {
-    let args = linker_args(builder, target, lld_threads);
+    let args = linker_args(builder, target, lld_threads, stage);
     let mut flags = cmd
         .get_envs()
         .find_map(|(k, v)| if k == OsStr::new("RUSTDOCFLAGS") { v } else { None })
diff --git a/src/bootstrap/src/utils/tests/mod.rs b/src/bootstrap/src/utils/tests/mod.rs
index 59c169b0f2b..5b568c1df5b 100644
--- a/src/bootstrap/src/utils/tests/mod.rs
+++ b/src/bootstrap/src/utils/tests/mod.rs
@@ -96,8 +96,6 @@ impl ConfigBuilder {
         // in-tree LLVM from sources.
         self.args.push("--set".to_string());
         self.args.push("llvm.download-ci-llvm=false".to_string());
-        self.args.push("--set".to_string());
-        self.args.push(format!("target.'{}'.llvm-config=false", get_host_target()));
 
         // Do not mess with the local rustc checkout build directory
         self.args.push("--build-dir".to_string());
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 9fe4c218121..e1742631f63 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -83,6 +83,7 @@
     - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
     - [m68k-unknown-none-elf](platform-support/m68k-unknown-none-elf.md)
     - [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
+    - [mips64-unknown-linux-muslabi64](platform-support/mips64-unknown-linux-muslabi64.md)
     - [mipsel-sony-psx](platform-support/mipsel-sony-psx.md)
     - [mipsel-unknown-linux-gnu](platform-support/mipsel-unknown-linux-gnu.md)
     - [mips\*-mti-none-elf](platform-support/mips-mti-none-elf.md)
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index bb109adf76f..07eafdf4c4c 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -235,15 +235,33 @@ coverage measurement. Its use is not recommended.
 
 ## link-self-contained
 
-On `windows-gnu`, `linux-musl`, and `wasi` targets, this flag controls whether the
-linker will use libraries and objects shipped with Rust instead of those in the system.
-It takes one of the following values:
+This flag controls whether the linker will use libraries and objects shipped with Rust instead of
+those in the system.  It also controls which binary is used for the linker itself. This allows
+overriding cases when detection fails or the user wants to use shipped libraries.
+
+You can enable or disable the usage of any self-contained components using one of the following values:
 
 * no value: rustc will use heuristic to disable self-contained mode if system has necessary tools.
 * `y`, `yes`, `on`, `true`: use only libraries/objects shipped with Rust.
 * `n`, `no`, `off` or `false`: rely on the user or the linker to provide non-Rust libraries/objects.
 
-This allows overriding cases when detection fails or user wants to use shipped libraries.
+It is also possible to enable or disable specific self-contained components in a more granular way.
+You can pass a comma-separated list of self-contained components, individually enabled
+(`+component`) or disabled (`-component`).
+
+Currently, only the `linker` granular option is stabilized, and only on the `x86_64-unknown-linux-gnu` target:
+- `linker`: toggle the usage of self-contained linker binaries (linker, dlltool, and their necessary libraries)
+
+Note that only the `-linker` opt-out is stable on the `x86_64-unknown-linux-gnu` target: `+linker` is
+already the default on this target.
+
+#### Implementation notes
+
+On the `x86_64-unknown-linux-gnu` target, when using the default linker flavor (using `cc` as the
+linker driver) and linker features (to try using `lld`), `rustc` will try to use the self-contained
+linker by passing a `-B /path/to/sysroot/` link argument to the driver to find `rust-lld` in the
+sysroot. For backwards-compatibility, and to limit name and `PATH` collisions, this is done using a
+shim executable (the `lld-wrapper` tool) that forwards execution to the `rust-lld` executable itself.
 
 ## linker
 
@@ -256,6 +274,39 @@ Note that on Unix-like targets (for example, `*-unknown-linux-gnu` or `*-unknown
 the C compiler (for example `cc` or `clang`) is used as the "linker" here, serving as a linker driver.
 It will invoke the actual linker with all the necessary flags to be able to link against the system libraries like libc.
 
+## linker-features
+
+The `-Clinker-features` flag allows enabling or disabling specific features used during linking.
+
+These feature flags are a flexible extension mechanism that is complementary to linker flavors,
+designed to avoid the combinatorial explosion of having to create a new set of flavors for each
+linker feature we'd want to use.
+
+The flag accepts a comma-separated list of features, individually enabled (`+feature`) or disabled
+(`-feature`).
+
+Currently only one is stable, and only on the `x86_64-unknown-linux-gnu` target:
+- `lld`: to toggle trying to use the lld linker, either the system-installed binary, or the self-contained
+  `rust-lld` linker (via the [`-Clink-self-contained=+linker`](#link-self-contained) flag).
+
+For example, use:
+- `-Clinker-features=+lld` to opt into using the `lld` linker, when possible (see the Implementation notes below)
+- `-Clinker-features=-lld` to opt out instead, for targets where it is configured as the default linker
+
+Note that only the `-lld` opt-out is stable on the `x86_64-unknown-linux-gnu` target: `+lld` is
+already the default on this target.
+
+#### Implementation notes
+
+On the `x86_64-unknown-linux-gnu` target, when using the default linker flavor (using `cc` as the
+linker driver), `rustc` will try to use lld by passing a `-fuse-ld=lld` link argument to the driver.
+`rustc` will also try to detect if that _causes_ an error during linking (for example, if GCC is too
+old to understand the flag, and returns an error) and will then retry linking without this argument,
+as a fallback.
+
+If the user _also_ passes a `-Clink-arg=-fuse-ld=$value`, both will be given to the linker
+driver but the user's will be passed last, and would generally have priority over `rustc`'s.
+
 ## linker-flavor
 
 This flag controls the linker flavor used by `rustc`. If a linker is given with
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 285b1e519b7..ed01de4c1c3 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -333,7 +333,7 @@ target | std | host | notes
 `mips-unknown-linux-uclibc` | ✓ |  | MIPS Linux with uClibc
 [`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? |  | MIPS64 for OpenWrt Linux musl 1.2.3
 `mips64-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 Linux, N64 ABI (kernel 4.4, glibc 2.23)
-`mips64-unknown-linux-muslabi64` | ✓ |  | MIPS64 Linux, N64 ABI, musl 1.2.3
+[`mips64-unknown-linux-muslabi64`](platform-support/mips64-unknown-linux-muslabi64.md) | ✓ | ✓ | MIPS64 Linux, N64 ABI, musl 1.2.3
 `mips64el-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 (little endian) Linux, N64 ABI (kernel 4.4, glibc 2.23)
 `mips64el-unknown-linux-muslabi64` | ✓ |  | MIPS64 (little endian) Linux, N64 ABI, musl 1.2.3
 `mipsel-sony-psp` | * |  | MIPS (LE) Sony PlayStation Portable (PSP)
diff --git a/src/doc/rustc/src/platform-support/mips64-unknown-linux-muslabi64.md b/src/doc/rustc/src/platform-support/mips64-unknown-linux-muslabi64.md
new file mode 100644
index 00000000000..60c0972bb3e
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/mips64-unknown-linux-muslabi64.md
@@ -0,0 +1,49 @@
+# mips64-unknown-linux-muslabi64
+
+**Tier: 3**
+
+Target for 64-bit big endian MIPS Linux programs using musl libc and the N64 ABI.
+
+## Target maintainers
+
+[@Gelbpunkt](https://github.com/Gelbpunkt)
+
+## Requirements
+
+Building the target itself requires a 64-bit big endian MIPS compiler that is
+supported by `cc-rs`.
+
+## Building the target
+
+The target can be built by enabling it for a `rustc` build.
+
+```toml
+[build]
+target = ["mips64-unknown-linux-muslabi64"]
+```
+
+Make sure your C compiler is included in `$PATH`, then add it to the
+`bootstrap.toml`:
+
+```toml
+[target.mips64-unknown-linux-muslabi64]
+cc = "mips64-linux-musl-gcc"
+cxx = "mips64-linux-musl-g++"
+ar = "mips64-linux-musl-ar"
+linker = "mips64-linux-musl-gcc"
+```
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for
+this target, you will first need to build Rust with the target enabled (see
+"Building the target" above).
+
+## Cross-compilation
+
+This target can be cross-compiled from any host.
+
+## Testing
+
+This target can be tested as normal with `x.py` on a 64-bit big endian MIPS
+host or via QEMU emulation.
diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md
index 4f065a554cf..a8a9e550581 100644
--- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md
+++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md
@@ -4,37 +4,35 @@
 
 The `wasm32-wasip1` target is a WebAssembly compilation target which
 assumes that the [WASIp1] (aka "WASI preview1") set of "syscalls" are available
-for use in the standard library. Historically this target in the Rust compiler
-was one of the first for WebAssembly where Rust and C code are explicitly
-intended to interoperate as well.
-
-There's a bit of history to the target and current development which is also
-worth explaining before going much further. Historically this target was
-originally called `wasm32-wasi` in both rustc and Clang. This was first added
-to Rust in 2019. In the intervening years leading up to 2024 the WASI standard
-continued to be developed and was eventually "rebased" on top of the [Component
-Model]. This was a large change to the WASI specification and was released as
-0.2.0 ("WASIp2" colloquially) in January 2024. The previous target's name in
-rustc, `wasm32-wasi`, was then renamed to `wasm32-wasip1`, to avoid
-confusion with this new target to be added to rustc as `wasm32-wasip2`.
-Some more context can be found in these MCPs:
-
-* [Rename wasm32-wasi target to wasm32-wasip1](https://github.com/rust-lang/compiler-team/issues/607)
-* [Smooth the renaming transition of wasm32-wasi](https://github.com/rust-lang/compiler-team/issues/695)
-
-At this point the `wasm32-wasip1` target is intended for historical
-compatibility with the first version of the WASI standard. As of now (January
-2024) the 0.2.0 target of WASI ("WASIp2") is relatively new. The state of
-WASI will likely change in few years after which point this documentation will
-probably receive another update.
-
-[WASI Preview1]: https://github.com/WebAssembly/WASI/tree/main/legacy/preview1
+for use in the standard library. This target explicitly supports interop with
+non-Rust code such as C and C++.
+
+The [WASIp1] set of syscalls is standard insofar as it was written down once by
+a set of folks and has not changed since then. Additionally the [WASIp1]
+syscalls have been adapted and adopted into a number of runtimes and embeddings.
+It is not standard in the sense that there are no formal semantics for each
+syscall and APIs are no longer receiving any maintenance (e.g. no new APIs, no
+new documentation, etc). After [WASIp1] was originally developed in 2019 the
+WASI standard effort has since been "rebased" on top of the [Component Model].
+This was a large change to the WASI specification and was released as 0.2.0
+("WASIp2" colloquially) in January 2024. Current standardization efforts are
+focused on the Component Model-based definition of WASI. At this point the
+`wasm32-wasip1` Rust target is intended for historical compatibility with
+[WASIp1] set of syscalls.
+
+[WASIp1]: https://github.com/WebAssembly/WASI/tree/main/legacy/preview1
 [Component Model]: https://github.com/webassembly/component-model
 
 Today the `wasm32-wasip1` target will generate core WebAssembly modules
 which will import functions from the `wasi_snapshot_preview1` module for
 OS-related functionality (e.g. printing).
 
+> **Note**: Prior to March 2024 this target was known as `wasm32-wasi` with some
+> historical context found in old MCPs:
+>
+> * [Rename wasm32-wasi target to wasm32-wasip1](https://github.com/rust-lang/compiler-team/issues/607)
+> * [Smooth the renaming transition of wasm32-wasi](https://github.com/rust-lang/compiler-team/issues/695)
+
 ## Target maintainers
 
 When this target was added to the compiler platform-specific documentation here
@@ -44,6 +42,7 @@ said since when this document was last updated those interested in maintaining
 this target are:
 
 [@alexcrichton](https://github.com/alexcrichton)
+[@loganek](https://github.com/loganek)
 
 ## Requirements
 
diff --git a/src/doc/unstable-book/src/compiler-flags/codegen-options.md b/src/doc/unstable-book/src/compiler-flags/codegen-options.md
index cc51554706d..f927e5c439c 100644
--- a/src/doc/unstable-book/src/compiler-flags/codegen-options.md
+++ b/src/doc/unstable-book/src/compiler-flags/codegen-options.md
@@ -51,10 +51,10 @@ instead of those in the system. The stable boolean values for this flag are coar
 - `mingw`: other MinGW libs and Windows import libs
 
 Out of the above self-contained linking components, `linker` is the only one currently implemented
-(beyond parsing the CLI options).
+(beyond parsing the CLI options) and stabilized.
 
 It refers to the LLD linker, built from the same LLVM revision used by rustc (named `rust-lld` to
 avoid naming conflicts), that is distributed via `rustup` with the compiler (and is used by default
-for the wasm targets). One can also opt-in to use it by combining this flag with an appropriate
-linker flavor: for example, `-Clinker-flavor=gnu-lld-cc -Clink-self-contained=+linker` will use the
-toolchain's `rust-lld` as the linker.
+for the wasm targets). One can also opt into using it by combining this flag with the appropriate
+linker feature: for example, `-Clinker-features=+lld -Clink-self-contained=+linker` will use the
+toolchain's `rust-lld` as the linker instead of the system's lld with `-Clinker-features=+lld` only.
diff --git a/src/doc/unstable-book/src/compiler-flags/linker-features.md b/src/doc/unstable-book/src/compiler-flags/linker-features.md
deleted file mode 100644
index 643fcf7c6d7..00000000000
--- a/src/doc/unstable-book/src/compiler-flags/linker-features.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# `linker-features`
-
---------------------
-
-The `-Zlinker-features` compiler flag allows enabling or disabling specific features used during
-linking, and is intended to be stabilized under the codegen options as `-Clinker-features`.
-
-These feature flags are a flexible extension mechanism that is complementary to linker flavors,
-designed to avoid the combinatorial explosion of having to create a new set of flavors for each
-linker feature we'd want to use.
-
-For example, this design allows:
-- default feature sets for principal flavors, or for specific targets.
-- flavor-specific features: for example, clang offers automatic cross-linking with `--target`, which
-  gcc-style compilers don't support. The *flavor* is still a C/C++ compiler, and we don't want to
-  multiply the number of flavors for this use-case. Instead, we can have a single `+target` feature.
-- umbrella features: for example, if clang accumulates more features in the future than just the
-  `+target` above. That could be modeled as `+clang`.
-- niche features for resolving specific issues: for example, on Apple targets the linker flag
-  implementing the `as-needed` native link modifier (#99424) is only possible on sufficiently recent
-  linker versions.
-- still allows for discovery and automation, for example via feature detection. This can be useful
-  in exotic environments/build systems.
-
-The flag accepts a comma-separated list of features, individually enabled (`+features`) or disabled
-(`-features`), though currently only one is exposed on the CLI:
-- `lld`: to toggle using the lld linker, either the system-installed binary, or the self-contained
-  `rust-lld` linker.
-
-As described above, this list is intended to grow in the future.
-
-One of the most common uses of this flag will be to toggle self-contained linking with `rust-lld` on
-and off: `-Clinker-features=+lld -Clink-self-contained=+linker` will use the toolchain's `rust-lld`
-as the linker. Inversely, `-Clinker-features=-lld` would opt out of that, if the current target had
-self-contained linking enabled by default.
diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish
index 69bd525a312..3009dd85e93 100644
--- a/src/etc/completions/x.fish
+++ b/src/etc/completions/x.fish
@@ -293,7 +293,7 @@ complete -c x -n "__fish_x_using_subcommand doc" -l skip-std-check-if-no-downloa
 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
-complete -c x -n "__fish_x_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)' -r
+complete -c x -n "__fish_x_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)' -r
 complete -c x -n "__fish_x_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
 complete -c x -n "__fish_x_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
 complete -c x -n "__fish_x_using_subcommand test" -l run -d 'whether to execute run-* tests' -r
diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1
index 7b142ba97ce..8002ec31592 100644
--- a/src/etc/completions/x.ps1
+++ b/src/etc/completions/x.ps1
@@ -339,7 +339,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
         'x;test' {
             [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
             [CompletionResult]::new('--compiletest-rustc-args', '--compiletest-rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running compiletest tests')
-            [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)')
+            [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)')
             [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
             [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
             [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index e982cde634f..4766a5ee0c7 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -293,7 +293,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand doc" -l skip-std-check-if-no-d
 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
-complete -c x.py -n "__fish_x.py_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)' -r
+complete -c x.py -n "__fish_x.py_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)' -r
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l run -d 'whether to execute run-* tests' -r
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index f4b26fac0bc..1aff3c433b4 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -339,7 +339,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
         'x.py;test' {
             [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
             [CompletionResult]::new('--compiletest-rustc-args', '--compiletest-rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running compiletest tests')
-            [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)')
+            [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)')
             [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
             [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
             [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index 8fc4f052252..77f995c1704 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -338,7 +338,7 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \
 '*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS:_default' \
-'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck, spellcheck\:fix)]:EXTRA_CHECKS:_default' \
+'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck)]:EXTRA_CHECKS:_default' \
 '--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
 '--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
 '--run=[whether to execute run-* tests]:auto | always | never:_default' \
diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh
index c495e8318ba..6c6d7b3f49f 100644
--- a/src/etc/completions/x.zsh
+++ b/src/etc/completions/x.zsh
@@ -338,7 +338,7 @@ _arguments "${_arguments_options[@]}" : \
 _arguments "${_arguments_options[@]}" : \
 '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \
 '*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS:_default' \
-'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck, spellcheck\:fix)]:EXTRA_CHECKS:_default' \
+'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck)]:EXTRA_CHECKS:_default' \
 '--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \
 '--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \
 '--run=[whether to execute run-* tests]:auto | always | never:_default' \
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 41c3f03b91b..0078671fcc5 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -25,7 +25,6 @@ use std::str::FromStr;
 use std::{fmt, fs};
 
 use indexmap::IndexMap;
-use itertools::Itertools;
 use regex::Regex;
 use rustc_data_structures::flock;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
@@ -44,6 +43,7 @@ use crate::docfs::PathError;
 use crate::error::Error;
 use crate::formats::Impl;
 use crate::formats::item_type::ItemType;
+use crate::html::format::join_with_double_colon;
 use crate::html::layout;
 use crate::html::render::ordered_json::{EscapedJson, OrderedJson};
 use crate::html::render::search_index::{SerializedSearchIndex, build_index};
@@ -608,7 +608,7 @@ impl TypeAliasPart {
                     for &(type_alias_fqp, type_alias_item) in type_aliases {
                         cx.id_map.borrow_mut().clear();
                         cx.deref_id_map.borrow_mut().clear();
-                        let type_alias_fqp = (*type_alias_fqp).iter().join("::");
+                        let type_alias_fqp = join_with_double_colon(&type_alias_fqp);
                         if let Some(ret) = &mut ret {
                             ret.aliases.push(type_alias_fqp);
                         } else {
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index abf3f3fcedd..e7163bead92 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -7,6 +7,7 @@ use rustc_ast::ast;
 use rustc_attr_data_structures::{self as attrs, DeprecatedSince};
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::DefId;
+use rustc_hir::{HeaderSafety, Safety};
 use rustc_metadata::rendered_const;
 use rustc_middle::{bug, ty};
 use rustc_span::{Pos, kw, sym};
@@ -381,10 +382,22 @@ impl FromClean<clean::Union> for Union {
 
 impl FromClean<rustc_hir::FnHeader> for FunctionHeader {
     fn from_clean(header: &rustc_hir::FnHeader, renderer: &JsonRenderer<'_>) -> Self {
+        let is_unsafe = match header.safety {
+            HeaderSafety::SafeTargetFeatures => {
+                // The type system's internal implementation details consider
+                // safe functions with the `#[target_feature]` attribute to be analogous
+                // to unsafe functions: `header.is_unsafe()` returns `true` for them.
+                // For rustdoc, this isn't the right decision, so we explicitly return `false`.
+                // Context: https://github.com/rust-lang/rust/issues/142655
+                false
+            }
+            HeaderSafety::Normal(Safety::Safe) => false,
+            HeaderSafety::Normal(Safety::Unsafe) => true,
+        };
         FunctionHeader {
             is_async: header.is_async(),
             is_const: header.is_const(),
-            is_unsafe: header.is_unsafe(),
+            is_unsafe,
             abi: header.abi.into_json(renderer),
         }
     }
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 9b1bf4cf041c1c1fe62cf03891ac90431615e78
+Subproject 99f0e0531688a822a753cc585b7408b069cb682
diff --git a/src/tools/clippy/.github/workflows/feature_freeze.yml b/src/tools/clippy/.github/workflows/feature_freeze.yml
index a5f8d4bc145..7ad58af77d4 100644
--- a/src/tools/clippy/.github/workflows/feature_freeze.yml
+++ b/src/tools/clippy/.github/workflows/feature_freeze.yml
@@ -1,7 +1,11 @@
 name: Feature freeze check
 
 on:
-  pull_request:
+  pull_request_target:
+    types:
+      - opened
+    branches:
+      - master
     paths:
       - 'clippy_lints/src/declared_lints.rs'
 
@@ -9,6 +13,12 @@ jobs:
   auto-comment:
     runs-on: ubuntu-latest
 
+    permissions:
+      pull-requests: write
+
+    # Do not in any case add code that runs anything coming from the  the content
+    # of the pull request, as malicious code would be able to access the private
+    # GitHub token.
     steps:
     - name: Check PR Changes
       id: pr-changes
@@ -19,7 +29,7 @@ jobs:
       run: |
         # Use GitHub API to create a comment on the PR
         PR_NUMBER=${{ github.event.pull_request.number }}
-        COMMENT="**Seems that you are trying to add a new lint!**\nWe are currently in a [feature freeze](https://doc.rust-lang.org/nightly/clippy/development/feature_freeze.html), so we are delaying all lint-adding PRs to August 1st and focusing on bugfixes.\nThanks a lot for your contribution, and sorry for the inconvenience.\nWith ❤ from the Clippy team"
+        COMMENT="**Seems that you are trying to add a new lint!**\nWe are currently in a [feature freeze](https://doc.rust-lang.org/nightly/clippy/development/feature_freeze.html), so we are delaying all lint-adding PRs to September 18 and focusing on bugfixes.\nThanks a lot for your contribution, and sorry for the inconvenience.\nWith ❤ from the Clippy team\n\n@rustbot note Feature-freeze\n@rustbot blocked\n@rustbot label +A-lint\n"
         GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
         COMMENT_URL="https://api.github.com/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments"
         curl -s -H "Authorization: token ${GITHUB_TOKEN}" -X POST $COMMENT_URL -d "{\"body\":\"$COMMENT\"}"
diff --git a/src/tools/clippy/.github/workflows/lintcheck.yml b/src/tools/clippy/.github/workflows/lintcheck.yml
index 70c805903d3..003d0395739 100644
--- a/src/tools/clippy/.github/workflows/lintcheck.yml
+++ b/src/tools/clippy/.github/workflows/lintcheck.yml
@@ -128,21 +128,27 @@ jobs:
     - name: Download JSON
       uses: actions/download-artifact@v4
 
+    - name: Store PR number
+      run: echo ${{ github.event.pull_request.number }} > pr.txt
+
     - name: Diff results
-      # GH's summery has a maximum size of 1024k:
-      # https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-markdown-summary
-      # That's why we first log to file and then to the summary and logs
+      # GH's summery has a maximum size of 1MiB:
+      # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#step-isolation-and-limits
+      # We upload the full diff as an artifact in case it's truncated
       run: |
-        ./target/debug/lintcheck diff {base,head}/ci_crates_logs.json --truncate >> truncated_diff.md
-        head -c 1024000 truncated_diff.md >> $GITHUB_STEP_SUMMARY
-        cat truncated_diff.md
-        ./target/debug/lintcheck diff {base,head}/ci_crates_logs.json >> full_diff.md
+        ./target/debug/lintcheck diff {base,head}/ci_crates_logs.json --truncate | head -c 1M > $GITHUB_STEP_SUMMARY
+        ./target/debug/lintcheck diff {base,head}/ci_crates_logs.json --write-summary summary.json > full_diff.md
 
     - name: Upload full diff
       uses: actions/upload-artifact@v4
       with:
-        name: diff
-        if-no-files-found: ignore
+        name: full_diff
+        path: full_diff.md
+
+    - name: Upload summary
+      uses: actions/upload-artifact@v4
+      with:
+        name: summary
         path: |
-          full_diff.md
-          truncated_diff.md
+          summary.json
+          pr.txt
diff --git a/src/tools/clippy/.github/workflows/lintcheck_summary.yml b/src/tools/clippy/.github/workflows/lintcheck_summary.yml
new file mode 100644
index 00000000000..52f52e155a0
--- /dev/null
+++ b/src/tools/clippy/.github/workflows/lintcheck_summary.yml
@@ -0,0 +1,106 @@
+name: Lintcheck summary
+
+# The workflow_run event runs in the context of the Clippy repo giving it write
+# access, needed here to create a PR comment when the PR originates from a fork
+#
+# The summary artifact is a JSON file that we verify in this action to prevent
+# the creation of arbitrary comments
+#
+# This action must not checkout/run code from the originating workflow_run
+# or directly interpolate ${{}} untrusted fields into code
+#
+# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run
+# https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#understanding-the-risk-of-script-injections
+
+on:
+  workflow_run:
+    workflows: [Lintcheck]
+    types: [completed]
+
+# Restrict the default permission scope https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#defining-access-for-the-github_token-scopes
+permissions:
+  pull-requests: write
+
+jobs:
+  download:
+    runs-on: ubuntu-latest
+    if: ${{ github.event.workflow_run.conclusion == 'success' }}
+    steps:
+      - name: Download artifact
+        uses: actions/download-artifact@v4
+        with:
+          name: summary
+          path: untrusted
+          run-id: ${{ github.event.workflow_run.id }}
+          github-token: ${{ github.token }}
+
+      - name: Format comment
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const fs = require("fs");
+            const assert = require("assert/strict");
+
+            function validateName(s) {
+              assert.match(s, /^[a-z0-9_:]+$/);
+              return s;
+            }
+
+            function validateInt(i) {
+              assert.ok(Number.isInteger(i));
+              return i;
+            }
+
+            function tryReadSummary() {
+              try {
+                return JSON.parse(fs.readFileSync("untrusted/summary.json"));
+              } catch {
+                return null;
+              }
+            }
+
+            const prNumber = parseInt(fs.readFileSync("untrusted/pr.txt"), 10);
+            core.exportVariable("PR", prNumber.toString());
+
+            const untrustedSummary = tryReadSummary();
+            if (!Array.isArray(untrustedSummary)) {
+              return;
+            }
+
+            let summary = `Lintcheck changes for ${context.payload.workflow_run.head_sha}
+            
+            | Lint | Added | Removed | Changed |
+            | ---- | ----: | ------: | ------: |
+            `;
+
+            for (const untrustedRow of untrustedSummary) {
+              const name = validateName(untrustedRow.name);
+
+              const added = validateInt(untrustedRow.added);
+              const removed = validateInt(untrustedRow.removed);
+              const changed = validateInt(untrustedRow.changed);
+
+              const id = name.replace("clippy::", "user-content-").replaceAll("_", "-");
+              const url = `https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${context.payload.workflow_run.id}#${id}`;
+
+              summary += `| [\`${name}\`](${url}) | ${added} | ${removed} | ${changed} |\n`;
+            }
+
+            summary += "\nThis comment will be updated if you push new changes";
+
+            fs.writeFileSync("summary.md", summary);
+
+      - name: Create/update comment
+        run: |
+          if [[ -f summary.md ]]; then
+             gh pr comment "$PR" --body-file summary.md --edit-last --create-if-none
+          else
+            # There were no changes detected by Lintcheck
+            # - If a comment exists from a previous run that did detect changes, edit it (--edit-last)
+            # - If no comment exists do not create one, the `gh` command exits with an error which
+            #   `|| true` ignores
+            gh pr comment "$PR" --body "No changes for ${{ github.event.workflow_run.head_sha }}" --edit-last || true
+          fi
+        env:
+          GH_TOKEN: ${{ github.token }}
+          GH_REPO: ${{ github.repository }}
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 1278427b5a7..f25f9ab54dd 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -28,13 +28,13 @@ declare_clippy_lint = { path = "declare_clippy_lint" }
 rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
 clippy_lints_internal = { path = "clippy_lints_internal", optional = true }
 tempfile = { version = "3.20", optional = true }
-termize = "0.1"
+termize = "0.2"
 color-print = "0.3.4"
 anstream = "0.6.18"
 
 [dev-dependencies]
 cargo_metadata = "0.18.1"
-ui_test = "0.29.2"
+ui_test = "0.30.2"
 regex = "1.5.5"
 serde = { version = "1.0.145", features = ["derive"] }
 serde_json = "1.0.122"
@@ -45,14 +45,6 @@ itertools = "0.12"
 pulldown-cmark = { version = "0.11", default-features = false, features = ["html"] }
 askama = { version = "0.14", default-features = false, features = ["alloc", "config", "derive"] }
 
-# UI test dependencies
-if_chain = "1.0"
-quote = "1.0.25"
-syn = { version = "2.0", features = ["full"] }
-futures = "0.3"
-parking_lot = "0.12"
-tokio = { version = "1", features = ["io-util"] }
-
 [build-dependencies]
 rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
 
diff --git a/src/tools/clippy/book/src/development/infrastructure/backport.md b/src/tools/clippy/book/src/development/infrastructure/backport.md
index 9526d8af1c9..47ea6a412c5 100644
--- a/src/tools/clippy/book/src/development/infrastructure/backport.md
+++ b/src/tools/clippy/book/src/development/infrastructure/backport.md
@@ -109,4 +109,4 @@ worth backporting this.
 When a PR is backported to Rust `beta`, label the PR with `beta-accepted`. This
 will then get picked up when [writing the changelog].
 
-[writing the changelog]: changelog_update.md#31-include-beta-accepted-prs
+[writing the changelog]: changelog_update.md#4-include-beta-accepted-prs
diff --git a/src/tools/clippy/book/src/development/infrastructure/changelog_update.md b/src/tools/clippy/book/src/development/infrastructure/changelog_update.md
index eede6b78d92..c96ff228b01 100644
--- a/src/tools/clippy/book/src/development/infrastructure/changelog_update.md
+++ b/src/tools/clippy/book/src/development/infrastructure/changelog_update.md
@@ -38,7 +38,7 @@ Usually you want to write the changelog of the **upcoming stable release**. Make
 sure though, that `beta` was already branched in the Rust repository.
 
 To find the commit hash, issue the following command when in a `rust-lang/rust`
-checkout:
+checkout (most of the time on the `upstream/beta` branch):
 ```
 git log --oneline -- src/tools/clippy/ | grep -o "Merge commit '[a-f0-9]*' into .*" | head -1 | sed -e "s/Merge commit '\([a-f0-9]*\)' into .*/\1/g"
 ```
@@ -48,16 +48,13 @@ git log --oneline -- src/tools/clippy/ | grep -o "Merge commit '[a-f0-9]*' into
 Once you've got the correct commit range, run
 
 ```
-util/fetch_prs_between.sh commit1 commit2 > changes.txt
+util/fetch_prs_between.sh start_commit end_commit > changes.txt
 ```
 
-where `commit2` is the commit hash from the previous command and `commit1`
-is the commit hash from the current CHANGELOG file.
+where `end_commit` is the commit hash from the previous command and `start_commit`
+is [the commit hash][beta_section] from the current CHANGELOG file.
 Open `changes.txt` file in your editor of choice.
 
-When updating the changelog it's also a good idea to make sure that `commit1` is
-already correct in the current changelog.
-
 ### 3. Authoring the final changelog
 
 The above script should have dumped all the relevant PRs to the file you
@@ -70,17 +67,7 @@ With the PRs filtered, you can start to take each PR and move the `changelog: `
 content to `CHANGELOG.md`. Adapt the wording as you see fit but try to keep it
 somewhat coherent.
 
-The order should roughly be:
-
-1. New lints
-2. Moves or deprecations of lints
-3. Changes that expand what code existing lints cover
-4. False positive fixes
-5. ICE fixes
-6. Documentation improvements
-7. Others
-
-As section headers, we use:
+The sections order should roughly be:
 
 ```
 ### New Lints
@@ -97,10 +84,10 @@ As section headers, we use:
 ### Others
 ```
 
-Please also be sure to update the Beta/Unreleased sections at the top with the
-relevant commit ranges.
+Please also be sure to update [the `Unreleased/Beta/In Rust Nightly` section][beta_section] at the top with the
+relevant commits ranges and to add the `Rust <version>` section with release date and PR ranges.
 
-#### 3.1 Include `beta-accepted` PRs
+### 4. Include `beta-accepted` PRs
 
 Look for the [`beta-accepted`] label and make sure to also include the PRs with
 that label in the changelog. If you can, remove the `beta-accepted` labels
@@ -109,7 +96,7 @@ that label in the changelog. If you can, remove the `beta-accepted` labels
 > _Note:_ Some of those PRs might even get backported to the previous `beta`.
 > Those have to be included in the changelog of the _previous_ release.
 
-### 4. Update `clippy::version` attributes
+### 5. Update `clippy::version` attributes
 
 Next, make sure to check that the `#[clippy::version]` attributes for the added
 lints contain the correct version. 
@@ -129,3 +116,4 @@ written for. If not, update the version to the changelog version.
 [rust_beta_tools]: https://github.com/rust-lang/rust/tree/beta/src/tools/clippy
 [rust_stable_tools]: https://github.com/rust-lang/rust/releases
 [`beta-accepted`]: https://github.com/rust-lang/rust-clippy/issues?q=label%3Abeta-accepted+
+[beta_section]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#unreleased--beta--in-rust-nightly
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index e9b7f42a183..992ed2c6aaa 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -892,6 +892,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns)
 * [`unused_trait_names`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_trait_names)
 * [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)
+* [`zero_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr)
 
 
 ## `pass-by-value-size-limit`
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 841facdca06..555f54bcfb8 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -794,6 +794,7 @@ define_Conf! {
         unnested_or_patterns,
         unused_trait_names,
         use_self,
+        zero_ptr,
     )]
     msrv: Msrv = Msrv::default(),
     /// The minimum size (in bytes) to consider a type for passing by reference instead of by value.
diff --git a/src/tools/clippy/clippy_dev/src/fmt.rs b/src/tools/clippy/clippy_dev/src/fmt.rs
index c1b6b370706..bd9e57c9f6d 100644
--- a/src/tools/clippy/clippy_dev/src/fmt.rs
+++ b/src/tools/clippy/clippy_dev/src/fmt.rs
@@ -223,7 +223,7 @@ fn fmt_conf(check: bool) -> Result<(), Error> {
         if check {
             return Err(Error::CheckFailed);
         }
-        fs::write(path, new_text.as_bytes())?;
+        fs::write(path, new_text)?;
     }
     Ok(())
 }
diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs
index 3361443196a..40aadf4589a 100644
--- a/src/tools/clippy/clippy_dev/src/lib.rs
+++ b/src/tools/clippy/clippy_dev/src/lib.rs
@@ -2,7 +2,6 @@
     rustc_private,
     exit_status_error,
     if_let_guard,
-    let_chains,
     os_str_slice,
     os_string_truncate,
     slice_split_once
diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
index 8b6bfaebbe5..c410a5da775 100644
--- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
+++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -266,7 +266,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
             .tcx
             .hir_attrs(item.hir_id())
             .iter()
-            .any(|attr| matches!(attr, Attribute::Parsed(AttributeKind::Repr{ .. })))
+            .any(|attr| matches!(attr, Attribute::Parsed(AttributeKind::Repr { .. })))
         {
             // Do not lint items with a `#[repr]` attribute as their layout may be imposed by an external API.
             return;
diff --git a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
index ad0a4f8cdf3..e3b125a8d5b 100644
--- a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
@@ -18,7 +18,8 @@ pub(super) fn check<'tcx>(
     cast_to: &'tcx Ty<'_>,
     msrv: Msrv,
 ) -> bool {
-    if matches!(cast_to.kind, TyKind::Ptr(_))
+    if let TyKind::Ptr(target) = cast_to.kind
+        && !matches!(target.ty.kind, TyKind::TraitObject(..))
         && let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind
         && !is_lint_allowed(cx, BORROW_AS_PTR, expr.hir_id)
     {
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index a2ecb5fb44a..2eebe849232 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::source::snippet;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
-use clippy_utils::{expr_or_init, sym};
+use clippy_utils::{expr_or_init, is_in_const_context, sym};
 use rustc_abi::IntegerType;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::def::{DefKind, Res};
@@ -168,7 +168,9 @@ pub(super) fn check(
 
     span_lint_and_then(cx, CAST_POSSIBLE_TRUNCATION, expr.span, msg, |diag| {
         diag.help("if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...");
-        if !cast_from.is_floating_point() {
+        // TODO: Remove the condition for const contexts when `try_from` and other commonly used methods
+        // become const fn.
+        if !is_in_const_context(cx) && !cast_from.is_floating_point() {
             offer_suggestion(cx, expr, cast_expr, cast_to_span, diag);
         }
     });
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index daae9a8bb08..37accff5eaa 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -878,7 +878,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
             confusing_method_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);
             fn_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);
             fn_to_numeric_cast_with_truncation::check(cx, expr, cast_from_expr, cast_from, cast_to);
-            zero_ptr::check(cx, expr, cast_from_expr, cast_to_hir);
+            zero_ptr::check(cx, expr, cast_from_expr, cast_to_hir, self.msrv);
 
             if self.msrv.meets(cx, msrvs::MANUAL_DANGLING_PTR) {
                 manual_dangling_ptr::check(cx, expr, cast_from_expr, cast_to_hir);
diff --git a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
index a34af6bc226..f4738e7b0d5 100644
--- a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
@@ -1,4 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{is_in_const_context, is_integer_literal, std_or_core};
 use rustc_errors::Applicability;
@@ -7,10 +8,10 @@ use rustc_lint::LateContext;
 
 use super::ZERO_PTR;
 
-pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>) {
+pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>, msrv: Msrv) {
     if let TyKind::Ptr(ref mut_ty) = to.kind
         && is_integer_literal(from, 0)
-        && !is_in_const_context(cx)
+        && (!is_in_const_context(cx) || msrv.meets(cx, msrvs::PTR_NULL))
         && let Some(std_or_core) = std_or_core(cx)
     {
         let (msg, sugg_fn) = match mut_ty.mutbl {
diff --git a/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs b/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs
index 2b659253763..6217fc4c897 100644
--- a/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs
+++ b/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs
@@ -1,9 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet;
+use clippy_utils::sugg::{self, Sugg};
 use clippy_utils::sym;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
 use rustc_middle::ty::{self, ExistentialPredicate, Ty, TyCtxt};
 use rustc_session::declare_lint_pass;
 
@@ -49,23 +50,18 @@ declare_lint_pass!(CoerceContainerToAny => [COERCE_CONTAINER_TO_ANY]);
 
 impl<'tcx> LateLintPass<'tcx> for CoerceContainerToAny {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
-        // If this expression has an effective type of `&dyn Any` ...
-        {
-            let coerced_ty = cx.typeck_results().expr_ty_adjusted(e);
-
-            let ty::Ref(_, coerced_ref_ty, _) = *coerced_ty.kind() else {
-                return;
-            };
-            if !is_dyn_any(cx.tcx, coerced_ref_ty) {
-                return;
-            }
+        // If this expression was coerced to `&dyn Any` ...
+        if !cx.typeck_results().expr_adjustments(e).last().is_some_and(|adj| {
+            matches!(adj.kind, Adjust::Pointer(PointerCoercion::Unsize)) && is_ref_dyn_any(cx.tcx, adj.target)
+        }) {
+            return;
         }
 
         let expr_ty = cx.typeck_results().expr_ty(e);
         let ty::Ref(_, expr_ref_ty, _) = *expr_ty.kind() else {
             return;
         };
-        // ... but only due to coercion ...
+        // ... but it's not actually `&dyn Any` ...
         if is_dyn_any(cx.tcx, expr_ref_ty) {
             return;
         }
@@ -78,23 +74,37 @@ impl<'tcx> LateLintPass<'tcx> for CoerceContainerToAny {
         }
 
         // ... that's probably not intended.
-        let (span, deref_count) = match e.kind {
+        let (target_expr, deref_count) = match e.kind {
             // If `e` was already an `&` expression, skip `*&` in the suggestion
-            ExprKind::AddrOf(_, _, referent) => (referent.span, depth),
-            _ => (e.span, depth + 1),
+            ExprKind::AddrOf(_, _, referent) => (referent, depth),
+            _ => (e, depth + 1),
         };
+        let ty::Ref(_, _, mutability) = *cx.typeck_results().expr_ty_adjusted(e).kind() else {
+            return;
+        };
+        let sugg = sugg::make_unop(
+            &format!("{}{}", mutability.ref_prefix_str(), str::repeat("*", deref_count)),
+            Sugg::hir(cx, target_expr, ".."),
+        );
         span_lint_and_sugg(
             cx,
             COERCE_CONTAINER_TO_ANY,
             e.span,
-            format!("coercing `{expr_ty}` to `&dyn Any`"),
+            format!("coercing `{expr_ty}` to `{}dyn Any`", mutability.ref_prefix_str()),
             "consider dereferencing",
-            format!("&{}{}", str::repeat("*", deref_count), snippet(cx, span, "x")),
+            sugg.to_string(),
             Applicability::MaybeIncorrect,
         );
     }
 }
 
+fn is_ref_dyn_any(tcx: TyCtxt<'_>, ty: Ty<'_>) -> bool {
+    let ty::Ref(_, ref_ty, _) = *ty.kind() else {
+        return false;
+    };
+    is_dyn_any(tcx, ref_ty)
+}
+
 fn is_dyn_any(tcx: TyCtxt<'_>, ty: Ty<'_>) -> bool {
     let ty::Dynamic(traits, ..) = ty.kind() else {
         return false;
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index 5c64216dd92..d5d937d9133 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -14,18 +14,25 @@ use rustc_span::def_id::LocalDefId;
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for methods with high cognitive complexity.
+    /// We used to think it measured how hard a method is to understand.
     ///
     /// ### Why is this bad?
-    /// Methods of high cognitive complexity tend to be hard to
-    /// both read and maintain. Also LLVM will tend to optimize small methods better.
+    /// Ideally, we would like to be able to measure how hard a function is
+    /// to understand given its context (what we call its Cognitive Complexity).
+    /// But that's not what this lint does. See "Known problems"
     ///
     /// ### Known problems
-    /// Sometimes it's hard to find a way to reduce the
-    /// complexity.
+    /// The true Cognitive Complexity of a method is not something we can
+    /// calculate using modern technology. This lint has been left in the
+    /// `nursery` so as to not mislead users into using this lint as a
+    /// measurement tool.
     ///
-    /// ### Example
-    /// You'll see it when you get the warning.
+    /// For more detailed information, see [rust-clippy#3793](https://github.com/rust-lang/rust-clippy/issues/3793)
+    ///
+    /// ### Lints to consider instead of this
+    ///
+    /// * [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting)
+    /// * [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)
     #[clippy::version = "1.35.0"]
     pub COGNITIVE_COMPLEXITY,
     nursery,
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
index d1a8590c59b..cf964d4b580 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
@@ -89,6 +89,10 @@ impl EarlyLintPass for DisallowedScriptIdents {
             // Fast path for ascii-only idents.
             if !symbol_str.is_ascii()
                 && let Some(script) = symbol_str.chars().find_map(|c| {
+                    if c.is_ascii() {
+                        return None;
+                    }
+
                     c.script_extension()
                         .iter()
                         .find(|script| !self.whitelist.contains(script))
diff --git a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
index 9ee32fced8c..3033ac0d0b0 100644
--- a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
 use clippy_utils::ty::{get_type_diagnostic_name, implements_trait_with_env, is_type_diagnostic_item};
 use clippy_utils::visitors::for_each_expr;
-use clippy_utils::{fulfill_or_allowed, is_doc_hidden, method_chain_args, return_ty};
+use clippy_utils::{fulfill_or_allowed, is_doc_hidden, is_inside_always_const_context, method_chain_args, return_ty};
 use rustc_hir::{BodyId, FnSig, OwnerId, Safety};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
@@ -99,13 +99,16 @@ fn find_panic(cx: &LateContext<'_>, body_id: BodyId) -> Option<Span> {
     let mut panic_span = None;
     let typeck = cx.tcx.typeck_body(body_id);
     for_each_expr(cx, cx.tcx.hir_body(body_id), |expr| {
+        if is_inside_always_const_context(cx.tcx, expr.hir_id) {
+            return ControlFlow::<!>::Continue(());
+        }
+
         if let Some(macro_call) = root_macro_call_first_node(cx, expr)
             && (is_panic(cx, macro_call.def_id)
                 || matches!(
                     cx.tcx.get_diagnostic_name(macro_call.def_id),
                     Some(sym::assert_macro | sym::assert_eq_macro | sym::assert_ne_macro)
                 ))
-            && !cx.tcx.hir_is_inside_const_context(expr.hir_id)
             && !fulfill_or_allowed(cx, MISSING_PANICS_DOC, [expr.hir_id])
             && panic_span.is_none()
         {
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 5ea55e102df..2bf52216b83 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -1249,7 +1249,9 @@ fn looks_like_refdef(doc: &str, range: Range<usize>) -> Option<Range<usize>> {
             b'[' => {
                 start = Some(i + offset);
             },
-            b']' if let Some(start) = start => {
+            b']' if let Some(start) = start
+                && doc.as_bytes().get(i + offset + 1) == Some(&b':') =>
+            {
                 return Some(start..i + offset + 1);
             },
             _ => {},
diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
index 7dda3e0fdb9..8ad09279071 100644
--- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
+++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
@@ -1,12 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::indent_of;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_attr_data_structures::AttributeKind;
-use rustc_attr_data_structures::find_attr;
-
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs
index cc8e4d7d9e2..487db69027a 100644
--- a/src/tools/clippy/clippy_lints/src/exit.rs
+++ b/src/tools/clippy/clippy_lints/src/exit.rs
@@ -1,5 +1,4 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::is_entrypoint_fn;
 use rustc_hir::{Expr, ExprKind, Item, ItemKind, OwnerNode};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -7,7 +6,8 @@ use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Detects calls to the `exit()` function which terminates the program.
+    /// Detects calls to the `exit()` function that are not in the `main` function. Calls to `exit()`
+    /// immediately terminate the program.
     ///
     /// ### Why restrict this?
     /// `exit()` immediately terminates the program with no information other than an exit code.
@@ -15,11 +15,24 @@ declare_clippy_lint! {
     ///
     /// Codebases may use this lint to require that all exits are performed either by panicking
     /// (which produces a message, a code location, and optionally a backtrace)
-    /// or by returning from `main()` (which is a single place to look).
+    /// or by calling `exit()` from `main()` (which is a single place to look).
     ///
-    /// ### Example
+    /// ### Good example
     /// ```no_run
-    /// std::process::exit(0)
+    /// fn main() {
+    ///     std::process::exit(0);
+    /// }
+    /// ```
+    ///
+    /// ### Bad example
+    /// ```no_run
+    /// fn main() {
+    ///     other_function();
+    /// }
+    ///
+    /// fn other_function() {
+    ///     std::process::exit(0);
+    /// }
     /// ```
     ///
     /// Use instead:
@@ -36,7 +49,7 @@ declare_clippy_lint! {
     #[clippy::version = "1.41.0"]
     pub EXIT,
     restriction,
-    "detects `std::process::exit` calls"
+    "detects `std::process::exit` calls outside of `main`"
 }
 
 declare_lint_pass!(Exit => [EXIT]);
@@ -48,10 +61,14 @@ impl<'tcx> LateLintPass<'tcx> for Exit {
             && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id()
             && cx.tcx.is_diagnostic_item(sym::process_exit, def_id)
             && let parent = cx.tcx.hir_get_parent_item(e.hir_id)
-            && let OwnerNode::Item(Item{kind: ItemKind::Fn{ .. }, ..}) = cx.tcx.hir_owner_node(parent)
-            // If the next item up is a function we check if it is an entry point
+            && let OwnerNode::Item(Item{kind: ItemKind::Fn{ ident, .. }, ..}) = cx.tcx.hir_owner_node(parent)
+            // If the next item up is a function we check if it isn't named "main"
             // and only then emit a linter warning
-            && !is_entrypoint_fn(cx, parent.to_def_id())
+
+            // if you instead check for the parent of the `exit()` call being the entrypoint function, as this worked before,
+            // in compilation contexts like --all-targets (which include --tests), you get false positives
+            // because in a test context, main is not the entrypoint function
+            && ident.name != sym::main
         {
             span_lint(cx, EXIT, e.span, "usage of `process::exit`");
         }
diff --git a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
index b3c9e860758..d5abaa547e8 100644
--- a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
@@ -2,8 +2,8 @@ use clippy_utils::consts::Constant::{F32, F64, Int};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::{
-    eq_expr_value, get_parent_expr, higher, is_in_const_context, is_inherent_method_call, is_no_std_crate,
-    numeric_literal, peel_blocks, sugg, sym,
+    eq_expr_value, get_parent_expr, has_ambiguous_literal_in_expr, higher, is_in_const_context,
+    is_inherent_method_call, is_no_std_crate, numeric_literal, peel_blocks, sugg, sym,
 };
 use rustc_ast::ast;
 use rustc_errors::Applicability;
@@ -455,7 +455,6 @@ fn is_float_mul_expr<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(&'
     None
 }
 
-// TODO: Fix rust-lang/rust-clippy#4735
 fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) {
     if let ExprKind::Binary(
         Spanned {
@@ -491,6 +490,14 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) {
             return;
         };
 
+        // Check if any variable in the expression has an ambiguous type (could be f32 or f64)
+        // see: https://github.com/rust-lang/rust-clippy/issues/14897
+        if (matches!(recv.kind, ExprKind::Path(_)) || matches!(recv.kind, ExprKind::Call(_, _)))
+            && has_ambiguous_literal_in_expr(cx, recv)
+        {
+            return;
+        }
+
         span_lint_and_sugg(
             cx,
             SUBOPTIMAL_FLOPS,
diff --git a/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs b/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs
index 823cf0f4322..e809987d75a 100644
--- a/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs
@@ -1,11 +1,22 @@
 use super::EMPTY_LOOP;
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::{is_in_panic_handler, is_no_std_crate};
+use clippy_utils::{is_in_panic_handler, is_no_std_crate, sym};
 
-use rustc_hir::{Block, Expr};
+use rustc_hir::{Block, Expr, ItemKind, Node};
 use rustc_lint::LateContext;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, loop_block: &Block<'_>) {
+    let parent_hir_id = cx.tcx.parent_hir_id(expr.hir_id);
+    if let Node::Item(parent_node) = cx.tcx.hir_node(parent_hir_id)
+        && matches!(parent_node.kind, ItemKind::Fn { .. })
+        && let attrs = cx.tcx.hir_attrs(parent_hir_id)
+        && attrs.iter().any(|attr| attr.has_name(sym::rustc_intrinsic))
+    {
+        // Intrinsic functions are expanded into an empty loop when lowering the AST
+        // to simplify the job of later passes which might expect any function to have a body.
+        return;
+    }
+
     if loop_block.stmts.is_empty() && loop_block.expr.is_none() && !is_in_panic_handler(cx, expr) {
         let msg = "empty `loop {}` wastes CPU cycles";
         let help = if is_no_std_crate(cx) {
diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
index 9ff82cdcb66..1f9a943f13d 100644
--- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
@@ -245,17 +245,36 @@ fn replace_in_pattern(
         }
 
         match pat.kind {
-            PatKind::Binding(_ann, _id, binding_name, opt_subpt) => {
-                let Some((pat_to_put, binding_mode)) = ident_map.get(&binding_name.name) else {
-                    break 'a;
-                };
-                let sn_pfx = binding_mode.prefix_str();
-                let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app);
-                if let Some(subpt) = opt_subpt {
-                    let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);
-                    return format!("{sn_pfx}{sn_ptp} @ {subpt}");
+            PatKind::Binding(ann, _id, binding_name, opt_subpt) => {
+                match (ident_map.get(&binding_name.name), opt_subpt) {
+                    (Some((pat_to_put, binding_mode)), opt_subpt) => {
+                        let sn_pfx = binding_mode.prefix_str();
+                        let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app);
+                        if let Some(subpt) = opt_subpt {
+                            let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);
+                            return format!("{sn_pfx}{sn_ptp} @ {subpt}");
+                        }
+                        return format!("{sn_pfx}{sn_ptp}");
+                    },
+                    (None, Some(subpt)) => {
+                        let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);
+                        // scanning for a value that matches is not sensitive to order
+                        #[expect(rustc::potential_query_instability)]
+                        if ident_map.values().any(|(other_pat, _)| {
+                            if let PatKind::Binding(_, _, other_name, _) = other_pat.kind {
+                                other_name == binding_name
+                            } else {
+                                false
+                            }
+                        }) {
+                            // this name is shadowed, and, therefore, not usable
+                            return subpt;
+                        }
+                        let binding_pfx = ann.prefix_str();
+                        return format!("{binding_pfx}{binding_name} @ {subpt}");
+                    },
+                    (None, None) => break 'a,
                 }
-                return format!("{sn_pfx}{sn_ptp}");
             },
             PatKind::Or(pats) => {
                 let patterns = pats
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 51696b38880..2d52a93f34e 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -4,16 +4,15 @@ use clippy_utils::is_doc_hidden;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_indent;
 use itertools::Itertools;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::{Expr, ExprKind, Item, ItemKind, QPath, TyKind, VariantData};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
-use rustc_attr_data_structures::find_attr;
-use rustc_attr_data_structures::AttributeKind;
+use rustc_span::def_id::LocalDefId;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
index ede68f30941..ae277da089f 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
@@ -332,9 +332,7 @@ impl<'a> NormalizedPat<'a> {
                 // TODO: Handle negative integers. They're currently treated as a wild match.
                 PatExprKind::Lit { lit, negated: false } => match lit.node {
                     LitKind::Str(sym, _) => Self::LitStr(sym),
-                    LitKind::ByteStr(byte_sym, _) | LitKind::CStr(byte_sym, _) => {
-                        Self::LitBytes(byte_sym)
-                    }
+                    LitKind::ByteStr(byte_sym, _) | LitKind::CStr(byte_sym, _) => Self::LitBytes(byte_sym),
                     LitKind::Byte(val) => Self::LitInt(val.into()),
                     LitKind::Char(val) => Self::LitInt(val.into()),
                     LitKind::Int(val, _) => Self::LitInt(val.get()),
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs b/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
index 4a61c223d2c..93325ca488e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
@@ -1,14 +1,16 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::get_parent_expr;
 use clippy_utils::msrvs::{self, Msrv};
-use clippy_utils::source::{snippet, snippet_opt};
+use clippy_utils::source::{snippet, snippet_with_applicability};
+use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::{get_parent_expr, sym};
+use rustc_ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
-use rustc_hir::{BinOpKind, Expr, ExprKind, QPath};
+use rustc_hir::{BinOpKind, Closure, Expr, ExprKind, QPath};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::{BytePos, Span, sym};
+use rustc_span::{Span, Symbol};
 
 use super::MANUAL_IS_VARIANT_AND;
 
@@ -62,54 +64,154 @@ pub(super) fn check(
     );
 }
 
-fn emit_lint(cx: &LateContext<'_>, op: BinOpKind, parent: &Expr<'_>, method_span: Span, is_option: bool) {
-    if let Some(before_map_snippet) = snippet_opt(cx, parent.span.with_hi(method_span.lo()))
-        && let Some(after_map_snippet) = snippet_opt(cx, method_span.with_lo(method_span.lo() + BytePos(3)))
-    {
-        span_lint_and_sugg(
-            cx,
-            MANUAL_IS_VARIANT_AND,
-            parent.span,
-            format!(
-                "called `.map() {}= {}()`",
-                if op == BinOpKind::Eq { '=' } else { '!' },
-                if is_option { "Some" } else { "Ok" },
-            ),
-            "use",
-            if is_option && op == BinOpKind::Ne {
-                format!("{before_map_snippet}is_none_or{after_map_snippet}",)
-            } else {
+#[derive(Clone, Copy, PartialEq)]
+enum Flavor {
+    Option,
+    Result,
+}
+
+impl Flavor {
+    const fn symbol(self) -> Symbol {
+        match self {
+            Self::Option => sym::Option,
+            Self::Result => sym::Result,
+        }
+    }
+
+    const fn positive(self) -> Symbol {
+        match self {
+            Self::Option => sym::Some,
+            Self::Result => sym::Ok,
+        }
+    }
+}
+
+#[derive(Clone, Copy, PartialEq)]
+enum Op {
+    Eq,
+    Ne,
+}
+
+impl std::fmt::Display for Op {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Self::Eq => write!(f, "=="),
+            Self::Ne => write!(f, "!="),
+        }
+    }
+}
+
+impl TryFrom<BinOpKind> for Op {
+    type Error = ();
+    fn try_from(op: BinOpKind) -> Result<Self, Self::Error> {
+        match op {
+            BinOpKind::Eq => Ok(Self::Eq),
+            BinOpKind::Ne => Ok(Self::Ne),
+            _ => Err(()),
+        }
+    }
+}
+
+/// Represents the argument of the `.map()` function, as a closure or as a path
+/// in case η-reduction is used.
+enum MapFunc<'hir> {
+    Closure(&'hir Closure<'hir>),
+    Path(&'hir Expr<'hir>),
+}
+
+impl<'hir> TryFrom<&'hir Expr<'hir>> for MapFunc<'hir> {
+    type Error = ();
+
+    fn try_from(expr: &'hir Expr<'hir>) -> Result<Self, Self::Error> {
+        match expr.kind {
+            ExprKind::Closure(closure) => Ok(Self::Closure(closure)),
+            ExprKind::Path(_) => Ok(Self::Path(expr)),
+            _ => Err(()),
+        }
+    }
+}
+
+impl<'hir> MapFunc<'hir> {
+    /// Build a suggestion suitable for use in a `.map()`-like function. η-expansion will be applied
+    /// as needed.
+    fn sugg(self, cx: &LateContext<'hir>, invert: bool, app: &mut Applicability) -> String {
+        match self {
+            Self::Closure(closure) => {
+                let body = Sugg::hir_with_applicability(cx, cx.tcx.hir_body(closure.body).value, "..", app);
                 format!(
-                    "{}{before_map_snippet}{}{after_map_snippet}",
-                    if op == BinOpKind::Eq { "" } else { "!" },
-                    if is_option { "is_some_and" } else { "is_ok_and" },
+                    "{} {}",
+                    snippet_with_applicability(cx, closure.fn_decl_span, "|..|", app),
+                    if invert { !body } else { body }
                 )
             },
-            Applicability::MachineApplicable,
-        );
+            Self::Path(expr) => {
+                let path = snippet_with_applicability(cx, expr.span, "_", app);
+                if invert {
+                    format!("|x| !{path}(x)")
+                } else {
+                    path.to_string()
+                }
+            },
+        }
     }
 }
 
+fn emit_lint<'tcx>(
+    cx: &LateContext<'tcx>,
+    span: Span,
+    op: Op,
+    flavor: Flavor,
+    in_some_or_ok: bool,
+    map_func: MapFunc<'tcx>,
+    recv: &Expr<'_>,
+) {
+    let mut app = Applicability::MachineApplicable;
+    let recv = snippet_with_applicability(cx, recv.span, "_", &mut app);
+
+    let (invert_expr, method, invert_body) = match (flavor, op) {
+        (Flavor::Option, Op::Eq) => (false, "is_some_and", !in_some_or_ok),
+        (Flavor::Option, Op::Ne) => (false, "is_none_or", in_some_or_ok),
+        (Flavor::Result, Op::Eq) => (false, "is_ok_and", !in_some_or_ok),
+        (Flavor::Result, Op::Ne) => (true, "is_ok_and", !in_some_or_ok),
+    };
+    span_lint_and_sugg(
+        cx,
+        MANUAL_IS_VARIANT_AND,
+        span,
+        format!("called `.map() {op} {pos}()`", pos = flavor.positive(),),
+        "use",
+        format!(
+            "{inversion}{recv}.{method}({body})",
+            inversion = if invert_expr { "!" } else { "" },
+            body = map_func.sugg(cx, invert_body, &mut app),
+        ),
+        app,
+    );
+}
+
 pub(super) fn check_map(cx: &LateContext<'_>, expr: &Expr<'_>) {
     if let Some(parent_expr) = get_parent_expr(cx, expr)
         && let ExprKind::Binary(op, left, right) = parent_expr.kind
-        && matches!(op.node, BinOpKind::Eq | BinOpKind::Ne)
         && op.span.eq_ctxt(expr.span)
+        && let Ok(op) = Op::try_from(op.node)
     {
         // Check `left` and `right` expression in any order, and for `Option` and `Result`
         for (expr1, expr2) in [(left, right), (right, left)] {
-            for item in [sym::Option, sym::Result] {
-                if let ExprKind::Call(call, ..) = expr1.kind
+            for flavor in [Flavor::Option, Flavor::Result] {
+                if let ExprKind::Call(call, [arg]) = expr1.kind
+                    && let ExprKind::Lit(lit) = arg.kind
+                    && let LitKind::Bool(bool_cst) = lit.node
                     && let ExprKind::Path(QPath::Resolved(_, path)) = call.kind
                     && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), _) = path.res
                     && let ty = cx.typeck_results().expr_ty(expr1)
                     && let ty::Adt(adt, args) = ty.kind()
-                    && cx.tcx.is_diagnostic_item(item, adt.did())
+                    && cx.tcx.is_diagnostic_item(flavor.symbol(), adt.did())
                     && args.type_at(0).is_bool()
-                    && let ExprKind::MethodCall(_, recv, _, span) = expr2.kind
-                    && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), item)
+                    && let ExprKind::MethodCall(_, recv, [map_expr], _) = expr2.kind
+                    && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), flavor.symbol())
+                    && let Ok(map_func) = MapFunc::try_from(map_expr)
                 {
-                    return emit_lint(cx, op.node, parent_expr, span, item == sym::Option);
+                    return emit_lint(cx, parent_expr.span, op, flavor, bool_cst, map_func, recv);
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index 2139466ce74..6ce7dd3d4d0 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -136,7 +136,7 @@ pub(super) fn check<'tcx>(
         fun_span: Option<Span>,
     ) -> bool {
         // (path, fn_has_argument, methods, suffix)
-        const KNOW_TYPES: [(Symbol, bool, &[Symbol], &str); 5] = [
+        const KNOW_TYPES: [(Symbol, bool, &[Symbol], &str); 7] = [
             (sym::BTreeEntry, false, &[sym::or_insert], "with"),
             (sym::HashMapEntry, false, &[sym::or_insert], "with"),
             (
@@ -146,7 +146,9 @@ pub(super) fn check<'tcx>(
                 "else",
             ),
             (sym::Option, false, &[sym::get_or_insert], "with"),
+            (sym::Option, true, &[sym::and], "then"),
             (sym::Result, true, &[sym::map_or, sym::or, sym::unwrap_or], "else"),
+            (sym::Result, true, &[sym::and], "then"),
         ];
 
         if KNOW_TYPES.iter().any(|k| k.2.contains(&name))
diff --git a/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs b/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs
index df8544f9220..54f38a322b8 100644
--- a/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs
@@ -1,5 +1,5 @@
 use rustc_errors::Applicability;
-use rustc_hir as hir;
+use rustc_hir::{self as hir, Node};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, GenericArg, Ty};
 use rustc_span::sym;
@@ -9,7 +9,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability};
 use clippy_utils::ty::get_type_diagnostic_name;
 use clippy_utils::visitors::for_each_unconsumed_temporary;
-use clippy_utils::{get_parent_expr, peel_blocks};
+use clippy_utils::{peel_blocks, potential_return_of_enclosing_body};
 
 use super::RETURN_AND_THEN;
 
@@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
     recv: &'tcx hir::Expr<'tcx>,
     arg: &'tcx hir::Expr<'_>,
 ) {
-    if cx.tcx.hir_get_fn_id_for_return_block(expr.hir_id).is_none() {
+    if !potential_return_of_enclosing_body(cx, expr) {
         return;
     }
 
@@ -55,15 +55,28 @@ pub(super) fn check<'tcx>(
         None => &body_snip,
     };
 
-    // If suggestion is going to get inserted as part of a `return` expression, it must be blockified.
-    let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr) {
-        let base_indent = indent_of(cx, parent_expr.span);
+    // If suggestion is going to get inserted as part of a `return` expression or as a match expression
+    // arm, it must be blockified.
+    let (parent_span_for_indent, opening_paren, closing_paren) = match cx.tcx.parent_hir_node(expr.hir_id) {
+        Node::Expr(parent_expr) if matches!(parent_expr.kind, hir::ExprKind::Break(..)) => {
+            (Some(parent_expr.span), "(", ")")
+        },
+        Node::Expr(parent_expr) => (Some(parent_expr.span), "", ""),
+        Node::Arm(match_arm) => (Some(match_arm.span), "", ""),
+        _ => (None, "", ""),
+    };
+    let sugg = if let Some(span) = parent_span_for_indent {
+        let base_indent = indent_of(cx, span);
         let inner_indent = base_indent.map(|i| i + 4);
         format!(
             "{}\n{}\n{}",
-            reindent_multiline(&format!("{{\nlet {arg_snip} = {recv_snip}?;"), true, inner_indent),
+            reindent_multiline(
+                &format!("{opening_paren}{{\nlet {arg_snip} = {recv_snip}?;"),
+                true,
+                inner_indent
+            ),
             reindent_multiline(inner, false, inner_indent),
-            reindent_multiline("}", false, base_indent),
+            reindent_multiline(&format!("}}{closing_paren}"), false, base_indent),
         )
     } else {
         format!(
diff --git a/src/tools/clippy/clippy_lints/src/methods/swap_with_temporary.rs b/src/tools/clippy/clippy_lints/src/methods/swap_with_temporary.rs
index de729fb343a..e378cbd6ae0 100644
--- a/src/tools/clippy/clippy_lints/src/methods/swap_with_temporary.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/swap_with_temporary.rs
@@ -4,6 +4,7 @@ use rustc_ast::BorrowKind;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::{Expr, ExprKind, Node, QPath};
 use rustc_lint::LateContext;
+use rustc_middle::ty::adjustment::Adjust;
 use rustc_span::sym;
 
 use super::SWAP_WITH_TEMPORARY;
@@ -11,12 +12,12 @@ use super::SWAP_WITH_TEMPORARY;
 const MSG_TEMPORARY: &str = "this expression returns a temporary value";
 const MSG_TEMPORARY_REFMUT: &str = "this is a mutable reference to a temporary value";
 
-pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>]) {
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, func: &Expr<'_>, args: &'tcx [Expr<'_>]) {
     if let ExprKind::Path(QPath::Resolved(_, func_path)) = func.kind
         && let Some(func_def_id) = func_path.res.opt_def_id()
         && cx.tcx.is_diagnostic_item(sym::mem_swap, func_def_id)
     {
-        match (ArgKind::new(&args[0]), ArgKind::new(&args[1])) {
+        match (ArgKind::new(cx, &args[0]), ArgKind::new(cx, &args[1])) {
             (ArgKind::RefMutToTemp(left_temp), ArgKind::RefMutToTemp(right_temp)) => {
                 emit_lint_useless(cx, expr, &args[0], &args[1], left_temp, right_temp);
             },
@@ -28,10 +29,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args
 }
 
 enum ArgKind<'tcx> {
-    // Mutable reference to a place, coming from a macro
-    RefMutToPlaceAsMacro(&'tcx Expr<'tcx>),
-    // Place behind a mutable reference
-    RefMutToPlace(&'tcx Expr<'tcx>),
+    // Mutable reference to a place, coming from a macro, and number of dereferences to use
+    RefMutToPlaceAsMacro(&'tcx Expr<'tcx>, usize),
+    // Place behind a mutable reference, and number of dereferences to use
+    RefMutToPlace(&'tcx Expr<'tcx>, usize),
     // Temporary value behind a mutable reference
     RefMutToTemp(&'tcx Expr<'tcx>),
     // Any other case
@@ -39,13 +40,29 @@ enum ArgKind<'tcx> {
 }
 
 impl<'tcx> ArgKind<'tcx> {
-    fn new(arg: &'tcx Expr<'tcx>) -> Self {
-        if let ExprKind::AddrOf(BorrowKind::Ref, _, target) = arg.kind {
-            if target.is_syntactic_place_expr() {
+    /// Build a new `ArgKind` from `arg`. There must be no false positive when returning a
+    /// `ArgKind::RefMutToTemp` variant, as this may cause a spurious lint to be emitted.
+    fn new(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Self {
+        if let ExprKind::AddrOf(BorrowKind::Ref, _, target) = arg.kind
+            && let adjustments = cx.typeck_results().expr_adjustments(arg)
+            && adjustments
+                .first()
+                .is_some_and(|adj| matches!(adj.kind, Adjust::Deref(None)))
+            && adjustments
+                .last()
+                .is_some_and(|adj| matches!(adj.kind, Adjust::Borrow(_)))
+        {
+            let extra_derefs = adjustments[1..adjustments.len() - 1]
+                .iter()
+                .filter(|adj| matches!(adj.kind, Adjust::Deref(_)))
+                .count();
+            // If a deref is used, `arg` might be a place expression. For example, a mutex guard
+            // would dereference into the mutex content which is probably not temporary.
+            if target.is_syntactic_place_expr() || extra_derefs > 0 {
                 if arg.span.from_expansion() {
-                    ArgKind::RefMutToPlaceAsMacro(arg)
+                    ArgKind::RefMutToPlaceAsMacro(arg, extra_derefs)
                 } else {
-                    ArgKind::RefMutToPlace(target)
+                    ArgKind::RefMutToPlace(target, extra_derefs)
                 }
             } else {
                 ArgKind::RefMutToTemp(target)
@@ -106,10 +123,15 @@ fn emit_lint_assign(cx: &LateContext<'_>, expr: &Expr<'_>, target: &ArgKind<'_>,
                 let mut applicability = Applicability::MachineApplicable;
                 let ctxt = expr.span.ctxt();
                 let assign_target = match target {
-                    ArgKind::Expr(target) | ArgKind::RefMutToPlaceAsMacro(target) => {
-                        Sugg::hir_with_context(cx, target, ctxt, "_", &mut applicability).deref()
-                    },
-                    ArgKind::RefMutToPlace(target) => Sugg::hir_with_context(cx, target, ctxt, "_", &mut applicability),
+                    ArgKind::Expr(target) => Sugg::hir_with_context(cx, target, ctxt, "_", &mut applicability).deref(),
+                    ArgKind::RefMutToPlaceAsMacro(arg, derefs) => (0..*derefs).fold(
+                        Sugg::hir_with_context(cx, arg, ctxt, "_", &mut applicability).deref(),
+                        |sugg, _| sugg.deref(),
+                    ),
+                    ArgKind::RefMutToPlace(target, derefs) => (0..*derefs).fold(
+                        Sugg::hir_with_context(cx, target, ctxt, "_", &mut applicability),
+                        |sugg, _| sugg.deref(),
+                    ),
                     ArgKind::RefMutToTemp(_) => unreachable!(),
                 };
                 let assign_source = Sugg::hir_with_context(cx, temp, ctxt, "_", &mut applicability);
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
index b90748dd158..4a9007c607c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
@@ -62,7 +62,8 @@ pub(super) fn check<'a>(
 
     let ext_def_span = def.span.until(map.span);
 
-    let (sugg, method, applicability) = if let ExprKind::Closure(map_closure) = map.kind
+    let (sugg, method, applicability) = if cx.typeck_results().expr_adjustments(recv).is_empty()
+            && let ExprKind::Closure(map_closure) = map.kind
             && let closure_body = cx.tcx.hir_body(map_closure.body)
             && let closure_body_value = closure_body.value.peel_blocks()
             && let ExprKind::Binary(op, l, r) = closure_body_value.kind
diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs
index 3ed4b1c2ea9..b3aa1a7286a 100644
--- a/src/tools/clippy/clippy_lints/src/needless_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs
@@ -199,11 +199,16 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
                 let mut applicability = Applicability::MachineApplicable;
                 let cond = Sugg::hir_with_applicability(cx, cond, "..", &mut applicability);
                 let lhs = snippet_with_applicability(cx, lhs_a.span, "..", &mut applicability);
-                let sugg = if a == b {
+                let mut sugg = if a == b {
                     format!("{cond}; {lhs} = {a:?};")
                 } else {
                     format!("{lhs} = {};", if a { cond } else { !cond })
                 };
+
+                if is_else_clause(cx.tcx, e) {
+                    sugg = format!("{{ {sugg} }}");
+                }
+
                 span_lint_and_sugg(
                     cx,
                     NEEDLESS_BOOL_ASSIGN,
diff --git a/src/tools/clippy/clippy_lints/src/neg_multiply.rs b/src/tools/clippy/clippy_lints/src/neg_multiply.rs
index 442280f9998..946114e1041 100644
--- a/src/tools/clippy/clippy_lints/src/neg_multiply.rs
+++ b/src/tools/clippy/clippy_lints/src/neg_multiply.rs
@@ -1,13 +1,13 @@
 use clippy_utils::consts::{self, Constant};
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_with_context;
+use clippy_utils::get_parent_expr;
+use clippy_utils::source::{snippet, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
 use rustc_ast::util::parser::ExprPrecedence;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::Span;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -33,6 +33,19 @@ declare_clippy_lint! {
 
 declare_lint_pass!(NegMultiply => [NEG_MULTIPLY]);
 
+fn is_in_parens_with_postfix(cx: &LateContext<'_>, mul_expr: &Expr<'_>) -> bool {
+    if let Some(parent) = get_parent_expr(cx, mul_expr) {
+        let mult_snippet = snippet(cx, mul_expr.span, "");
+        if has_enclosing_paren(&mult_snippet)
+            && let ExprKind::MethodCall(_, _, _, _) = parent.kind
+        {
+            return true;
+        }
+    }
+
+    false
+}
+
 impl<'tcx> LateLintPass<'tcx> for NegMultiply {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
         if let ExprKind::Binary(ref op, left, right) = e.kind
@@ -40,15 +53,15 @@ impl<'tcx> LateLintPass<'tcx> for NegMultiply {
         {
             match (&left.kind, &right.kind) {
                 (&ExprKind::Unary(..), &ExprKind::Unary(..)) => {},
-                (&ExprKind::Unary(UnOp::Neg, lit), _) => check_mul(cx, e.span, lit, right),
-                (_, &ExprKind::Unary(UnOp::Neg, lit)) => check_mul(cx, e.span, lit, left),
+                (&ExprKind::Unary(UnOp::Neg, lit), _) => check_mul(cx, e, lit, right),
+                (_, &ExprKind::Unary(UnOp::Neg, lit)) => check_mul(cx, e, lit, left),
                 _ => {},
             }
         }
     }
 }
 
-fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
+fn check_mul(cx: &LateContext<'_>, mul_expr: &Expr<'_>, lit: &Expr<'_>, exp: &Expr<'_>) {
     const F16_ONE: u16 = 1.0_f16.to_bits();
     const F128_ONE: u128 = 1.0_f128.to_bits();
     if let ExprKind::Lit(l) = lit.kind
@@ -63,8 +76,19 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
         && cx.typeck_results().expr_ty(exp).is_numeric()
     {
         let mut applicability = Applicability::MachineApplicable;
-        let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability);
-        let suggestion = if !from_macro && cx.precedence(exp) < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) {
+        let (snip, from_macro) = snippet_with_context(cx, exp.span, mul_expr.span.ctxt(), "..", &mut applicability);
+
+        let needs_parens_for_postfix = is_in_parens_with_postfix(cx, mul_expr);
+
+        let suggestion = if needs_parens_for_postfix {
+            // Special case: when the multiplication is in parentheses followed by a method call
+            // we need to preserve the grouping but negate the inner expression.
+            // Consider this expression: `((a.delta - 0.5).abs() * -1.0).total_cmp(&1.0)`
+            // We need to end up with: `(-(a.delta - 0.5).abs()).total_cmp(&1.0)`
+            // Otherwise, without the parentheses we would try to negate an Ordering:
+            // `-(a.delta - 0.5).abs().total_cmp(&1.0)`
+            format!("(-{snip})")
+        } else if !from_macro && cx.precedence(exp) < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) {
             format!("-({snip})")
         } else {
             format!("-{snip}")
@@ -72,7 +96,7 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
         span_lint_and_sugg(
             cx,
             NEG_MULTIPLY,
-            span,
+            mul_expr.span,
             "this multiplication by -1 can be written more succinctly",
             "consider using",
             suggestion,
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 02c48166131..72e6503e7e4 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
 use clippy_utils::source::SpanRangeExt;
-use clippy_utils::ty::has_drop;
+use clippy_utils::ty::{expr_type_is_certain, has_drop};
 use clippy_utils::{
     in_automatically_derived, is_inside_always_const_context, is_lint_allowed, path_to_local, peel_blocks,
 };
@@ -340,11 +340,13 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
         },
         ExprKind::Array(v) | ExprKind::Tup(v) => Some(v.iter().collect()),
         ExprKind::Repeat(inner, _)
-        | ExprKind::Cast(inner, _)
         | ExprKind::Type(inner, _)
         | ExprKind::Unary(_, inner)
         | ExprKind::Field(inner, _)
         | ExprKind::AddrOf(_, _, inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
+        ExprKind::Cast(inner, _) if expr_type_is_certain(cx, inner) => {
+            reduce_expression(cx, inner).or_else(|| Some(vec![inner]))
+        },
         ExprKind::Struct(_, fields, ref base) => {
             if has_drop(cx, cx.typeck_results().expr_ty(expr)) {
                 None
diff --git a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
index 0faa7b9e646..21e1ab0f4f2 100644
--- a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::get_enclosing_block;
-use clippy_utils::source::snippet;
+use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::{implements_trait, is_copy};
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
@@ -61,12 +61,13 @@ pub(crate) fn check<'tcx>(
                         e.span,
                         "needlessly taken reference of both operands",
                         |diag| {
-                            let lsnip = snippet(cx, l.span, "...").to_string();
-                            let rsnip = snippet(cx, r.span, "...").to_string();
+                            let mut applicability = Applicability::MachineApplicable;
+                            let (lsnip, _) = snippet_with_context(cx, l.span, e.span.ctxt(), "...", &mut applicability);
+                            let (rsnip, _) = snippet_with_context(cx, r.span, e.span.ctxt(), "...", &mut applicability);
                             diag.multipart_suggestion(
                                 "use the values directly",
-                                vec![(left.span, lsnip), (right.span, rsnip)],
-                                Applicability::MachineApplicable,
+                                vec![(left.span, lsnip.to_string()), (right.span, rsnip.to_string())],
+                                applicability,
                             );
                         },
                     );
@@ -80,13 +81,9 @@ pub(crate) fn check<'tcx>(
                         e.span,
                         "needlessly taken reference of left operand",
                         |diag| {
-                            let lsnip = snippet(cx, l.span, "...").to_string();
-                            diag.span_suggestion(
-                                left.span,
-                                "use the left value directly",
-                                lsnip,
-                                Applicability::MachineApplicable,
-                            );
+                            let mut applicability = Applicability::MachineApplicable;
+                            let (lsnip, _) = snippet_with_context(cx, l.span, e.span.ctxt(), "...", &mut applicability);
+                            diag.span_suggestion(left.span, "use the left value directly", lsnip, applicability);
                         },
                     );
                 } else if !lcpy
@@ -99,7 +96,8 @@ pub(crate) fn check<'tcx>(
                         e.span,
                         "needlessly taken reference of right operand",
                         |diag| {
-                            let rsnip = snippet(cx, r.span, "...").to_string();
+                            let mut applicability = Applicability::MachineApplicable;
+                            let (rsnip, _) = snippet_with_context(cx, r.span, e.span.ctxt(), "...", &mut applicability);
                             diag.span_suggestion(
                                 right.span,
                                 "use the right value directly",
@@ -131,7 +129,8 @@ pub(crate) fn check<'tcx>(
                         e.span,
                         "needlessly taken reference of left operand",
                         |diag| {
-                            let lsnip = snippet(cx, l.span, "...").to_string();
+                            let mut applicability = Applicability::MachineApplicable;
+                            let (lsnip, _) = snippet_with_context(cx, l.span, e.span.ctxt(), "...", &mut applicability);
                             diag.span_suggestion(
                                 left.span,
                                 "use the left value directly",
@@ -158,7 +157,8 @@ pub(crate) fn check<'tcx>(
                     && implements_trait(cx, cx.typeck_results().expr_ty(left), trait_id, &[rty.into()])
                 {
                     span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |diag| {
-                        let rsnip = snippet(cx, r.span, "...").to_string();
+                        let mut applicability = Applicability::MachineApplicable;
+                        let (rsnip, _) = snippet_with_context(cx, r.span, e.span.ctxt(), "...", &mut applicability);
                         diag.span_suggestion(
                             right.span,
                             "use the right value directly",
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index 84597269a58..1c23fe998ad 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -5,9 +5,7 @@ use hir::Param;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
-use rustc_hir::{
-    ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, Node, intravisit as hir_visit,
-};
+use rustc_hir::{ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, intravisit as hir_visit};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty;
@@ -198,15 +196,15 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
                             hint = hint.asyncify();
                         }
 
-                        let is_in_fn_call_arg = if let Node::Expr(expr) = cx.tcx.parent_hir_node(expr.hir_id) {
-                            matches!(expr.kind, ExprKind::Call(_, _))
-                        } else {
-                            false
-                        };
-
-                        // avoid clippy::double_parens
-                        if !is_in_fn_call_arg {
-                            hint = hint.maybe_paren();
+                        // If the closure body is a block with a single expression, suggest just the inner expression,
+                        // not the block. Example: `(|| { Some(true) })()` should suggest
+                        // `Some(true)`
+                        if let ExprKind::Block(block, _) = body.kind
+                            && block.stmts.is_empty()
+                            && let Some(expr) = block.expr
+                        {
+                            hint = Sugg::hir_with_context(cx, expr, full_expr.span.ctxt(), "..", &mut applicability)
+                                .maybe_paren();
                         }
 
                         diag.span_suggestion(full_expr.span, "try doing something like", hint, applicability);
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index 442b3250d86..cf70e883bd0 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -1,10 +1,10 @@
 use clippy_config::Conf;
-use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
 use clippy_utils::is_from_proc_macro;
 use clippy_utils::msrvs::Msrv;
 use rustc_attr_data_structures::{StabilityLevel, StableSince};
 use rustc_errors::Applicability;
-use rustc_hir::def::Res;
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Block, Body, HirId, Path, PathSegment};
 use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
@@ -88,49 +88,52 @@ declare_clippy_lint! {
 }
 
 pub struct StdReexports {
-    lint_point: (Span, Option<LintPoint>),
+    lint_points: Option<(Span, Vec<LintPoint>)>,
     msrv: Msrv,
 }
 
 impl StdReexports {
     pub fn new(conf: &'static Conf) -> Self {
         Self {
-            lint_point: Default::default(),
+            lint_points: Option::default(),
             msrv: conf.msrv,
         }
     }
 
-    fn lint_if_finish(&mut self, cx: &LateContext<'_>, (span, item): (Span, Option<LintPoint>)) {
-        if span.source_equal(self.lint_point.0) {
-            return;
+    fn lint_if_finish(&mut self, cx: &LateContext<'_>, krate: Span, lint_point: LintPoint) {
+        match &mut self.lint_points {
+            Some((prev_krate, prev_lints)) if prev_krate.overlaps(krate) => {
+                prev_lints.push(lint_point);
+            },
+            _ => emit_lints(cx, self.lint_points.replace((krate, vec![lint_point]))),
         }
-
-        if !self.lint_point.0.is_dummy() {
-            emit_lints(cx, &self.lint_point);
-        }
-
-        self.lint_point = (span, item);
     }
 }
 
 impl_lint_pass!(StdReexports => [STD_INSTEAD_OF_CORE, STD_INSTEAD_OF_ALLOC, ALLOC_INSTEAD_OF_CORE]);
 
-type LintPoint = (&'static Lint, &'static str, &'static str);
+#[derive(Debug)]
+enum LintPoint {
+    Available(Span, &'static Lint, &'static str, &'static str),
+    Conflict,
+}
 
 impl<'tcx> LateLintPass<'tcx> for StdReexports {
     fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, _: HirId) {
-        if let Res::Def(_, def_id) = path.res
+        if let Res::Def(def_kind, def_id) = path.res
             && let Some(first_segment) = get_first_segment(path)
             && is_stable(cx, def_id, self.msrv)
             && !path.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, &first_segment.ident)
+            && !matches!(def_kind, DefKind::Macro(_))
+            && let Some(last_segment) = path.segments.last()
         {
             let (lint, used_mod, replace_with) = match first_segment.ident.name {
                 sym::std => match cx.tcx.crate_name(def_id.krate) {
                     sym::core => (STD_INSTEAD_OF_CORE, "std", "core"),
                     sym::alloc => (STD_INSTEAD_OF_ALLOC, "std", "alloc"),
                     _ => {
-                        self.lint_if_finish(cx, (first_segment.ident.span, None));
+                        self.lint_if_finish(cx, first_segment.ident.span, LintPoint::Conflict);
                         return;
                     },
                 },
@@ -138,44 +141,84 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
                     if cx.tcx.crate_name(def_id.krate) == sym::core {
                         (ALLOC_INSTEAD_OF_CORE, "alloc", "core")
                     } else {
-                        self.lint_if_finish(cx, (first_segment.ident.span, None));
+                        self.lint_if_finish(cx, first_segment.ident.span, LintPoint::Conflict);
                         return;
                     }
                 },
-                _ => return,
+                _ => {
+                    self.lint_if_finish(cx, first_segment.ident.span, LintPoint::Conflict);
+                    return;
+                },
             };
 
-            self.lint_if_finish(cx, (first_segment.ident.span, Some((lint, used_mod, replace_with))));
+            self.lint_if_finish(
+                cx,
+                first_segment.ident.span,
+                LintPoint::Available(last_segment.ident.span, lint, used_mod, replace_with),
+            );
         }
     }
 
     fn check_block_post(&mut self, cx: &LateContext<'tcx>, _: &Block<'tcx>) {
-        self.lint_if_finish(cx, Default::default());
+        emit_lints(cx, self.lint_points.take());
     }
 
     fn check_body_post(&mut self, cx: &LateContext<'tcx>, _: &Body<'tcx>) {
-        self.lint_if_finish(cx, Default::default());
+        emit_lints(cx, self.lint_points.take());
     }
 
     fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
-        self.lint_if_finish(cx, Default::default());
+        emit_lints(cx, self.lint_points.take());
     }
 }
 
-fn emit_lints(cx: &LateContext<'_>, (span, item): &(Span, Option<LintPoint>)) {
-    let Some((lint, used_mod, replace_with)) = item else {
+fn emit_lints(cx: &LateContext<'_>, lint_points: Option<(Span, Vec<LintPoint>)>) {
+    let Some((krate_span, lint_points)) = lint_points else {
         return;
     };
 
-    span_lint_and_sugg(
-        cx,
-        lint,
-        *span,
-        format!("used import from `{used_mod}` instead of `{replace_with}`"),
-        format!("consider importing the item from `{replace_with}`"),
-        (*replace_with).to_string(),
-        Applicability::MachineApplicable,
-    );
+    let mut lint: Option<(&'static Lint, &'static str, &'static str)> = None;
+    let mut has_conflict = false;
+    for lint_point in &lint_points {
+        match lint_point {
+            LintPoint::Available(_, l, used_mod, replace_with)
+                if lint.is_none_or(|(prev_l, ..)| l.name == prev_l.name) =>
+            {
+                lint = Some((l, used_mod, replace_with));
+            },
+            _ => {
+                has_conflict = true;
+                break;
+            },
+        }
+    }
+
+    if !has_conflict && let Some((lint, used_mod, replace_with)) = lint {
+        span_lint_and_sugg(
+            cx,
+            lint,
+            krate_span,
+            format!("used import from `{used_mod}` instead of `{replace_with}`"),
+            format!("consider importing the item from `{replace_with}`"),
+            (*replace_with).to_string(),
+            Applicability::MachineApplicable,
+        );
+        return;
+    }
+
+    for lint_point in lint_points {
+        let LintPoint::Available(span, lint, used_mod, replace_with) = lint_point else {
+            continue;
+        };
+        span_lint_and_help(
+            cx,
+            lint,
+            span,
+            format!("used import from `{used_mod}` instead of `{replace_with}`"),
+            None,
+            format!("consider importing the item from `{replace_with}`"),
+        );
+    }
 }
 
 /// Returns the first named segment of a [`Path`].
diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
index 6cc4b589a72..45c0d459d90 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -143,7 +143,8 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
         if let Some(tail) = block.expr
             && !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, tail.hir_id)
             && !tail.span.in_external_macro(cx.tcx.sess.source_map())
-            && let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, tail.span, tail.hir_id)
+            && let HasSafetyComment::Yes(pos) =
+                stmt_has_safety_comment(cx, tail.span, tail.hir_id, self.accept_comment_above_attributes)
             && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, tail, pos)
         {
             span_lint_and_then(
@@ -167,7 +168,8 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
         };
         if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, stmt.hir_id)
             && !stmt.span.in_external_macro(cx.tcx.sess.source_map())
-            && let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, stmt.span, stmt.hir_id)
+            && let HasSafetyComment::Yes(pos) =
+                stmt_has_safety_comment(cx, stmt.span, stmt.hir_id, self.accept_comment_above_attributes)
             && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, expr, pos)
         {
             span_lint_and_then(
@@ -540,7 +542,12 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf
 
 /// Checks if the lines immediately preceding the item contain a safety comment.
 #[allow(clippy::collapsible_match)]
-fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> HasSafetyComment {
+fn stmt_has_safety_comment(
+    cx: &LateContext<'_>,
+    span: Span,
+    hir_id: HirId,
+    accept_comment_above_attributes: bool,
+) -> HasSafetyComment {
     match span_from_macro_expansion_has_safety_comment(cx, span) {
         HasSafetyComment::Maybe => (),
         has_safety_comment => return has_safety_comment,
@@ -555,6 +562,13 @@ fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> H
         _ => return HasSafetyComment::Maybe,
     };
 
+    // if span_with_attrs_has_safety_comment(cx, span, hir_id, accept_comment_above_attrib
+    // }
+    let mut span = span;
+    if accept_comment_above_attributes {
+        span = include_attrs_in_span(cx, hir_id, span);
+    }
+
     let source_map = cx.sess().source_map();
     if let Some(comment_start) = comment_start
         && let Ok(unsafe_line) = source_map.lookup_line(span.lo())
diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs
index 8ceaa3dc58e..e67afc7f5a8 100644
--- a/src/tools/clippy/clippy_lints/src/unused_async.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_async.rs
@@ -169,7 +169,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
         let iter = self
             .unused_async_fns
             .iter()
-            .filter(|UnusedAsyncFn { def_id, .. }| (!self.async_fns_as_value.contains(def_id)));
+            .filter(|UnusedAsyncFn { def_id, .. }| !self.async_fns_as_value.contains(def_id));
 
         for fun in iter {
             span_lint_hir_and_then(
diff --git a/src/tools/clippy/clippy_lints_internal/src/symbols.rs b/src/tools/clippy/clippy_lints_internal/src/symbols.rs
index 7b5d58824c3..74712097e71 100644
--- a/src/tools/clippy/clippy_lints_internal/src/symbols.rs
+++ b/src/tools/clippy/clippy_lints_internal/src/symbols.rs
@@ -65,7 +65,7 @@ pub struct Symbols {
 impl_lint_pass!(Symbols => [INTERNING_LITERALS, SYMBOL_AS_STR]);
 
 impl Symbols {
-    fn lit_suggestion(&self, lit: &Lit) -> Option<(Span, String)> {
+    fn lit_suggestion(&self, lit: Lit) -> Option<(Span, String)> {
         if let LitKind::Str(name, _) = lit.node {
             let sugg = if let Some((prefix, name)) = self.symbol_map.get(&name.as_u32()) {
                 format!("{prefix}::{name}")
diff --git a/src/tools/clippy/clippy_test_deps/Cargo.toml b/src/tools/clippy/clippy_test_deps/Cargo.toml
new file mode 100644
index 00000000000..f41334f0ade
--- /dev/null
+++ b/src/tools/clippy/clippy_test_deps/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "clippy_test_deps"
+version = "0.1.0"
+edition = "2021"
+
+# Add dependencies here to make them available in ui tests.
+
+[dependencies]
+regex = "1.5.5"
+serde = { version = "1.0.145", features = ["derive"] }
+if_chain = "1.0"
+quote = "1.0.25"
+syn = { version = "2.0", features = ["full"] }
+futures = "0.3"
+parking_lot = "0.12"
+tokio = { version = "1", features = ["io-util"] }
+itertools = "0.12"
diff --git a/tests/run-make/rust-lld-by-default-beta-stable/main.rs b/src/tools/clippy/clippy_test_deps/src/main.rs
index f328e4d9d04..f328e4d9d04 100644
--- a/tests/run-make/rust-lld-by-default-beta-stable/main.rs
+++ b/src/tools/clippy/clippy_test_deps/src/main.rs
diff --git a/src/tools/clippy/clippy_utils/README.md b/src/tools/clippy/clippy_utils/README.md
index 649748d1534..645b644d9f4 100644
--- a/src/tools/clippy/clippy_utils/README.md
+++ b/src/tools/clippy/clippy_utils/README.md
@@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
 
 <!-- begin autogenerated nightly -->
 ```
-nightly-2025-06-26
+nightly-2025-07-10
 ```
 <!-- end autogenerated nightly -->
 
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index 4c7a589e185..34472eaab93 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -1,5 +1,8 @@
+use crate::source::SpanRangeExt;
+use crate::{sym, tokenize_with_text};
 use rustc_ast::attr;
 use rustc_ast::attr::AttributeExt;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_errors::Applicability;
 use rustc_lexer::TokenKind;
 use rustc_lint::LateContext;
@@ -7,10 +10,6 @@ use rustc_middle::ty::{AdtDef, TyCtxt};
 use rustc_session::Session;
 use rustc_span::{Span, Symbol};
 use std::str::FromStr;
-use rustc_attr_data_structures::find_attr;
-use crate::source::SpanRangeExt;
-use crate::{sym, tokenize_with_text};
-use rustc_attr_data_structures::AttributeKind;
 
 /// Deprecation status of attributes known by Clippy.
 pub enum DeprecationStatus {
@@ -168,7 +167,8 @@ pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {
     adt.is_variant_list_non_exhaustive()
         || find_attr!(tcx.get_all_attrs(adt.did()), AttributeKind::NonExhaustive(..))
         || adt.variants().iter().any(|variant_def| {
-            variant_def.is_field_list_non_exhaustive() || find_attr!(tcx.get_all_attrs(variant_def.def_id), AttributeKind::NonExhaustive(..))
+            variant_def.is_field_list_non_exhaustive()
+                || find_attr!(tcx.get_all_attrs(variant_def.def_id), AttributeKind::NonExhaustive(..))
         })
         || adt
             .all_fields()
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index ba0376e4d40..94b7055ad20 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -304,9 +304,7 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option<Ty<'tcx>>) -> Constan
     match *lit {
         LitKind::Str(ref is, _) => Constant::Str(is.to_string()),
         LitKind::Byte(b) => Constant::Int(u128::from(b)),
-        LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => {
-            Constant::Binary(s.as_byte_str().to_vec())
-        }
+        LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(s.as_byte_str().to_vec()),
         LitKind::Char(c) => Constant::Char(c),
         LitKind::Int(n, _) => Constant::Int(n.get()),
         LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty {
@@ -568,9 +566,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 } else {
                     match &lit.node {
                         LitKind::Str(is, _) => Some(is.is_empty()),
-                        LitKind::ByteStr(s, _) | LitKind::CStr(s, _) => {
-                            Some(s.as_byte_str().is_empty())
-                        }
+                        LitKind::ByteStr(s, _) | LitKind::CStr(s, _) => Some(s.as_byte_str().is_empty()),
                         _ => None,
                     }
                 }
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 0ca494f16e3..6f19ce80cf6 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -2,6 +2,7 @@ use crate::consts::ConstEvalCtxt;
 use crate::macros::macro_backtrace;
 use crate::source::{SpanRange, SpanRangeExt, walk_span_to_context};
 use crate::tokenize_with_text;
+use rustc_ast::ast;
 use rustc_ast::ast::InlineAsmTemplatePiece;
 use rustc_data_structures::fx::FxHasher;
 use rustc_hir::MatchSource::TryDesugar;
@@ -9,8 +10,8 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
     AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField,
     ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeKind,
-    Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr,
-    TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind,
+    Node, Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind,
+    StructTailExpr, TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind,
 };
 use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::LateContext;
@@ -1004,8 +1005,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     self.hash_expr(e);
                 }
             },
-            ExprKind::Match(e, arms, s) => {
-                self.hash_expr(e);
+            ExprKind::Match(scrutinee, arms, _) => {
+                self.hash_expr(scrutinee);
 
                 for arm in *arms {
                     self.hash_pat(arm.pat);
@@ -1014,8 +1015,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     }
                     self.hash_expr(arm.body);
                 }
-
-                s.hash(&mut self.s);
             },
             ExprKind::MethodCall(path, receiver, args, _fn_span) => {
                 self.hash_name(path.ident.name);
@@ -1058,8 +1057,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
             ExprKind::Use(expr, _) => {
                 self.hash_expr(expr);
             },
-            ExprKind::Unary(lop, le) => {
-                std::mem::discriminant(lop).hash(&mut self.s);
+            ExprKind::Unary(l_op, le) => {
+                std::mem::discriminant(l_op).hash(&mut self.s);
                 self.hash_expr(le);
             },
             ExprKind::UnsafeBinderCast(kind, expr, ty) => {
@@ -1394,3 +1393,70 @@ fn eq_span_tokens(
     }
     f(cx, left.into_range(), right.into_range(), pred)
 }
+
+/// Returns true if the expression contains ambiguous literals (unsuffixed float or int literals)
+/// that could be interpreted as either f32/f64 or i32/i64 depending on context.
+pub fn has_ambiguous_literal_in_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    match expr.kind {
+        ExprKind::Path(ref qpath) => {
+            if let Res::Local(hir_id) = cx.qpath_res(qpath, expr.hir_id)
+                && let Node::LetStmt(local) = cx.tcx.parent_hir_node(hir_id)
+                && local.ty.is_none()
+                && let Some(init) = local.init
+            {
+                return has_ambiguous_literal_in_expr(cx, init);
+            }
+            false
+        },
+        ExprKind::Lit(lit) => matches!(
+            lit.node,
+            ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) | ast::LitKind::Int(_, ast::LitIntType::Unsuffixed)
+        ),
+
+        ExprKind::Array(exprs) | ExprKind::Tup(exprs) => exprs.iter().any(|e| has_ambiguous_literal_in_expr(cx, e)),
+
+        ExprKind::Assign(lhs, rhs, _) | ExprKind::AssignOp(_, lhs, rhs) | ExprKind::Binary(_, lhs, rhs) => {
+            has_ambiguous_literal_in_expr(cx, lhs) || has_ambiguous_literal_in_expr(cx, rhs)
+        },
+
+        ExprKind::Unary(_, e)
+        | ExprKind::Cast(e, _)
+        | ExprKind::Type(e, _)
+        | ExprKind::DropTemps(e)
+        | ExprKind::AddrOf(_, _, e)
+        | ExprKind::Field(e, _)
+        | ExprKind::Index(e, _, _)
+        | ExprKind::Yield(e, _) => has_ambiguous_literal_in_expr(cx, e),
+
+        ExprKind::MethodCall(_, receiver, args, _) | ExprKind::Call(receiver, args) => {
+            has_ambiguous_literal_in_expr(cx, receiver) || args.iter().any(|e| has_ambiguous_literal_in_expr(cx, e))
+        },
+
+        ExprKind::Closure(Closure { body, .. }) => {
+            let body = cx.tcx.hir_body(*body);
+            let closure_expr = crate::peel_blocks(body.value);
+            has_ambiguous_literal_in_expr(cx, closure_expr)
+        },
+
+        ExprKind::Block(blk, _) => blk.expr.as_ref().is_some_and(|e| has_ambiguous_literal_in_expr(cx, e)),
+
+        ExprKind::If(cond, then_expr, else_expr) => {
+            has_ambiguous_literal_in_expr(cx, cond)
+                || has_ambiguous_literal_in_expr(cx, then_expr)
+                || else_expr.as_ref().is_some_and(|e| has_ambiguous_literal_in_expr(cx, e))
+        },
+
+        ExprKind::Match(scrutinee, arms, _) => {
+            has_ambiguous_literal_in_expr(cx, scrutinee)
+                || arms.iter().any(|arm| has_ambiguous_literal_in_expr(cx, arm.body))
+        },
+
+        ExprKind::Loop(body, ..) => body.expr.is_some_and(|e| has_ambiguous_literal_in_expr(cx, e)),
+
+        ExprKind::Ret(opt_expr) | ExprKind::Break(_, opt_expr) => {
+            opt_expr.as_ref().is_some_and(|e| has_ambiguous_literal_in_expr(cx, e))
+        },
+
+        _ => false,
+    }
+}
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index c01f0ffaac9..2e03743e621 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -77,7 +77,8 @@ pub mod visitors;
 pub use self::attrs::*;
 pub use self::check_proc_macro::{is_from_proc_macro, is_span_if, is_span_match};
 pub use self::hir_utils::{
-    HirEqInterExpr, SpanlessEq, SpanlessHash, both, count_eq, eq_expr_value, hash_expr, hash_stmt, is_bool, over,
+    HirEqInterExpr, SpanlessEq, SpanlessHash, both, count_eq, eq_expr_value, has_ambiguous_literal_in_expr, hash_expr,
+    hash_stmt, is_bool, over,
 };
 
 use core::mem;
@@ -3497,3 +3498,64 @@ pub fn is_expr_default<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) ->
         false
     }
 }
+
+/// Checks if `expr` may be directly used as the return value of its enclosing body.
+/// The following cases are covered:
+/// - `expr` as the last expression of the body, or of a block that can be used as the return value
+/// - `return expr`
+/// - then or else part of a `if` in return position
+/// - arm body of a `match` in a return position
+/// - `break expr` or `break 'label expr` if the loop or block being exited is used as a return
+///   value
+///
+/// Contrary to [`TyCtxt::hir_get_fn_id_for_return_block()`], if `expr` is part of a
+/// larger expression, for example a field expression of a `struct`, it will not be
+/// considered as matching the condition and will return `false`.
+///
+/// Also, even if `expr` is assigned to a variable which is later returned, this function
+/// will still return `false` because `expr` is not used *directly* as the return value
+/// as it goes through the intermediate variable.
+pub fn potential_return_of_enclosing_body(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    let enclosing_body_owner = cx
+        .tcx
+        .local_def_id_to_hir_id(cx.tcx.hir_enclosing_body_owner(expr.hir_id));
+    let mut prev_id = expr.hir_id;
+    let mut skip_until_id = None;
+    for (hir_id, node) in cx.tcx.hir_parent_iter(expr.hir_id) {
+        if hir_id == enclosing_body_owner {
+            return true;
+        }
+        if let Some(id) = skip_until_id {
+            prev_id = hir_id;
+            if id == hir_id {
+                skip_until_id = None;
+            }
+            continue;
+        }
+        match node {
+            Node::Block(Block { expr, .. }) if expr.is_some_and(|expr| expr.hir_id == prev_id) => {},
+            Node::Arm(arm) if arm.body.hir_id == prev_id => {},
+            Node::Expr(expr) => match expr.kind {
+                ExprKind::Ret(_) => return true,
+                ExprKind::If(_, then, opt_else)
+                    if then.hir_id == prev_id || opt_else.is_some_and(|els| els.hir_id == prev_id) => {},
+                ExprKind::Match(_, arms, _) if arms.iter().any(|arm| arm.hir_id == prev_id) => {},
+                ExprKind::Block(block, _) if block.hir_id == prev_id => {},
+                ExprKind::Break(
+                    Destination {
+                        target_id: Ok(target_id),
+                        ..
+                    },
+                    _,
+                ) => skip_until_id = Some(target_id),
+                _ => break,
+            },
+            _ => break,
+        }
+        prev_id = hir_id;
+    }
+
+    // `expr` is used as part of "something" and is not returned directly from its
+    // enclosing body.
+    false
+}
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 7a0bef1a9bb..24ed4c3a8be 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -74,7 +74,7 @@ msrv_aliases! {
     1,28,0 { FROM_BOOL, REPEAT_WITH, SLICE_FROM_REF }
     1,27,0 { ITERATOR_TRY_FOLD }
     1,26,0 { RANGE_INCLUSIVE, STRING_RETAIN }
-    1,24,0 { IS_ASCII_DIGIT }
+    1,24,0 { IS_ASCII_DIGIT, PTR_NULL }
     1,18,0 { HASH_MAP_RETAIN, HASH_SET_RETAIN }
     1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }
     1,16,0 { STR_REPEAT }
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index bffbcf073ab..fe208c032f4 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -889,7 +889,7 @@ impl AdtVariantInfo {
                     .enumerate()
                     .map(|(i, f)| (i, approx_ty_size(cx, f.ty(cx.tcx, subst))))
                     .collect::<Vec<_>>();
-                fields_size.sort_by(|(_, a_size), (_, b_size)| (a_size.cmp(b_size)));
+                fields_size.sort_by(|(_, a_size), (_, b_size)| a_size.cmp(b_size));
 
                 Self {
                     ind: i,
@@ -898,7 +898,7 @@ impl AdtVariantInfo {
                 }
             })
             .collect::<Vec<_>>();
-        variants_size.sort_by(|a, b| (b.size.cmp(&a.size)));
+        variants_size.sort_by(|a, b| b.size.cmp(&a.size));
         variants_size
     }
 }
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index fc6e30a9804..ba5cbc73836 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -1,3 +1,5 @@
+use crate::msrvs::Msrv;
+use crate::qualify_min_const_fn::is_stable_const_fn;
 use crate::ty::needs_ordered_drop;
 use crate::{get_enclosing_block, path_to_local_id};
 use core::ops::ControlFlow;
@@ -343,17 +345,17 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
                     .cx
                     .qpath_res(p, hir_id)
                     .opt_def_id()
-                    .is_some_and(|id| self.cx.tcx.is_const_fn(id)) => {},
+                    .is_some_and(|id| is_stable_const_fn(self.cx, id, Msrv::default())) => {},
                 ExprKind::MethodCall(..)
                     if self
                         .cx
                         .typeck_results()
                         .type_dependent_def_id(e.hir_id)
-                        .is_some_and(|id| self.cx.tcx.is_const_fn(id)) => {},
+                        .is_some_and(|id| is_stable_const_fn(self.cx, id, Msrv::default())) => {},
                 ExprKind::Binary(_, lhs, rhs)
                     if self.cx.typeck_results().expr_ty(lhs).peel_refs().is_primitive_ty()
                         && self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {},
-                ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_ref() => (),
+                ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_raw_ptr() => (),
                 ExprKind::Unary(_, e) if self.cx.typeck_results().expr_ty(e).peel_refs().is_primitive_ty() => (),
                 ExprKind::Index(base, _, _)
                     if matches!(
@@ -388,7 +390,8 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
                 | ExprKind::Repeat(..)
                 | ExprKind::Struct(..)
                 | ExprKind::Tup(_)
-                | ExprKind::Type(..) => (),
+                | ExprKind::Type(..)
+                | ExprKind::UnsafeBinderCast(..) => (),
 
                 _ => {
                     return ControlFlow::Break(());
@@ -676,10 +679,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
                     helper(typeck, true, else_expr, f)?;
                 }
             },
-            ExprKind::Type(e, _) => {
-                helper(typeck, consume, e, f)?;
-            },
-            ExprKind::UnsafeBinderCast(_, e, _) => {
+            ExprKind::Type(e, _) | ExprKind::UnsafeBinderCast(_, e, _) => {
                 helper(typeck, consume, e, f)?;
             },
 
diff --git a/src/tools/clippy/lintcheck/src/config.rs b/src/tools/clippy/lintcheck/src/config.rs
index 83c3d7aba02..3b2ebf0c28a 100644
--- a/src/tools/clippy/lintcheck/src/config.rs
+++ b/src/tools/clippy/lintcheck/src/config.rs
@@ -68,6 +68,9 @@ pub(crate) enum Commands {
         /// This will limit the number of warnings that will be printed for each lint
         #[clap(long)]
         truncate: bool,
+        /// Write the diff summary to a JSON file if there are any changes
+        #[clap(long, value_name = "PATH")]
+        write_summary: Option<PathBuf>,
     },
     /// Create a lintcheck crates TOML file containing the top N popular crates
     Popular {
diff --git a/src/tools/clippy/lintcheck/src/json.rs b/src/tools/clippy/lintcheck/src/json.rs
index 8ea0a41ed36..808997ff022 100644
--- a/src/tools/clippy/lintcheck/src/json.rs
+++ b/src/tools/clippy/lintcheck/src/json.rs
@@ -4,8 +4,8 @@
 //! loading warnings from JSON files, and generating human-readable diffs
 //! between different linting runs.
 
-use std::fs;
-use std::path::Path;
+use std::path::{Path, PathBuf};
+use std::{fmt, fs};
 
 use itertools::{EitherOrBoth, Itertools};
 use serde::{Deserialize, Serialize};
@@ -17,7 +17,6 @@ const DEFAULT_LIMIT_PER_LINT: usize = 300;
 /// Target for total warnings to display across all lints when truncating output.
 const TRUNCATION_TOTAL_TARGET: usize = 1000;
 
-/// Representation of a single Clippy warning for JSON serialization.
 #[derive(Debug, Deserialize, Serialize)]
 struct LintJson {
     /// The lint name e.g. `clippy::bytes_nth`
@@ -29,7 +28,6 @@ struct LintJson {
 }
 
 impl LintJson {
-    /// Returns a tuple of name and `file_line` for sorting and comparison.
     fn key(&self) -> impl Ord + '_ {
         (self.name.as_str(), self.file_line.as_str())
     }
@@ -40,6 +38,57 @@ impl LintJson {
     }
 }
 
+#[derive(Debug, Serialize)]
+struct SummaryRow {
+    name: String,
+    added: usize,
+    removed: usize,
+    changed: usize,
+}
+
+#[derive(Debug, Serialize)]
+struct Summary(Vec<SummaryRow>);
+
+impl fmt::Display for Summary {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(
+            "\
+| Lint | Added | Removed | Changed |
+| ---- | ----: | ------: | ------: |
+",
+        )?;
+
+        for SummaryRow {
+            name,
+            added,
+            changed,
+            removed,
+        } in &self.0
+        {
+            let html_id = to_html_id(name);
+            writeln!(f, "| [`{name}`](#{html_id}) | {added} | {changed} | {removed} |")?;
+        }
+
+        Ok(())
+    }
+}
+
+impl Summary {
+    fn new(lints: &[LintWarnings]) -> Self {
+        Summary(
+            lints
+                .iter()
+                .map(|lint| SummaryRow {
+                    name: lint.name.clone(),
+                    added: lint.added.len(),
+                    removed: lint.removed.len(),
+                    changed: lint.changed.len(),
+                })
+                .collect(),
+        )
+    }
+}
+
 /// Creates the log file output for [`crate::config::OutputFormat::Json`]
 pub(crate) fn output(clippy_warnings: Vec<ClippyWarning>) -> String {
     let mut lints: Vec<LintJson> = clippy_warnings
@@ -74,7 +123,7 @@ fn load_warnings(path: &Path) -> Vec<LintJson> {
 ///
 /// Compares warnings from `old_path` and `new_path`, then displays a summary table
 /// and detailed information about added, removed, and changed warnings.
-pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
+pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool, write_summary: Option<PathBuf>) {
     let old_warnings = load_warnings(old_path);
     let new_warnings = load_warnings(new_path);
 
@@ -108,13 +157,16 @@ pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
         }
     }
 
-    print_summary_table(&lint_warnings);
-    println!();
-
     if lint_warnings.is_empty() {
         return;
     }
 
+    let summary = Summary::new(&lint_warnings);
+    if let Some(path) = write_summary {
+        let json = serde_json::to_string(&summary).unwrap();
+        fs::write(path, json).unwrap();
+    }
+
     let truncate_after = if truncate {
         // Max 15 ensures that we at least have five messages per lint
         DEFAULT_LIMIT_PER_LINT
@@ -126,6 +178,7 @@ pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
         usize::MAX
     };
 
+    println!("{summary}");
     for lint in lint_warnings {
         print_lint_warnings(&lint, truncate_after);
     }
@@ -140,13 +193,11 @@ struct LintWarnings {
     changed: Vec<(LintJson, LintJson)>,
 }
 
-/// Prints a formatted report for a single lint type with its warnings.
 fn print_lint_warnings(lint: &LintWarnings, truncate_after: usize) {
     let name = &lint.name;
     let html_id = to_html_id(name);
 
-    // The additional anchor is added for non GH viewers that don't prefix ID's
-    println!(r#"## `{name}` <a id="user-content-{html_id}"></a>"#);
+    println!(r#"<h2 id="{html_id}"><code>{name}</code></h2>"#);
     println!();
 
     print!(
@@ -162,22 +213,6 @@ fn print_lint_warnings(lint: &LintWarnings, truncate_after: usize) {
     print_changed_diff(&lint.changed, truncate_after / 3);
 }
 
-/// Prints a summary table of all lints with counts of added, removed, and changed warnings.
-fn print_summary_table(lints: &[LintWarnings]) {
-    println!("| Lint                                       | Added   | Removed | Changed |");
-    println!("| ------------------------------------------ | ------: | ------: | ------: |");
-
-    for lint in lints {
-        println!(
-            "| {:<62} | {:>7} | {:>7} | {:>7} |",
-            format!("[`{}`](#user-content-{})", lint.name, to_html_id(&lint.name)),
-            lint.added.len(),
-            lint.removed.len(),
-            lint.changed.len()
-        );
-    }
-}
-
 /// Prints a section of warnings with a header and formatted code blocks.
 fn print_warnings(title: &str, warnings: &[LintJson], truncate_after: usize) {
     if warnings.is_empty() {
@@ -248,17 +283,16 @@ fn truncate<T>(list: &[T], truncate_after: usize) -> &[T] {
     }
 }
 
-/// Prints a level 3 heading with an appropriate HTML ID for linking.
 fn print_h3(lint: &str, title: &str) {
     let html_id = to_html_id(lint);
-    // We have to use HTML here to be able to manually add an id.
-    println!(r#"### {title} <a id="user-content-{html_id}-{title}"></a>"#);
+    // We have to use HTML here to be able to manually add an id, GitHub doesn't add them automatically
+    println!(r#"<h3 id="{html_id}-{title}">{title}</h3>"#);
 }
 
-/// GitHub's markdown parsers doesn't like IDs with `::` and `_`. This simplifies
-/// the lint name for the HTML ID.
+/// Creates a custom ID allowed by GitHub, they must start with `user-content-` and cannot contain
+/// `::`/`_`
 fn to_html_id(lint_name: &str) -> String {
-    lint_name.replace("clippy::", "").replace('_', "-")
+    lint_name.replace("clippy::", "user-content-").replace('_', "-")
 }
 
 /// This generates the `x added` string for the start of the job summery.
@@ -270,9 +304,6 @@ fn count_string(lint: &str, label: &str, count: usize) -> String {
         format!("0 {label}")
     } else {
         let html_id = to_html_id(lint);
-        // GitHub's job summaries don't add HTML ids to headings. That's why we
-        // manually have to add them. GitHub prefixes these manual ids with
-        // `user-content-` and that's how we end up with these awesome links :D
-        format!("[{count} {label}](#user-content-{html_id}-{label})")
+        format!("[{count} {label}](#{html_id}-{label})")
     }
 }
diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs
index eb390eecbcc..3a60cfa79f4 100644
--- a/src/tools/clippy/lintcheck/src/main.rs
+++ b/src/tools/clippy/lintcheck/src/main.rs
@@ -303,7 +303,12 @@ fn main() {
     let config = LintcheckConfig::new();
 
     match config.subcommand {
-        Some(Commands::Diff { old, new, truncate }) => json::diff(&old, &new, truncate),
+        Some(Commands::Diff {
+            old,
+            new,
+            truncate,
+            write_summary,
+        }) => json::diff(&old, &new, truncate, write_summary),
         Some(Commands::Popular { output, number }) => popular_crates::fetch(output, number).unwrap(),
         None => lintcheck(config),
     }
diff --git a/src/tools/clippy/rust-toolchain.toml b/src/tools/clippy/rust-toolchain.toml
index 124756a3600..f46e079db3f 100644
--- a/src/tools/clippy/rust-toolchain.toml
+++ b/src/tools/clippy/rust-toolchain.toml
@@ -1,6 +1,6 @@
 [toolchain]
 # begin autogenerated nightly
-channel = "nightly-2025-06-26"
+channel = "nightly-2025-07-10"
 # end autogenerated nightly
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index cefe654fef6..aa786334711 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -16,8 +16,10 @@ use test_utils::IS_RUSTC_TEST_SUITE;
 use ui_test::custom_flags::Flag;
 use ui_test::custom_flags::edition::Edition;
 use ui_test::custom_flags::rustfix::RustfixMode;
+use ui_test::dependencies::DependencyBuilder;
 use ui_test::spanned::Spanned;
-use ui_test::{Args, CommandBuilder, Config, Match, error_on_output_conflict, status_emitter};
+use ui_test::status_emitter::StatusEmitter;
+use ui_test::{Args, CommandBuilder, Config, Match, error_on_output_conflict};
 
 use std::collections::{BTreeMap, HashMap};
 use std::env::{self, set_var, var_os};
@@ -27,46 +29,26 @@ use std::path::{Path, PathBuf};
 use std::sync::mpsc::{Sender, channel};
 use std::{fs, iter, thread};
 
-// Test dependencies may need an `extern crate` here to ensure that they show up
-// in the depinfo file (otherwise cargo thinks they are unused)
-extern crate futures;
-extern crate if_chain;
-extern crate itertools;
-extern crate parking_lot;
-extern crate quote;
-extern crate syn;
-extern crate tokio;
-
 mod test_utils;
 
-/// All crates used in UI tests are listed here
-static TEST_DEPENDENCIES: &[&str] = &[
-    "clippy_config",
-    "clippy_lints",
-    "clippy_utils",
-    "futures",
-    "if_chain",
-    "itertools",
-    "parking_lot",
-    "quote",
-    "regex",
-    "serde_derive",
-    "serde",
-    "syn",
-    "tokio",
-];
-
-/// Produces a string with an `--extern` flag for all UI test crate
-/// dependencies.
+/// All crates used in internal UI tests are listed here.
+/// We directly re-use these crates from their normal clippy builds, so we don't have them
+/// in `clippy_test_devs`. That saves a lot of time but also means they don't work in a stage 1
+/// test in rustc bootstrap.
+static INTERNAL_TEST_DEPENDENCIES: &[&str] = &["clippy_config", "clippy_lints", "clippy_utils"];
+
+/// Produces a string with an `--extern` flag for all `INTERNAL_TEST_DEPENDENCIES`.
 ///
 /// The dependency files are located by parsing the depinfo file for this test
 /// module. This assumes the `-Z binary-dep-depinfo` flag is enabled. All test
 /// dependencies must be added to Cargo.toml at the project root. Test
 /// dependencies that are not *directly* used by this test module require an
 /// `extern crate` declaration.
-fn extern_flags() -> Vec<String> {
+fn internal_extern_flags() -> Vec<String> {
+    let current_exe_path = env::current_exe().unwrap();
+    let deps_path = current_exe_path.parent().unwrap();
     let current_exe_depinfo = {
-        let mut path = env::current_exe().unwrap();
+        let mut path = current_exe_path.clone();
         path.set_extension("d");
         fs::read_to_string(path).unwrap()
     };
@@ -88,7 +70,7 @@ fn extern_flags() -> Vec<String> {
             Some((name, path_str))
         };
         if let Some((name, path)) = parse_name_path()
-            && TEST_DEPENDENCIES.contains(&name)
+            && INTERNAL_TEST_DEPENDENCIES.contains(&name)
         {
             // A dependency may be listed twice if it is available in sysroot,
             // and the sysroot dependencies are listed first. As of the writing,
@@ -96,7 +78,7 @@ fn extern_flags() -> Vec<String> {
             crates.insert(name, path);
         }
     }
-    let not_found: Vec<&str> = TEST_DEPENDENCIES
+    let not_found: Vec<&str> = INTERNAL_TEST_DEPENDENCIES
         .iter()
         .copied()
         .filter(|n| !crates.contains_key(n))
@@ -111,6 +93,7 @@ fn extern_flags() -> Vec<String> {
     crates
         .into_iter()
         .map(|(name, path)| format!("--extern={name}={path}"))
+        .chain([format!("-Ldependency={}", deps_path.display())])
         .collect()
 }
 
@@ -119,7 +102,6 @@ const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");
 
 struct TestContext {
     args: Args,
-    extern_flags: Vec<String>,
     diagnostic_collector: Option<DiagnosticCollector>,
     collector_thread: Option<thread::JoinHandle<()>>,
 }
@@ -134,7 +116,6 @@ impl TestContext {
             .unzip();
         Self {
             args,
-            extern_flags: extern_flags(),
             diagnostic_collector,
             collector_thread,
         }
@@ -158,6 +139,15 @@ impl TestContext {
         };
         let defaults = config.comment_defaults.base();
         defaults.set_custom("edition", Edition("2024".into()));
+        defaults.set_custom(
+            "dependencies",
+            DependencyBuilder {
+                program: CommandBuilder::cargo(),
+                crate_manifest_path: Path::new("clippy_test_deps").join("Cargo.toml"),
+                build_std: None,
+                bless_lockfile: self.args.bless,
+            },
+        );
         defaults.exit_status = None.into();
         if mandatory_annotations {
             defaults.require_annotations = Some(Spanned::dummy(true)).into();
@@ -182,12 +172,10 @@ impl TestContext {
                 "-Zui-testing",
                 "-Zdeduplicate-diagnostics=no",
                 "-Dwarnings",
-                &format!("-Ldependency={}", deps_path.display()),
             ]
             .map(OsString::from),
         );
 
-        config.program.args.extend(self.extern_flags.iter().map(OsString::from));
         // Prevent rustc from creating `rustc-ice-*` files the console output is enough.
         config.program.envs.push(("RUSTC_ICE".into(), Some("0".into())));
 
@@ -217,7 +205,7 @@ fn run_ui(cx: &TestContext) {
         vec![config],
         ui_test::default_file_filter,
         ui_test::default_per_file_config,
-        status_emitter::Text::from(cx.args.format),
+        Box::<dyn StatusEmitter>::from(cx.args.format),
     )
     .unwrap();
 }
@@ -227,13 +215,17 @@ fn run_internal_tests(cx: &TestContext) {
         return;
     }
     let mut config = cx.base_config("ui-internal", true);
+    config
+        .program
+        .args
+        .extend(internal_extern_flags().iter().map(OsString::from));
     config.bless_command = Some("cargo uitest --features internal -- -- --bless".into());
 
     ui_test::run_tests_generic(
         vec![config],
         ui_test::default_file_filter,
         ui_test::default_per_file_config,
-        status_emitter::Text::from(cx.args.format),
+        Box::<dyn StatusEmitter>::from(cx.args.format),
     )
     .unwrap();
 }
@@ -257,7 +249,7 @@ fn run_ui_toml(cx: &TestContext) {
                 .envs
                 .push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into())));
         },
-        status_emitter::Text::from(cx.args.format),
+        Box::<dyn StatusEmitter>::from(cx.args.format),
     )
     .unwrap();
 }
@@ -304,7 +296,7 @@ fn run_ui_cargo(cx: &TestContext) {
                 .then(|| ui_test::default_any_file_filter(path, config) && !ignored_32bit(path))
         },
         |_config, _file_contents| {},
-        status_emitter::Text::from(cx.args.format),
+        Box::<dyn StatusEmitter>::from(cx.args.format),
     )
     .unwrap();
 }
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
index 20cdff5fcd1..cebfc48a884 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
@@ -450,5 +450,13 @@ help: consider removing the safety comment
 LL |     // SAFETY: unnecessary_safety_comment triggers here
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 52 previous errors
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:733:12
+   |
+LL |     return unsafe { h() };
+   |            ^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: aborting due to 53 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
index 91a02bc3d7c..a2d7c1b6c79 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
@@ -723,4 +723,15 @@ fn issue_13039() {
     _ = unsafe { foo() }
 }
 
+fn rfl_issue15034() -> i32 {
+    unsafe fn h() -> i32 {
+        1i32
+    }
+    // This shouldn't lint with accept-comment-above-attributes! Thus fixing a false positive!
+    // SAFETY: My safety comment!
+    #[allow(clippy::unnecessary_cast)]
+    return unsafe { h() };
+    //~[disabled]^ ERROR: unsafe block missing a safety comment
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.fixed b/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
index 3ba2eea59f0..3f6e5245b87 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
@@ -47,3 +47,9 @@ fn implicit_cast() {
     // Do not lint references to temporaries
     core::ptr::eq(&0i32, &1i32);
 }
+
+fn issue_15141() {
+    let a = String::new();
+    // Don't lint cast to dyn trait pointers
+    let b = &a as *const dyn std::any::Any;
+}
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.rs b/src/tools/clippy/tests/ui/borrow_as_ptr.rs
index 8cdd0512da5..20f4f40e001 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr.rs
@@ -47,3 +47,9 @@ fn implicit_cast() {
     // Do not lint references to temporaries
     core::ptr::eq(&0i32, &1i32);
 }
+
+fn issue_15141() {
+    let a = String::new();
+    // Don't lint cast to dyn trait pointers
+    let b = &a as *const dyn std::any::Any;
+}
diff --git a/src/tools/clippy/tests/ui/cast_size.32bit.stderr b/src/tools/clippy/tests/ui/cast_size.32bit.stderr
index cb1620e36a2..5811cb3607b 100644
--- a/src/tools/clippy/tests/ui/cast_size.32bit.stderr
+++ b/src/tools/clippy/tests/ui/cast_size.32bit.stderr
@@ -177,6 +177,14 @@ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bi
 LL |     9_999_999_999_999_999usize as f64;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: casting `usize` to `u16` may truncate the value
+  --> tests/ui/cast_size.rs:71:20
+   |
+LL |     const N: u16 = M as u16;
+   |                    ^^^^^^^^
+   |
+   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
+
 error: literal out of range for `usize`
   --> tests/ui/cast_size.rs:63:5
    |
@@ -186,5 +194,5 @@ LL |     9_999_999_999_999_999usize as f64;
    = note: the literal `9_999_999_999_999_999usize` does not fit into the type `usize` whose range is `0..=4294967295`
    = note: `#[deny(overflowing_literals)]` on by default
 
-error: aborting due to 19 previous errors
+error: aborting due to 20 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_size.64bit.stderr b/src/tools/clippy/tests/ui/cast_size.64bit.stderr
index b6000a52abb..ba1419583ae 100644
--- a/src/tools/clippy/tests/ui/cast_size.64bit.stderr
+++ b/src/tools/clippy/tests/ui/cast_size.64bit.stderr
@@ -177,5 +177,13 @@ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bi
 LL |     9_999_999_999_999_999usize as f64;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 18 previous errors
+error: casting `usize` to `u16` may truncate the value
+  --> tests/ui/cast_size.rs:71:20
+   |
+LL |     const N: u16 = M as u16;
+   |                    ^^^^^^^^
+   |
+   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
+
+error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_size.rs b/src/tools/clippy/tests/ui/cast_size.rs
index e5bef2a99d5..ecc58669419 100644
--- a/src/tools/clippy/tests/ui/cast_size.rs
+++ b/src/tools/clippy/tests/ui/cast_size.rs
@@ -65,3 +65,9 @@ fn main() {
     //~[32bit]^^ ERROR: literal out of range for `usize`
     // 999_999_999_999_999_999_999_999_999_999u128 as f128;
 }
+
+fn issue15163() {
+    const M: usize = 100;
+    const N: u16 = M as u16;
+    //~^ cast_possible_truncation
+}
diff --git a/src/tools/clippy/tests/ui/coerce_container_to_any.fixed b/src/tools/clippy/tests/ui/coerce_container_to_any.fixed
index ae9d3ef9656..b5b3f15b4de 100644
--- a/src/tools/clippy/tests/ui/coerce_container_to_any.fixed
+++ b/src/tools/clippy/tests/ui/coerce_container_to_any.fixed
@@ -3,7 +3,7 @@
 use std::any::Any;
 
 fn main() {
-    let x: Box<dyn Any> = Box::new(());
+    let mut x: Box<dyn Any> = Box::new(());
     let ref_x = &x;
 
     f(&*x);
@@ -15,12 +15,23 @@ fn main() {
     let _: &dyn Any = &*x;
     //~^ coerce_container_to_any
 
+    let _: &dyn Any = &*x;
+    //~^ coerce_container_to_any
+
+    let _: &mut dyn Any = &mut *x;
+    //~^ coerce_container_to_any
+
     f(&42);
     f(&Box::new(()));
     f(&Box::new(Box::new(())));
+    let ref_x = &x;
     f(&**ref_x);
     f(&*x);
     let _: &dyn Any = &*x;
+
+    // https://github.com/rust-lang/rust-clippy/issues/15045
+    #[allow(clippy::needless_borrow)]
+    (&x).downcast_ref::<()>().unwrap();
 }
 
 fn f(_: &dyn Any) {}
diff --git a/src/tools/clippy/tests/ui/coerce_container_to_any.rs b/src/tools/clippy/tests/ui/coerce_container_to_any.rs
index 9948bd48e0d..4d6527bb552 100644
--- a/src/tools/clippy/tests/ui/coerce_container_to_any.rs
+++ b/src/tools/clippy/tests/ui/coerce_container_to_any.rs
@@ -3,7 +3,7 @@
 use std::any::Any;
 
 fn main() {
-    let x: Box<dyn Any> = Box::new(());
+    let mut x: Box<dyn Any> = Box::new(());
     let ref_x = &x;
 
     f(&x);
@@ -15,12 +15,23 @@ fn main() {
     let _: &dyn Any = &x;
     //~^ coerce_container_to_any
 
+    let _: &dyn Any = &mut x;
+    //~^ coerce_container_to_any
+
+    let _: &mut dyn Any = &mut x;
+    //~^ coerce_container_to_any
+
     f(&42);
     f(&Box::new(()));
     f(&Box::new(Box::new(())));
+    let ref_x = &x;
     f(&**ref_x);
     f(&*x);
     let _: &dyn Any = &*x;
+
+    // https://github.com/rust-lang/rust-clippy/issues/15045
+    #[allow(clippy::needless_borrow)]
+    (&x).downcast_ref::<()>().unwrap();
 }
 
 fn f(_: &dyn Any) {}
diff --git a/src/tools/clippy/tests/ui/coerce_container_to_any.stderr b/src/tools/clippy/tests/ui/coerce_container_to_any.stderr
index 00ab77e0ce0..26389c9186e 100644
--- a/src/tools/clippy/tests/ui/coerce_container_to_any.stderr
+++ b/src/tools/clippy/tests/ui/coerce_container_to_any.stderr
@@ -19,5 +19,17 @@ error: coercing `&std::boxed::Box<dyn std::any::Any>` to `&dyn Any`
 LL |     let _: &dyn Any = &x;
    |                       ^^ help: consider dereferencing: `&*x`
 
-error: aborting due to 3 previous errors
+error: coercing `&mut std::boxed::Box<dyn std::any::Any>` to `&dyn Any`
+  --> tests/ui/coerce_container_to_any.rs:18:23
+   |
+LL |     let _: &dyn Any = &mut x;
+   |                       ^^^^^^ help: consider dereferencing: `&*x`
+
+error: coercing `&mut std::boxed::Box<dyn std::any::Any>` to `&mut dyn Any`
+  --> tests/ui/coerce_container_to_any.rs:21:27
+   |
+LL |     let _: &mut dyn Any = &mut x;
+   |                           ^^^^^^ help: consider dereferencing: `&mut *x`
+
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/disallowed_script_idents.rs b/src/tools/clippy/tests/ui/disallowed_script_idents.rs
index 08fd1d9669e..dae380045ae 100644
--- a/src/tools/clippy/tests/ui/disallowed_script_idents.rs
+++ b/src/tools/clippy/tests/ui/disallowed_script_idents.rs
@@ -15,3 +15,17 @@ fn main() {
     let カウンタ = 10;
     //~^ disallowed_script_idents
 }
+
+fn issue15116() {
+    const ÄÖÜ: u8 = 0;
+    const _ÄÖÜ: u8 = 0;
+    const Ä_ÖÜ: u8 = 0;
+    const ÄÖ_Ü: u8 = 0;
+    const ÄÖÜ_: u8 = 0;
+    let äöüß = 1;
+    let _äöüß = 1;
+    let ä_öüß = 1;
+    let äö_üß = 1;
+    let äöü_ß = 1;
+    let äöüß_ = 1;
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.fixed b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.fixed
index 065f4486e39..5c57c58fbc0 100644
--- a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.fixed
@@ -72,8 +72,6 @@ pub struct NotEmptyTight;
 
 /// ## Heading
 ///
-/// - [x][] - Done
-//~^ ERROR: link reference defined in list item
-/// - [ ][] - Not Done
-//~^ ERROR: link reference defined in list item
+/// - [x] - Done
+/// - [ ] - Not Done
 pub struct GithubCheckboxes;
diff --git a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.rs b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.rs
index c7eab50c8b3..06b6ba49e19 100644
--- a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.rs
+++ b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.rs
@@ -73,7 +73,5 @@ pub struct NotEmptyTight;
 /// ## Heading
 ///
 /// - [x] - Done
-//~^ ERROR: link reference defined in list item
 /// - [ ] - Not Done
-//~^ ERROR: link reference defined in list item
 pub struct GithubCheckboxes;
diff --git a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.stderr b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.stderr
index 5a815dabf4d..27314c7e968 100644
--- a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.stderr
@@ -144,29 +144,5 @@ help: for an intra-doc link, add `[]` between the label and the colon
 LL | /// - [link][]: def "title"
    |             ++
 
-error: link reference defined in list item
-  --> tests/ui/doc/doc_nested_refdef_list_item.rs:75:7
-   |
-LL | /// - [x] - Done
-   |       ^^^
-   |
-   = help: link definitions are not shown in rendered documentation
-help: for an intra-doc link, add `[]` between the label and the colon
-   |
-LL | /// - [x][] - Done
-   |          ++
-
-error: link reference defined in list item
-  --> tests/ui/doc/doc_nested_refdef_list_item.rs:77:7
-   |
-LL | /// - [ ] - Not Done
-   |       ^^^
-   |
-   = help: link definitions are not shown in rendered documentation
-help: for an intra-doc link, add `[]` between the label and the colon
-   |
-LL | /// - [ ][] - Not Done
-   |          ++
-
-error: aborting due to 14 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/empty_loop_intrinsic.rs b/src/tools/clippy/tests/ui/empty_loop_intrinsic.rs
new file mode 100644
index 00000000000..a550e560965
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_loop_intrinsic.rs
@@ -0,0 +1,13 @@
+//@check-pass
+
+#![warn(clippy::empty_loop)]
+#![feature(intrinsics)]
+#![feature(rustc_attrs)]
+
+// From issue #15200
+#[rustc_intrinsic]
+#[rustc_nounwind]
+/// # Safety
+pub const unsafe fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/exit1_compile_flag_test.rs b/src/tools/clippy/tests/ui/exit1_compile_flag_test.rs
new file mode 100644
index 00000000000..9f83ed32533
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit1_compile_flag_test.rs
@@ -0,0 +1,17 @@
+//@compile-flags: --test
+#![warn(clippy::exit)]
+
+fn not_main() {
+    if true {
+        std::process::exit(4);
+        //~^ exit
+    }
+}
+
+fn main() {
+    if true {
+        std::process::exit(2);
+    };
+    not_main();
+    std::process::exit(1);
+}
diff --git a/src/tools/clippy/tests/ui/exit1_compile_flag_test.stderr b/src/tools/clippy/tests/ui/exit1_compile_flag_test.stderr
new file mode 100644
index 00000000000..6e33c39f0d7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit1_compile_flag_test.stderr
@@ -0,0 +1,11 @@
+error: usage of `process::exit`
+  --> tests/ui/exit1_compile_flag_test.rs:6:9
+   |
+LL |         std::process::exit(4);
+   |         ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::exit` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::exit)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/exit2_compile_flag_test.rs b/src/tools/clippy/tests/ui/exit2_compile_flag_test.rs
new file mode 100644
index 00000000000..0b994ebc56c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit2_compile_flag_test.rs
@@ -0,0 +1,15 @@
+//@compile-flags: --test
+#![warn(clippy::exit)]
+
+fn also_not_main() {
+    std::process::exit(3);
+    //~^ exit
+}
+
+fn main() {
+    if true {
+        std::process::exit(2);
+    };
+    also_not_main();
+    std::process::exit(1);
+}
diff --git a/src/tools/clippy/tests/ui/exit2_compile_flag_test.stderr b/src/tools/clippy/tests/ui/exit2_compile_flag_test.stderr
new file mode 100644
index 00000000000..51eb26e9c2a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit2_compile_flag_test.stderr
@@ -0,0 +1,11 @@
+error: usage of `process::exit`
+  --> tests/ui/exit2_compile_flag_test.rs:5:5
+   |
+LL |     std::process::exit(3);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::exit` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::exit)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/exit3_compile_flag_test.rs b/src/tools/clippy/tests/ui/exit3_compile_flag_test.rs
new file mode 100644
index 00000000000..f8131ead2da
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit3_compile_flag_test.rs
@@ -0,0 +1,11 @@
+//@ check-pass
+//@compile-flags: --test
+
+#![warn(clippy::exit)]
+
+fn main() {
+    if true {
+        std::process::exit(2);
+    };
+    std::process::exit(1);
+}
diff --git a/src/tools/clippy/tests/ui/exit4.rs b/src/tools/clippy/tests/ui/exit4.rs
new file mode 100644
index 00000000000..821a26fd78b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit4.rs
@@ -0,0 +1,8 @@
+//@ check-pass
+//@compile-flags: --test
+
+#![warn(clippy::exit)]
+
+fn main() {
+    std::process::exit(0)
+}
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
index 83aeddb2a1f..884bae00432 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
@@ -69,3 +69,47 @@ fn _issue11831() {
 
     let _ = a + b * c;
 }
+
+fn _issue14897() {
+    let x = 1.0;
+    let _ = x * 2.0 + 0.5; // should not suggest mul_add
+    let _ = 0.5 + x * 2.0; // should not suggest mul_add
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+    let _ = 1.2 + x * 1.2; // should not suggest mul_add
+
+    let x = -1.0;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = { 4.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = if 1 > 2 { 1.0 } else { 2.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = 2.4 + 1.2;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let f = || 4.0;
+    let x = f();
+    let _ = 0.5 + f() * 1.2; // should not suggest mul_add
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = 0.1;
+    let y = x;
+    let z = y;
+    let _ = 0.5 + z * 1.2; // should not suggest mul_add
+
+    let _ = 2.0f64.mul_add(x, 0.5);
+    //~^ suboptimal_flops
+    let _ = 2.0f64.mul_add(x, 0.5);
+    //~^ suboptimal_flops
+
+    let _ = 2.0f64.mul_add(4.0, x);
+    //~^ suboptimal_flops
+
+    let y: f64 = 1.0;
+    let _ = y.mul_add(2.0, 0.5);
+    //~^ suboptimal_flops
+    let _ = 1.0f64.mul_add(2.0, 0.5);
+    //~^ suboptimal_flops
+}
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.rs b/src/tools/clippy/tests/ui/floating_point_mul_add.rs
index 039ee8d053f..9ceb2ec9606 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.rs
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.rs
@@ -69,3 +69,47 @@ fn _issue11831() {
 
     let _ = a + b * c;
 }
+
+fn _issue14897() {
+    let x = 1.0;
+    let _ = x * 2.0 + 0.5; // should not suggest mul_add
+    let _ = 0.5 + x * 2.0; // should not suggest mul_add
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+    let _ = 1.2 + x * 1.2; // should not suggest mul_add
+
+    let x = -1.0;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = { 4.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = if 1 > 2 { 1.0 } else { 2.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = 2.4 + 1.2;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let f = || 4.0;
+    let x = f();
+    let _ = 0.5 + f() * 1.2; // should not suggest mul_add
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = 0.1;
+    let y = x;
+    let z = y;
+    let _ = 0.5 + z * 1.2; // should not suggest mul_add
+
+    let _ = 0.5 + 2.0 * x;
+    //~^ suboptimal_flops
+    let _ = 2.0 * x + 0.5;
+    //~^ suboptimal_flops
+
+    let _ = x + 2.0 * 4.0;
+    //~^ suboptimal_flops
+
+    let y: f64 = 1.0;
+    let _ = y * 2.0 + 0.5;
+    //~^ suboptimal_flops
+    let _ = 1.0 * 2.0 + 0.5;
+    //~^ suboptimal_flops
+}
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
index 6482127bcc0..dad65ddf2ec 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
@@ -79,5 +79,35 @@ error: multiply and add expressions can be calculated more efficiently and accur
 LL |     let _ = a - (b * u as f64);
    |             ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)`
 
-error: aborting due to 13 previous errors
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:102:13
+   |
+LL |     let _ = 0.5 + 2.0 * x;
+   |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(x, 0.5)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:104:13
+   |
+LL |     let _ = 2.0 * x + 0.5;
+   |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(x, 0.5)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:107:13
+   |
+LL |     let _ = x + 2.0 * 4.0;
+   |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, x)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:111:13
+   |
+LL |     let _ = y * 2.0 + 0.5;
+   |             ^^^^^^^^^^^^^ help: consider using: `y.mul_add(2.0, 0.5)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:113:13
+   |
+LL |     let _ = 1.0 * 2.0 + 0.5;
+   |             ^^^^^^^^^^^^^^^ help: consider using: `1.0f64.mul_add(2.0, 0.5)`
+
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_is_variant_and.fixed b/src/tools/clippy/tests/ui/manual_is_variant_and.fixed
index 6425f32c09c..65a9cfa6e64 100644
--- a/src/tools/clippy/tests/ui/manual_is_variant_and.fixed
+++ b/src/tools/clippy/tests/ui/manual_is_variant_and.fixed
@@ -61,7 +61,7 @@ fn option_methods() {
 
     let _ = Some(2).is_some_and(|x| x % 2 == 0);
     //~^ manual_is_variant_and
-    let _ = Some(2).is_none_or(|x| x % 2 == 0);
+    let _ = Some(2).is_none_or(|x| x % 2 != 0);
     //~^ manual_is_variant_and
     let _ = Some(2).is_some_and(|x| x % 2 == 0);
     //~^ manual_is_variant_and
@@ -116,3 +116,113 @@ fn main() {
     option_methods();
     result_methods();
 }
+
+fn issue15202() {
+    let xs = [None, Some(b'_'), Some(b'1')];
+    for x in xs {
+        let a1 = x.is_none_or(|b| !b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_none_or(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.is_none_or(|b| b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_none_or(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.is_some_and(|b| b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_some_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.is_some_and(|b| !b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_some_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    let xs = [Err("foo"), Ok(b'_'), Ok(b'1')];
+    for x in xs {
+        let a1 = !x.is_ok_and(|b| b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = !x.is_ok_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = !x.is_ok_and(|b| !b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = !x.is_ok_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.is_ok_and(|b| b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_ok_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.is_ok_and(|b| !b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_ok_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+}
+
+mod with_func {
+    fn iad(b: u8) -> bool {
+        b.is_ascii_digit()
+    }
+
+    fn check_option(b: Option<u8>) {
+        let a1 = b.is_some_and(iad);
+        //~^ manual_is_variant_and
+        let a2 = b.is_some_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = b.is_some_and(|x| !iad(x));
+        //~^ manual_is_variant_and
+        let a2 = b.is_some_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = b.is_none_or(|x| !iad(x));
+        //~^ manual_is_variant_and
+        let a2 = b.is_none_or(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = b.is_none_or(iad);
+        //~^ manual_is_variant_and
+        let a2 = b.is_none_or(iad);
+        assert_eq!(a1, a2);
+    }
+
+    fn check_result(b: Result<u8, ()>) {
+        let a1 = b.is_ok_and(iad);
+        //~^ manual_is_variant_and
+        let a2 = b.is_ok_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = b.is_ok_and(|x| !iad(x));
+        //~^ manual_is_variant_and
+        let a2 = b.is_ok_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = !b.is_ok_and(iad);
+        //~^ manual_is_variant_and
+        let a2 = !b.is_ok_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = !b.is_ok_and(|x| !iad(x));
+        //~^ manual_is_variant_and
+        let a2 = !b.is_ok_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_variant_and.rs b/src/tools/clippy/tests/ui/manual_is_variant_and.rs
index e069e97a04d..85b45d654a7 100644
--- a/src/tools/clippy/tests/ui/manual_is_variant_and.rs
+++ b/src/tools/clippy/tests/ui/manual_is_variant_and.rs
@@ -125,3 +125,113 @@ fn main() {
     option_methods();
     result_methods();
 }
+
+fn issue15202() {
+    let xs = [None, Some(b'_'), Some(b'1')];
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) != Some(true);
+        //~^ manual_is_variant_and
+        let a2 = x.is_none_or(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) != Some(false);
+        //~^ manual_is_variant_and
+        let a2 = x.is_none_or(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) == Some(true);
+        //~^ manual_is_variant_and
+        let a2 = x.is_some_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) == Some(false);
+        //~^ manual_is_variant_and
+        let a2 = x.is_some_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    let xs = [Err("foo"), Ok(b'_'), Ok(b'1')];
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) != Ok(true);
+        //~^ manual_is_variant_and
+        let a2 = !x.is_ok_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) != Ok(false);
+        //~^ manual_is_variant_and
+        let a2 = !x.is_ok_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) == Ok(true);
+        //~^ manual_is_variant_and
+        let a2 = x.is_ok_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) == Ok(false);
+        //~^ manual_is_variant_and
+        let a2 = x.is_ok_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+}
+
+mod with_func {
+    fn iad(b: u8) -> bool {
+        b.is_ascii_digit()
+    }
+
+    fn check_option(b: Option<u8>) {
+        let a1 = b.map(iad) == Some(true);
+        //~^ manual_is_variant_and
+        let a2 = b.is_some_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) == Some(false);
+        //~^ manual_is_variant_and
+        let a2 = b.is_some_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) != Some(true);
+        //~^ manual_is_variant_and
+        let a2 = b.is_none_or(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) != Some(false);
+        //~^ manual_is_variant_and
+        let a2 = b.is_none_or(iad);
+        assert_eq!(a1, a2);
+    }
+
+    fn check_result(b: Result<u8, ()>) {
+        let a1 = b.map(iad) == Ok(true);
+        //~^ manual_is_variant_and
+        let a2 = b.is_ok_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) == Ok(false);
+        //~^ manual_is_variant_and
+        let a2 = b.is_ok_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) != Ok(true);
+        //~^ manual_is_variant_and
+        let a2 = !b.is_ok_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) != Ok(false);
+        //~^ manual_is_variant_and
+        let a2 = !b.is_ok_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_variant_and.stderr b/src/tools/clippy/tests/ui/manual_is_variant_and.stderr
index f770319a268..da36b5a07d2 100644
--- a/src/tools/clippy/tests/ui/manual_is_variant_and.stderr
+++ b/src/tools/clippy/tests/ui/manual_is_variant_and.stderr
@@ -54,7 +54,7 @@ error: called `.map() != Some()`
   --> tests/ui/manual_is_variant_and.rs:70:13
    |
 LL |     let _ = Some(2).map(|x| x % 2 == 0) != Some(true);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_none_or(|x| x % 2 == 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_none_or(|x| x % 2 != 0)`
 
 error: called `.map() == Some()`
   --> tests/ui/manual_is_variant_and.rs:72:13
@@ -126,5 +126,101 @@ error: called `map(<f>).unwrap_or_default()` on a `Result` value
 LL |     let _ = res2.map(char::is_alphanumeric).unwrap_or_default(); // should lint
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_ok_and(char::is_alphanumeric)`
 
-error: aborting due to 15 previous errors
+error: called `.map() != Some()`
+  --> tests/ui/manual_is_variant_and.rs:132:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) != Some(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_none_or(|b| !b.is_ascii_digit())`
+
+error: called `.map() != Some()`
+  --> tests/ui/manual_is_variant_and.rs:139:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) != Some(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_none_or(|b| b.is_ascii_digit())`
+
+error: called `.map() == Some()`
+  --> tests/ui/manual_is_variant_and.rs:146:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) == Some(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_some_and(|b| b.is_ascii_digit())`
+
+error: called `.map() == Some()`
+  --> tests/ui/manual_is_variant_and.rs:153:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) == Some(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_some_and(|b| !b.is_ascii_digit())`
+
+error: called `.map() != Ok()`
+  --> tests/ui/manual_is_variant_and.rs:161:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) != Ok(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!x.is_ok_and(|b| b.is_ascii_digit())`
+
+error: called `.map() != Ok()`
+  --> tests/ui/manual_is_variant_and.rs:168:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) != Ok(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!x.is_ok_and(|b| !b.is_ascii_digit())`
+
+error: called `.map() == Ok()`
+  --> tests/ui/manual_is_variant_and.rs:175:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) == Ok(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_ok_and(|b| b.is_ascii_digit())`
+
+error: called `.map() == Ok()`
+  --> tests/ui/manual_is_variant_and.rs:182:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) == Ok(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_ok_and(|b| !b.is_ascii_digit())`
+
+error: called `.map() == Some()`
+  --> tests/ui/manual_is_variant_and.rs:195:18
+   |
+LL |         let a1 = b.map(iad) == Some(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_some_and(iad)`
+
+error: called `.map() == Some()`
+  --> tests/ui/manual_is_variant_and.rs:200:18
+   |
+LL |         let a1 = b.map(iad) == Some(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_some_and(|x| !iad(x))`
+
+error: called `.map() != Some()`
+  --> tests/ui/manual_is_variant_and.rs:205:18
+   |
+LL |         let a1 = b.map(iad) != Some(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_none_or(|x| !iad(x))`
+
+error: called `.map() != Some()`
+  --> tests/ui/manual_is_variant_and.rs:210:18
+   |
+LL |         let a1 = b.map(iad) != Some(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_none_or(iad)`
+
+error: called `.map() == Ok()`
+  --> tests/ui/manual_is_variant_and.rs:217:18
+   |
+LL |         let a1 = b.map(iad) == Ok(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_ok_and(iad)`
+
+error: called `.map() == Ok()`
+  --> tests/ui/manual_is_variant_and.rs:222:18
+   |
+LL |         let a1 = b.map(iad) == Ok(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_ok_and(|x| !iad(x))`
+
+error: called `.map() != Ok()`
+  --> tests/ui/manual_is_variant_and.rs:227:18
+   |
+LL |         let a1 = b.map(iad) != Ok(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: use: `!b.is_ok_and(iad)`
+
+error: called `.map() != Ok()`
+  --> tests/ui/manual_is_variant_and.rs:232:18
+   |
+LL |         let a1 = b.map(iad) != Ok(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!b.is_ok_and(|x| !iad(x))`
+
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.fixed b/src/tools/clippy/tests/ui/manual_let_else_match.fixed
index 588ba5edd8f..15f604aec29 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.fixed
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.fixed
@@ -137,3 +137,48 @@ fn not_fire() {
 fn issue11579() {
     let Some(msg) = Some("hi") else { unreachable!("can't happen") };
 }
+
+#[derive(Clone, Copy)]
+struct Issue9939<T> {
+    avalanche: T,
+}
+
+fn issue9939() {
+    let issue = Some(Issue9939 { avalanche: 1 });
+    let Some(Issue9939 { avalanche: tornado }) = issue else { unreachable!("can't happen") };
+    let issue = Some(Issue9939 { avalanche: true });
+    let Some(Issue9939 { avalanche: acid_rain }) = issue else { unreachable!("can't happen") };
+    assert_eq!(tornado, 1);
+    assert!(acid_rain);
+
+    // without shadowing
+    let _x @ Some(Issue9939 { avalanche: _y }) = issue else { unreachable!("can't happen") };
+
+    // with shadowing
+    let Some(Issue9939 { avalanche: _x }) = issue else { unreachable!("can't happen") };
+}
+
+#[derive(Clone, Copy)]
+struct Issue9939b<T, U> {
+    earthquake: T,
+    hurricane: U,
+}
+
+fn issue9939b() {
+    let issue = Some(Issue9939b {
+        earthquake: true,
+        hurricane: 1,
+    });
+    let issue @ Some(Issue9939b { earthquake: flood, hurricane: drought }) = issue else { unreachable!("can't happen") };
+    assert_eq!(drought, 1);
+    assert!(flood);
+    assert!(issue.is_some());
+
+    // without shadowing
+    let _x @ Some(Issue9939b { earthquake: erosion, hurricane: _y }) = issue else { unreachable!("can't happen") };
+    assert!(erosion);
+
+    // with shadowing
+    let Some(Issue9939b { earthquake: erosion, hurricane: _x }) = issue else { unreachable!("can't happen") };
+    assert!(erosion);
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.rs b/src/tools/clippy/tests/ui/manual_let_else_match.rs
index 6416753bac1..44a044b142b 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.rs
@@ -177,3 +177,76 @@ fn issue11579() {
         _ => unreachable!("can't happen"),
     };
 }
+
+#[derive(Clone, Copy)]
+struct Issue9939<T> {
+    avalanche: T,
+}
+
+fn issue9939() {
+    let issue = Some(Issue9939 { avalanche: 1 });
+    let tornado = match issue {
+        //~^ manual_let_else
+        Some(Issue9939 { avalanche }) => avalanche,
+        _ => unreachable!("can't happen"),
+    };
+    let issue = Some(Issue9939 { avalanche: true });
+    let acid_rain = match issue {
+        //~^ manual_let_else
+        Some(Issue9939 { avalanche: tornado }) => tornado,
+        _ => unreachable!("can't happen"),
+    };
+    assert_eq!(tornado, 1);
+    assert!(acid_rain);
+
+    // without shadowing
+    let _y = match issue {
+        //~^ manual_let_else
+        _x @ Some(Issue9939 { avalanche }) => avalanche,
+        None => unreachable!("can't happen"),
+    };
+
+    // with shadowing
+    let _x = match issue {
+        //~^ manual_let_else
+        _x @ Some(Issue9939 { avalanche }) => avalanche,
+        None => unreachable!("can't happen"),
+    };
+}
+
+#[derive(Clone, Copy)]
+struct Issue9939b<T, U> {
+    earthquake: T,
+    hurricane: U,
+}
+
+fn issue9939b() {
+    let issue = Some(Issue9939b {
+        earthquake: true,
+        hurricane: 1,
+    });
+    let (issue, drought, flood) = match issue {
+        //~^ manual_let_else
+        flood @ Some(Issue9939b { earthquake, hurricane }) => (flood, hurricane, earthquake),
+        None => unreachable!("can't happen"),
+    };
+    assert_eq!(drought, 1);
+    assert!(flood);
+    assert!(issue.is_some());
+
+    // without shadowing
+    let (_y, erosion) = match issue {
+        //~^ manual_let_else
+        _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),
+        None => unreachable!("can't happen"),
+    };
+    assert!(erosion);
+
+    // with shadowing
+    let (_x, erosion) = match issue {
+        //~^ manual_let_else
+        _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),
+        None => unreachable!("can't happen"),
+    };
+    assert!(erosion);
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.stderr b/src/tools/clippy/tests/ui/manual_let_else_match.stderr
index 393562c629b..ed6117ebffb 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.stderr
@@ -101,5 +101,75 @@ LL | |         _ => unreachable!("can't happen"),
 LL | |     };
    | |______^ help: consider writing: `let Some(msg) = Some("hi") else { unreachable!("can't happen") };`
 
-error: aborting due to 10 previous errors
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:188:5
+   |
+LL | /     let tornado = match issue {
+LL | |
+LL | |         Some(Issue9939 { avalanche }) => avalanche,
+LL | |         _ => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let Some(Issue9939 { avalanche: tornado }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:194:5
+   |
+LL | /     let acid_rain = match issue {
+LL | |
+LL | |         Some(Issue9939 { avalanche: tornado }) => tornado,
+LL | |         _ => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let Some(Issue9939 { avalanche: acid_rain }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:203:5
+   |
+LL | /     let _y = match issue {
+LL | |
+LL | |         _x @ Some(Issue9939 { avalanche }) => avalanche,
+LL | |         None => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let _x @ Some(Issue9939 { avalanche: _y }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:210:5
+   |
+LL | /     let _x = match issue {
+LL | |
+LL | |         _x @ Some(Issue9939 { avalanche }) => avalanche,
+LL | |         None => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let Some(Issue9939 { avalanche: _x }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:228:5
+   |
+LL | /     let (issue, drought, flood) = match issue {
+LL | |
+LL | |         flood @ Some(Issue9939b { earthquake, hurricane }) => (flood, hurricane, earthquake),
+LL | |         None => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let issue @ Some(Issue9939b { earthquake: flood, hurricane: drought }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:238:5
+   |
+LL | /     let (_y, erosion) = match issue {
+LL | |
+LL | |         _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),
+LL | |         None => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let _x @ Some(Issue9939b { earthquake: erosion, hurricane: _y }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:246:5
+   |
+LL | /     let (_x, erosion) = match issue {
+LL | |
+LL | |         _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),
+LL | |         None => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let Some(Issue9939b { earthquake: erosion, hurricane: _x }) = issue else { unreachable!("can't happen") };`
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/missing_panics_doc.rs b/src/tools/clippy/tests/ui/missing_panics_doc.rs
index ffdae8504f7..d016e099e30 100644
--- a/src/tools/clippy/tests/ui/missing_panics_doc.rs
+++ b/src/tools/clippy/tests/ui/missing_panics_doc.rs
@@ -250,3 +250,31 @@ pub fn issue_12760<const N: usize>() {
         }
     }
 }
+
+/// This needs documenting
+pub fn unwrap_expect_etc_in_const() {
+    let a = const { std::num::NonZeroUsize::new(1).unwrap() };
+    // This should still pass the lint even if it is guaranteed to panic at compile-time
+    let b = const { std::num::NonZeroUsize::new(0).unwrap() };
+}
+
+/// This needs documenting
+pub const fn unwrap_expect_etc_in_const_fn_fails() {
+    //~^ missing_panics_doc
+    let a = std::num::NonZeroUsize::new(1).unwrap();
+}
+
+/// This needs documenting
+pub const fn assert_in_const_fn_fails() {
+    //~^ missing_panics_doc
+    let x = 0;
+    if x == 0 {
+        panic!();
+    }
+}
+
+/// This needs documenting
+pub const fn in_const_fn<const N: usize>(n: usize) {
+    //~^ missing_panics_doc
+    assert!(N > n);
+}
diff --git a/src/tools/clippy/tests/ui/missing_panics_doc.stderr b/src/tools/clippy/tests/ui/missing_panics_doc.stderr
index 7f0acf8de9b..85a00914427 100644
--- a/src/tools/clippy/tests/ui/missing_panics_doc.stderr
+++ b/src/tools/clippy/tests/ui/missing_panics_doc.stderr
@@ -180,5 +180,41 @@ note: first possible panic found here
 LL |         *v.last().expect("passed an empty thing")
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 15 previous errors
+error: docs for function which may panic missing `# Panics` section
+  --> tests/ui/missing_panics_doc.rs:262:1
+   |
+LL | pub const fn unwrap_expect_etc_in_const_fn_fails() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first possible panic found here
+  --> tests/ui/missing_panics_doc.rs:264:13
+   |
+LL |     let a = std::num::NonZeroUsize::new(1).unwrap();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: docs for function which may panic missing `# Panics` section
+  --> tests/ui/missing_panics_doc.rs:268:1
+   |
+LL | pub const fn assert_in_const_fn_fails() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first possible panic found here
+  --> tests/ui/missing_panics_doc.rs:272:9
+   |
+LL |         panic!();
+   |         ^^^^^^^^
+
+error: docs for function which may panic missing `# Panics` section
+  --> tests/ui/missing_panics_doc.rs:277:1
+   |
+LL | pub const fn in_const_fn<const N: usize>(n: usize) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first possible panic found here
+  --> tests/ui/missing_panics_doc.rs:279:5
+   |
+LL |     assert!(N > n);
+   |     ^^^^^^^^^^^^^^
+
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.fixed b/src/tools/clippy/tests/ui/needless_bool_assign.fixed
index e0c717ecda2..d6fab4c51b5 100644
--- a/src/tools/clippy/tests/ui/needless_bool_assign.fixed
+++ b/src/tools/clippy/tests/ui/needless_bool_assign.fixed
@@ -33,3 +33,12 @@ fn main() {
         b = true;
     }
 }
+
+fn issue15063(x: bool, y: bool) {
+    let mut z = false;
+
+    if x && y {
+        todo!()
+    } else { z = x || y; }
+    //~^^^^^ needless_bool_assign
+}
diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.rs b/src/tools/clippy/tests/ui/needless_bool_assign.rs
index 3e4fecefa78..c504f61f4dd 100644
--- a/src/tools/clippy/tests/ui/needless_bool_assign.rs
+++ b/src/tools/clippy/tests/ui/needless_bool_assign.rs
@@ -45,3 +45,16 @@ fn main() {
         b = true;
     }
 }
+
+fn issue15063(x: bool, y: bool) {
+    let mut z = false;
+
+    if x && y {
+        todo!()
+    } else if x || y {
+        z = true;
+    } else {
+        z = false;
+    }
+    //~^^^^^ needless_bool_assign
+}
diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.stderr b/src/tools/clippy/tests/ui/needless_bool_assign.stderr
index f33a4bc0c59..1d09b8b25a0 100644
--- a/src/tools/clippy/tests/ui/needless_bool_assign.stderr
+++ b/src/tools/clippy/tests/ui/needless_bool_assign.stderr
@@ -51,5 +51,16 @@ LL | |     }
    = note: `-D clippy::if-same-then-else` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]`
 
-error: aborting due to 4 previous errors
+error: this if-then-else expression assigns a bool literal
+  --> tests/ui/needless_bool_assign.rs:54:12
+   |
+LL |       } else if x || y {
+   |  ____________^
+LL | |         z = true;
+LL | |     } else {
+LL | |         z = false;
+LL | |     }
+   | |_____^ help: you can reduce it to: `{ z = x || y; }`
+
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/neg_multiply.fixed b/src/tools/clippy/tests/ui/neg_multiply.fixed
index ff6e08300e2..32d466e88fc 100644
--- a/src/tools/clippy/tests/ui/neg_multiply.fixed
+++ b/src/tools/clippy/tests/ui/neg_multiply.fixed
@@ -82,3 +82,15 @@ fn float() {
 
     -1.0 * -1.0; // should be ok
 }
+
+struct Y {
+    delta: f64,
+}
+
+fn nested() {
+    let a = Y { delta: 1.0 };
+    let b = Y { delta: 1.0 };
+    let _ = (-(a.delta - 0.5).abs()).total_cmp(&1.0);
+    //~^ neg_multiply
+    let _ = (-(a.delta - 0.5).abs()).total_cmp(&1.0);
+}
diff --git a/src/tools/clippy/tests/ui/neg_multiply.rs b/src/tools/clippy/tests/ui/neg_multiply.rs
index b0f4e85c78e..241a72c6d99 100644
--- a/src/tools/clippy/tests/ui/neg_multiply.rs
+++ b/src/tools/clippy/tests/ui/neg_multiply.rs
@@ -82,3 +82,15 @@ fn float() {
 
     -1.0 * -1.0; // should be ok
 }
+
+struct Y {
+    delta: f64,
+}
+
+fn nested() {
+    let a = Y { delta: 1.0 };
+    let b = Y { delta: 1.0 };
+    let _ = ((a.delta - 0.5).abs() * -1.0).total_cmp(&1.0);
+    //~^ neg_multiply
+    let _ = (-(a.delta - 0.5).abs()).total_cmp(&1.0);
+}
diff --git a/src/tools/clippy/tests/ui/neg_multiply.stderr b/src/tools/clippy/tests/ui/neg_multiply.stderr
index 2ef7e32ce05..f4fb6d3ce54 100644
--- a/src/tools/clippy/tests/ui/neg_multiply.stderr
+++ b/src/tools/clippy/tests/ui/neg_multiply.stderr
@@ -97,5 +97,11 @@ error: this multiplication by -1 can be written more succinctly
 LL |     (3.0_f32 as f64) * -1.0;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `-(3.0_f32 as f64)`
 
-error: aborting due to 16 previous errors
+error: this multiplication by -1 can be written more succinctly
+  --> tests/ui/neg_multiply.rs:93:13
+   |
+LL |     let _ = ((a.delta - 0.5).abs() * -1.0).total_cmp(&1.0);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-(a.delta - 0.5).abs())`
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/op_ref.fixed b/src/tools/clippy/tests/ui/op_ref.fixed
index f412190b9fd..4bf4b91888c 100644
--- a/src/tools/clippy/tests/ui/op_ref.fixed
+++ b/src/tools/clippy/tests/ui/op_ref.fixed
@@ -110,3 +110,37 @@ mod issue_2597 {
         &array[idx] < val
     }
 }
+
+#[allow(clippy::needless_if)]
+fn issue15063() {
+    use std::ops::BitAnd;
+
+    macro_rules! mac {
+        ($e:expr) => {
+            $e.clone()
+        };
+    }
+
+    let x = 1;
+    if x == mac!(1) {}
+    //~^ op_ref
+
+    #[derive(Copy, Clone)]
+    struct Y(i32);
+    impl BitAnd for Y {
+        type Output = Y;
+        fn bitand(self, rhs: Y) -> Y {
+            Y(self.0 & rhs.0)
+        }
+    }
+    impl<'a> BitAnd<&'a Y> for Y {
+        type Output = Y;
+        fn bitand(self, rhs: &'a Y) -> Y {
+            Y(self.0 & rhs.0)
+        }
+    }
+    let x = Y(1);
+    let y = Y(2);
+    let z = x & mac!(y);
+    //~^ op_ref
+}
diff --git a/src/tools/clippy/tests/ui/op_ref.rs b/src/tools/clippy/tests/ui/op_ref.rs
index a4bbd86c7e9..9a192661aaf 100644
--- a/src/tools/clippy/tests/ui/op_ref.rs
+++ b/src/tools/clippy/tests/ui/op_ref.rs
@@ -110,3 +110,37 @@ mod issue_2597 {
         &array[idx] < val
     }
 }
+
+#[allow(clippy::needless_if)]
+fn issue15063() {
+    use std::ops::BitAnd;
+
+    macro_rules! mac {
+        ($e:expr) => {
+            $e.clone()
+        };
+    }
+
+    let x = 1;
+    if &x == &mac!(1) {}
+    //~^ op_ref
+
+    #[derive(Copy, Clone)]
+    struct Y(i32);
+    impl BitAnd for Y {
+        type Output = Y;
+        fn bitand(self, rhs: Y) -> Y {
+            Y(self.0 & rhs.0)
+        }
+    }
+    impl<'a> BitAnd<&'a Y> for Y {
+        type Output = Y;
+        fn bitand(self, rhs: &'a Y) -> Y {
+            Y(self.0 & rhs.0)
+        }
+    }
+    let x = Y(1);
+    let y = Y(2);
+    let z = x & &mac!(y);
+    //~^ op_ref
+}
diff --git a/src/tools/clippy/tests/ui/op_ref.stderr b/src/tools/clippy/tests/ui/op_ref.stderr
index 51c2963a9ee..8a58b154c81 100644
--- a/src/tools/clippy/tests/ui/op_ref.stderr
+++ b/src/tools/clippy/tests/ui/op_ref.stderr
@@ -36,5 +36,25 @@ LL |         let _ = two + &three;
    |                       |
    |                       help: use the right value directly: `three`
 
-error: aborting due to 4 previous errors
+error: needlessly taken reference of both operands
+  --> tests/ui/op_ref.rs:125:8
+   |
+LL |     if &x == &mac!(1) {}
+   |        ^^^^^^^^^^^^^^
+   |
+help: use the values directly
+   |
+LL -     if &x == &mac!(1) {}
+LL +     if x == mac!(1) {}
+   |
+
+error: taken reference of right operand
+  --> tests/ui/op_ref.rs:144:13
+   |
+LL |     let z = x & &mac!(y);
+   |             ^^^^--------
+   |                 |
+   |                 help: use the right value directly: `mac!(y)`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed
index 34f3e046841..bcd2602edb6 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/or_fun_call.fixed
@@ -439,4 +439,24 @@ fn test_option_get_or_insert() {
     //~^ or_fun_call
 }
 
+fn test_option_and() {
+    // assume that this is slow call
+    fn g() -> Option<u8> {
+        Some(99)
+    }
+    let mut x = Some(42_u8);
+    let _ = x.and_then(|_| g());
+    //~^ or_fun_call
+}
+
+fn test_result_and() {
+    // assume that this is slow call
+    fn g() -> Result<u8, ()> {
+        Ok(99)
+    }
+    let mut x: Result<u8, ()> = Ok(42);
+    let _ = x.and_then(|_| g());
+    //~^ or_fun_call
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.rs b/src/tools/clippy/tests/ui/or_fun_call.rs
index dc57bd6060a..8d1202ebf91 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.rs
+++ b/src/tools/clippy/tests/ui/or_fun_call.rs
@@ -439,4 +439,24 @@ fn test_option_get_or_insert() {
     //~^ or_fun_call
 }
 
+fn test_option_and() {
+    // assume that this is slow call
+    fn g() -> Option<u8> {
+        Some(99)
+    }
+    let mut x = Some(42_u8);
+    let _ = x.and(g());
+    //~^ or_fun_call
+}
+
+fn test_result_and() {
+    // assume that this is slow call
+    fn g() -> Result<u8, ()> {
+        Ok(99)
+    }
+    let mut x: Result<u8, ()> = Ok(42);
+    let _ = x.and(g());
+    //~^ or_fun_call
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr
index 0f159fe8bff..585ee2d0e19 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/or_fun_call.stderr
@@ -264,5 +264,17 @@ error: function call inside of `get_or_insert`
 LL |     let _ = x.get_or_insert(g());
    |               ^^^^^^^^^^^^^^^^^^ help: try: `get_or_insert_with(g)`
 
-error: aborting due to 41 previous errors
+error: function call inside of `and`
+  --> tests/ui/or_fun_call.rs:448:15
+   |
+LL |     let _ = x.and(g());
+   |               ^^^^^^^^ help: try: `and_then(|_| g())`
+
+error: function call inside of `and`
+  --> tests/ui/or_fun_call.rs:458:15
+   |
+LL |     let _ = x.and(g());
+   |               ^^^^^^^^ help: try: `and_then(|_| g())`
+
+error: aborting due to 43 previous errors
 
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
index 099c118e64e..9f6643e8d52 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
@@ -60,7 +60,7 @@ fn issue9956() {
     //~^ redundant_closure_call
 
     // immediately calling only one closure, so we can't remove the other ones
-    let a = (|| || 123);
+    let a = || || 123;
     //~^ redundant_closure_call
     dbg!(a()());
 
@@ -144,3 +144,15 @@ fn issue_12358() {
     // different.
     make_closure!(x)();
 }
+
+#[rustfmt::skip]
+fn issue_9583() {
+    Some(true) == Some(true);
+     //~^ redundant_closure_call
+    Some(true) == Some(true);
+    //~^ redundant_closure_call
+    Some(if 1 > 2 {1} else {2}) == Some(2);
+    //~^ redundant_closure_call
+    Some( 1 > 2 ) == Some(true);
+    //~^ redundant_closure_call
+}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
index da5dd7ef263..34f22878678 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
@@ -144,3 +144,15 @@ fn issue_12358() {
     // different.
     make_closure!(x)();
 }
+
+#[rustfmt::skip]
+fn issue_9583() {
+    (|| { Some(true) })() == Some(true);
+     //~^ redundant_closure_call
+    (|| Some(true))() == Some(true);
+    //~^ redundant_closure_call
+    (|| { Some(if 1 > 2 {1} else {2}) })() == Some(2);
+    //~^ redundant_closure_call
+    (|| { Some( 1 > 2 ) })() == Some(true);
+    //~^ redundant_closure_call
+}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
index 2c35aafbe31..a5591cf7813 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
@@ -95,7 +95,7 @@ error: try not to call a closure in the expression where it is declared
   --> tests/ui/redundant_closure_call_fixable.rs:63:13
    |
 LL |     let a = (|| || || 123)();
-   |             ^^^^^^^^^^^^^^^^ help: try doing something like: `(|| || 123)`
+   |             ^^^^^^^^^^^^^^^^ help: try doing something like: `|| || 123`
 
 error: try not to call a closure in the expression where it is declared
   --> tests/ui/redundant_closure_call_fixable.rs:68:13
@@ -145,5 +145,29 @@ error: try not to call a closure in the expression where it is declared
 LL |     std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();
    |                            ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32`
 
-error: aborting due to 17 previous errors
+error: try not to call a closure in the expression where it is declared
+  --> tests/ui/redundant_closure_call_fixable.rs:150:5
+   |
+LL |     (|| { Some(true) })() == Some(true);
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(true)`
+
+error: try not to call a closure in the expression where it is declared
+  --> tests/ui/redundant_closure_call_fixable.rs:152:5
+   |
+LL |     (|| Some(true))() == Some(true);
+   |     ^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(true)`
+
+error: try not to call a closure in the expression where it is declared
+  --> tests/ui/redundant_closure_call_fixable.rs:154:5
+   |
+LL |     (|| { Some(if 1 > 2 {1} else {2}) })() == Some(2);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(if 1 > 2 {1} else {2})`
+
+error: try not to call a closure in the expression where it is declared
+  --> tests/ui/redundant_closure_call_fixable.rs:156:5
+   |
+LL |     (|| { Some( 1 > 2 ) })() == Some(true);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some( 1 > 2 )`
+
+error: aborting due to 21 previous errors
 
diff --git a/src/tools/clippy/tests/ui/return_and_then.fixed b/src/tools/clippy/tests/ui/return_and_then.fixed
index 8d9481d1595..8ee259b97f3 100644
--- a/src/tools/clippy/tests/ui/return_and_then.fixed
+++ b/src/tools/clippy/tests/ui/return_and_then.fixed
@@ -99,6 +99,92 @@ fn main() {
         };
         None
     }
+
+    #[expect(clippy::diverging_sub_expression)]
+    fn with_return_in_expression() -> Option<i32> {
+        _ = (
+            return {
+                let x = Some("")?;
+                if x.len() > 2 { Some(3) } else { None }
+            },
+            //~^ return_and_then
+            10,
+        );
+    }
+
+    fn inside_if(a: bool, i: Option<u32>) -> Option<u32> {
+        if a {
+            let i = i?;
+            if i > 3 { Some(i) } else { None }
+            //~^ return_and_then
+        } else {
+            Some(42)
+        }
+    }
+
+    fn inside_match(a: u32, i: Option<u32>) -> Option<u32> {
+        match a {
+            1 | 2 => {
+                let i = i?;
+                if i > 3 { Some(i) } else { None }
+            },
+            //~^ return_and_then
+            3 | 4 => Some(42),
+            _ => None,
+        }
+    }
+
+    fn inside_match_and_block_and_if(a: u32, i: Option<u32>) -> Option<u32> {
+        match a {
+            1 | 2 => {
+                let a = a * 3;
+                if a.is_multiple_of(2) {
+                    let i = i?;
+                    if i > 3 { Some(i) } else { None }
+                    //~^ return_and_then
+                } else {
+                    Some(10)
+                }
+            },
+            3 | 4 => Some(42),
+            _ => None,
+        }
+    }
+
+    #[expect(clippy::never_loop)]
+    fn with_break(i: Option<u32>) -> Option<u32> {
+        match i {
+            Some(1) => loop {
+                break ({
+                    let i = i?;
+                    if i > 3 { Some(i) } else { None }
+                });
+                //~^ return_and_then
+            },
+            Some(2) => 'foo: loop {
+                loop {
+                    break 'foo ({
+                        let i = i?;
+                        if i > 3 { Some(i) } else { None }
+                    });
+                    //~^ return_and_then
+                }
+            },
+            Some(3) => 'bar: {
+                break 'bar ({
+                    let i = i?;
+                    if i > 3 { Some(i) } else { None }
+                });
+                //~^ return_and_then
+            },
+            Some(4) => 'baz: loop {
+                _ = loop {
+                    break i.and_then(|i| if i > 3 { Some(i) } else { None });
+                };
+            },
+            _ => None,
+        }
+    }
 }
 
 fn gen_option(n: i32) -> Option<i32> {
@@ -124,3 +210,48 @@ mod issue14781 {
         Ok(())
     }
 }
+
+mod issue15111 {
+    #[derive(Debug)]
+    struct EvenOdd {
+        even: Option<u32>,
+        odd: Option<u32>,
+    }
+
+    impl EvenOdd {
+        fn new(i: Option<u32>) -> Self {
+            Self {
+                even: i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }),
+                odd: i.and_then(|i| if i.is_multiple_of(2) { None } else { Some(i) }),
+            }
+        }
+    }
+
+    fn with_if_let(i: Option<u32>) -> u32 {
+        if let Some(x) = i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }) {
+            x
+        } else {
+            std::hint::black_box(0)
+        }
+    }
+
+    fn main() {
+        let _ = EvenOdd::new(Some(2));
+    }
+}
+
+mod issue14927 {
+    use std::path::Path;
+    struct A {
+        pub func: fn(check: bool, a: &Path, b: Option<&Path>),
+    }
+    const MY_A: A = A {
+        func: |check, a, b| {
+            if check {
+                let _ = ();
+            } else if let Some(parent) = b.and_then(|p| p.parent()) {
+                let _ = ();
+            }
+        },
+    };
+}
diff --git a/src/tools/clippy/tests/ui/return_and_then.rs b/src/tools/clippy/tests/ui/return_and_then.rs
index beada921a91..dcb344f142b 100644
--- a/src/tools/clippy/tests/ui/return_and_then.rs
+++ b/src/tools/clippy/tests/ui/return_and_then.rs
@@ -90,6 +90,75 @@ fn main() {
         };
         None
     }
+
+    #[expect(clippy::diverging_sub_expression)]
+    fn with_return_in_expression() -> Option<i32> {
+        _ = (
+            return Some("").and_then(|x| if x.len() > 2 { Some(3) } else { None }),
+            //~^ return_and_then
+            10,
+        );
+    }
+
+    fn inside_if(a: bool, i: Option<u32>) -> Option<u32> {
+        if a {
+            i.and_then(|i| if i > 3 { Some(i) } else { None })
+            //~^ return_and_then
+        } else {
+            Some(42)
+        }
+    }
+
+    fn inside_match(a: u32, i: Option<u32>) -> Option<u32> {
+        match a {
+            1 | 2 => i.and_then(|i| if i > 3 { Some(i) } else { None }),
+            //~^ return_and_then
+            3 | 4 => Some(42),
+            _ => None,
+        }
+    }
+
+    fn inside_match_and_block_and_if(a: u32, i: Option<u32>) -> Option<u32> {
+        match a {
+            1 | 2 => {
+                let a = a * 3;
+                if a.is_multiple_of(2) {
+                    i.and_then(|i| if i > 3 { Some(i) } else { None })
+                    //~^ return_and_then
+                } else {
+                    Some(10)
+                }
+            },
+            3 | 4 => Some(42),
+            _ => None,
+        }
+    }
+
+    #[expect(clippy::never_loop)]
+    fn with_break(i: Option<u32>) -> Option<u32> {
+        match i {
+            Some(1) => loop {
+                break i.and_then(|i| if i > 3 { Some(i) } else { None });
+                //~^ return_and_then
+            },
+            Some(2) => 'foo: loop {
+                loop {
+                    break 'foo i.and_then(|i| if i > 3 { Some(i) } else { None });
+                    //~^ return_and_then
+                }
+            },
+            Some(3) => 'bar: {
+                break 'bar i.and_then(|i| if i > 3 { Some(i) } else { None });
+                //~^ return_and_then
+            },
+            Some(4) => 'baz: loop {
+                _ = loop {
+                    break i.and_then(|i| if i > 3 { Some(i) } else { None });
+                };
+            },
+            _ => None,
+        }
+    }
 }
 
 fn gen_option(n: i32) -> Option<i32> {
@@ -115,3 +184,48 @@ mod issue14781 {
         Ok(())
     }
 }
+
+mod issue15111 {
+    #[derive(Debug)]
+    struct EvenOdd {
+        even: Option<u32>,
+        odd: Option<u32>,
+    }
+
+    impl EvenOdd {
+        fn new(i: Option<u32>) -> Self {
+            Self {
+                even: i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }),
+                odd: i.and_then(|i| if i.is_multiple_of(2) { None } else { Some(i) }),
+            }
+        }
+    }
+
+    fn with_if_let(i: Option<u32>) -> u32 {
+        if let Some(x) = i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }) {
+            x
+        } else {
+            std::hint::black_box(0)
+        }
+    }
+
+    fn main() {
+        let _ = EvenOdd::new(Some(2));
+    }
+}
+
+mod issue14927 {
+    use std::path::Path;
+    struct A {
+        pub func: fn(check: bool, a: &Path, b: Option<&Path>),
+    }
+    const MY_A: A = A {
+        func: |check, a, b| {
+            if check {
+                let _ = ();
+            } else if let Some(parent) = b.and_then(|p| p.parent()) {
+                let _ = ();
+            }
+        },
+    };
+}
diff --git a/src/tools/clippy/tests/ui/return_and_then.stderr b/src/tools/clippy/tests/ui/return_and_then.stderr
index 5feca882860..33867ea818a 100644
--- a/src/tools/clippy/tests/ui/return_and_then.stderr
+++ b/src/tools/clippy/tests/ui/return_and_then.stderr
@@ -146,5 +146,99 @@ LL +                 if x.len() > 2 { Some(3) } else { None }
 LL ~             };
    |
 
-error: aborting due to 10 previous errors
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:97:20
+   |
+LL |             return Some("").and_then(|x| if x.len() > 2 { Some(3) } else { None }),
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~             return {
+LL +                 let x = Some("")?;
+LL +                 if x.len() > 2 { Some(3) } else { None }
+LL ~             },
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:105:13
+   |
+LL |             i.and_then(|i| if i > 3 { Some(i) } else { None })
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~             let i = i?;
+LL +             if i > 3 { Some(i) } else { None }
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:114:22
+   |
+LL |             1 | 2 => i.and_then(|i| if i > 3 { Some(i) } else { None }),
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~             1 | 2 => {
+LL +                 let i = i?;
+LL +                 if i > 3 { Some(i) } else { None }
+LL ~             },
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:126:21
+   |
+LL |                     i.and_then(|i| if i > 3 { Some(i) } else { None })
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~                     let i = i?;
+LL +                     if i > 3 { Some(i) } else { None }
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:141:23
+   |
+LL |                 break i.and_then(|i| if i > 3 { Some(i) } else { None });
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~                 break ({
+LL +                     let i = i?;
+LL +                     if i > 3 { Some(i) } else { None }
+LL ~                 });
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:146:32
+   |
+LL |                     break 'foo i.and_then(|i| if i > 3 { Some(i) } else { None });
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~                     break 'foo ({
+LL +                         let i = i?;
+LL +                         if i > 3 { Some(i) } else { None }
+LL ~                     });
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:151:28
+   |
+LL |                 break 'bar i.and_then(|i| if i > 3 { Some(i) } else { None });
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~                 break 'bar ({
+LL +                     let i = i?;
+LL +                     if i > 3 { Some(i) } else { None }
+LL ~                 });
+   |
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.fixed b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
index 1820ade422f..603ab0accb0 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.fixed
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
@@ -8,7 +8,6 @@ extern crate alloc;
 #[macro_use]
 extern crate proc_macro_derive;
 
-#[warn(clippy::std_instead_of_core)]
 fn std_instead_of_core() {
     // Regular import
     use core::hash::Hasher;
@@ -90,9 +89,3 @@ fn msrv_1_76(_: std::net::IpAddr) {}
 #[clippy::msrv = "1.77"]
 fn msrv_1_77(_: core::net::IpAddr) {}
 //~^ std_instead_of_core
-
-#[warn(clippy::std_instead_of_core)]
-#[rustfmt::skip]
-fn issue14982() {
-    use std::{collections::HashMap, hash::Hash};
-}
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.rs b/src/tools/clippy/tests/ui/std_instead_of_core.rs
index 32c49330981..b6d4abad9f8 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.rs
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.rs
@@ -8,7 +8,6 @@ extern crate alloc;
 #[macro_use]
 extern crate proc_macro_derive;
 
-#[warn(clippy::std_instead_of_core)]
 fn std_instead_of_core() {
     // Regular import
     use std::hash::Hasher;
@@ -90,9 +89,3 @@ fn msrv_1_76(_: std::net::IpAddr) {}
 #[clippy::msrv = "1.77"]
 fn msrv_1_77(_: std::net::IpAddr) {}
 //~^ std_instead_of_core
-
-#[warn(clippy::std_instead_of_core)]
-#[rustfmt::skip]
-fn issue14982() {
-    use std::{collections::HashMap, hash::Hash};
-}
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.stderr b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
index 45d60d235ce..a5f8fbbe37c 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.stderr
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
@@ -1,5 +1,5 @@
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:14:9
+  --> tests/ui/std_instead_of_core.rs:13:9
    |
 LL |     use std::hash::Hasher;
    |         ^^^ help: consider importing the item from `core`: `core`
@@ -8,61 +8,61 @@ LL |     use std::hash::Hasher;
    = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_core)]`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:17:11
+  --> tests/ui/std_instead_of_core.rs:16:11
    |
 LL |     use ::std::hash::Hash;
    |           ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:23:9
+  --> tests/ui/std_instead_of_core.rs:22:9
    |
 LL |     use std::fmt::{Debug, Result};
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:28:9
+  --> tests/ui/std_instead_of_core.rs:27:9
    |
 LL |     use std::{
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:35:15
+  --> tests/ui/std_instead_of_core.rs:34:15
    |
 LL |     let ptr = std::ptr::null::<u32>();
    |               ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:37:21
+  --> tests/ui/std_instead_of_core.rs:36:21
    |
 LL |     let ptr_mut = ::std::ptr::null_mut::<usize>();
    |                     ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:41:16
+  --> tests/ui/std_instead_of_core.rs:40:16
    |
 LL |     let cell = std::cell::Cell::new(8u32);
    |                ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:43:27
+  --> tests/ui/std_instead_of_core.rs:42:27
    |
 LL |     let cell_absolute = ::std::cell::Cell::new(8u32);
    |                           ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:48:9
+  --> tests/ui/std_instead_of_core.rs:47:9
    |
 LL |     use std::error::Error;
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:52:9
+  --> tests/ui/std_instead_of_core.rs:51:9
    |
 LL |     use std::iter::Iterator;
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `alloc`
-  --> tests/ui/std_instead_of_core.rs:59:9
+  --> tests/ui/std_instead_of_core.rs:58:9
    |
 LL |     use std::vec;
    |         ^^^ help: consider importing the item from `alloc`: `alloc`
@@ -71,13 +71,13 @@ LL |     use std::vec;
    = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]`
 
 error: used import from `std` instead of `alloc`
-  --> tests/ui/std_instead_of_core.rs:61:9
+  --> tests/ui/std_instead_of_core.rs:60:9
    |
 LL |     use std::vec::Vec;
    |         ^^^ help: consider importing the item from `alloc`: `alloc`
 
 error: used import from `alloc` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:67:9
+  --> tests/ui/std_instead_of_core.rs:66:9
    |
 LL |     use alloc::slice::from_ref;
    |         ^^^^^ help: consider importing the item from `core`: `core`
@@ -86,13 +86,13 @@ LL |     use alloc::slice::from_ref;
    = help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:82:9
+  --> tests/ui/std_instead_of_core.rs:81:9
    |
 LL |         std::intrinsics::copy(a, b, 1);
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:91:17
+  --> tests/ui/std_instead_of_core.rs:90:17
    |
 LL | fn msrv_1_77(_: std::net::IpAddr) {}
    |                 ^^^ help: consider importing the item from `core`: `core`
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.rs b/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.rs
new file mode 100644
index 00000000000..957f472a454
--- /dev/null
+++ b/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.rs
@@ -0,0 +1,18 @@
+//@no-rustfix
+
+#![warn(clippy::std_instead_of_core)]
+#![warn(clippy::std_instead_of_alloc)]
+#![allow(unused_imports)]
+
+#[rustfmt::skip]
+fn issue14982() {
+    use std::{collections::HashMap, hash::Hash};
+    //~^ std_instead_of_core
+}
+
+#[rustfmt::skip]
+fn issue15143() {
+    use std::{error::Error, vec::Vec, fs::File};
+    //~^ std_instead_of_core
+    //~| std_instead_of_alloc
+}
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.stderr b/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.stderr
new file mode 100644
index 00000000000..0cdec56c992
--- /dev/null
+++ b/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.stderr
@@ -0,0 +1,30 @@
+error: used import from `std` instead of `core`
+  --> tests/ui/std_instead_of_core_unfixable.rs:9:43
+   |
+LL |     use std::{collections::HashMap, hash::Hash};
+   |                                           ^^^^
+   |
+   = help: consider importing the item from `core`
+   = note: `-D clippy::std-instead-of-core` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_core)]`
+
+error: used import from `std` instead of `core`
+  --> tests/ui/std_instead_of_core_unfixable.rs:15:22
+   |
+LL |     use std::{error::Error, vec::Vec, fs::File};
+   |                      ^^^^^
+   |
+   = help: consider importing the item from `core`
+
+error: used import from `std` instead of `alloc`
+  --> tests/ui/std_instead_of_core_unfixable.rs:15:34
+   |
+LL |     use std::{error::Error, vec::Vec, fs::File};
+   |                                  ^^^
+   |
+   = help: consider importing the item from `alloc`
+   = note: `-D clippy::std-instead-of-alloc` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/swap_with_temporary.fixed b/src/tools/clippy/tests/ui/swap_with_temporary.fixed
index 4007d998ba0..4b4b0d4aebd 100644
--- a/src/tools/clippy/tests/ui/swap_with_temporary.fixed
+++ b/src/tools/clippy/tests/ui/swap_with_temporary.fixed
@@ -72,3 +72,49 @@ fn dont_lint_those(s: &mut S, v: &mut [String], w: Option<&mut String>) {
     swap(&mut s.t, v.get_mut(0).unwrap());
     swap(w.unwrap(), &mut s.t);
 }
+
+fn issue15166() {
+    use std::sync::Mutex;
+
+    struct A {
+        thing: Mutex<Vec<u8>>,
+    }
+
+    impl A {
+        fn a(&self) {
+            let mut new_vec = vec![42];
+            // Do not lint here, as neither `new_vec` nor the result of `.lock().unwrap()` are temporaries
+            swap(&mut new_vec, &mut self.thing.lock().unwrap());
+            for v in new_vec {
+                // Do something with v
+            }
+            // Here `vec![42]` is temporary though, and a proper dereference will have to be used in the fix
+            *self.thing.lock().unwrap() = vec![42];
+            //~^ ERROR: swapping with a temporary value is inefficient
+        }
+    }
+}
+
+fn multiple_deref() {
+    let mut v1 = &mut &mut &mut vec![42];
+    ***v1 = vec![];
+    //~^ ERROR: swapping with a temporary value is inefficient
+
+    struct Wrapper<T: ?Sized>(T);
+    impl<T: ?Sized> std::ops::Deref for Wrapper<T> {
+        type Target = T;
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+    impl<T: ?Sized> std::ops::DerefMut for Wrapper<T> {
+        fn deref_mut(&mut self) -> &mut Self::Target {
+            &mut self.0
+        }
+    }
+
+    use std::sync::Mutex;
+    let mut v1 = Mutex::new(Wrapper(Wrapper(vec![42])));
+    ***v1.lock().unwrap() = vec![];
+    //~^ ERROR: swapping with a temporary value is inefficient
+}
diff --git a/src/tools/clippy/tests/ui/swap_with_temporary.rs b/src/tools/clippy/tests/ui/swap_with_temporary.rs
index d403c086c0f..8e35e6144d9 100644
--- a/src/tools/clippy/tests/ui/swap_with_temporary.rs
+++ b/src/tools/clippy/tests/ui/swap_with_temporary.rs
@@ -72,3 +72,49 @@ fn dont_lint_those(s: &mut S, v: &mut [String], w: Option<&mut String>) {
     swap(&mut s.t, v.get_mut(0).unwrap());
     swap(w.unwrap(), &mut s.t);
 }
+
+fn issue15166() {
+    use std::sync::Mutex;
+
+    struct A {
+        thing: Mutex<Vec<u8>>,
+    }
+
+    impl A {
+        fn a(&self) {
+            let mut new_vec = vec![42];
+            // Do not lint here, as neither `new_vec` nor the result of `.lock().unwrap()` are temporaries
+            swap(&mut new_vec, &mut self.thing.lock().unwrap());
+            for v in new_vec {
+                // Do something with v
+            }
+            // Here `vec![42]` is temporary though, and a proper dereference will have to be used in the fix
+            swap(&mut vec![42], &mut self.thing.lock().unwrap());
+            //~^ ERROR: swapping with a temporary value is inefficient
+        }
+    }
+}
+
+fn multiple_deref() {
+    let mut v1 = &mut &mut &mut vec![42];
+    swap(&mut ***v1, &mut vec![]);
+    //~^ ERROR: swapping with a temporary value is inefficient
+
+    struct Wrapper<T: ?Sized>(T);
+    impl<T: ?Sized> std::ops::Deref for Wrapper<T> {
+        type Target = T;
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+    impl<T: ?Sized> std::ops::DerefMut for Wrapper<T> {
+        fn deref_mut(&mut self) -> &mut Self::Target {
+            &mut self.0
+        }
+    }
+
+    use std::sync::Mutex;
+    let mut v1 = Mutex::new(Wrapper(Wrapper(vec![42])));
+    swap(&mut vec![], &mut v1.lock().unwrap());
+    //~^ ERROR: swapping with a temporary value is inefficient
+}
diff --git a/src/tools/clippy/tests/ui/swap_with_temporary.stderr b/src/tools/clippy/tests/ui/swap_with_temporary.stderr
index 59355771a96..5ca4fccd37a 100644
--- a/src/tools/clippy/tests/ui/swap_with_temporary.stderr
+++ b/src/tools/clippy/tests/ui/swap_with_temporary.stderr
@@ -96,5 +96,41 @@ note: this expression returns a temporary value
 LL |     swap(mac!(refmut y), &mut func());
    |                               ^^^^^^
 
-error: aborting due to 8 previous errors
+error: swapping with a temporary value is inefficient
+  --> tests/ui/swap_with_temporary.rs:92:13
+   |
+LL |             swap(&mut vec![42], &mut self.thing.lock().unwrap());
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `*self.thing.lock().unwrap() = vec![42]`
+   |
+note: this expression returns a temporary value
+  --> tests/ui/swap_with_temporary.rs:92:23
+   |
+LL |             swap(&mut vec![42], &mut self.thing.lock().unwrap());
+   |                       ^^^^^^^^
+
+error: swapping with a temporary value is inefficient
+  --> tests/ui/swap_with_temporary.rs:100:5
+   |
+LL |     swap(&mut ***v1, &mut vec![]);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `***v1 = vec![]`
+   |
+note: this expression returns a temporary value
+  --> tests/ui/swap_with_temporary.rs:100:27
+   |
+LL |     swap(&mut ***v1, &mut vec![]);
+   |                           ^^^^^^
+
+error: swapping with a temporary value is inefficient
+  --> tests/ui/swap_with_temporary.rs:118:5
+   |
+LL |     swap(&mut vec![], &mut v1.lock().unwrap());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `***v1.lock().unwrap() = vec![]`
+   |
+note: this expression returns a temporary value
+  --> tests/ui/swap_with_temporary.rs:118:15
+   |
+LL |     swap(&mut vec![], &mut v1.lock().unwrap());
+   |               ^^^^^^
+
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs b/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs
index 2e67fb65efc..3bae23f1984 100644
--- a/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs
+++ b/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs
@@ -4,6 +4,7 @@
 // Normalize the emitted location so this doesn't need
 // updating everytime someone adds or removes a line.
 //@normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC"
+//@normalize-stderr-test: "src/tools/clippy/" -> ""
 
 #![warn(clippy::let_and_return, clippy::unnecessary_cast)]
 
@@ -12,7 +13,7 @@ fn main() {
     let a = 3u32;
     let b = a as u32;
     //~^ unnecessary_cast
-    
+
     // Check the provenance of a lint sent through `TyCtxt::node_span_lint()`
     let c = {
         let d = 42;
diff --git a/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr
index 9d6538112bf..d5533877b45 100644
--- a/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr
+++ b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr
@@ -4,7 +4,7 @@ error: casting to the same type is unnecessary (`u32` -> `u32`)
 LL |     let b = a as u32;
    |             ^^^^^^^^ help: try: `a`
    |
-   = note: -Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs:LL:CC
+   = note: -Ztrack-diagnostics: created at clippy_lints/src/casts/unnecessary_cast.rs:LL:CC
    = note: `-D clippy::unnecessary-cast` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]`
 
@@ -16,7 +16,7 @@ LL |         let d = 42;
 LL |         d
    |         ^
    |
-   = note: -Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/returns.rs:LL:CC
+   = note: -Ztrack-diagnostics: created at clippy_lints/src/returns.rs:LL:CC
    = note: `-D clippy::let-and-return` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]`
 help: return the expression directly
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
index 3c724397284..3109c4af8e2 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
@@ -130,3 +130,13 @@ fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
     //~^ unnecessary_map_or
     x && y
 }
+
+fn issue15180() {
+    let s = std::sync::Mutex::new(Some("foo"));
+    _ = s.lock().unwrap().is_some_and(|s| s == "foo");
+    //~^ unnecessary_map_or
+
+    let s = &&&&Some("foo");
+    _ = s.is_some_and(|s| s == "foo");
+    //~^ unnecessary_map_or
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.rs b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
index e734a27bada..52a55f9fc9e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
@@ -134,3 +134,13 @@ fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
     //~^ unnecessary_map_or
     x && y
 }
+
+fn issue15180() {
+    let s = std::sync::Mutex::new(Some("foo"));
+    _ = s.lock().unwrap().map_or(false, |s| s == "foo");
+    //~^ unnecessary_map_or
+
+    let s = &&&&Some("foo");
+    _ = s.map_or(false, |s| s == "foo");
+    //~^ unnecessary_map_or
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
index 0f9466a6a6b..99e17e8b34b 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
@@ -326,5 +326,29 @@ LL -     let y = b.map_or(true, |b| b == *s);
 LL +     let y = b.is_none_or(|b| b == *s);
    |
 
-error: aborting due to 26 previous errors
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:140:9
+   |
+LL |     _ = s.lock().unwrap().map_or(false, |s| s == "foo");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_some_and instead
+   |
+LL -     _ = s.lock().unwrap().map_or(false, |s| s == "foo");
+LL +     _ = s.lock().unwrap().is_some_and(|s| s == "foo");
+   |
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:144:9
+   |
+LL |     _ = s.map_or(false, |s| s == "foo");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_some_and instead
+   |
+LL -     _ = s.map_or(false, |s| s == "foo");
+LL +     _ = s.is_some_and(|s| s == "foo");
+   |
+
+error: aborting due to 28 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.fixed b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
index 645b56fe95e..ac9fa4de20a 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
@@ -144,3 +144,16 @@ const fn foo() {
     assert!([42, 55].len() > get_usize());
     //~^ unnecessary_operation
 }
+
+fn issue15173() {
+    // No lint as `Box::new(None)` alone would be ambiguous
+    Box::new(None) as Box<Option<i32>>;
+}
+
+#[expect(clippy::redundant_closure_call)]
+fn issue15173_original<MsU>(handler: impl FnOnce() -> MsU + Clone + 'static) {
+    Box::new(move |value| {
+        (|_| handler.clone()())(value);
+        None
+    }) as Box<dyn Fn(i32) -> Option<i32>>;
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.rs b/src/tools/clippy/tests/ui/unnecessary_operation.rs
index 97e90269c5c..a3e6c6288ad 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.rs
@@ -150,3 +150,16 @@ const fn foo() {
     [42, 55][get_usize()];
     //~^ unnecessary_operation
 }
+
+fn issue15173() {
+    // No lint as `Box::new(None)` alone would be ambiguous
+    Box::new(None) as Box<Option<i32>>;
+}
+
+#[expect(clippy::redundant_closure_call)]
+fn issue15173_original<MsU>(handler: impl FnOnce() -> MsU + Clone + 'static) {
+    Box::new(move |value| {
+        (|_| handler.clone()())(value);
+        None
+    }) as Box<dyn Fn(i32) -> Option<i32>>;
+}
diff --git a/src/tools/clippy/tests/ui/zero_ptr.fixed b/src/tools/clippy/tests/ui/zero_ptr.fixed
index f2375d57f3a..f9d9d2db176 100644
--- a/src/tools/clippy/tests/ui/zero_ptr.fixed
+++ b/src/tools/clippy/tests/ui/zero_ptr.fixed
@@ -16,3 +16,11 @@ fn main() {
     let z = 0;
     let _ = z as *const usize; // this is currently not caught
 }
+
+const fn in_const_context() {
+    #[clippy::msrv = "1.23"]
+    let _: *const usize = 0 as *const _;
+    #[clippy::msrv = "1.24"]
+    let _: *const usize = std::ptr::null();
+    //~^ zero_ptr
+}
diff --git a/src/tools/clippy/tests/ui/zero_ptr.rs b/src/tools/clippy/tests/ui/zero_ptr.rs
index ee01e426a43..41455fee5b5 100644
--- a/src/tools/clippy/tests/ui/zero_ptr.rs
+++ b/src/tools/clippy/tests/ui/zero_ptr.rs
@@ -16,3 +16,11 @@ fn main() {
     let z = 0;
     let _ = z as *const usize; // this is currently not caught
 }
+
+const fn in_const_context() {
+    #[clippy::msrv = "1.23"]
+    let _: *const usize = 0 as *const _;
+    #[clippy::msrv = "1.24"]
+    let _: *const usize = 0 as *const _;
+    //~^ zero_ptr
+}
diff --git a/src/tools/clippy/tests/ui/zero_ptr.stderr b/src/tools/clippy/tests/ui/zero_ptr.stderr
index 8dc781f3625..81269de6c60 100644
--- a/src/tools/clippy/tests/ui/zero_ptr.stderr
+++ b/src/tools/clippy/tests/ui/zero_ptr.stderr
@@ -31,5 +31,11 @@ error: `0 as *mut _` detected
 LL |     foo(0 as *const _, 0 as *mut _);
    |                        ^^^^^^^^^^^ help: try: `std::ptr::null_mut()`
 
-error: aborting due to 5 previous errors
+error: `0 as *const _` detected
+  --> tests/ui/zero_ptr.rs:24:27
+   |
+LL |     let _: *const usize = 0 as *const _;
+   |                           ^^^^^^^^^^^^^ help: try: `std::ptr::null()`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index 4f370758c00..805baf2af6d 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -15,6 +15,8 @@ allow-unauthenticated = [
 
 [close]
 
+[transfer]
+
 [issue-links]
 
 [mentions."clippy_lints/src/doc"]
@@ -43,12 +45,15 @@ reviewed_label = "S-waiting-on-author"
 [autolabel."S-waiting-on-review"]
 new_pr = true
 
+[concern]
+# These labels are set when there are unresolved concerns, removed otherwise
+labels = ["S-waiting-on-concerns"]
+
 [assign]
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
 users_on_vacation = [
     "matthiaskrgr",
     "Manishearth",
-    "blyxyas",
 ]
 
 [assign.owners]
diff --git a/src/tools/clippy/util/gh-pages/index_template.html b/src/tools/clippy/util/gh-pages/index_template.html
index 865b9523c39..6f380ec8fee 100644
--- a/src/tools/clippy/util/gh-pages/index_template.html
+++ b/src/tools/clippy/util/gh-pages/index_template.html
@@ -149,49 +149,45 @@ Otherwise, have a great day =^.^=
                 <article class="panel panel-default" id="{{lint.id}}"> {# #}
                     <input id="label-{{lint.id}}" type="checkbox"> {# #}
                     <label for="label-{{lint.id}}"> {# #}
-                        <header class="panel-heading"> {# #}
-                            <h2 class="panel-title"> {# #}
-                                <div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
-                                    <span>{{lint.id}}</span> {#+ #}
-                                    <a href="#{{lint.id}}" class="lint-anchor anchor label label-default">&para;</a> {#+ #}
-                                    <a href="" class="copy-to-clipboard anchor label label-default"> {# #}
-                                        &#128203; {# #}
-                                    </a> {# #}
-                                </div> {# #}
+                        <h2 class="lint-title"> {# #}
+                            <div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
+                                {{lint.id +}}
+                                <a href="#{{lint.id}}" class="anchor label label-default">&para;</a> {#+ #}
+                                <a href="" class="copy-to-clipboard anchor label label-default"> {# #}
+                                    &#128203; {# #}
+                                </a> {# #}
+                            </div> {# #}
 
-                                <div class="panel-title-addons"> {# #}
-                                    <span class="label label-lint-group label-default label-group-{{lint.group}}">{{lint.group}}</span> {#+ #}
+                            <span class="label label-lint-group label-default label-group-{{lint.group}}">{{lint.group}}</span> {#+ #}
 
-                                    <span class="label label-lint-level label-lint-level-{{lint.level}}">{{lint.level}}</span> {#+ #}
+                            <span class="label label-lint-level label-lint-level-{{lint.level}}">{{lint.level}}</span> {#+ #}
 
-                                    <span class="label label-doc-folding"></span> {# #}
-                                </div> {# #}
-                            </h2> {# #}
-                        </header> {# #}
+                            <span class="label label-doc-folding"></span> {# #}
+                        </h2> {# #}
                     </label> {# #}
 
                     <div class="list-group lint-docs"> {# #}
                         <div class="list-group-item lint-doc-md">{{Self::markdown(lint.docs)}}</div> {# #}
                         <div class="lint-additional-info-container">
                             {# Applicability #}
-                            <div class="lint-additional-info-item"> {# #}
-                                <span> Applicability: </span> {# #}
+                            <div> {# #}
+                                Applicability: {#+ #}
                                 <span class="label label-default label-applicability">{{ lint.applicability_str() }}</span> {# #}
                                 <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/enum.Applicability.html#variants">(?)</a> {# #}
                             </div>
                             {# Clippy version #}
-                            <div class="lint-additional-info-item"> {# #}
-                                <span>{% if lint.group == "deprecated" %}Deprecated{% else %} Added{% endif +%} in: </span> {# #}
+                            <div> {# #}
+                                {% if lint.group == "deprecated" %}Deprecated{% else %} Added{% endif +%} in: {#+ #}
                                 <span class="label label-default label-version">{{lint.version}}</span> {# #}
                             </div>
                             {# Open related issues #}
-                            <div class="lint-additional-info-item"> {# #}
+                            <div> {# #}
                                 <a href="https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+{{lint.id}}">Related Issues</a> {# #}
                             </div>
 
                             {# Jump to source #}
                             {% if let Some(id_location) = lint.id_location %}
-                                <div class="lint-additional-info-item"> {# #}
+                                <div> {# #}
                                     <a href="https://github.com/rust-lang/rust-clippy/blob/master/{{id_location}}">View Source</a> {# #}
                                 </div>
                             {% endif %}
diff --git a/src/tools/clippy/util/gh-pages/script.js b/src/tools/clippy/util/gh-pages/script.js
index 285aa34e701..ee13f1c0cd8 100644
--- a/src/tools/clippy/util/gh-pages/script.js
+++ b/src/tools/clippy/util/gh-pages/script.js
@@ -554,10 +554,10 @@ function addListeners() {
             return;
         }
 
-        if (event.target.classList.contains("lint-anchor")) {
-            lintAnchor(event);
-        } else if (event.target.classList.contains("copy-to-clipboard")) {
+        if (event.target.classList.contains("copy-to-clipboard")) {
             copyToClipboard(event);
+        } else if (event.target.classList.contains("anchor")) {
+            lintAnchor(event);
         }
     });
 
diff --git a/src/tools/clippy/util/gh-pages/style.css b/src/tools/clippy/util/gh-pages/style.css
index 3cc7a919c23..022ea875200 100644
--- a/src/tools/clippy/util/gh-pages/style.css
+++ b/src/tools/clippy/util/gh-pages/style.css
@@ -50,11 +50,25 @@ div.panel div.panel-body  button.open {
 
 .panel-heading { cursor: pointer; }
 
-.panel-title { display: flex; flex-wrap: wrap;}
-.panel-title .label { display: inline-block; }
+.lint-title {
+    cursor: pointer;
+    margin-top: 0;
+    margin-bottom: 0;
+    font-size: 16px;
+    display: flex;
+    flex-wrap: wrap;
+    background: var(--theme-hover);
+    color: var(--fg);
+    border: 1px solid var(--theme-popup-border);
+    padding: 10px 15px;
+    border-top-left-radius: 3px;
+    border-top-right-radius: 3px;
+    gap: 4px;
+}
+
+.lint-title .label { display: inline-block; }
 
 .panel-title-name { flex: 1; min-width: 400px;}
-.panel-title-name span { vertical-align: bottom; }
 
 .panel .panel-title-name .anchor { display: none; }
 .panel:hover .panel-title-name .anchor { display: inline;}
@@ -147,7 +161,7 @@ div.panel div.panel-body  button.open {
         display: flex;
         flex-flow: column;
     }
-    .lint-additional-info-item + .lint-additional-info-item {
+    .lint-additional-info-container > div + div {
         border-top: 1px solid var(--theme-popup-border);
     }
 }
@@ -156,12 +170,12 @@ div.panel div.panel-body  button.open {
         display: flex;
         flex-flow: row;
     }
-    .lint-additional-info-item + .lint-additional-info-item {
+    .lint-additional-info-container > div + div {
         border-left: 1px solid var(--theme-popup-border);
     }
 }
 
-.lint-additional-info-item {
+.lint-additional-info-container > div {
     display: inline-flex;
     min-width: 200px;
     flex-grow: 1;
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 3e879e0e4bb..933a32392bd 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1777,6 +1777,12 @@ impl<'test> TestCx<'test> {
         // Allow tests to use internal features.
         rustc.args(&["-A", "internal_features"]);
 
+        // Allow tests to have unused parens and braces.
+        // Add #![deny(unused_parens, unused_braces)] to the test file if you want to
+        // test that these lints are working.
+        rustc.args(&["-A", "unused_parens"]);
+        rustc.args(&["-A", "unused_braces"]);
+
         if self.props.force_host {
             self.maybe_add_external_args(&mut rustc, &self.config.host_rustcflags);
             if !is_rustdoc {
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 693b8916d89..35399dbf4cb 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1014,8 +1014,6 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
 
     const PANIC_ON_ALLOC_FAIL: bool = false;
 
-    const TRACING_ENABLED: bool = cfg!(feature = "tracing");
-
     #[inline(always)]
     fn enforce_alignment(ecx: &MiriInterpCx<'tcx>) -> bool {
         ecx.machine.check_alignment != AlignmentCheck::None
@@ -1827,6 +1825,16 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         #[cfg(not(target_os = "linux"))]
         MiriAllocParams::Global
     }
+
+    fn enter_trace_span(span: impl FnOnce() -> tracing::Span) -> impl EnteredTraceSpan {
+        #[cfg(feature = "tracing")]
+        { span().entered() }
+        #[cfg(not(feature = "tracing"))]
+        {
+            let _ = span; // so we avoid the "unused variable" warning
+            ()
+        }
+    }
 }
 
 /// Trait for callbacks handling asynchronous machine operations.
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index 705a1750ae8..2d2aab86eda 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -106,7 +106,10 @@ llvm-config = "{llvm_config}"
             "tests/incremental",
             "tests/mir-opt",
             "tests/pretty",
+            // Make sure that we don't use too new GLIBC symbols on x64
             "tests/run-make/glibc-symbols-x86_64-unknown-linux-gnu",
+            // Make sure that we use LLD by default on x64
+            "tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist",
             "tests/ui",
             "tests/crashes",
         ];
diff --git a/src/tools/run-make-support/CHANGELOG.md b/src/tools/run-make-support/CHANGELOG.md
deleted file mode 100644
index c1b7b618a92..00000000000
--- a/src/tools/run-make-support/CHANGELOG.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Changelog
-
-All notable changes to the `run_make_support` library should be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the support
-library should adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) even if it's
-not intended for public consumption (it's moreso to help internally, to help test writers track
-changes to the support library).
-
-This support library will probably never reach 1.0. Please bump the minor version in `Cargo.toml` if
-you make any breaking changes or other significant changes, or bump the patch version for bug fixes.
-
-## [0.2.0] - 2024-06-11
-
-### Added
-
-- Added `fs_wrapper` module which provides panic-on-fail helpers for their respective `std::fs`
-  counterparts, the motivation is to:
-    - Reduce littering `.unwrap()` or `.expect()` everywhere for fs operations
-    - Help the test writer avoid forgetting to check fs results (even though enforced by
-      `-Dunused_must_use`)
-    - Provide better panic messages by default
-- Added `path()` helper which creates a `Path` relative to `cwd()` (but is less noisy).
-
-### Changed
-
-- Marked many functions with `#[must_use]`, and rmake.rs are now compiled with `-Dunused_must_use`.
-
-## [0.1.0] - 2024-06-09
-
-### Changed
-
-- Use *drop bombs* to enforce that commands are executed; a command invocation will panic if it is
-  constructed but never executed. Execution methods `Command::{run, run_fail}` will defuse the drop
-  bomb.
-- Added `Command` helpers that forward to `std::process::Command` counterparts.
-
-### Removed
-
-- The `env_var` method which was incorrectly named and is `env_clear` underneath and is a footgun
-  from `impl_common_helpers`. For example, removing `TMPDIR` on Unix and `TMP`/`TEMP` breaks
-  `std::env::temp_dir` and wrecks anything using that, such as rustc's codgen.
-- Removed `Deref`/`DerefMut` for `run_make_support::Command` -> `std::process::Command` because it
-  causes a method chain like `htmldocck().arg().run()` to fail, because `arg()` resolves to
-  `std::process::Command` which also returns a `&mut std::process::Command`, causing the `run()` to
-  be not found.
-
-## [0.0.0] - 2024-06-09
-
-Consider this version to contain all changes made to the support library before we started to track
-changes in this changelog.
-
-### Added
-
-- Custom command wrappers around `std::process::Command` (`run_make_support::Command`) and custom
-  wrapper around `std::process::Output` (`CompletedProcess`) to make it more convenient to work with
-  commands and their output, and help avoid forgetting to check for exit status.
-    - `Command`: `set_stdin`, `run`, `run_fail`.
-    - `CompletedProcess`: `std{err,out}_utf8`, `status`, `assert_std{err,out}_{equals, contains,
-      not_contains}`, `assert_exit_code`.
-- `impl_common_helpers` macro to avoid repeating adding common convenience methods, including:
-    - Environment manipulation methods: `env`, `env_remove`
-    - Command argument providers: `arg`, `args`
-    - Common invocation inspection (of the command invocation up until `inspect` is called):
-      `inspect`
-    - Execution methods: `run` (for commands expected to succeed execution, exit status `0`) and
-      `run_fail` (for commands expected to fail execution, exit status non-zero).
-- Command wrappers around: `rustc`, `clang`, `cc`, `rustc`, `rustdoc`, `llvm-readobj`.
-- Thin helpers to construct `python` and `htmldocck` commands.
-- `run` and `run_fail` (like `Command::{run, run_fail}`) for running binaries, which sets suitable
-  env vars (like `LD_LIB_PATH` or equivalent, `TARGET_RPATH_ENV`, `PATH` on Windows).
-- Pseudo command `diff` which has similar functionality as the cli util but not the same API.
-- Convenience panic-on-fail helpers `env_var`, `env_var_os`, `cwd` for their `std::env` conterparts.
-- Convenience panic-on-fail helpers for reading respective env vars: `target`, `source_root`.
-- Platform check helpers: `is_windows`, `is_msvc`, `cygpath_windows`, `uname`.
-- fs helpers: `copy_dir_all`.
-- `recursive_diff` helper.
-- Generic `assert_not_contains` helper.
-- Scoped run-with-teardown helper `run_in_tmpdir` which is designed to run commands in a temporary
-  directory that is cleared when closure returns.
-- Helpers for constructing the name of binaries and libraries: `rust_lib_name`, `static_lib_name`,
-  `bin_name`, `dynamic_lib_name`.
-- Re-export libraries: `gimli`, `object`, `regex`, `wasmparsmer`.
diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml
index 3226f467ba4..a4e7534137d 100644
--- a/src/tools/run-make-support/Cargo.toml
+++ b/src/tools/run-make-support/Cargo.toml
@@ -1,18 +1,27 @@
 [package]
 name = "run_make_support"
-version = "0.2.0"
-edition = "2021"
+version = "0.0.0"
+edition = "2024"
 
 [dependencies]
+
+# These dependencies are either used to implement part of support library
+# functionality, or re-exported to test recipe programs via the support library,
+# or both.
+
+# tidy-alphabetical-start
 bstr = "1.12"
+gimli = "0.32"
+libc = "0.2"
 object = "0.37"
+regex = "1.11"
+serde_json = "1.0"
 similar = "2.7"
 wasmparser = { version = "0.219", default-features = false, features = ["std"] }
-regex = "1.11"
-gimli = "0.32"
+# tidy-alphabetical-end
+
+# Shared with bootstrap and compiletest
 build_helper = { path = "../../build_helper" }
-serde_json = "1.0"
-libc = "0.2"
 
 [lib]
 crate-type = ["lib", "dylib"]
diff --git a/src/tools/run-make-support/src/artifact_names.rs b/src/tools/run-make-support/src/artifact_names.rs
index b0d588d3550..a889b30e145 100644
--- a/src/tools/run-make-support/src/artifact_names.rs
+++ b/src/tools/run-make-support/src/artifact_names.rs
@@ -2,7 +2,7 @@
 //! libraries which are target-dependent.
 
 use crate::target;
-use crate::targets::is_msvc;
+use crate::targets::is_windows_msvc;
 
 /// Construct the static library name based on the target.
 #[track_caller]
@@ -10,7 +10,7 @@ use crate::targets::is_msvc;
 pub fn static_lib_name(name: &str) -> String {
     assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace");
 
-    if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") }
+    if is_windows_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") }
 }
 
 /// Construct the dynamic library name based on the target.
@@ -45,7 +45,7 @@ pub fn dynamic_lib_extension() -> &'static str {
 #[track_caller]
 #[must_use]
 pub fn msvc_import_dynamic_lib_name(name: &str) -> String {
-    assert!(is_msvc(), "this function is exclusive to MSVC");
+    assert!(is_windows_msvc(), "this function is exclusive to MSVC");
     assert!(!name.contains(char::is_whitespace), "import library name cannot contain whitespace");
 
     format!("{name}.dll.lib")
diff --git a/src/tools/run-make-support/src/external_deps/c_build.rs b/src/tools/run-make-support/src/external_deps/c_build.rs
index 9dd30713f95..ecbf5ba8fe0 100644
--- a/src/tools/run-make-support/src/external_deps/c_build.rs
+++ b/src/tools/run-make-support/src/external_deps/c_build.rs
@@ -4,7 +4,7 @@ use crate::artifact_names::{dynamic_lib_name, static_lib_name};
 use crate::external_deps::c_cxx_compiler::{cc, cxx};
 use crate::external_deps::llvm::llvm_ar;
 use crate::path_helpers::path;
-use crate::targets::{is_darwin, is_msvc, is_windows};
+use crate::targets::{is_darwin, is_windows, is_windows_msvc};
 
 // FIXME(Oneirical): These native build functions should take a Path-based generic.
 
@@ -24,12 +24,12 @@ pub fn build_native_static_lib_optimized(lib_name: &str) -> PathBuf {
 
 #[track_caller]
 fn build_native_static_lib_internal(lib_name: &str, optimzed: bool) -> PathBuf {
-    let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
+    let obj_file = if is_windows_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
     let src = format!("{lib_name}.c");
     let lib_path = static_lib_name(lib_name);
 
     let mut cc = cc();
-    if !is_msvc() {
+    if !is_windows_msvc() {
         cc.arg("-v");
     }
     if optimzed {
@@ -37,7 +37,7 @@ fn build_native_static_lib_internal(lib_name: &str, optimzed: bool) -> PathBuf {
     }
     cc.arg("-c").out_exe(&obj_file).input(src).optimize().run();
 
-    let obj_file = if is_msvc() {
+    let obj_file = if is_windows_msvc() {
         PathBuf::from(format!("{lib_name}.obj"))
     } else {
         PathBuf::from(format!("{lib_name}.o"))
@@ -50,16 +50,17 @@ fn build_native_static_lib_internal(lib_name: &str, optimzed: bool) -> PathBuf {
 /// [`std::env::consts::DLL_PREFIX`] and [`std::env::consts::DLL_EXTENSION`].
 #[track_caller]
 pub fn build_native_dynamic_lib(lib_name: &str) -> PathBuf {
-    let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
+    let obj_file = if is_windows_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
     let src = format!("{lib_name}.c");
     let lib_path = dynamic_lib_name(lib_name);
-    if is_msvc() {
+    if is_windows_msvc() {
         cc().arg("-c").out_exe(&obj_file).input(src).run();
     } else {
         cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
     };
-    let obj_file = if is_msvc() { format!("{lib_name}.obj") } else { format!("{lib_name}.o") };
-    if is_msvc() {
+    let obj_file =
+        if is_windows_msvc() { format!("{lib_name}.obj") } else { format!("{lib_name}.o") };
+    if is_windows_msvc() {
         let out_arg = format!("-out:{lib_path}");
         cc().input(&obj_file).args(&["-link", "-dll", &out_arg]).run();
     } else if is_darwin() {
@@ -79,15 +80,15 @@ pub fn build_native_dynamic_lib(lib_name: &str) -> PathBuf {
 /// Built from a C++ file.
 #[track_caller]
 pub fn build_native_static_lib_cxx(lib_name: &str) -> PathBuf {
-    let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
+    let obj_file = if is_windows_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
     let src = format!("{lib_name}.cpp");
     let lib_path = static_lib_name(lib_name);
-    if is_msvc() {
+    if is_windows_msvc() {
         cxx().arg("-EHs").arg("-c").out_exe(&obj_file).input(src).run();
     } else {
         cxx().arg("-c").out_exe(&obj_file).input(src).run();
     };
-    let obj_file = if is_msvc() {
+    let obj_file = if is_windows_msvc() {
         PathBuf::from(format!("{lib_name}.obj"))
     } else {
         PathBuf::from(format!("{lib_name}.o"))
diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs
index 0e6d6ea6075..31469e669e1 100644
--- a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs
+++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs
@@ -1,7 +1,7 @@
 use std::path::Path;
 
 use crate::command::Command;
-use crate::{env_var, is_msvc};
+use crate::{env_var, is_windows_msvc};
 
 /// Construct a new platform-specific C compiler invocation.
 ///
@@ -82,7 +82,7 @@ impl Cc {
     pub fn out_exe(&mut self, name: &str) -> &mut Self {
         let mut path = std::path::PathBuf::from(name);
 
-        if is_msvc() {
+        if is_windows_msvc() {
             path.set_extension("exe");
             let fe_path = path.clone();
             path.set_extension("");
@@ -108,7 +108,7 @@ impl Cc {
     /// Optimize the output.
     /// Equivalent to `-O3` for GNU-compatible linkers or `-O2` for MSVC linkers.
     pub fn optimize(&mut self) -> &mut Self {
-        if is_msvc() {
+        if is_windows_msvc() {
             self.cmd.arg("-O2");
         } else {
             self.cmd.arg("-O3");
diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs
index c0317633873..ac7392641c0 100644
--- a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs
+++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs
@@ -1,9 +1,9 @@
-use crate::{is_msvc, is_win7, is_windows, uname};
+use crate::{is_win7, is_windows, is_windows_msvc, uname};
 
 /// `EXTRACFLAGS`
 pub fn extra_c_flags() -> Vec<&'static str> {
     if is_windows() {
-        if is_msvc() {
+        if is_windows_msvc() {
             let mut libs =
                 vec!["ws2_32.lib", "userenv.lib", "bcrypt.lib", "ntdll.lib", "synchronization.lib"];
             if is_win7() {
@@ -29,7 +29,7 @@ pub fn extra_c_flags() -> Vec<&'static str> {
 /// `EXTRACXXFLAGS`
 pub fn extra_cxx_flags() -> Vec<&'static str> {
     if is_windows() {
-        if is_msvc() { vec![] } else { vec!["-lstdc++"] }
+        if is_windows_msvc() { vec![] } else { vec!["-lstdc++"] }
     } else {
         match &uname()[..] {
             "Darwin" => vec!["-lc++"],
diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs
index 72a1e062a38..1ea549ca7ea 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -6,7 +6,7 @@ use crate::command::Command;
 use crate::env::env_var;
 use crate::path_helpers::cwd;
 use crate::util::set_host_compiler_dylib_path;
-use crate::{is_aix, is_darwin, is_msvc, is_windows, target, uname};
+use crate::{is_aix, is_darwin, is_windows, is_windows_msvc, target, uname};
 
 /// Construct a new `rustc` invocation. This will automatically set the library
 /// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
@@ -377,7 +377,7 @@ impl Rustc {
             // So we end up with the following hack: we link use static:-bundle to only
             // link the parts of libstdc++ that we actually use, which doesn't include
             // the dependency on the pthreads DLL.
-            if !is_msvc() {
+            if !is_windows_msvc() {
                 self.cmd.arg("-lstatic:-bundle=stdc++");
             };
         } else if is_darwin() {
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 67d8c351a59..29cd6c4ad15 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -3,9 +3,6 @@
 //! notably is built via cargo: this means that if your test wants some non-trivial utility, such
 //! as `object` or `wasmparser`, they can be re-exported and be made available through this library.
 
-// We want to control use declaration ordering and spacing (and preserve use group comments), so
-// skip rustfmt on this file.
-#![cfg_attr(rustfmt, rustfmt::skip)]
 #![warn(unreachable_pub)]
 
 mod command;
@@ -22,8 +19,8 @@ pub mod path_helpers;
 pub mod run;
 pub mod scoped_run;
 pub mod string;
-pub mod targets;
 pub mod symbols;
+pub mod targets;
 
 // Internally we call our fs-related support module as `fs`, but re-export its content as `rfs`
 // to tests to avoid colliding with commonly used `use std::fs;`.
@@ -36,77 +33,56 @@ pub mod rfs {
 }
 
 // Re-exports of third-party library crates.
-// tidy-alphabetical-start
-pub use bstr;
-pub use gimli;
-pub use libc;
-pub use object;
-pub use regex;
-pub use serde_json;
-pub use similar;
-pub use wasmparser;
-// tidy-alphabetical-end
+pub use {bstr, gimli, libc, object, regex, serde_json, similar, wasmparser};
 
-// Re-exports of external dependencies.
-pub use external_deps::{
-    cargo, c_build, c_cxx_compiler, clang, htmldocck, llvm, python, rustc, rustdoc
+// Helpers for building names of output artifacts that are potentially target-specific.
+pub use crate::artifact_names::{
+    bin_name, dynamic_lib_extension, dynamic_lib_name, msvc_import_dynamic_lib_name, rust_lib_name,
+    static_lib_name,
 };
-
-// These rely on external dependencies.
-pub use c_cxx_compiler::{Cc, Gcc, cc, cxx, extra_c_flags, extra_cxx_flags, gcc};
-pub use c_build::{
+pub use crate::assertion_helpers::{
+    assert_contains, assert_contains_regex, assert_count_is, assert_dirs_are_equal, assert_equals,
+    assert_not_contains, assert_not_contains_regex,
+};
+// `diff` is implemented in terms of the [similar] library.
+//
+// [similar]: https://github.com/mitsuhiko/similar
+pub use crate::diff::{Diff, diff};
+// Panic-on-fail [`std::env::var`] and [`std::env::var_os`] wrappers.
+pub use crate::env::{env_var, env_var_os, set_current_dir};
+pub use crate::external_deps::c_build::{
     build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_cxx,
     build_native_static_lib_optimized,
 };
-pub use cargo::cargo;
-pub use clang::{clang, Clang};
-pub use htmldocck::htmldocck;
-pub use llvm::{
-    llvm_ar, llvm_bcanalyzer, llvm_dis, llvm_dwarfdump, llvm_filecheck, llvm_nm, llvm_objcopy,
-    llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, LlvmBcanalyzer, LlvmDis, LlvmDwarfdump,
-    LlvmFilecheck, LlvmNm, LlvmObjcopy, LlvmObjdump, LlvmProfdata, LlvmReadobj,
-};
-pub use python::python_command;
-pub use rustc::{bare_rustc, rustc, rustc_path, Rustc};
-pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
-
-/// [`diff`][mod@diff] is implemented in terms of the [similar] library.
-///
-/// [similar]: https://github.com/mitsuhiko/similar
-pub use diff::{diff, Diff};
-
-/// Panic-on-fail [`std::env::var`] and [`std::env::var_os`] wrappers.
-pub use env::{env_var, env_var_os, set_current_dir};
-
-/// Convenience helpers for running binaries and other commands.
-pub use run::{cmd, run, run_fail, run_with_args};
-
-/// Helpers for checking target information.
-pub use targets::{
-    apple_os, is_aix, is_darwin, is_msvc, is_windows, is_windows_gnu, is_windows_msvc, is_win7, llvm_components_contain,
-    target, uname,
+// Re-exports of external dependencies.
+pub use crate::external_deps::c_cxx_compiler::{
+    Cc, Gcc, cc, cxx, extra_c_flags, extra_cxx_flags, gcc,
 };
-
-/// Helpers for building names of output artifacts that are potentially target-specific.
-pub use artifact_names::{
-    bin_name, dynamic_lib_extension, dynamic_lib_name, msvc_import_dynamic_lib_name, rust_lib_name,
-    static_lib_name,
+pub use crate::external_deps::cargo::cargo;
+pub use crate::external_deps::clang::{Clang, clang};
+pub use crate::external_deps::htmldocck::htmldocck;
+pub use crate::external_deps::llvm::{
+    self, LlvmAr, LlvmBcanalyzer, LlvmDis, LlvmDwarfdump, LlvmFilecheck, LlvmNm, LlvmObjcopy,
+    LlvmObjdump, LlvmProfdata, LlvmReadobj, llvm_ar, llvm_bcanalyzer, llvm_dis, llvm_dwarfdump,
+    llvm_filecheck, llvm_nm, llvm_objcopy, llvm_objdump, llvm_profdata, llvm_readobj,
 };
-
-/// Path-related helpers.
-pub use path_helpers::{
+pub use crate::external_deps::python::python_command;
+pub use crate::external_deps::rustc::{self, Rustc, bare_rustc, rustc, rustc_path};
+pub use crate::external_deps::rustdoc::{Rustdoc, bare_rustdoc, rustdoc};
+// Path-related helpers.
+pub use crate::path_helpers::{
     build_root, cwd, filename_contains, filename_not_in_denylist, has_extension, has_prefix,
     has_suffix, not_contains, path, shallow_find_directories, shallow_find_files, source_root,
 };
-
-/// Helpers for scoped test execution where certain properties are attempted to be maintained.
-pub use scoped_run::{run_in_tmpdir, test_while_readonly};
-
-pub use assertion_helpers::{
-    assert_contains, assert_contains_regex, assert_count_is, assert_dirs_are_equal, assert_equals,
-    assert_not_contains, assert_not_contains_regex,
-};
-
-pub use string::{
+// Convenience helpers for running binaries and other commands.
+pub use crate::run::{cmd, run, run_fail, run_with_args};
+// Helpers for scoped test execution where certain properties are attempted to be maintained.
+pub use crate::scoped_run::{run_in_tmpdir, test_while_readonly};
+pub use crate::string::{
     count_regex_matches_in_files_with_extension, invalid_utf8_contains, invalid_utf8_not_contains,
 };
+// Helpers for checking target information.
+pub use crate::targets::{
+    apple_os, is_aix, is_darwin, is_win7, is_windows, is_windows_gnu, is_windows_msvc,
+    llvm_components_contain, target, uname,
+};
diff --git a/src/tools/run-make-support/src/linker.rs b/src/tools/run-make-support/src/linker.rs
index 89093cf0113..b2893ad88fe 100644
--- a/src/tools/run-make-support/src/linker.rs
+++ b/src/tools/run-make-support/src/linker.rs
@@ -1,6 +1,6 @@
 use regex::Regex;
 
-use crate::{Rustc, is_msvc};
+use crate::{Rustc, is_windows_msvc};
 
 /// Asserts that `rustc` uses LLD for linking when executed.
 pub fn assert_rustc_uses_lld(rustc: &mut Rustc) {
@@ -22,7 +22,7 @@ pub fn assert_rustc_doesnt_use_lld(rustc: &mut Rustc) {
 
 fn get_stderr_with_linker_messages(rustc: &mut Rustc) -> String {
     // lld-link is used if msvc, otherwise a gnu-compatible lld is used.
-    let linker_version_flag = if is_msvc() { "--version" } else { "-Wl,-v" };
+    let linker_version_flag = if is_windows_msvc() { "--version" } else { "-Wl,-v" };
 
     let output = rustc.arg("-Wlinker-messages").link_arg(linker_version_flag).run();
     output.stderr_utf8()
diff --git a/src/tools/run-make-support/src/targets.rs b/src/tools/run-make-support/src/targets.rs
index 1ab2e2ab2be..b20e12561fb 100644
--- a/src/tools/run-make-support/src/targets.rs
+++ b/src/tools/run-make-support/src/targets.rs
@@ -16,10 +16,10 @@ pub fn is_windows() -> bool {
     target().contains("windows")
 }
 
-/// Check if target uses msvc.
+/// Check if target is windows-msvc.
 #[must_use]
-pub fn is_msvc() -> bool {
-    target().contains("msvc")
+pub fn is_windows_msvc() -> bool {
+    target().ends_with("windows-msvc")
 }
 
 /// Check if target is windows-gnu.
@@ -28,12 +28,6 @@ pub fn is_windows_gnu() -> bool {
     target().ends_with("windows-gnu")
 }
 
-/// Check if target is windows-msvc.
-#[must_use]
-pub fn is_windows_msvc() -> bool {
-    target().ends_with("windows-msvc")
-}
-
 /// Check if target is win7.
 #[must_use]
 pub fn is_win7() -> bool {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
index 22b7f5ac9fd..56fd12e1f2b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
@@ -489,6 +489,14 @@ impl PatCx for MatchCheckCtx<'_> {
     fn complexity_exceeded(&self) -> Result<(), Self::Error> {
         Err(())
     }
+
+    fn report_mixed_deref_pat_ctors(
+        &self,
+        _deref_pat: &DeconstructedPat<'_>,
+        _normal_pat: &DeconstructedPat<'_>,
+    ) {
+        // FIXME(deref_patterns): This could report an error comparable to the one in rustc.
+    }
 }
 
 impl fmt::Debug for MatchCheckCtx<'_> {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
index d258c5d8191..37f83f6dee6 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
@@ -25,7 +25,7 @@ impl flags::Scip {
         eprintln!("Generating SCIP start...");
         let now = Instant::now();
 
-        let no_progress = &|s| (eprintln!("rust-analyzer: Loading {s}"));
+        let no_progress = &|s| eprintln!("rust-analyzer: Loading {s}");
         let root =
             vfs::AbsPathBuf::assert_utf8(std::env::current_dir()?.join(&self.path)).normalize();
 
diff --git a/src/tools/test-float-parse/src/lib.rs b/src/tools/test-float-parse/src/lib.rs
index 0bd4878f9a6..1321a3c3354 100644
--- a/src/tools/test-float-parse/src/lib.rs
+++ b/src/tools/test-float-parse/src/lib.rs
@@ -340,7 +340,7 @@ fn launch_tests(tests: &mut [TestInfo], cfg: &Config) -> Duration {
     for test in tests.iter_mut() {
         test.progress = Some(ui::Progress::new(test, &mut all_progress_bars));
         ui::set_panic_hook(&all_progress_bars);
-        ((test.launch)(test, cfg));
+        (test.launch)(test, cfg);
     }
 
     start.elapsed()
diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs
index d2da63a9703..baab46752a5 100644
--- a/src/tools/tidy/src/ext_tool_checks.rs
+++ b/src/tools/tidy/src/ext_tool_checks.rs
@@ -20,8 +20,11 @@
 use std::ffi::OsStr;
 use std::path::{Path, PathBuf};
 use std::process::Command;
+use std::str::FromStr;
 use std::{fmt, fs, io};
 
+use crate::CiInfo;
+
 const MIN_PY_REV: (u32, u32) = (3, 9);
 const MIN_PY_REV_STR: &str = "≥3.9";
 
@@ -36,15 +39,19 @@ const RUFF_CONFIG_PATH: &[&str] = &["src", "tools", "tidy", "config", "ruff.toml
 const RUFF_CACHE_PATH: &[&str] = &["cache", "ruff_cache"];
 const PIP_REQ_PATH: &[&str] = &["src", "tools", "tidy", "config", "requirements.txt"];
 
+// this must be kept in sync with with .github/workflows/spellcheck.yml
+const SPELLCHECK_DIRS: &[&str] = &["compiler", "library", "src/bootstrap", "src/librustdoc"];
+
 pub fn check(
     root_path: &Path,
     outdir: &Path,
+    ci_info: &CiInfo,
     bless: bool,
     extra_checks: Option<&str>,
     pos_args: &[String],
     bad: &mut bool,
 ) {
-    if let Err(e) = check_impl(root_path, outdir, bless, extra_checks, pos_args) {
+    if let Err(e) = check_impl(root_path, outdir, ci_info, bless, extra_checks, pos_args) {
         tidy_error!(bad, "{e}");
     }
 }
@@ -52,6 +59,7 @@ pub fn check(
 fn check_impl(
     root_path: &Path,
     outdir: &Path,
+    ci_info: &CiInfo,
     bless: bool,
     extra_checks: Option<&str>,
     pos_args: &[String],
@@ -61,25 +69,45 @@ fn check_impl(
 
     // Split comma-separated args up
     let lint_args = match extra_checks {
-        Some(s) => s.strip_prefix("--extra-checks=").unwrap().split(',').collect(),
+        Some(s) => s
+            .strip_prefix("--extra-checks=")
+            .unwrap()
+            .split(',')
+            .map(|s| {
+                if s == "spellcheck:fix" {
+                    eprintln!("warning: `spellcheck:fix` is no longer valid, use `--extra-checks=spellcheck --bless`");
+                }
+                (ExtraCheckArg::from_str(s), s)
+            })
+            .filter_map(|(res, src)| match res {
+                Ok(arg) => {
+                    if arg.is_inactive_auto(ci_info) {
+                        None
+                    } else {
+                        Some(arg)
+                    }
+                }
+                Err(err) => {
+                    // only warn because before bad extra checks would be silently ignored.
+                    eprintln!("warning: bad extra check argument {src:?}: {err:?}");
+                    None
+                }
+            })
+            .collect(),
         None => vec![],
     };
 
-    if lint_args.contains(&"spellcheck:fix") {
-        return Err(Error::Generic(
-            "`spellcheck:fix` is no longer valid, use `--extra=check=spellcheck --bless`"
-                .to_string(),
-        ));
+    macro_rules! extra_check {
+        ($lang:ident, $kind:ident) => {
+            lint_args.iter().any(|arg| arg.matches(ExtraCheckLang::$lang, ExtraCheckKind::$kind))
+        };
     }
 
-    let python_all = lint_args.contains(&"py");
-    let python_lint = lint_args.contains(&"py:lint") || python_all;
-    let python_fmt = lint_args.contains(&"py:fmt") || python_all;
-    let shell_all = lint_args.contains(&"shell");
-    let shell_lint = lint_args.contains(&"shell:lint") || shell_all;
-    let cpp_all = lint_args.contains(&"cpp");
-    let cpp_fmt = lint_args.contains(&"cpp:fmt") || cpp_all;
-    let spellcheck = lint_args.contains(&"spellcheck");
+    let python_lint = extra_check!(Py, Lint);
+    let python_fmt = extra_check!(Py, Fmt);
+    let shell_lint = extra_check!(Shell, Lint);
+    let cpp_fmt = extra_check!(Cpp, Fmt);
+    let spellcheck = extra_check!(Spellcheck, None);
 
     let mut py_path = None;
 
@@ -234,15 +262,9 @@ fn check_impl(
 
     if spellcheck {
         let config_path = root_path.join("typos.toml");
-        // sync target files with .github/workflows/spellcheck.yml
-        let mut args = vec![
-            "-c",
-            config_path.as_os_str().to_str().unwrap(),
-            "./compiler",
-            "./library",
-            "./src/bootstrap",
-            "./src/librustdoc",
-        ];
+        let mut args = vec!["-c", config_path.as_os_str().to_str().unwrap()];
+
+        args.extend_from_slice(SPELLCHECK_DIRS);
 
         if bless {
             eprintln!("spellcheck files and fix");
@@ -638,3 +660,136 @@ impl From<io::Error> for Error {
         Self::Io(value)
     }
 }
+
+#[derive(Debug)]
+enum ExtraCheckParseError {
+    #[allow(dead_code, reason = "shown through Debug")]
+    UnknownKind(String),
+    #[allow(dead_code)]
+    UnknownLang(String),
+    UnsupportedKindForLang,
+    /// Too many `:`
+    TooManyParts,
+    /// Tried to parse the empty string
+    Empty,
+    /// `auto` specified without lang part.
+    AutoRequiresLang,
+}
+
+struct ExtraCheckArg {
+    auto: bool,
+    lang: ExtraCheckLang,
+    /// None = run all extra checks for the given lang
+    kind: Option<ExtraCheckKind>,
+}
+
+impl ExtraCheckArg {
+    fn matches(&self, lang: ExtraCheckLang, kind: ExtraCheckKind) -> bool {
+        self.lang == lang && self.kind.map(|k| k == kind).unwrap_or(true)
+    }
+
+    /// Returns `true` if this is an auto arg and the relevant files are not modified.
+    fn is_inactive_auto(&self, ci_info: &CiInfo) -> bool {
+        if !self.auto {
+            return false;
+        }
+        let ext = match self.lang {
+            ExtraCheckLang::Py => ".py",
+            ExtraCheckLang::Cpp => ".cpp",
+            ExtraCheckLang::Shell => ".sh",
+            ExtraCheckLang::Spellcheck => {
+                return !crate::files_modified(ci_info, |s| {
+                    SPELLCHECK_DIRS.iter().any(|dir| Path::new(s).starts_with(dir))
+                });
+            }
+        };
+        !crate::files_modified(ci_info, |s| s.ends_with(ext))
+    }
+
+    fn has_supported_kind(&self) -> bool {
+        let Some(kind) = self.kind else {
+            // "run all extra checks" mode is supported for all languages.
+            return true;
+        };
+        use ExtraCheckKind::*;
+        let supported_kinds: &[_] = match self.lang {
+            ExtraCheckLang::Py => &[Fmt, Lint],
+            ExtraCheckLang::Cpp => &[Fmt],
+            ExtraCheckLang::Shell => &[Lint],
+            ExtraCheckLang::Spellcheck => &[],
+        };
+        supported_kinds.contains(&kind)
+    }
+}
+
+impl FromStr for ExtraCheckArg {
+    type Err = ExtraCheckParseError;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        let mut auto = false;
+        let mut parts = s.split(':');
+        let Some(mut first) = parts.next() else {
+            return Err(ExtraCheckParseError::Empty);
+        };
+        if first == "auto" {
+            let Some(part) = parts.next() else {
+                return Err(ExtraCheckParseError::AutoRequiresLang);
+            };
+            auto = true;
+            first = part;
+        }
+        let second = parts.next();
+        if parts.next().is_some() {
+            return Err(ExtraCheckParseError::TooManyParts);
+        }
+        let arg = Self { auto, lang: first.parse()?, kind: second.map(|s| s.parse()).transpose()? };
+        if !arg.has_supported_kind() {
+            return Err(ExtraCheckParseError::UnsupportedKindForLang);
+        }
+
+        Ok(arg)
+    }
+}
+
+#[derive(PartialEq, Copy, Clone)]
+enum ExtraCheckLang {
+    Py,
+    Shell,
+    Cpp,
+    Spellcheck,
+}
+
+impl FromStr for ExtraCheckLang {
+    type Err = ExtraCheckParseError;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        Ok(match s {
+            "py" => Self::Py,
+            "shell" => Self::Shell,
+            "cpp" => Self::Cpp,
+            "spellcheck" => Self::Spellcheck,
+            _ => return Err(ExtraCheckParseError::UnknownLang(s.to_string())),
+        })
+    }
+}
+
+#[derive(PartialEq, Copy, Clone)]
+enum ExtraCheckKind {
+    Lint,
+    Fmt,
+    /// Never parsed, but used as a placeholder for
+    /// langs that never have a specific kind.
+    None,
+}
+
+impl FromStr for ExtraCheckKind {
+    type Err = ExtraCheckParseError;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        Ok(match s {
+            "lint" => Self::Lint,
+            "fmt" => Self::Fmt,
+            _ => return Err(ExtraCheckParseError::UnknownKind(s.to_string())),
+        })
+    }
+}
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 237737f0f16..77855392b4d 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -124,6 +124,40 @@ pub fn git_diff<S: AsRef<OsStr>>(base_commit: &str, extra_arg: S) -> Option<Stri
     Some(String::from_utf8_lossy(&output.stdout).into())
 }
 
+/// Returns true if any modified file matches the predicate, if we are in CI, or if unable to list modified files.
+pub fn files_modified(ci_info: &CiInfo, pred: impl Fn(&str) -> bool) -> bool {
+    if CiEnv::is_ci() {
+        // assume everything is modified on CI because we really don't want false positives there.
+        return true;
+    }
+    let Some(base_commit) = &ci_info.base_commit else {
+        eprintln!("No base commit, assuming all files are modified");
+        return true;
+    };
+    match crate::git_diff(&base_commit, "--name-status") {
+        Some(output) => {
+            let modified_files = output.lines().filter_map(|ln| {
+                let (status, name) = ln
+                    .trim_end()
+                    .split_once('\t')
+                    .expect("bad format from `git diff --name-status`");
+                if status == "M" { Some(name) } else { None }
+            });
+            for modified_file in modified_files {
+                if pred(modified_file) {
+                    return true;
+                }
+            }
+            false
+        }
+        None => {
+            eprintln!("warning: failed to run `git diff` to check for changes");
+            eprintln!("warning: assuming all files are modified");
+            true
+        }
+    }
+}
+
 pub mod alphabetical;
 pub mod bins;
 pub mod debug_artifacts;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index ef6ff5c9277..1eb5485f2b8 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -173,7 +173,15 @@ fn main() {
         };
         check!(unstable_book, &src_path, collected);
 
-        check!(ext_tool_checks, &root_path, &output_directory, bless, extra_checks, pos_args);
+        check!(
+            ext_tool_checks,
+            &root_path,
+            &output_directory,
+            &ci_info,
+            bless,
+            extra_checks,
+            pos_args
+        );
     });
 
     if bad.load(Ordering::Relaxed) {
diff --git a/src/tools/tidy/src/rustdoc_json.rs b/src/tools/tidy/src/rustdoc_json.rs
index dfbb35d69f1..19b8e79ec33 100644
--- a/src/tools/tidy/src/rustdoc_json.rs
+++ b/src/tools/tidy/src/rustdoc_json.rs
@@ -14,22 +14,10 @@ pub fn check(src_path: &Path, ci_info: &crate::CiInfo, bad: &mut bool) {
     };
 
     // First we check that `src/rustdoc-json-types` was modified.
-    match crate::git_diff(&base_commit, "--name-status") {
-        Some(output) => {
-            if !output
-                .lines()
-                .any(|line| line.starts_with("M") && line.contains(RUSTDOC_JSON_TYPES))
-            {
-                // `rustdoc-json-types` was not modified so nothing more to check here.
-                println!("`rustdoc-json-types` was not modified.");
-                return;
-            }
-        }
-        None => {
-            *bad = true;
-            eprintln!("error: failed to run `git diff` in rustdoc_json check");
-            return;
-        }
+    if !crate::files_modified(ci_info, |p| p == RUSTDOC_JSON_TYPES) {
+        // `rustdoc-json-types` was not modified so nothing more to check here.
+        println!("`rustdoc-json-types` was not modified.");
+        return;
     }
     // Then we check that if `FORMAT_VERSION` was updated, the `Latest feature:` was also updated.
     match crate::git_diff(&base_commit, src_path.join("rustdoc-json-types")) {
diff --git a/src/tools/unicode-table-generator/src/range_search.rs b/src/tools/unicode-table-generator/src/range_search.rs
index 02f9cf16d4d..4d1dd9b423b 100644
--- a/src/tools/unicode-table-generator/src/range_search.rs
+++ b/src/tools/unicode-table-generator/src/range_search.rs
@@ -80,7 +80,7 @@ unsafe fn skip_search<const SOR: usize, const OFFSETS: usize>(
     let needle = needle as u32;
 
     let last_idx =
-        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| (header.0 << 11)) {
+        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header.0 << 11) {
             Ok(idx) => idx + 1,
             Err(idx) => idx,
         };
diff --git a/tests/codegen/enum/enum-aggregate.rs b/tests/codegen/enum/enum-aggregate.rs
index b6a9b8dd814..0161e5f3fa1 100644
--- a/tests/codegen/enum/enum-aggregate.rs
+++ b/tests/codegen/enum/enum-aggregate.rs
@@ -112,17 +112,14 @@ fn make_uninhabited_err_indirectly(n: Never) -> Result<u32, Never> {
 
 #[no_mangle]
 fn make_fully_uninhabited_result(v: u32, n: Never) -> Result<(u32, Never), (Never, u32)> {
-    // We don't try to do this in SSA form since the whole type is uninhabited.
+    // Actually reaching this would be UB, so we don't actually build a result.
 
     // CHECK-LABEL: { i32, i32 } @make_fully_uninhabited_result(i32 %v)
-    // CHECK: %[[ALLOC_V:.+]] = alloca [4 x i8]
-    // CHECK: %[[RET:.+]] = alloca [8 x i8]
-    // CHECK: store i32 %v, ptr %[[ALLOC_V]]
-    // CHECK: %[[TEMP_V:.+]] = load i32, ptr %[[ALLOC_V]]
-    // CHECK: %[[INNER:.+]] = getelementptr inbounds i8, ptr %[[RET]]
-    // CHECK: store i32 %[[TEMP_V]], ptr %[[INNER]]
-    // CHECK: call void @llvm.trap()
-    // CHECK: unreachable
+    // CHECK-NEXT: start:
+    // CHECK-NEXT: call void @llvm.trap()
+    // CHECK-NEXT: call void @llvm.trap()
+    // CHECK-NEXT: call void @llvm.trap()
+    // CHECK-NEXT: unreachable
     Ok((v, n))
 }
 
diff --git a/tests/codegen/enum/enum-match.rs b/tests/codegen/enum/enum-match.rs
index 6da6ad1f078..98635008d06 100644
--- a/tests/codegen/enum/enum-match.rs
+++ b/tests/codegen/enum/enum-match.rs
@@ -98,7 +98,7 @@ pub enum Enum2 {
     E,
 }
 
-// CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match2(i8{{.+}}%0)
+// CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i8 [0-9]+, -?[0-9]+\))?}} i8 @match2(i8{{.+}}%0)
 // CHECK-NEXT: start:
 // CHECK-NEXT: %[[REL_VAR:.+]] = add i8 %0, 2
 // CHECK-NEXT: %[[REL_VAR_WIDE:.+]] = zext i8 %[[REL_VAR]] to i64
diff --git a/tests/codegen/error-provide.rs b/tests/codegen/error-provide.rs
index 25a66078fd4..7f091e34359 100644
--- a/tests/codegen/error-provide.rs
+++ b/tests/codegen/error-provide.rs
@@ -37,9 +37,9 @@ impl std::error::Error for MyError {
         // and eliminate redundant ones, rather than compare one-by-one.
 
         // CHECK-NEXT: start:
-        // CHECK-NEXT: %[[SCRUTINEE:[^ ]+]] = load i64, ptr
-        // CHECK-NEXT: switch i64 %[[SCRUTINEE]], label %{{.*}} [
-        // CHECK-COUNT-3: i64 {{.*}}, label %{{.*}}
+        // CHECK-NEXT: %[[SCRUTINEE:[^ ]+]] = load i128, ptr
+        // CHECK-NEXT: switch i128 %[[SCRUTINEE]], label %{{.*}} [
+        // CHECK-COUNT-3: i128 {{.*}}, label %{{.*}}
         // CHECK-NEXT: ]
         request
             .provide_ref::<MyBacktrace1>(&self.backtrace1)
diff --git a/tests/codegen/simd/aggregate-simd.rs b/tests/codegen/simd/aggregate-simd.rs
new file mode 100644
index 00000000000..065e429a4c7
--- /dev/null
+++ b/tests/codegen/simd/aggregate-simd.rs
@@ -0,0 +1,106 @@
+//@ compile-flags: -C opt-level=3 -C no-prepopulate-passes
+//@ only-64bit
+
+#![feature(core_intrinsics, repr_simd)]
+#![no_std]
+#![crate_type = "lib"]
+
+use core::intrinsics::simd::{simd_add, simd_extract};
+
+#[repr(simd)]
+#[derive(Clone, Copy)]
+pub struct Simd<T, const N: usize>([T; N]);
+
+#[repr(simd, packed)]
+#[derive(Clone, Copy)]
+pub struct PackedSimd<T, const N: usize>([T; N]);
+
+#[repr(transparent)]
+pub struct Transparent<T>(T);
+
+// These tests don't actually care about the add/extract, but it ensures the
+// aggregated temporaries are only used in potentially-SSA ways.
+
+#[no_mangle]
+pub fn simd_aggregate_pot(x: [u32; 4], y: [u32; 4]) -> u32 {
+    // CHECK-LABEL: simd_aggregate_pot
+    // CHECK: %a = load <4 x i32>, ptr %x, align 4
+    // CHECK: %b = load <4 x i32>, ptr %y, align 4
+    // CHECK: add <4 x i32> %a, %b
+
+    unsafe {
+        let a = Simd(x);
+        let b = Simd(y);
+        let c = simd_add(a, b);
+        simd_extract(c, 1)
+    }
+}
+
+#[no_mangle]
+pub fn simd_aggregate_npot(x: [u32; 7], y: [u32; 7]) -> u32 {
+    // CHECK-LABEL: simd_aggregate_npot
+    // CHECK: %a = load <7 x i32>, ptr %x, align 4
+    // CHECK: %b = load <7 x i32>, ptr %y, align 4
+    // CHECK: add <7 x i32> %a, %b
+
+    unsafe {
+        let a = Simd(x);
+        let b = Simd(y);
+        let c = simd_add(a, b);
+        simd_extract(c, 1)
+    }
+}
+
+#[no_mangle]
+pub fn packed_simd_aggregate_pot(x: [u32; 4], y: [u32; 4]) -> u32 {
+    // CHECK-LABEL: packed_simd_aggregate_pot
+    // CHECK: %a = load <4 x i32>, ptr %x, align 4
+    // CHECK: %b = load <4 x i32>, ptr %y, align 4
+    // CHECK: add <4 x i32> %a, %b
+
+    unsafe {
+        let a = PackedSimd(x);
+        let b = PackedSimd(y);
+        let c = simd_add(a, b);
+        simd_extract(c, 1)
+    }
+}
+
+#[no_mangle]
+pub fn packed_simd_aggregate_npot(x: [u32; 7], y: [u32; 7]) -> u32 {
+    // CHECK-LABEL: packed_simd_aggregate_npot
+    // CHECK: %b = alloca [28 x i8], align 4
+    // CHECK: %a = alloca [28 x i8], align 4
+    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %x, i64 28, i1 false)
+    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %b, ptr align 4 %y, i64 28, i1 false)
+    // CHECK: %[[TEMPA:.+]] = load <7 x i32>, ptr %a, align 4
+    // CHECK: %[[TEMPB:.+]] = load <7 x i32>, ptr %b, align 4
+    // CHECK: add <7 x i32> %[[TEMPA]], %[[TEMPB]]
+
+    unsafe {
+        let a = PackedSimd(x);
+        let b = PackedSimd(y);
+        let c = simd_add(a, b);
+        simd_extract(c, 1)
+    }
+}
+
+#[no_mangle]
+pub fn transparent_simd_aggregate(x: [u32; 4]) -> u32 {
+    // The transparent wrapper can just use the same SSA value as its field.
+    // No extra processing or spilling needed.
+
+    // CHECK-LABEL: transparent_simd_aggregate
+    // CHECK-NOT: alloca
+    // CHECK: %[[RET:.+]] = alloca [4 x i8]
+    // CHECK-NOT: alloca
+    // CHECK: %a = load <4 x i32>, ptr %x, align 4
+    // CHECK: %[[TEMP:.+]] = extractelement <4 x i32> %a, i32 1
+    // CHECK: store i32 %[[TEMP]], ptr %[[RET]]
+
+    unsafe {
+        let a = Simd(x);
+        let b = Transparent(a);
+        simd_extract(b.0, 1)
+    }
+}
diff --git a/tests/codegen/union-aggregate.rs b/tests/codegen/union-aggregate.rs
index 3c6053379fa..aac66c5dcdd 100644
--- a/tests/codegen/union-aggregate.rs
+++ b/tests/codegen/union-aggregate.rs
@@ -4,6 +4,7 @@
 
 #![crate_type = "lib"]
 #![feature(transparent_unions)]
+#![feature(repr_simd)]
 
 #[repr(transparent)]
 union MU<T: Copy> {
@@ -83,3 +84,25 @@ fn make_mu_pair_uninit() -> MU<(u8, u32)> {
     // CHECK-NEXT: ret { i8, i32 } undef
     MU { uninit: () }
 }
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct I32X32([i32; 32]);
+
+#[no_mangle]
+fn make_mu_simd(x: I32X32) -> MU<I32X32> {
+    // CHECK-LABEL: void @make_mu_simd(ptr{{.+}}%_0, ptr{{.+}}%x)
+    // CHECK-NEXT: start:
+    // CHECK-NEXT: %[[TEMP:.+]] = load <32 x i32>, ptr %x,
+    // CHECK-NEXT: store <32 x i32> %[[TEMP]], ptr %_0,
+    // CHECK-NEXT: ret void
+    MU { value: x }
+}
+
+#[no_mangle]
+fn make_mu_simd_uninit() -> MU<I32X32> {
+    // CHECK-LABEL: void @make_mu_simd_uninit(ptr{{.+}}%_0)
+    // CHECK-NEXT: start:
+    // CHECK-NEXT: ret void
+    MU { uninit: () }
+}
diff --git a/tests/mir-opt/otherwise_drops.result_ok.ElaborateDrops.diff b/tests/mir-opt/otherwise_drops.result_ok.ElaborateDrops.diff
new file mode 100644
index 00000000000..9bd4db723d4
--- /dev/null
+++ b/tests/mir-opt/otherwise_drops.result_ok.ElaborateDrops.diff
@@ -0,0 +1,108 @@
+- // MIR for `result_ok` before ElaborateDrops
++ // MIR for `result_ok` after ElaborateDrops
+  
+  fn result_ok(_1: Result<String, ()>) -> Option<String> {
+      debug result => _1;
+      let mut _0: std::option::Option<std::string::String>;
+      let mut _2: isize;
+      let _3: std::string::String;
+      let mut _4: std::string::String;
++     let mut _5: bool;
++     let mut _6: isize;
++     let mut _7: isize;
+      scope 1 {
+          debug s => _3;
+      }
+  
+      bb0: {
++         _5 = const false;
++         _5 = const true;
+          PlaceMention(_1);
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [0: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          _0 = Option::<String>::None;
+          goto -> bb5;
+      }
+  
+      bb2: {
+          StorageLive(_3);
+          _3 = move ((_1 as Ok).0: std::string::String);
+          StorageLive(_4);
+          _4 = move _3;
+          _0 = Option::<String>::Some(move _4);
+-         drop(_4) -> [return: bb3, unwind: bb7];
++         goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_4);
+-         drop(_3) -> [return: bb4, unwind: bb8];
++         goto -> bb4;
+      }
+  
+      bb4: {
+          StorageDead(_3);
+          goto -> bb5;
+      }
+  
+      bb5: {
+-         drop(_1) -> [return: bb6, unwind: bb9];
++         goto -> bb16;
+      }
+  
+      bb6: {
+          return;
+      }
+  
+      bb7 (cleanup): {
+-         drop(_3) -> [return: bb8, unwind terminate(cleanup)];
++         goto -> bb8;
+      }
+  
+      bb8 (cleanup): {
+-         drop(_1) -> [return: bb9, unwind terminate(cleanup)];
++         goto -> bb9;
+      }
+  
+      bb9 (cleanup): {
+          resume;
++     }
++ 
++     bb10: {
++         goto -> bb6;
++     }
++ 
++     bb11 (cleanup): {
++         goto -> bb9;
++     }
++ 
++     bb12 (cleanup): {
++         goto -> bb9;
++     }
++ 
++     bb13: {
++         goto -> bb10;
++     }
++ 
++     bb14: {
++         goto -> bb10;
++     }
++ 
++     bb15 (cleanup): {
++         goto -> bb9;
++     }
++ 
++     bb16: {
++         _6 = discriminant(_1);
++         switchInt(move _6) -> [0: bb13, otherwise: bb14];
++     }
++ 
++     bb17 (cleanup): {
++         _7 = discriminant(_1);
++         switchInt(move _7) -> [0: bb11, otherwise: bb15];
+      }
+  }
+  
diff --git a/tests/mir-opt/otherwise_drops.rs b/tests/mir-opt/otherwise_drops.rs
new file mode 100644
index 00000000000..c4bc05b593c
--- /dev/null
+++ b/tests/mir-opt/otherwise_drops.rs
@@ -0,0 +1,13 @@
+//@ compile-flags: -C panic=abort
+//@ test-mir-pass: ElaborateDrops
+
+// Ensures there are no drops for the wildcard match arm.
+
+// EMIT_MIR otherwise_drops.result_ok.ElaborateDrops.diff
+fn result_ok(result: Result<String, ()>) -> Option<String> {
+    // CHECK-NOT: drop
+    match result {
+        Ok(s) => Some(s),
+        _ => None,
+    }
+}
diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff
index e2d3c6c41b8..0d5fcf9ef14 100644
--- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff
+++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff
@@ -96,7 +96,6 @@
   
       bb2: {
           StorageLive(_8);
-          _28 = const false;
           _8 = move ((_5 as Ok).0: std::boxed::Box<dyn std::fmt::Display>);
           StorageLive(_9);
           StorageLive(_10);
@@ -186,7 +185,7 @@
       bb9: {
           StorageDead(_6);
           _29 = discriminant(_5);
-          switchInt(move _29) -> [0: bb11, otherwise: bb13];
+          switchInt(move _29) -> [0: bb10, otherwise: bb11];
       }
   
       bb10: {
@@ -200,14 +199,6 @@
       }
   
       bb11: {
-          switchInt(copy _28) -> [0: bb10, otherwise: bb12];
-      }
-  
-      bb12: {
-          drop(((_5 as Ok).0: std::boxed::Box<dyn std::fmt::Display>)) -> [return: bb10, unwind unreachable];
-      }
-  
-      bb13: {
           drop(_5) -> [return: bb10, unwind unreachable];
       }
   }
diff --git a/tests/run-make/archive-duplicate-names/rmake.rs b/tests/run-make/archive-duplicate-names/rmake.rs
index 62a35566199..0c352b3ae1b 100644
--- a/tests/run-make/archive-duplicate-names/rmake.rs
+++ b/tests/run-make/archive-duplicate-names/rmake.rs
@@ -6,7 +6,7 @@
 //@ ignore-cross-compile
 // Reason: the compiled binary is executed
 
-use run_make_support::{cc, is_msvc, llvm_ar, rfs, run, rustc};
+use run_make_support::{cc, is_windows_msvc, llvm_ar, rfs, run, rustc};
 
 fn main() {
     rfs::create_dir("a");
@@ -15,7 +15,7 @@ fn main() {
     compile_obj_force_foo("b", "bar");
     let mut ar = llvm_ar();
     ar.obj_to_ar().arg("libfoo.a");
-    if is_msvc() {
+    if is_windows_msvc() {
         ar.arg("a/foo.obj").arg("b/foo.obj").run();
     } else {
         ar.arg("a/foo.o").arg("b/foo.o").run();
@@ -27,9 +27,9 @@ fn main() {
 
 #[track_caller]
 pub fn compile_obj_force_foo(dir: &str, lib_name: &str) {
-    let obj_file = if is_msvc() { format!("{dir}/foo") } else { format!("{dir}/foo.o") };
+    let obj_file = if is_windows_msvc() { format!("{dir}/foo") } else { format!("{dir}/foo.o") };
     let src = format!("{lib_name}.c");
-    if is_msvc() {
+    if is_windows_msvc() {
         cc().arg("-c").out_exe(&obj_file).input(src).run();
     } else {
         cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
diff --git a/tests/run-make/c-link-to-rust-dylib/rmake.rs b/tests/run-make/c-link-to-rust-dylib/rmake.rs
index 3a48af8a366..ece0c81d2da 100644
--- a/tests/run-make/c-link-to-rust-dylib/rmake.rs
+++ b/tests/run-make/c-link-to-rust-dylib/rmake.rs
@@ -3,12 +3,14 @@
 
 //@ ignore-cross-compile
 
-use run_make_support::{cc, cwd, dynamic_lib_extension, is_msvc, rfs, run, run_fail, rustc};
+use run_make_support::{
+    cc, cwd, dynamic_lib_extension, is_windows_msvc, rfs, run, run_fail, rustc,
+};
 
 fn main() {
     rustc().input("foo.rs").run();
 
-    if is_msvc() {
+    if is_windows_msvc() {
         let lib = "foo.dll.lib";
 
         cc().input("bar.c").arg(lib).out_exe("bar").run();
diff --git a/tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs b/tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs
index 62e1748b6fb..ba5fe589acb 100644
--- a/tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs
+++ b/tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs
@@ -8,11 +8,11 @@
 //@ needs-unwind
 // Reason: this test exercises unwinding a panic
 
-use run_make_support::{cc, is_msvc, llvm_ar, run, rustc, static_lib_name};
+use run_make_support::{cc, is_windows_msvc, llvm_ar, run, rustc, static_lib_name};
 
 fn main() {
     // Compile `add.c` into an object file.
-    if is_msvc() {
+    if is_windows_msvc() {
         cc().arg("-c").out_exe("add").input("add.c").run();
     } else {
         cc().arg("-v").arg("-c").out_exe("add.o").input("add.c").run();
@@ -24,7 +24,7 @@ fn main() {
     rustc().emit("obj").input("panic.rs").run();
 
     // Now, create an archive using these two objects.
-    if is_msvc() {
+    if is_windows_msvc() {
         llvm_ar().obj_to_ar().args(&[&static_lib_name("add"), "add.obj", "panic.o"]).run();
     } else {
         llvm_ar().obj_to_ar().args(&[&static_lib_name("add"), "add.o", "panic.o"]).run();
diff --git a/tests/run-make/cdylib-dylib-linkage/rmake.rs b/tests/run-make/cdylib-dylib-linkage/rmake.rs
index a8fd8e2d168..3c145d9f99c 100644
--- a/tests/run-make/cdylib-dylib-linkage/rmake.rs
+++ b/tests/run-make/cdylib-dylib-linkage/rmake.rs
@@ -9,7 +9,7 @@
 
 use run_make_support::{
     bin_name, cc, dynamic_lib_extension, dynamic_lib_name, filename_contains, has_extension,
-    has_prefix, has_suffix, is_msvc, msvc_import_dynamic_lib_name, path, run, rustc,
+    has_prefix, has_suffix, is_windows_msvc, msvc_import_dynamic_lib_name, path, run, rustc,
     shallow_find_files, target,
 };
 
@@ -19,7 +19,7 @@ fn main() {
     let sysroot = rustc().print("sysroot").run().stdout_utf8();
     let sysroot = sysroot.trim();
     let target_sysroot = path(sysroot).join("lib/rustlib").join(target()).join("lib");
-    if is_msvc() {
+    if is_windows_msvc() {
         let mut libs = shallow_find_files(&target_sysroot, |path| {
             has_prefix(path, "libstd-") && has_suffix(path, ".dll.lib")
         });
diff --git a/tests/run-make/cdylib/rmake.rs b/tests/run-make/cdylib/rmake.rs
index 21b83d1b1a9..21fd8b486c4 100644
--- a/tests/run-make/cdylib/rmake.rs
+++ b/tests/run-make/cdylib/rmake.rs
@@ -10,13 +10,13 @@
 
 //@ ignore-cross-compile
 
-use run_make_support::{cc, cwd, dynamic_lib_name, is_msvc, rfs, run, rustc};
+use run_make_support::{cc, cwd, dynamic_lib_name, is_windows_msvc, rfs, run, rustc};
 
 fn main() {
     rustc().input("bar.rs").run();
     rustc().input("foo.rs").run();
 
-    if is_msvc() {
+    if is_windows_msvc() {
         cc().input("foo.c").arg("foo.dll.lib").out_exe("foo").run();
     } else {
         cc().input("foo.c").arg("-lfoo").library_search_path(cwd()).output("foo").run();
diff --git a/tests/run-make/compiler-rt-works-on-mingw/rmake.rs b/tests/run-make/compiler-rt-works-on-mingw/rmake.rs
index f1b41f96312..b15e56db1bb 100644
--- a/tests/run-make/compiler-rt-works-on-mingw/rmake.rs
+++ b/tests/run-make/compiler-rt-works-on-mingw/rmake.rs
@@ -5,7 +5,7 @@
 
 //@ only-windows-gnu
 
-use run_make_support::{cxx, is_msvc, llvm_ar, run, rustc, static_lib_name};
+use run_make_support::{cxx, llvm_ar, run, rustc, static_lib_name};
 
 fn main() {
     cxx().input("foo.cpp").arg("-c").out_exe("foo.o").run();
diff --git a/tests/run-make/compressed-debuginfo-zstd/rmake.rs b/tests/run-make/compressed-debuginfo-zstd/rmake.rs
index cd8cf223047..8d7e5c089da 100644
--- a/tests/run-make/compressed-debuginfo-zstd/rmake.rs
+++ b/tests/run-make/compressed-debuginfo-zstd/rmake.rs
@@ -26,7 +26,7 @@ fn prepare_and_check<F: FnOnce(&mut Rustc) -> &mut Rustc>(to_find: &str, prepare
     run_in_tmpdir(|| {
         let mut rustc = Rustc::new();
         rustc
-            .arg("-Zlinker-features=+lld")
+            .arg("-Clinker-features=+lld")
             .arg("-Clink-self-contained=+linker")
             .arg("-Zunstable-options")
             .arg("-Cdebuginfo=full")
diff --git a/tests/run-make/link-args-order/rmake.rs b/tests/run-make/link-args-order/rmake.rs
index 7a67c12f74c..e3c730bfec5 100644
--- a/tests/run-make/link-args-order/rmake.rs
+++ b/tests/run-make/link-args-order/rmake.rs
@@ -6,10 +6,10 @@
 // checks that linker arguments remain intact and in the order they were originally passed in.
 // See https://github.com/rust-lang/rust/pull/70665
 
-use run_make_support::{is_msvc, rustc};
+use run_make_support::{is_windows_msvc, rustc};
 
 fn main() {
-    let linker = if is_msvc() { "msvc" } else { "ld" };
+    let linker = if is_windows_msvc() { "msvc" } else { "ld" };
 
     rustc()
         .input("empty.rs")
diff --git a/tests/run-make/link-dedup/rmake.rs b/tests/run-make/link-dedup/rmake.rs
index 874e6e0083b..84fdf87e9c7 100644
--- a/tests/run-make/link-dedup/rmake.rs
+++ b/tests/run-make/link-dedup/rmake.rs
@@ -9,7 +9,7 @@
 
 use std::fmt::Write;
 
-use run_make_support::{is_msvc, rustc, target};
+use run_make_support::{is_windows_msvc, rustc, target};
 
 fn main() {
     rustc().input("depa.rs").run();
@@ -32,7 +32,7 @@ fn main() {
 fn needle_from_libs(libs: &[&str]) -> String {
     let mut needle = String::new();
     for lib in libs {
-        if is_msvc() {
+        if is_windows_msvc() {
             needle.write_fmt(format_args!(r#""{lib}.lib" "#)).unwrap();
         } else if target().contains("wasm") {
             needle.write_fmt(format_args!(r#""-l" "{lib}" "#)).unwrap();
diff --git a/tests/run-make/native-link-modifier-bundle/rmake.rs b/tests/run-make/native-link-modifier-bundle/rmake.rs
index 058b66b15f1..64ee7733498 100644
--- a/tests/run-make/native-link-modifier-bundle/rmake.rs
+++ b/tests/run-make/native-link-modifier-bundle/rmake.rs
@@ -20,7 +20,7 @@
 // Reason: cross-compilation fails to export native symbols
 
 use run_make_support::{
-    build_native_static_lib, dynamic_lib_name, is_msvc, llvm_nm, rust_lib_name, rustc,
+    build_native_static_lib, dynamic_lib_name, is_windows_msvc, llvm_nm, rust_lib_name, rustc,
     static_lib_name,
 };
 
@@ -60,7 +60,7 @@ fn main() {
         .assert_stdout_contains_regex("U _*native_func");
 
     // This part of the test does not function on Windows MSVC - no symbols are printed.
-    if !is_msvc() {
+    if !is_windows_msvc() {
         // Build a cdylib, `native-staticlib` will not appear on the linker line because it was
         // bundled previously. The cdylib will contain the `native_func` symbol in the end.
         rustc()
diff --git a/tests/run-make/native-link-modifier-whole-archive/rmake.rs b/tests/run-make/native-link-modifier-whole-archive/rmake.rs
index b8b814043e5..90b0203e278 100644
--- a/tests/run-make/native-link-modifier-whole-archive/rmake.rs
+++ b/tests/run-make/native-link-modifier-whole-archive/rmake.rs
@@ -10,11 +10,11 @@
 // Reason: compiling C++ code does not work well when cross-compiling
 // plus, the compiled binary is executed
 
-use run_make_support::{cxx, is_msvc, llvm_ar, run, run_with_args, rustc, static_lib_name};
+use run_make_support::{cxx, is_windows_msvc, llvm_ar, run, run_with_args, rustc, static_lib_name};
 
 fn main() {
     let mut cxx = cxx();
-    if is_msvc() {
+    if is_windows_msvc() {
         cxx.arg("-EHs");
     }
     cxx.input("c_static_lib_with_constructor.cpp")
@@ -24,7 +24,7 @@ fn main() {
 
     let mut llvm_ar = llvm_ar();
     llvm_ar.obj_to_ar();
-    if is_msvc() {
+    if is_windows_msvc() {
         llvm_ar
             .output_input(
                 static_lib_name("c_static_lib_with_constructor"),
diff --git a/tests/run-make/pointer-auth-link-with-c/rmake.rs b/tests/run-make/pointer-auth-link-with-c/rmake.rs
index 7b6dff10eae..a4d7454e575 100644
--- a/tests/run-make/pointer-auth-link-with-c/rmake.rs
+++ b/tests/run-make/pointer-auth-link-with-c/rmake.rs
@@ -9,7 +9,7 @@
 //@ ignore-cross-compile
 // Reason: the compiled binary is executed
 
-use run_make_support::{build_native_static_lib, cc, is_msvc, llvm_ar, run, rustc};
+use run_make_support::{build_native_static_lib, cc, is_windows_msvc, llvm_ar, run, rustc};
 
 fn main() {
     build_native_static_lib("test");
@@ -21,7 +21,7 @@ fn main() {
         .input("test.c")
         .arg("-mbranch-protection=bti+pac-ret+leaf")
         .run();
-    let obj_file = if is_msvc() { "test.obj" } else { "test" };
+    let obj_file = if is_windows_msvc() { "test.obj" } else { "test" };
     llvm_ar().obj_to_ar().output_input("libtest.a", &obj_file).run();
     rustc().arg("-Zbranch-protection=bti,pac-ret,leaf").input("test.rs").run();
     run("test");
@@ -33,7 +33,7 @@ fn main() {
     //     .input("test.c")
     //     .arg("-mbranch-protection=bti+pac-ret+pc+leaf")
     //     .run();
-    // let obj_file = if is_msvc() { "test.obj" } else { "test" };
+    // let obj_file = if is_windows_msvc() { "test.obj" } else { "test" };
     // llvm_ar().obj_to_ar().output_input("libtest.a", &obj_file).run();
     // rustc().arg("-Zbranch-protection=bti,pac-ret,pc,leaf").input("test.rs").run();
     // run("test");
diff --git a/tests/run-make/print-native-static-libs/rmake.rs b/tests/run-make/print-native-static-libs/rmake.rs
index a51ac934c72..4502c874cae 100644
--- a/tests/run-make/print-native-static-libs/rmake.rs
+++ b/tests/run-make/print-native-static-libs/rmake.rs
@@ -12,7 +12,7 @@
 //@ ignore-cross-compile
 //@ ignore-wasm
 
-use run_make_support::{is_msvc, rustc};
+use run_make_support::{is_windows_msvc, rustc};
 
 fn main() {
     // build supporting crate
@@ -41,9 +41,9 @@ fn main() {
             ($lib:literal in $args:ident) => {{
                 let lib = format!(
                     "{}{}{}",
-                    if !is_msvc() { "-l" } else { "" },
+                    if !is_windows_msvc() { "-l" } else { "" },
                     $lib,
-                    if !is_msvc() { "" } else { ".lib" },
+                    if !is_windows_msvc() { "" } else { ".lib" },
                 );
                 let found = $args.contains(&&*lib);
                 assert!(found, "unable to find lib `{}` in those linker args: {:?}", lib, $args);
diff --git a/tests/run-make/raw-dylib-alt-calling-convention/rmake.rs b/tests/run-make/raw-dylib-alt-calling-convention/rmake.rs
index 1a1622f2754..0843c6beae8 100644
--- a/tests/run-make/raw-dylib-alt-calling-convention/rmake.rs
+++ b/tests/run-make/raw-dylib-alt-calling-convention/rmake.rs
@@ -9,7 +9,9 @@
 //@ only-x86
 //@ only-windows
 
-use run_make_support::{build_native_dynamic_lib, diff, is_msvc, run, run_with_args, rustc};
+use run_make_support::{
+    build_native_dynamic_lib, diff, is_windows_msvc, run, run_with_args, rustc,
+};
 
 fn main() {
     rustc()
@@ -21,7 +23,7 @@ fn main() {
     build_native_dynamic_lib("extern");
     let out = run("driver").stdout_utf8();
     diff().expected_file("output.txt").actual_text("actual", out).normalize(r#"\r"#, "").run();
-    if is_msvc() {
+    if is_windows_msvc() {
         let out_msvc = run_with_args("driver", &["true"]).stdout_utf8();
         diff()
             .expected_file("output.msvc.txt")
diff --git a/tests/run-make/raw-dylib-import-name-type/rmake.rs b/tests/run-make/raw-dylib-import-name-type/rmake.rs
index 13a2c99150e..71f255ab39f 100644
--- a/tests/run-make/raw-dylib-import-name-type/rmake.rs
+++ b/tests/run-make/raw-dylib-import-name-type/rmake.rs
@@ -11,14 +11,14 @@
 //@ only-windows
 // Reason: this test specifically exercises a 32bit Windows calling convention.
 
-use run_make_support::{cc, diff, is_msvc, run, rustc};
+use run_make_support::{cc, diff, is_windows_msvc, run, rustc};
 
 // NOTE: build_native_dynamic lib is not used, as the special `def` files
 // must be passed to the CC compiler.
 
 fn main() {
     rustc().crate_type("bin").input("driver.rs").run();
-    if is_msvc() {
+    if is_windows_msvc() {
         cc().arg("-c").out_exe("extern").input("extern.c").run();
         cc().input("extern.obj")
             .arg("extern.msvc.def")
diff --git a/tests/run-make/raw-dylib-inline-cross-dylib/rmake.rs b/tests/run-make/raw-dylib-inline-cross-dylib/rmake.rs
index 6e3b31a0cdb..a167e8198a7 100644
--- a/tests/run-make/raw-dylib-inline-cross-dylib/rmake.rs
+++ b/tests/run-make/raw-dylib-inline-cross-dylib/rmake.rs
@@ -7,7 +7,7 @@
 
 //@ only-windows
 
-use run_make_support::{cc, diff, is_msvc, llvm_objdump, run, rustc};
+use run_make_support::{cc, diff, is_windows_msvc, llvm_objdump, run, rustc};
 
 fn main() {
     rustc()
@@ -31,7 +31,7 @@ fn main() {
         .assert_stdout_not_contains("inline_library_function")
         // Make sure we do find an import to the functions we expect to be imported.
         .assert_stdout_contains("library_function");
-    if is_msvc() {
+    if is_windows_msvc() {
         cc().arg("-c").out_exe("extern_1").input("extern_1.c").run();
         cc().arg("-c").out_exe("extern_2").input("extern_2.c").run();
         cc().input("extern_1.obj")
diff --git a/tests/run-make/raw-dylib-link-ordinal/rmake.rs b/tests/run-make/raw-dylib-link-ordinal/rmake.rs
index b52181ae3f9..43274b9765b 100644
--- a/tests/run-make/raw-dylib-link-ordinal/rmake.rs
+++ b/tests/run-make/raw-dylib-link-ordinal/rmake.rs
@@ -11,7 +11,7 @@
 
 //@ only-windows
 
-use run_make_support::{cc, diff, is_msvc, run, rustc};
+use run_make_support::{cc, diff, is_windows_msvc, run, rustc};
 
 // NOTE: build_native_dynamic lib is not used, as the special `def` files
 // must be passed to the CC compiler.
@@ -19,7 +19,7 @@ use run_make_support::{cc, diff, is_msvc, run, rustc};
 fn main() {
     rustc().crate_type("lib").crate_name("raw_dylib_test").input("lib.rs").run();
     rustc().crate_type("bin").input("driver.rs").run();
-    if is_msvc() {
+    if is_windows_msvc() {
         cc().arg("-c").out_exe("exporter").input("exporter.c").run();
         cc().input("exporter.obj")
             .arg("exporter.def")
diff --git a/tests/run-make/raw-dylib-stdcall-ordinal/rmake.rs b/tests/run-make/raw-dylib-stdcall-ordinal/rmake.rs
index 320ea1520d8..f898cc0f8c8 100644
--- a/tests/run-make/raw-dylib-stdcall-ordinal/rmake.rs
+++ b/tests/run-make/raw-dylib-stdcall-ordinal/rmake.rs
@@ -10,7 +10,7 @@
 //@ only-windows
 // Reason: this test specifically exercises a 32bit Windows calling convention.
 
-use run_make_support::{cc, diff, is_msvc, run, rustc};
+use run_make_support::{cc, diff, is_windows_msvc, run, rustc};
 
 // NOTE: build_native_dynamic lib is not used, as the special `def` files
 // must be passed to the CC compiler.
@@ -18,7 +18,7 @@ use run_make_support::{cc, diff, is_msvc, run, rustc};
 fn main() {
     rustc().crate_type("lib").crate_name("raw_dylib_test").input("lib.rs").run();
     rustc().crate_type("bin").input("driver.rs").run();
-    if is_msvc() {
+    if is_windows_msvc() {
         cc().arg("-c").out_exe("exporter").input("exporter.c").run();
         cc().input("exporter.obj")
             .arg("exporter-msvc.def")
diff --git a/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs b/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs
index ff0438a6b72..f0929a3ee85 100644
--- a/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs
+++ b/tests/run-make/rlib-format-packed-bundled-libs/rmake.rs
@@ -8,8 +8,8 @@
 // Reason: cross-compilation fails to export native symbols
 
 use run_make_support::{
-    bin_name, build_native_static_lib, cwd, filename_contains, is_msvc, llvm_ar, llvm_nm, rfs,
-    rust_lib_name, rustc, shallow_find_files,
+    bin_name, build_native_static_lib, cwd, filename_contains, is_windows_msvc, llvm_ar, llvm_nm,
+    rfs, rust_lib_name, rustc, shallow_find_files,
 };
 
 fn main() {
@@ -74,7 +74,7 @@ fn main() {
         .assert_stdout_contains_regex("native_dep_1.*native_dep_2.*native_dep_3");
 
     // The binary "main" will not contain any symbols on MSVC.
-    if !is_msvc() {
+    if !is_windows_msvc() {
         llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f1");
         llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f2");
         llvm_nm().input(bin_name("main")).run().assert_stdout_contains_regex("T.*native_f3");
diff --git a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs
deleted file mode 100644
index 9a08991c4b8..00000000000
--- a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Ensure that rust-lld is *not* used as the default linker on `x86_64-unknown-linux-gnu` on stable
-// or beta.
-
-//@ ignore-nightly
-//@ only-x86_64-unknown-linux-gnu
-
-use run_make_support::linker::assert_rustc_doesnt_use_lld;
-use run_make_support::rustc;
-
-fn main() {
-    // A regular compilation should not use rust-lld by default. We'll check that by asking the
-    // linker to display its version number with a link-arg.
-    assert_rustc_doesnt_use_lld(rustc().input("main.rs"));
-}
diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs
index e2b065a10b1..90ba424ffe9 100644
--- a/tests/run-make/rust-lld-custom-target/rmake.rs
+++ b/tests/run-make/rust-lld-custom-target/rmake.rs
@@ -23,7 +23,8 @@ fn main() {
         rustc()
             .crate_type("cdylib")
             .target("custom-target.json")
-            .arg("-Zlinker-features=-lld")
+            .arg("-Clinker-features=-lld")
+            .arg("-Zunstable-options")
             .input("lib.rs"),
     );
 }
diff --git a/tests/run-make/rust-lld-link-script-provide/rmake.rs b/tests/run-make/rust-lld-link-script-provide/rmake.rs
index e78a411bc15..c637dff9038 100644
--- a/tests/run-make/rust-lld-link-script-provide/rmake.rs
+++ b/tests/run-make/rust-lld-link-script-provide/rmake.rs
@@ -10,7 +10,7 @@ use run_make_support::rustc;
 fn main() {
     rustc()
         .input("main.rs")
-        .arg("-Zlinker-features=+lld")
+        .arg("-Clinker-features=+lld")
         .arg("-Clink-self-contained=+linker")
         .arg("-Zunstable-options")
         .link_arg("-Tscript.t")
diff --git a/tests/run-make/rust-lld-by-default-nightly/main.rs b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/main.rs
index e9f655fc09e..e9f655fc09e 100644
--- a/tests/run-make/rust-lld-by-default-nightly/main.rs
+++ b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/main.rs
diff --git a/tests/run-make/rust-lld-by-default-nightly/rmake.rs b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs
index 3ff1e2770e6..c315d36a39d 100644
--- a/tests/run-make/rust-lld-by-default-nightly/rmake.rs
+++ b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs
@@ -1,19 +1,16 @@
-// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu` on the nightly
-// channel, and that it can also be turned off with a CLI flag.
+// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu`
+// dist artifacts and that it can also be turned off with a CLI flag.
 
-//@ needs-rust-lld
-//@ ignore-beta
-//@ ignore-stable
+//@ only-dist
 //@ only-x86_64-unknown-linux-gnu
 
 use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld};
 use run_make_support::rustc;
 
 fn main() {
-    // A regular compilation should use rust-lld by default. We'll check that by asking the linker
-    // to display its version number with a link-arg.
+    // A regular compilation should use rust-lld by default.
     assert_rustc_uses_lld(rustc().input("main.rs"));
 
     // But it can still be disabled by turning the linker feature off.
-    assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs"));
+    assert_rustc_doesnt_use_lld(rustc().arg("-Clinker-features=-lld").input("main.rs"));
 }
diff --git a/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/main.rs b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/main.rs
new file mode 100644
index 00000000000..e9f655fc09e
--- /dev/null
+++ b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/main.rs
@@ -0,0 +1,5 @@
+// Test linking using `cc` with `rust-lld`, which is on by default on the x86_64-unknown-linux-gnu
+// target.
+// See https://github.com/rust-lang/compiler-team/issues/510 for more info
+
+fn main() {}
diff --git a/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs
new file mode 100644
index 00000000000..00415d27aaf
--- /dev/null
+++ b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs
@@ -0,0 +1,20 @@
+// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu`
+// and that it can also be turned off with a CLI flag.
+//
+// This version of the test checks that LLD is used by default when LLD is enabled in the
+// toolchain. There is a separate test that checks that LLD is used for dist artifacts
+// unconditionally.
+
+//@ needs-rust-lld
+//@ only-x86_64-unknown-linux-gnu
+
+use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld};
+use run_make_support::rustc;
+
+fn main() {
+    // A regular compilation should use rust-lld by default.
+    assert_rustc_uses_lld(rustc().input("main.rs"));
+
+    // But it can still be disabled by turning the linker feature off.
+    assert_rustc_doesnt_use_lld(rustc().arg("-Clinker-features=-lld").input("main.rs"));
+}
diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs
index 9470f5d0be1..932c2697ba0 100644
--- a/tests/run-make/rust-lld/rmake.rs
+++ b/tests/run-make/rust-lld/rmake.rs
@@ -1,5 +1,5 @@
-// Test linking using `cc` with `rust-lld`, using the unstable CLI described in MCP 510
-// see https://github.com/rust-lang/compiler-team/issues/510 for more info
+// Test linking using `cc` with `rust-lld`, using the `-Clinker-features` and
+// `-Clink-self-contained` CLI flags.
 
 //@ needs-rust-lld
 //@ ignore-s390x lld does not yet support s390x as target
@@ -12,14 +12,16 @@ fn main() {
     // asking the linker to display its version number with a link-arg.
     assert_rustc_uses_lld(
         rustc()
-            .arg("-Zlinker-features=+lld")
+            .arg("-Clinker-features=+lld")
             .arg("-Clink-self-contained=+linker")
-            .arg("-Zunstable-options")
+            .arg("-Zunstable-options") // the opt-ins are unstable
             .input("main.rs"),
     );
 
     // It should not be used when we explicitly opt out of lld.
-    assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs"));
+    assert_rustc_doesnt_use_lld(
+        rustc().arg("-Clinker-features=-lld").arg("-Zunstable-options").input("main.rs"),
+    );
 
     // While we're here, also check that the last linker feature flag "wins" when passed multiple
     // times to rustc.
@@ -27,9 +29,9 @@ fn main() {
         rustc()
             .arg("-Clink-self-contained=+linker")
             .arg("-Zunstable-options")
-            .arg("-Zlinker-features=-lld")
-            .arg("-Zlinker-features=+lld")
-            .arg("-Zlinker-features=-lld,+lld")
+            .arg("-Clinker-features=-lld")
+            .arg("-Clinker-features=+lld")
+            .arg("-Clinker-features=-lld,+lld")
             .input("main.rs"),
     );
 }
diff --git a/tests/run-make/split-debuginfo/rmake.rs b/tests/run-make/split-debuginfo/rmake.rs
index 530a5d119f1..e8de5aed172 100644
--- a/tests/run-make/split-debuginfo/rmake.rs
+++ b/tests/run-make/split-debuginfo/rmake.rs
@@ -61,8 +61,8 @@ use std::collections::BTreeSet;
 
 use run_make_support::rustc::Rustc;
 use run_make_support::{
-    cwd, has_extension, is_darwin, is_msvc, is_windows, llvm_dwarfdump, run_in_tmpdir, rustc,
-    shallow_find_directories, shallow_find_files, uname,
+    cwd, has_extension, is_darwin, is_windows, is_windows_msvc, llvm_dwarfdump, run_in_tmpdir,
+    rustc, shallow_find_directories, shallow_find_files, uname,
 };
 
 /// `-C debuginfo`. See <https://doc.rust-lang.org/rustc/codegen-options/index.html#debuginfo>.
@@ -1296,7 +1296,7 @@ fn main() {
     // identify which combination isn't exercised with a 6-layers nested for loop iterating through
     // each of the cli flag enum variants.
 
-    if is_msvc() {
+    if is_windows_msvc() {
         // FIXME: the windows-msvc test coverage is sparse at best.
 
         windows_msvc_tests::split_debuginfo(SplitDebuginfo::Off, DebuginfoLevel::Unspecified);
diff --git a/tests/run-make/static-dylib-by-default/rmake.rs b/tests/run-make/static-dylib-by-default/rmake.rs
index 133210c74e7..b1160c63297 100644
--- a/tests/run-make/static-dylib-by-default/rmake.rs
+++ b/tests/run-make/static-dylib-by-default/rmake.rs
@@ -9,7 +9,7 @@
 // Reason: the compiled binary is executed
 
 use run_make_support::{
-    cc, cwd, dynamic_lib_name, extra_c_flags, has_extension, is_msvc, rfs, run, rustc,
+    cc, cwd, dynamic_lib_name, extra_c_flags, has_extension, is_windows_msvc, rfs, run, rustc,
     shallow_find_files,
 };
 
@@ -22,13 +22,13 @@ fn main() {
     // bar.dll.exp // export library for the dylib
     // msvc's underlying link.exe requires the import library for the dynamic library as input.
     // That is why the library is bar.dll.lib, not bar.dll.
-    let library = if is_msvc() { "bar.dll.lib" } else { &dynamic_lib_name("bar") };
+    let library = if is_windows_msvc() { "bar.dll.lib" } else { &dynamic_lib_name("bar") };
     cc().input("main.c").out_exe("main").arg(library).args(extra_c_flags()).run();
     for rlib in shallow_find_files(cwd(), |path| has_extension(path, "rlib")) {
         rfs::remove_file(rlib);
     }
     rfs::remove_file(dynamic_lib_name("foo"));
-    if is_msvc() {
+    if is_windows_msvc() {
         rfs::remove_file("foo.dll.lib");
     }
     run("main");
diff --git a/tests/run-make/staticlib-dylib-linkage/rmake.rs b/tests/run-make/staticlib-dylib-linkage/rmake.rs
index 8dd1ac0ffbd..9582ca19831 100644
--- a/tests/run-make/staticlib-dylib-linkage/rmake.rs
+++ b/tests/run-make/staticlib-dylib-linkage/rmake.rs
@@ -9,7 +9,7 @@
 //@ ignore-wasm
 // Reason: WASM does not support dynamic libraries
 
-use run_make_support::{cc, is_msvc, regex, run, rustc, static_lib_name};
+use run_make_support::{cc, is_windows_msvc, regex, run, rustc, static_lib_name};
 
 fn main() {
     rustc().arg("-Cprefer-dynamic").input("bar.rs").run();
@@ -27,7 +27,7 @@ fn main() {
     let (_, native_link_args) = libs.split_once("note: native-static-libs: ").unwrap();
     // divide the command-line arguments in a vec
     let mut native_link_args = native_link_args.split(' ').collect::<Vec<&str>>();
-    if is_msvc() {
+    if is_windows_msvc() {
         // For MSVC pass the arguments on to the linker.
         native_link_args.insert(0, "-link");
     }
diff --git a/tests/run-make/symbol-visibility/rmake.rs b/tests/run-make/symbol-visibility/rmake.rs
index 49c8e87707b..e3d276d6da8 100644
--- a/tests/run-make/symbol-visibility/rmake.rs
+++ b/tests/run-make/symbol-visibility/rmake.rs
@@ -9,7 +9,7 @@
 // See https://github.com/rust-lang/rust/issues/37530
 
 use run_make_support::object::read::Object;
-use run_make_support::{bin_name, dynamic_lib_name, is_msvc, object, regex, rfs, rustc};
+use run_make_support::{bin_name, dynamic_lib_name, is_windows_msvc, object, regex, rfs, rustc};
 
 fn main() {
     let cdylib_name = dynamic_lib_name("a_cdylib");
@@ -64,7 +64,7 @@ fn main() {
     );
 
     // FIXME(nbdd0121): This is broken in MinGW, see https://github.com/rust-lang/rust/pull/95604#issuecomment-1101564032
-    if is_msvc() {
+    if is_windows_msvc() {
         // Check that an executable does not export any dynamic symbols
         symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), false);
         symbols_check(
@@ -130,7 +130,7 @@ fn main() {
     );
 
     // FIXME(nbdd0121): This is broken in MinGW, see https://github.com/rust-lang/rust/pull/95604#issuecomment-1101564032
-    if is_msvc() {
+    if is_windows_msvc() {
         // Check that an executable does not export any dynamic symbols
         symbols_check(&exe_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), false);
         symbols_check(
diff --git a/tests/rustdoc-json/attrs/target_feature.rs b/tests/rustdoc-json/attrs/target_feature.rs
index ee2b3235f72..80262d8e332 100644
--- a/tests/rustdoc-json/attrs/target_feature.rs
+++ b/tests/rustdoc-json/attrs/target_feature.rs
@@ -1,17 +1,40 @@
 //@ only-x86_64
 
 //@ is "$.index[?(@.name=='test1')].attrs" '["#[target_feature(enable=\"avx\")]"]'
+//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
 #[target_feature(enable = "avx")]
 pub fn test1() {}
 
 //@ is "$.index[?(@.name=='test2')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]'
+//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
 #[target_feature(enable = "avx,avx2")]
 pub fn test2() {}
 
 //@ is "$.index[?(@.name=='test3')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]'
+//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
 #[target_feature(enable = "avx", enable = "avx2")]
 pub fn test3() {}
 
 //@ is "$.index[?(@.name=='test4')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\", enable=\"avx512f\")]"]'
+//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
 #[target_feature(enable = "avx", enable = "avx2,avx512f")]
 pub fn test4() {}
+
+//@ is "$.index[?(@.name=='test_unsafe_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
+//@ is "$.index[?(@.name=='test_unsafe_fn')].inner.function.header.is_unsafe" true
+#[target_feature(enable = "avx")]
+pub unsafe fn test_unsafe_fn() {}
+
+pub struct Example;
+
+impl Example {
+    //@ is "$.index[?(@.name=='safe_assoc_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
+    //@ is "$.index[?(@.name=='safe_assoc_fn')].inner.function.header.is_unsafe" false
+    #[target_feature(enable = "avx")]
+    pub fn safe_assoc_fn() {}
+
+    //@ is "$.index[?(@.name=='unsafe_assoc_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
+    //@ is "$.index[?(@.name=='unsafe_assoc_fn')].inner.function.header.is_unsafe" true
+    #[target_feature(enable = "avx")]
+    pub unsafe fn unsafe_assoc_fn() {}
+}
diff --git a/tests/ui-fulldeps/auxiliary/obtain-borrowck-input.rs b/tests/ui-fulldeps/auxiliary/obtain-borrowck-input.rs
index 7213e06792a..9cfc901eabe 100644
--- a/tests/ui-fulldeps/auxiliary/obtain-borrowck-input.rs
+++ b/tests/ui-fulldeps/auxiliary/obtain-borrowck-input.rs
@@ -28,6 +28,10 @@ const fn foo() -> usize {
     1
 }
 
+fn with_nested_body(opt: Option<i32>) -> Option<i32> {
+    opt.map(|x| x + 1)
+}
+
 fn main() {
     let bar: [Bar; foo()] = [Bar::new()];
     assert_eq!(bar[0].provided(), foo());
diff --git a/tests/ui-fulldeps/obtain-borrowck.rs b/tests/ui-fulldeps/obtain-borrowck.rs
index 84f6970c83a..08213fd7588 100644
--- a/tests/ui-fulldeps/obtain-borrowck.rs
+++ b/tests/ui-fulldeps/obtain-borrowck.rs
@@ -9,16 +9,17 @@
 
 //! This program implements a rustc driver that retrieves MIR bodies with
 //! borrowck information. This cannot be done in a straightforward way because
-//! `get_body_with_borrowck_facts`–the function for retrieving a MIR body with
-//! borrowck facts–can panic if the body is stolen before it is invoked.
+//! `get_bodies_with_borrowck_facts`–the function for retrieving MIR bodies with
+//! borrowck facts–can panic if the bodies are stolen before it is invoked.
 //! Therefore, the driver overrides `mir_borrowck` query (this is done in the
-//! `config` callback), which retrieves the body that is about to be borrow
-//! checked and stores it in a thread local `MIR_BODIES`. Then, `after_analysis`
+//! `config` callback), which retrieves the bodies that are about to be borrow
+//! checked and stores them in a thread local `MIR_BODIES`. Then, `after_analysis`
 //! callback triggers borrow checking of all MIR bodies by retrieving
 //! `optimized_mir` and pulls out the MIR bodies with the borrowck information
 //! from the thread local storage.
 
 extern crate rustc_borrowck;
+extern crate rustc_data_structures;
 extern crate rustc_driver;
 extern crate rustc_hir;
 extern crate rustc_interface;
@@ -30,6 +31,7 @@ use std::collections::HashMap;
 use std::thread_local;
 
 use rustc_borrowck::consumers::{self, BodyWithBorrowckFacts, ConsumerOptions};
+use rustc_data_structures::fx::FxHashMap;
 use rustc_driver::Compilation;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
@@ -129,13 +131,15 @@ thread_local! {
 
 fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ProvidedValue<'tcx> {
     let opts = ConsumerOptions::PoloniusInputFacts;
-    let body_with_facts = consumers::get_body_with_borrowck_facts(tcx, def_id, opts);
+    let bodies_with_facts = consumers::get_bodies_with_borrowck_facts(tcx, def_id, opts);
     // SAFETY: The reader casts the 'static lifetime to 'tcx before using it.
-    let body_with_facts: BodyWithBorrowckFacts<'static> =
-        unsafe { std::mem::transmute(body_with_facts) };
+    let bodies_with_facts: FxHashMap<LocalDefId, BodyWithBorrowckFacts<'static>> =
+        unsafe { std::mem::transmute(bodies_with_facts) };
     MIR_BODIES.with(|state| {
         let mut map = state.borrow_mut();
-        assert!(map.insert(def_id, body_with_facts).is_none());
+        for (def_id, body_with_facts) in bodies_with_facts {
+            assert!(map.insert(def_id, body_with_facts).is_none());
+        }
     });
     let mut providers = Providers::default();
     rustc_borrowck::provide(&mut providers);
diff --git a/tests/ui-fulldeps/obtain-borrowck.run.stdout b/tests/ui-fulldeps/obtain-borrowck.run.stdout
index e011622e6b2..09d3e50f42d 100644
--- a/tests/ui-fulldeps/obtain-borrowck.run.stdout
+++ b/tests/ui-fulldeps/obtain-borrowck.run.stdout
@@ -3,6 +3,8 @@ Bodies retrieved for:
 ::foo
 ::main
 ::main::{constant#0}
+::with_nested_body
+::with_nested_body::{closure#0}
 ::{impl#0}::new
 ::{impl#1}::provided
 ::{impl#1}::required
diff --git a/tests/ui/async-await/issues/issue-54752-async-block.rs b/tests/ui/async-await/issues/issue-54752-async-block.rs
index 452b6794bee..164c1885da1 100644
--- a/tests/ui/async-await/issues/issue-54752-async-block.rs
+++ b/tests/ui/async-await/issues/issue-54752-async-block.rs
@@ -4,4 +4,3 @@
 //@ pp-exact
 
 fn main() { let _a = (async { }); }
-//~^ WARNING unnecessary parentheses around assigned value
diff --git a/tests/ui/async-await/issues/issue-54752-async-block.stderr b/tests/ui/async-await/issues/issue-54752-async-block.stderr
deleted file mode 100644
index 8cc849dd985..00000000000
--- a/tests/ui/async-await/issues/issue-54752-async-block.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-warning: unnecessary parentheses around assigned value
-  --> $DIR/issue-54752-async-block.rs:6:22
-   |
-LL | fn main() { let _a = (async { }); }
-   |                      ^         ^
-   |
-   = note: `#[warn(unused_parens)]` on by default
-help: remove these parentheses
-   |
-LL - fn main() { let _a = (async { }); }
-LL + fn main() { let _a = async { }; }
-   |
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr
index 2f7bf50ead5..5bcb0c4dc0a 100644
--- a/tests/ui/attributes/malformed-attrs.stderr
+++ b/tests/ui/attributes/malformed-attrs.stderr
@@ -40,12 +40,6 @@ error: malformed `crate_name` attribute input
 LL | #[crate_name]
    | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]`
 
-error: malformed `export_stable` attribute input
-  --> $DIR/malformed-attrs.rs:81:1
-   |
-LL | #[export_stable = 1]
-   | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]`
-
 error: malformed `coverage` attribute input
   --> $DIR/malformed-attrs.rs:90:1
    |
@@ -140,24 +134,12 @@ error: malformed `fundamental` attribute input
 LL | #[fundamental()]
    | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]`
 
-error: malformed `ffi_pure` attribute input
-  --> $DIR/malformed-attrs.rs:165:5
-   |
-LL |     #[unsafe(ffi_pure = 1)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_pure]`
-
 error: malformed `link_ordinal` attribute input
   --> $DIR/malformed-attrs.rs:167:5
    |
 LL |     #[link_ordinal]
    |     ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_ordinal(ordinal)]`
 
-error: malformed `ffi_const` attribute input
-  --> $DIR/malformed-attrs.rs:171:5
-   |
-LL |     #[unsafe(ffi_const = 1)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_const]`
-
 error: malformed `linkage` attribute input
   --> $DIR/malformed-attrs.rs:173:5
    |
@@ -481,6 +463,15 @@ LL | #[target_feature]
    | expected this to be a list
    | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]`
 
+error[E0565]: malformed `export_stable` attribute input
+  --> $DIR/malformed-attrs.rs:81:1
+   |
+LL | #[export_stable = 1]
+   | ^^^^^^^^^^^^^^^^---^
+   | |               |
+   | |               didn't expect any arguments here
+   | help: must be of the form: `#[export_stable]`
+
 error[E0539]: malformed `link_name` attribute input
   --> $DIR/malformed-attrs.rs:86:1
    |
@@ -537,6 +528,24 @@ LL | #[rustc_layout_scalar_valid_range_end]
    | expected this to be a list
    | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]`
 
+error[E0565]: malformed `ffi_pure` attribute input
+  --> $DIR/malformed-attrs.rs:165:5
+   |
+LL |     #[unsafe(ffi_pure = 1)]
+   |     ^^^^^^^^^^^^^^^^^^---^^
+   |     |                 |
+   |     |                 didn't expect any arguments here
+   |     help: must be of the form: `#[ffi_pure]`
+
+error[E0565]: malformed `ffi_const` attribute input
+  --> $DIR/malformed-attrs.rs:171:5
+   |
+LL |     #[unsafe(ffi_const = 1)]
+   |     ^^^^^^^^^^^^^^^^^^^---^^
+   |     |                  |
+   |     |                  didn't expect any arguments here
+   |     help: must be of the form: `#[ffi_const]`
+
 error[E0565]: malformed `non_exhaustive` attribute input
   --> $DIR/malformed-attrs.rs:197:1
    |
diff --git a/tests/ui/output-slot-variants.rs b/tests/ui/codegen/output-slot-init-vs-noninit.rs
index 97757e74fc4..55586843740 100644
--- a/tests/ui/output-slot-variants.rs
+++ b/tests/ui/codegen/output-slot-init-vs-noninit.rs
@@ -1,26 +1,48 @@
+//! Check that output slots work correctly for both initializing and non-initializing assignments.
+//!
+//! Regression test for <https://github.com/rust-lang/rust/issues/24>.
+
 //@ run-pass
 
 #![allow(dead_code)]
 #![allow(unused_assignments)]
 #![allow(unknown_lints)]
-
 #![allow(dead_assignment)]
 #![allow(unused_variables)]
 
-struct A { a: isize, b: isize }
-struct Abox { a: Box<isize>, b: Box<isize> }
+struct A {
+    a: isize,
+    b: isize,
+}
 
-fn ret_int_i() -> isize { 10 }
+struct Abox {
+    a: Box<isize>,
+    b: Box<isize>,
+}
 
-fn ret_ext_i() -> Box<isize> { Box::new(10) }
+fn ret_int_i() -> isize {
+    10
+}
 
-fn ret_int_rec() -> A { A {a: 10, b: 10} }
+fn ret_ext_i() -> Box<isize> {
+    Box::new(10)
+}
 
-fn ret_ext_rec() -> Box<A> { Box::new(A {a: 10, b: 10}) }
+fn ret_int_rec() -> A {
+    A { a: 10, b: 10 }
+}
 
-fn ret_ext_mem() -> Abox { Abox {a: Box::new(10), b: Box::new(10) } }
+fn ret_ext_rec() -> Box<A> {
+    Box::new(A { a: 10, b: 10 })
+}
+
+fn ret_ext_mem() -> Abox {
+    Abox { a: Box::new(10), b: Box::new(10) }
+}
 
-fn ret_ext_ext_mem() -> Box<Abox> { Box::new(Abox{a: Box::new(10), b: Box::new(10) }) }
+fn ret_ext_ext_mem() -> Box<Abox> {
+    Box::new(Abox { a: Box::new(10), b: Box::new(10) })
+}
 
 pub fn main() {
     let mut int_i: isize;
@@ -29,40 +51,28 @@ pub fn main() {
     let mut ext_rec: Box<A>;
     let mut ext_mem: Abox;
     let mut ext_ext_mem: Box<Abox>;
-    int_i = ret_int_i(); // initializing
 
+    int_i = ret_int_i(); // initializing
     int_i = ret_int_i(); // non-initializing
-
     int_i = ret_int_i(); // non-initializing
 
     ext_i = ret_ext_i(); // initializing
-
     ext_i = ret_ext_i(); // non-initializing
-
     ext_i = ret_ext_i(); // non-initializing
 
     int_rec = ret_int_rec(); // initializing
-
     int_rec = ret_int_rec(); // non-initializing
-
     int_rec = ret_int_rec(); // non-initializing
 
     ext_rec = ret_ext_rec(); // initializing
-
     ext_rec = ret_ext_rec(); // non-initializing
-
     ext_rec = ret_ext_rec(); // non-initializing
 
     ext_mem = ret_ext_mem(); // initializing
-
     ext_mem = ret_ext_mem(); // non-initializing
-
     ext_mem = ret_ext_mem(); // non-initializing
 
     ext_ext_mem = ret_ext_ext_mem(); // initializing
-
     ext_ext_mem = ret_ext_ext_mem(); // non-initializing
-
     ext_ext_mem = ret_ext_ext_mem(); // non-initializing
-
 }
diff --git a/tests/ui/optimization-remark.rs b/tests/ui/codegen/remark-flag-functionality.rs
index 165fc63c007..797c55ba830 100644
--- a/tests/ui/optimization-remark.rs
+++ b/tests/ui/codegen/remark-flag-functionality.rs
@@ -1,24 +1,26 @@
+//! Check that `-Cremark` flag correctly emits LLVM optimization remarks.
+//!
+//! Regression test for <https://github.com/rust-lang/rust/issues/90924>.
+
 //@ build-pass
 //@ ignore-pass
 //@ revisions: all inline merge1 merge2
 //@ compile-flags: --crate-type=lib -Cdebuginfo=1 -Copt-level=2
-//
+
 // Check that remarks can be enabled individually or with "all":
-//
 //@ [all]    compile-flags: -Cremark=all
 //@ [inline] compile-flags: -Cremark=inline
-//
+
 // Check that values of -Cremark flag are accumulated:
-//
 //@ [merge1] compile-flags: -Cremark=all    -Cremark=giraffe
 //@ [merge2] compile-flags: -Cremark=inline -Cremark=giraffe
+
 //@ dont-check-compiler-stderr
 //@ dont-require-annotations: NOTE
 
 #[no_mangle]
 #[inline(never)]
-pub fn f() {
-}
+pub fn f() {}
 
 #[no_mangle]
 pub fn g() {
diff --git a/tests/ui/codegen/shift-right-operand-mutation.rs b/tests/ui/codegen/shift-right-operand-mutation.rs
new file mode 100644
index 00000000000..b37a0baa6f8
--- /dev/null
+++ b/tests/ui/codegen/shift-right-operand-mutation.rs
@@ -0,0 +1,19 @@
+//! Ensure shift operations don't mutate their right operand.
+//!
+//! This test checks that expressions like `0 << b` don't accidentally
+//! modify the variable `b` due to codegen issues with virtual registers.
+//!
+//! Regression test for <https://github.com/rust-lang/rust/issues/152>.
+
+//@ run-pass
+
+pub fn main() {
+    let mut b: usize = 1;
+    while b < size_of::<usize>() {
+        // This shift operation should not mutate `b`
+        let _ = 0_usize << b;
+        b <<= 1;
+        std::hint::black_box(b);
+    }
+    assert_eq!(size_of::<usize>(), b);
+}
diff --git a/tests/ui/codegen/sret-aliasing-rules.rs b/tests/ui/codegen/sret-aliasing-rules.rs
new file mode 100644
index 00000000000..f35e722f764
--- /dev/null
+++ b/tests/ui/codegen/sret-aliasing-rules.rs
@@ -0,0 +1,28 @@
+//! Check that functions with sret results don't violate aliasing rules.
+//!
+//! When `foo = func(&mut foo)` is called, the compiler must avoid creating
+//! two mutable references to the same variable simultaneously (one for the
+//! parameter and one for the hidden sret out-pointer).
+//!
+//! Regression test for <https://github.com/rust-lang/rust/pull/18250>.
+
+//@ run-pass
+
+#[derive(Copy, Clone)]
+pub struct Foo {
+    f1: isize,
+    _f2: isize,
+}
+
+#[inline(never)]
+pub fn foo(f: &mut Foo) -> Foo {
+    let ret = *f;
+    f.f1 = 0;
+    ret
+}
+
+pub fn main() {
+    let mut f = Foo { f1: 8, _f2: 9 };
+    f = foo(&mut f);
+    assert_eq!(f.f1, 8);
+}
diff --git a/tests/ui/const-generics/issues/issue-90318.rs b/tests/ui/const-generics/issues/issue-90318.rs
index 317ddad49cd..dfba90a5575 100644
--- a/tests/ui/const-generics/issues/issue-90318.rs
+++ b/tests/ui/const-generics/issues/issue-90318.rs
@@ -1,5 +1,6 @@
 #![feature(const_type_id)]
 #![feature(generic_const_exprs)]
+#![feature(const_trait_impl)]
 #![feature(core_intrinsics)]
 #![allow(incomplete_features)]
 
@@ -13,7 +14,6 @@ fn consume<T: 'static>(_val: T)
 where
     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
     //~^ ERROR overly complex generic constant
-    //~| ERROR: cannot call
 {
 }
 
@@ -21,7 +21,6 @@ fn test<T: 'static>()
 where
     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
     //~^ ERROR overly complex generic constant
-    //~| ERROR: cannot call
 {
 }
 
diff --git a/tests/ui/const-generics/issues/issue-90318.stderr b/tests/ui/const-generics/issues/issue-90318.stderr
index 9c7cb5ceb58..7031230db91 100644
--- a/tests/ui/const-generics/issues/issue-90318.stderr
+++ b/tests/ui/const-generics/issues/issue-90318.stderr
@@ -1,5 +1,5 @@
 error: overly complex generic constant
-  --> $DIR/issue-90318.rs:14:8
+  --> $DIR/issue-90318.rs:15:8
    |
 LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
    |        ^^-----------------^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,26 +20,5 @@ LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
    = help: consider moving this anonymous constant into a `const` function
    = note: this operation may be supported in the future
 
-error[E0015]: cannot call non-const operator in constants
-  --> $DIR/issue-90318.rs:14:10
-   |
-LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: impl defined here, but it is not `const`
-  --> $SRC_DIR/core/src/any.rs:LL:COL
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const operator in constants
-  --> $DIR/issue-90318.rs:22:10
-   |
-LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: impl defined here, but it is not `const`
-  --> $SRC_DIR/core/src/any.rs:LL:COL
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/const_cmp_type_id.rs b/tests/ui/consts/const_cmp_type_id.rs
index dca0615083a..def615bd92b 100644
--- a/tests/ui/consts/const_cmp_type_id.rs
+++ b/tests/ui/consts/const_cmp_type_id.rs
@@ -6,10 +6,9 @@ use std::any::TypeId;
 fn main() {
     const {
         assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
-        //~^ ERROR the trait bound `TypeId: const PartialEq` is not satisfied
         assert!(TypeId::of::<()>() != TypeId::of::<u8>());
-        //~^ ERROR the trait bound `TypeId: const PartialEq` is not satisfied
         let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
+        //~^ ERROR: cannot call non-const operator in constants
         // can't assert `_a` because it is not deterministic
         // FIXME(const_trait_impl) make it pass
     }
diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr
index a8242a200ef..540eec5098b 100644
--- a/tests/ui/consts/const_cmp_type_id.stderr
+++ b/tests/ui/consts/const_cmp_type_id.stderr
@@ -1,15 +1,13 @@
-error[E0277]: the trait bound `TypeId: const PartialEq` is not satisfied
-  --> $DIR/const_cmp_type_id.rs:8:17
+error[E0015]: cannot call non-const operator in constants
+  --> $DIR/const_cmp_type_id.rs:10:18
    |
-LL |         assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0277]: the trait bound `TypeId: const PartialEq` is not satisfied
-  --> $DIR/const_cmp_type_id.rs:10:17
+LL |         let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-LL |         assert!(TypeId::of::<()>() != TypeId::of::<u8>());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/const_transmute_type_id.rs b/tests/ui/consts/const_transmute_type_id.rs
new file mode 100644
index 00000000000..56ead6a622b
--- /dev/null
+++ b/tests/ui/consts/const_transmute_type_id.rs
@@ -0,0 +1,11 @@
+#![feature(const_type_id, const_trait_impl)]
+
+use std::any::TypeId;
+
+const _: () = {
+    let id = TypeId::of::<u8>();
+    let id: u8 = unsafe { (&raw const id).cast::<u8>().read() };
+    //~^ ERROR: unable to turn pointer into integer
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const_transmute_type_id.stderr b/tests/ui/consts/const_transmute_type_id.stderr
new file mode 100644
index 00000000000..85bd4ea2736
--- /dev/null
+++ b/tests/ui/consts/const_transmute_type_id.stderr
@@ -0,0 +1,12 @@
+error[E0080]: unable to turn pointer into integer
+  --> $DIR/const_transmute_type_id.rs:7:27
+   |
+LL |     let id: u8 = unsafe { (&raw const id).cast::<u8>().read() };
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` 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
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const_transmute_type_id2.rs b/tests/ui/consts/const_transmute_type_id2.rs
new file mode 100644
index 00000000000..e29cf8171ac
--- /dev/null
+++ b/tests/ui/consts/const_transmute_type_id2.rs
@@ -0,0 +1,14 @@
+//@ normalize-stderr: "0x(ff)+" -> "<u128::MAX>"
+
+#![feature(const_type_id, const_trait_impl)]
+
+use std::any::TypeId;
+
+const _: () = {
+    let a: TypeId = unsafe { std::mem::transmute(u128::MAX) };
+    let b: TypeId = unsafe { std::mem::transmute(u128::MAX) };
+    assert!(a == b);
+    //~^ ERROR: pointer must point to some allocation
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const_transmute_type_id2.stderr b/tests/ui/consts/const_transmute_type_id2.stderr
new file mode 100644
index 00000000000..5646eb1257d
--- /dev/null
+++ b/tests/ui/consts/const_transmute_type_id2.stderr
@@ -0,0 +1,15 @@
+error[E0080]: pointer not dereferenceable: pointer must point to some allocation, but got <u128::MAX>[noalloc] which is a dangling pointer (it has no provenance)
+  --> $DIR/const_transmute_type_id2.rs:10:13
+   |
+LL |     assert!(a == b);
+   |             ^^^^^^ evaluation of `_` failed inside this call
+   |
+note: inside `<TypeId as PartialEq>::eq`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+note: inside `<TypeId as PartialEq>::eq::compiletime`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+   = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const_transmute_type_id3.rs b/tests/ui/consts/const_transmute_type_id3.rs
new file mode 100644
index 00000000000..a870d6e7e80
--- /dev/null
+++ b/tests/ui/consts/const_transmute_type_id3.rs
@@ -0,0 +1,16 @@
+#![feature(const_type_id, const_trait_impl)]
+
+use std::any::TypeId;
+
+const _: () = {
+    let a = TypeId::of::<()>();
+    let mut b = TypeId::of::<()>();
+    unsafe {
+        let ptr = &mut b as *mut TypeId as *mut usize;
+        std::ptr::write(ptr.offset(1), 999);
+    }
+    assert!(a == b);
+    //~^ ERROR: one of the TypeId arguments is invalid, the hash does not match the type it represents
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const_transmute_type_id3.stderr b/tests/ui/consts/const_transmute_type_id3.stderr
new file mode 100644
index 00000000000..8cfdcfebaa4
--- /dev/null
+++ b/tests/ui/consts/const_transmute_type_id3.stderr
@@ -0,0 +1,15 @@
+error[E0080]: type_id_eq: one of the TypeId arguments is invalid, the hash does not match the type it represents
+  --> $DIR/const_transmute_type_id3.rs:12:13
+   |
+LL |     assert!(a == b);
+   |             ^^^^^^ evaluation of `_` failed inside this call
+   |
+note: inside `<TypeId as PartialEq>::eq`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+note: inside `<TypeId as PartialEq>::eq::compiletime`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+   = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const_transmute_type_id4.rs b/tests/ui/consts/const_transmute_type_id4.rs
new file mode 100644
index 00000000000..bc71f961a51
--- /dev/null
+++ b/tests/ui/consts/const_transmute_type_id4.rs
@@ -0,0 +1,16 @@
+#![feature(const_type_id, const_trait_impl)]
+
+use std::any::TypeId;
+
+const _: () = {
+    let a = TypeId::of::<()>();
+    let mut b = TypeId::of::<()>();
+    unsafe {
+        let ptr = &mut b as *mut TypeId as *mut *const ();
+        std::ptr::write(ptr.offset(0), main as fn() as *const ());
+    }
+    assert!(a == b);
+    //~^ ERROR: type_id_eq: `TypeId` provenance is not a type id
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const_transmute_type_id4.stderr b/tests/ui/consts/const_transmute_type_id4.stderr
new file mode 100644
index 00000000000..b418a79d7f0
--- /dev/null
+++ b/tests/ui/consts/const_transmute_type_id4.stderr
@@ -0,0 +1,15 @@
+error[E0080]: type_id_eq: `TypeId` provenance is not a type id
+  --> $DIR/const_transmute_type_id4.rs:12:13
+   |
+LL |     assert!(a == b);
+   |             ^^^^^^ evaluation of `_` failed inside this call
+   |
+note: inside `<TypeId as PartialEq>::eq`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+note: inside `<TypeId as PartialEq>::eq::compiletime`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+   = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/issue-73976-monomorphic.rs b/tests/ui/consts/issue-73976-monomorphic.rs
index 561c1976051..3bfdb397afb 100644
--- a/tests/ui/consts/issue-73976-monomorphic.rs
+++ b/tests/ui/consts/issue-73976-monomorphic.rs
@@ -1,4 +1,4 @@
-//@ known-bug: #110395
+//@ check-pass
 //
 // This test is complement to the test in issue-73976-polymorphic.rs.
 // In that test we ensure that polymorphic use of type_id and type_name in patterns
diff --git a/tests/ui/consts/issue-73976-monomorphic.stderr b/tests/ui/consts/issue-73976-monomorphic.stderr
deleted file mode 100644
index 367d5be09da..00000000000
--- a/tests/ui/consts/issue-73976-monomorphic.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0277]: the trait bound `TypeId: [const] PartialEq` is not satisfied
-  --> $DIR/issue-73976-monomorphic.rs:21:5
-   |
-LL |     GetTypeId::<T>::VALUE == GetTypeId::<usize>::VALUE
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs
index 0df8482bec1..93a5e8e4f45 100644
--- a/tests/ui/consts/rustc-impl-const-stability.rs
+++ b/tests/ui/consts/rustc-impl-const-stability.rs
@@ -2,7 +2,7 @@
 //@ known-bug: #110395
 
 #![crate_type = "lib"]
-#![feature(staged_api, const_trait_impl)]
+#![feature(staged_api, const_trait_impl, const_default)]
 #![stable(feature = "foo", since = "1.0.0")]
 
 #[stable(feature = "potato", since = "1.27.0")]
@@ -12,8 +12,8 @@ pub struct Data {
 
 #[stable(feature = "potato", since = "1.27.0")]
 #[rustc_const_unstable(feature = "data_foo", issue = "none")]
-impl const Default for Data {
-    fn default() -> Data {
-        Data { _data: 42 }
+impl const std::fmt::Debug for Data {
+    fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+        Ok(())
     }
 }
diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr
index 19c6bb5907f..a3ef4031a13 100644
--- a/tests/ui/consts/rustc-impl-const-stability.stderr
+++ b/tests/ui/consts/rustc-impl-const-stability.stderr
@@ -1,8 +1,8 @@
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
+error: const `impl` for trait `Debug` which is not marked with `#[const_trait]`
   --> $DIR/rustc-impl-const-stability.rs:15:12
    |
-LL | impl const Default for Data {
-   |            ^^^^^^^ this trait is not `const`
+LL | impl const std::fmt::Debug for Data {
+   |            ^^^^^^^^^^^^^^^ this trait is not `const`
    |
    = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
    = note: adding a non-const method body in the future would be a breaking change
diff --git a/tests/ui/error-codes/E0424.stderr b/tests/ui/error-codes/E0424.stderr
index d02da3e4ecb..831a070bf6c 100644
--- a/tests/ui/error-codes/E0424.stderr
+++ b/tests/ui/error-codes/E0424.stderr
@@ -40,8 +40,6 @@ LL |     fn qux(&self) {
 error[E0424]: expected unit struct, unit variant or constant, found module `self`
   --> $DIR/E0424.rs:20:9
    |
-LL | fn main () {
-   |    ---- this function can't have a `self` parameter
 LL |     let self = "self";
    |         ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
 
diff --git a/tests/ui/float/conv-bits-runtime-const.rs b/tests/ui/float/conv-bits-runtime-const.rs
index 3046728fe66..1373001b74d 100644
--- a/tests/ui/float/conv-bits-runtime-const.rs
+++ b/tests/ui/float/conv-bits-runtime-const.rs
@@ -5,25 +5,24 @@
 
 #![feature(f16)]
 #![feature(f128)]
+#![feature(cfg_target_has_reliable_f16_f128)]
 #![allow(unused_macro_rules)]
+// expect the unexpected (`target_has_reliable_*` are not "known" configs since they are unstable)
+#![expect(unexpected_cfgs)]
 
 use std::hint::black_box;
 
 macro_rules! both_assert {
-    ($a:expr) => {
-        {
-            const _: () = assert!($a);
-            // `black_box` prevents promotion, and MIR opts are disabled above, so this is truly
-            // going through LLVM.
-            assert!(black_box($a));
-        }
-    };
-    ($a:expr, $b:expr) => {
-        {
-            const _: () = assert!($a == $b);
-            assert_eq!(black_box($a), black_box($b));
-        }
-    };
+    ($a:expr) => {{
+        const _: () = assert!($a);
+        // `black_box` prevents promotion, and MIR opts are disabled above, so this is truly
+        // going through LLVM.
+        assert!(black_box($a));
+    }};
+    ($a:expr, $b:expr) => {{
+        const _: () = assert!($a == $b);
+        assert_eq!(black_box($a), black_box($b));
+    }};
 }
 
 fn has_broken_floats() -> bool {
@@ -31,8 +30,8 @@ fn has_broken_floats() -> bool {
     cfg!(all(target_arch = "x86", not(target_feature = "sse2")))
 }
 
-#[cfg(target_arch = "x86_64")]
-fn f16(){
+#[cfg(target_has_reliable_f16)]
+fn f16() {
     both_assert!((1f16).to_bits(), 0x3c00);
     both_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00);
     both_assert!((12.5f16).to_bits(), 0x4a40);
@@ -122,7 +121,7 @@ fn f64() {
     }
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(target_has_reliable_f128)]
 fn f128() {
     both_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000);
     both_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000);
@@ -154,12 +153,10 @@ fn f128() {
 }
 
 fn main() {
+    #[cfg(target_has_reliable_f16)]
+    f16();
     f32();
     f64();
-
-    #[cfg(target_arch = "x86_64")]
-    {
-        f16();
-        f128();
-    }
+    #[cfg(target_has_reliable_f128)]
+    f128();
 }
diff --git a/tests/ui/imports/ambiguous-1.rs b/tests/ui/imports/ambiguous-1.rs
index d175444c0f2..31f39eee62b 100644
--- a/tests/ui/imports/ambiguous-1.rs
+++ b/tests/ui/imports/ambiguous-1.rs
@@ -1,6 +1,8 @@
 //@ check-pass
 // https://github.com/rust-lang/rust/pull/112743#issuecomment-1601986883
 
+#![warn(ambiguous_glob_imports)]
+
 macro_rules! m {
     () => {
       pub fn id() {}
diff --git a/tests/ui/imports/ambiguous-1.stderr b/tests/ui/imports/ambiguous-1.stderr
index 61b3077c354..04ff3a36c74 100644
--- a/tests/ui/imports/ambiguous-1.stderr
+++ b/tests/ui/imports/ambiguous-1.stderr
@@ -1,5 +1,5 @@
 warning: ambiguous glob re-exports
-  --> $DIR/ambiguous-1.rs:11:13
+  --> $DIR/ambiguous-1.rs:13:13
    |
 LL |     pub use self::evp::*;
    |             ^^^^^^^^^^^^ the name `id` in the value namespace is first re-exported here
@@ -10,7 +10,7 @@ LL |     pub use self::handwritten::*;
    = note: `#[warn(ambiguous_glob_reexports)]` on by default
 
 warning: `id` is ambiguous
-  --> $DIR/ambiguous-1.rs:27:5
+  --> $DIR/ambiguous-1.rs:29:5
    |
 LL |     id();
    |     ^^ ambiguous name
@@ -19,18 +19,50 @@ LL |     id();
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `id` could refer to the function imported here
-  --> $DIR/ambiguous-1.rs:11:13
+  --> $DIR/ambiguous-1.rs:13:13
    |
 LL |     pub use self::evp::*;
    |             ^^^^^^^^^^^^
    = help: consider adding an explicit import of `id` to disambiguate
 note: `id` could also refer to the function imported here
-  --> $DIR/ambiguous-1.rs:13:13
+  --> $DIR/ambiguous-1.rs:15:13
    |
 LL |     pub use self::handwritten::*;
    |             ^^^^^^^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `id` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+note: the lint level is defined here
+  --> $DIR/ambiguous-1.rs:4:9
+   |
+LL | #![warn(ambiguous_glob_imports)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: 2 warnings emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: `id` is ambiguous
+  --> $DIR/ambiguous-1.rs:29:5
+   |
+LL |     id();
+   |     ^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `id` could refer to the function imported here
+  --> $DIR/ambiguous-1.rs:13:13
+   |
+LL |     pub use self::evp::*;
+   |             ^^^^^^^^^^^^
+   = help: consider adding an explicit import of `id` to disambiguate
+note: `id` could also refer to the function imported here
+  --> $DIR/ambiguous-1.rs:15:13
+   |
+LL |     pub use self::handwritten::*;
+   |             ^^^^^^^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `id` to disambiguate
+note: the lint level is defined here
+  --> $DIR/ambiguous-1.rs:4:9
+   |
+LL | #![warn(ambiguous_glob_imports)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/imports/ambiguous-10.rs b/tests/ui/imports/ambiguous-10.rs
index 7c14e3343eb..166b01ede12 100644
--- a/tests/ui/imports/ambiguous-10.rs
+++ b/tests/ui/imports/ambiguous-10.rs
@@ -1,4 +1,3 @@
-//@ check-pass
 // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296
 
 mod a {
@@ -14,6 +13,6 @@ mod b {
 use crate::a::*;
 use crate::b::*;
 fn c(_: Token) {}
-//~^ WARNING `Token` is ambiguous
+//~^ ERROR `Token` is ambiguous
 //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 fn main() { }
diff --git a/tests/ui/imports/ambiguous-10.stderr b/tests/ui/imports/ambiguous-10.stderr
index 704af616b43..cd36795b3c0 100644
--- a/tests/ui/imports/ambiguous-10.stderr
+++ b/tests/ui/imports/ambiguous-10.stderr
@@ -1,5 +1,5 @@
-warning: `Token` is ambiguous
-  --> $DIR/ambiguous-10.rs:16:9
+error: `Token` is ambiguous
+  --> $DIR/ambiguous-10.rs:15:9
    |
 LL | fn c(_: Token) {}
    |         ^^^^^ ambiguous name
@@ -8,18 +8,42 @@ LL | fn c(_: Token) {}
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `Token` could refer to the enum imported here
-  --> $DIR/ambiguous-10.rs:14:5
+  --> $DIR/ambiguous-10.rs:13:5
    |
 LL | use crate::a::*;
    |     ^^^^^^^^^^^
    = help: consider adding an explicit import of `Token` to disambiguate
 note: `Token` could also refer to the enum imported here
-  --> $DIR/ambiguous-10.rs:15:5
+  --> $DIR/ambiguous-10.rs:14:5
    |
 LL | use crate::b::*;
    |     ^^^^^^^^^^^
    = help: consider adding an explicit import of `Token` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
+error: aborting due to 1 previous error
 
-warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+error: `Token` is ambiguous
+  --> $DIR/ambiguous-10.rs:15:9
+   |
+LL | fn c(_: Token) {}
+   |         ^^^^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `Token` could refer to the enum imported here
+  --> $DIR/ambiguous-10.rs:13:5
+   |
+LL | use crate::a::*;
+   |     ^^^^^^^^^^^
+   = help: consider adding an explicit import of `Token` to disambiguate
+note: `Token` could also refer to the enum imported here
+  --> $DIR/ambiguous-10.rs:14:5
+   |
+LL | use crate::b::*;
+   |     ^^^^^^^^^^^
+   = help: consider adding an explicit import of `Token` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/ambiguous-12.rs b/tests/ui/imports/ambiguous-12.rs
index a033b51f709..543396b8dfe 100644
--- a/tests/ui/imports/ambiguous-12.rs
+++ b/tests/ui/imports/ambiguous-12.rs
@@ -1,4 +1,3 @@
-//@ check-pass
 // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296
 
 macro_rules! m {
@@ -20,6 +19,6 @@ use crate::public::*;
 
 fn main() {
     b();
-    //~^ WARNING `b` is ambiguous
+    //~^ ERROR `b` is ambiguous
     //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
diff --git a/tests/ui/imports/ambiguous-12.stderr b/tests/ui/imports/ambiguous-12.stderr
index 4725c38849c..273a4ed3c0f 100644
--- a/tests/ui/imports/ambiguous-12.stderr
+++ b/tests/ui/imports/ambiguous-12.stderr
@@ -1,5 +1,5 @@
-warning: `b` is ambiguous
-  --> $DIR/ambiguous-12.rs:22:5
+error: `b` is ambiguous
+  --> $DIR/ambiguous-12.rs:21:5
    |
 LL |     b();
    |     ^ ambiguous name
@@ -8,18 +8,42 @@ LL |     b();
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `b` could refer to the function imported here
-  --> $DIR/ambiguous-12.rs:18:5
+  --> $DIR/ambiguous-12.rs:17:5
    |
 LL | use crate::ciphertext::*;
    |     ^^^^^^^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `b` to disambiguate
 note: `b` could also refer to the function imported here
-  --> $DIR/ambiguous-12.rs:19:5
+  --> $DIR/ambiguous-12.rs:18:5
    |
 LL | use crate::public::*;
    |     ^^^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `b` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
+error: aborting due to 1 previous error
 
-warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+error: `b` is ambiguous
+  --> $DIR/ambiguous-12.rs:21:5
+   |
+LL |     b();
+   |     ^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `b` could refer to the function imported here
+  --> $DIR/ambiguous-12.rs:17:5
+   |
+LL | use crate::ciphertext::*;
+   |     ^^^^^^^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `b` to disambiguate
+note: `b` could also refer to the function imported here
+  --> $DIR/ambiguous-12.rs:18:5
+   |
+LL | use crate::public::*;
+   |     ^^^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `b` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/ambiguous-13.rs b/tests/ui/imports/ambiguous-13.rs
index 1ea04e05d57..3569dd5d9ad 100644
--- a/tests/ui/imports/ambiguous-13.rs
+++ b/tests/ui/imports/ambiguous-13.rs
@@ -1,4 +1,3 @@
-//@ check-pass
 // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296
 
 pub mod object {
@@ -17,6 +16,6 @@ use crate::object::*;
 use crate::content::*;
 
 fn a(_: Rect) {}
-//~^ WARNING `Rect` is ambiguous
+//~^ ERROR `Rect` is ambiguous
 //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 fn main() { }
diff --git a/tests/ui/imports/ambiguous-13.stderr b/tests/ui/imports/ambiguous-13.stderr
index 3e78100b658..c4a42c01c91 100644
--- a/tests/ui/imports/ambiguous-13.stderr
+++ b/tests/ui/imports/ambiguous-13.stderr
@@ -1,5 +1,5 @@
-warning: `Rect` is ambiguous
-  --> $DIR/ambiguous-13.rs:19:9
+error: `Rect` is ambiguous
+  --> $DIR/ambiguous-13.rs:18:9
    |
 LL | fn a(_: Rect) {}
    |         ^^^^ ambiguous name
@@ -8,18 +8,42 @@ LL | fn a(_: Rect) {}
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `Rect` could refer to the struct imported here
-  --> $DIR/ambiguous-13.rs:16:5
+  --> $DIR/ambiguous-13.rs:15:5
    |
 LL | use crate::object::*;
    |     ^^^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `Rect` to disambiguate
 note: `Rect` could also refer to the struct imported here
-  --> $DIR/ambiguous-13.rs:17:5
+  --> $DIR/ambiguous-13.rs:16:5
    |
 LL | use crate::content::*;
    |     ^^^^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `Rect` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
+error: aborting due to 1 previous error
 
-warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+error: `Rect` is ambiguous
+  --> $DIR/ambiguous-13.rs:18:9
+   |
+LL | fn a(_: Rect) {}
+   |         ^^^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `Rect` could refer to the struct imported here
+  --> $DIR/ambiguous-13.rs:15:5
+   |
+LL | use crate::object::*;
+   |     ^^^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `Rect` to disambiguate
+note: `Rect` could also refer to the struct imported here
+  --> $DIR/ambiguous-13.rs:16:5
+   |
+LL | use crate::content::*;
+   |     ^^^^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `Rect` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/ambiguous-14.rs b/tests/ui/imports/ambiguous-14.rs
index 30d14be9d0e..f752387aa7e 100644
--- a/tests/ui/imports/ambiguous-14.rs
+++ b/tests/ui/imports/ambiguous-14.rs
@@ -1,4 +1,3 @@
-//@ check-pass
 // https://github.com/rust-lang/rust/issues/98467
 
 mod a {
@@ -21,6 +20,6 @@ mod g {
 
 fn main() {
     g::foo();
-    //~^ WARNING `foo` is ambiguous
+    //~^ ERROR `foo` is ambiguous
     //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
diff --git a/tests/ui/imports/ambiguous-14.stderr b/tests/ui/imports/ambiguous-14.stderr
index bece5853668..f3115f8c8b5 100644
--- a/tests/ui/imports/ambiguous-14.stderr
+++ b/tests/ui/imports/ambiguous-14.stderr
@@ -1,5 +1,5 @@
-warning: `foo` is ambiguous
-  --> $DIR/ambiguous-14.rs:23:8
+error: `foo` is ambiguous
+  --> $DIR/ambiguous-14.rs:22:8
    |
 LL |     g::foo();
    |        ^^^ ambiguous name
@@ -8,18 +8,42 @@ LL |     g::foo();
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `foo` could refer to the function imported here
-  --> $DIR/ambiguous-14.rs:13:13
+  --> $DIR/ambiguous-14.rs:12:13
    |
 LL |     pub use a::*;
    |             ^^^^
    = help: consider adding an explicit import of `foo` to disambiguate
 note: `foo` could also refer to the function imported here
-  --> $DIR/ambiguous-14.rs:14:13
+  --> $DIR/ambiguous-14.rs:13:13
    |
 LL |     pub use b::*;
    |             ^^^^
    = help: consider adding an explicit import of `foo` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
+error: aborting due to 1 previous error
 
-warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+error: `foo` is ambiguous
+  --> $DIR/ambiguous-14.rs:22:8
+   |
+LL |     g::foo();
+   |        ^^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `foo` could refer to the function imported here
+  --> $DIR/ambiguous-14.rs:12:13
+   |
+LL |     pub use a::*;
+   |             ^^^^
+   = help: consider adding an explicit import of `foo` to disambiguate
+note: `foo` could also refer to the function imported here
+  --> $DIR/ambiguous-14.rs:13:13
+   |
+LL |     pub use b::*;
+   |             ^^^^
+   = help: consider adding an explicit import of `foo` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/ambiguous-15.rs b/tests/ui/imports/ambiguous-15.rs
index b9e8f020d43..07d8893b2de 100644
--- a/tests/ui/imports/ambiguous-15.rs
+++ b/tests/ui/imports/ambiguous-15.rs
@@ -1,4 +1,3 @@
-//@ check-pass
 // https://github.com/rust-lang/rust/pull/113099#issuecomment-1638206152
 
 mod t2 {
@@ -21,7 +20,7 @@ mod t3 {
 
 use self::t3::*;
 fn a<E: Error>(_: E) {}
-//~^ WARNING `Error` is ambiguous
+//~^ ERROR `Error` is ambiguous
 //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 fn main() {}
diff --git a/tests/ui/imports/ambiguous-15.stderr b/tests/ui/imports/ambiguous-15.stderr
index 838256752d0..1312f2c63c4 100644
--- a/tests/ui/imports/ambiguous-15.stderr
+++ b/tests/ui/imports/ambiguous-15.stderr
@@ -1,5 +1,5 @@
-warning: `Error` is ambiguous
-  --> $DIR/ambiguous-15.rs:23:9
+error: `Error` is ambiguous
+  --> $DIR/ambiguous-15.rs:22:9
    |
 LL | fn a<E: Error>(_: E) {}
    |         ^^^^^ ambiguous name
@@ -8,18 +8,42 @@ LL | fn a<E: Error>(_: E) {}
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `Error` could refer to the trait imported here
-  --> $DIR/ambiguous-15.rs:22:5
+  --> $DIR/ambiguous-15.rs:21:5
    |
 LL | use self::t3::*;
    |     ^^^^^^^^^^^
    = help: consider adding an explicit import of `Error` to disambiguate
 note: `Error` could also refer to the enum imported here
-  --> $DIR/ambiguous-15.rs:16:9
+  --> $DIR/ambiguous-15.rs:15:9
    |
 LL | pub use t2::*;
    |         ^^^^^
    = help: consider adding an explicit import of `Error` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
-warning: 1 warning emitted
+error: aborting due to 1 previous error
+
+Future incompatibility report: Future breakage diagnostic:
+error: `Error` is ambiguous
+  --> $DIR/ambiguous-15.rs:22:9
+   |
+LL | fn a<E: Error>(_: E) {}
+   |         ^^^^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `Error` could refer to the trait imported here
+  --> $DIR/ambiguous-15.rs:21:5
+   |
+LL | use self::t3::*;
+   |     ^^^^^^^^^^^
+   = help: consider adding an explicit import of `Error` to disambiguate
+note: `Error` could also refer to the enum imported here
+  --> $DIR/ambiguous-15.rs:15:9
+   |
+LL | pub use t2::*;
+   |         ^^^^^
+   = help: consider adding an explicit import of `Error` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/ambiguous-16.rs b/tests/ui/imports/ambiguous-16.rs
index ed30c9d241a..f31c78d18a3 100644
--- a/tests/ui/imports/ambiguous-16.rs
+++ b/tests/ui/imports/ambiguous-16.rs
@@ -1,4 +1,3 @@
-//@ check-pass
 // https://github.com/rust-lang/rust/pull/113099
 
 mod framing {
@@ -21,7 +20,7 @@ mod framing {
 }
 
 use crate::framing::ConfirmedTranscriptHashInput;
-//~^ WARNING `ConfirmedTranscriptHashInput` is ambiguous
+//~^ ERROR `ConfirmedTranscriptHashInput` is ambiguous
 //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 fn main() { }
diff --git a/tests/ui/imports/ambiguous-16.stderr b/tests/ui/imports/ambiguous-16.stderr
index 7366cabc47a..ae65f9a84fc 100644
--- a/tests/ui/imports/ambiguous-16.stderr
+++ b/tests/ui/imports/ambiguous-16.stderr
@@ -1,5 +1,5 @@
-warning: `ConfirmedTranscriptHashInput` is ambiguous
-  --> $DIR/ambiguous-16.rs:23:21
+error: `ConfirmedTranscriptHashInput` is ambiguous
+  --> $DIR/ambiguous-16.rs:22:21
    |
 LL | use crate::framing::ConfirmedTranscriptHashInput;
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name
@@ -8,18 +8,42 @@ LL | use crate::framing::ConfirmedTranscriptHashInput;
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `ConfirmedTranscriptHashInput` could refer to the struct imported here
-  --> $DIR/ambiguous-16.rs:19:13
+  --> $DIR/ambiguous-16.rs:18:13
    |
 LL |     pub use self::public_message::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `ConfirmedTranscriptHashInput` to disambiguate
 note: `ConfirmedTranscriptHashInput` could also refer to the struct imported here
-  --> $DIR/ambiguous-16.rs:20:13
+  --> $DIR/ambiguous-16.rs:19:13
    |
 LL |     pub use self::public_message_in::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `ConfirmedTranscriptHashInput` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
+error: aborting due to 1 previous error
 
-warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+error: `ConfirmedTranscriptHashInput` is ambiguous
+  --> $DIR/ambiguous-16.rs:22:21
+   |
+LL | use crate::framing::ConfirmedTranscriptHashInput;
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `ConfirmedTranscriptHashInput` could refer to the struct imported here
+  --> $DIR/ambiguous-16.rs:18:13
+   |
+LL |     pub use self::public_message::*;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `ConfirmedTranscriptHashInput` to disambiguate
+note: `ConfirmedTranscriptHashInput` could also refer to the struct imported here
+  --> $DIR/ambiguous-16.rs:19:13
+   |
+LL |     pub use self::public_message_in::*;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `ConfirmedTranscriptHashInput` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/ambiguous-17.rs b/tests/ui/imports/ambiguous-17.rs
index 28c9c1cc864..520ac70c6f1 100644
--- a/tests/ui/imports/ambiguous-17.rs
+++ b/tests/ui/imports/ambiguous-17.rs
@@ -1,4 +1,3 @@
-//@ check-pass
 // https://github.com/rust-lang/rust/pull/113099#issuecomment-1638206152
 
 pub use evp::*; //~ WARNING ambiguous glob re-exports
@@ -24,6 +23,6 @@ mod handwritten {
 
 fn main() {
     id();
-    //~^ WARNING `id` is ambiguous
+    //~^ ERROR `id` is ambiguous
     //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
diff --git a/tests/ui/imports/ambiguous-17.stderr b/tests/ui/imports/ambiguous-17.stderr
index 55bc01095c7..a87e2572d63 100644
--- a/tests/ui/imports/ambiguous-17.stderr
+++ b/tests/ui/imports/ambiguous-17.stderr
@@ -1,5 +1,5 @@
 warning: ambiguous glob re-exports
-  --> $DIR/ambiguous-17.rs:4:9
+  --> $DIR/ambiguous-17.rs:3:9
    |
 LL | pub use evp::*;
    |         ^^^^^^ the name `id` in the value namespace is first re-exported here
@@ -8,8 +8,8 @@ LL | pub use handwritten::*;
    |
    = note: `#[warn(ambiguous_glob_reexports)]` on by default
 
-warning: `id` is ambiguous
-  --> $DIR/ambiguous-17.rs:26:5
+error: `id` is ambiguous
+  --> $DIR/ambiguous-17.rs:25:5
    |
 LL |     id();
    |     ^^ ambiguous name
@@ -18,18 +18,42 @@ LL |     id();
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `id` could refer to the function imported here
-  --> $DIR/ambiguous-17.rs:4:9
+  --> $DIR/ambiguous-17.rs:3:9
    |
 LL | pub use evp::*;
    |         ^^^^^^
    = help: consider adding an explicit import of `id` to disambiguate
 note: `id` could also refer to the function imported here
-  --> $DIR/ambiguous-17.rs:5:9
+  --> $DIR/ambiguous-17.rs:4:9
    |
 LL | pub use handwritten::*;
    |         ^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `id` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
-warning: 2 warnings emitted
+error: aborting due to 1 previous error; 1 warning emitted
+
+Future incompatibility report: Future breakage diagnostic:
+error: `id` is ambiguous
+  --> $DIR/ambiguous-17.rs:25:5
+   |
+LL |     id();
+   |     ^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `id` could refer to the function imported here
+  --> $DIR/ambiguous-17.rs:3:9
+   |
+LL | pub use evp::*;
+   |         ^^^^^^
+   = help: consider adding an explicit import of `id` to disambiguate
+note: `id` could also refer to the function imported here
+  --> $DIR/ambiguous-17.rs:4:9
+   |
+LL | pub use handwritten::*;
+   |         ^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `id` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/ambiguous-3.rs b/tests/ui/imports/ambiguous-3.rs
index aa98ffe395e..ff0dcc221ec 100644
--- a/tests/ui/imports/ambiguous-3.rs
+++ b/tests/ui/imports/ambiguous-3.rs
@@ -1,10 +1,9 @@
-//@ check-pass
 // https://github.com/rust-lang/rust/issues/47525
 
 fn main() {
     use a::*;
     x();
-    //~^ WARNING `x` is ambiguous
+    //~^ ERROR `x` is ambiguous
     //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
 
diff --git a/tests/ui/imports/ambiguous-3.stderr b/tests/ui/imports/ambiguous-3.stderr
index f019f6d8957..8766db5654a 100644
--- a/tests/ui/imports/ambiguous-3.stderr
+++ b/tests/ui/imports/ambiguous-3.stderr
@@ -1,5 +1,5 @@
-warning: `x` is ambiguous
-  --> $DIR/ambiguous-3.rs:6:5
+error: `x` is ambiguous
+  --> $DIR/ambiguous-3.rs:5:5
    |
 LL |     x();
    |     ^ ambiguous name
@@ -8,18 +8,42 @@ LL |     x();
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `x` could refer to the function imported here
-  --> $DIR/ambiguous-3.rs:19:13
+  --> $DIR/ambiguous-3.rs:18:13
    |
 LL |     pub use self::b::*;
    |             ^^^^^^^^^^
    = help: consider adding an explicit import of `x` to disambiguate
 note: `x` could also refer to the function imported here
-  --> $DIR/ambiguous-3.rs:20:13
+  --> $DIR/ambiguous-3.rs:19:13
    |
 LL |     pub use self::c::*;
    |             ^^^^^^^^^^
    = help: consider adding an explicit import of `x` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
+error: aborting due to 1 previous error
 
-warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+error: `x` is ambiguous
+  --> $DIR/ambiguous-3.rs:5:5
+   |
+LL |     x();
+   |     ^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `x` could refer to the function imported here
+  --> $DIR/ambiguous-3.rs:18:13
+   |
+LL |     pub use self::b::*;
+   |             ^^^^^^^^^^
+   = help: consider adding an explicit import of `x` to disambiguate
+note: `x` could also refer to the function imported here
+  --> $DIR/ambiguous-3.rs:19:13
+   |
+LL |     pub use self::c::*;
+   |             ^^^^^^^^^^
+   = help: consider adding an explicit import of `x` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/ambiguous-4-extern.rs b/tests/ui/imports/ambiguous-4-extern.rs
index a045ab3d8a5..bc856af852d 100644
--- a/tests/ui/imports/ambiguous-4-extern.rs
+++ b/tests/ui/imports/ambiguous-4-extern.rs
@@ -1,6 +1,8 @@
 //@ check-pass
 // https://github.com/rust-lang/rust/pull/112743#issuecomment-1601986883
 
+#![warn(ambiguous_glob_imports)]
+
 macro_rules! m {
     () => {
       pub fn id() {}
diff --git a/tests/ui/imports/ambiguous-4-extern.stderr b/tests/ui/imports/ambiguous-4-extern.stderr
index 0011973212b..a9427ac0350 100644
--- a/tests/ui/imports/ambiguous-4-extern.stderr
+++ b/tests/ui/imports/ambiguous-4-extern.stderr
@@ -1,5 +1,5 @@
 warning: ambiguous glob re-exports
-  --> $DIR/ambiguous-4-extern.rs:10:9
+  --> $DIR/ambiguous-4-extern.rs:12:9
    |
 LL | pub use evp::*;
    |         ^^^^^^ the name `id` in the value namespace is first re-exported here
@@ -9,7 +9,7 @@ LL | pub use handwritten::*;
    = note: `#[warn(ambiguous_glob_reexports)]` on by default
 
 warning: `id` is ambiguous
-  --> $DIR/ambiguous-4-extern.rs:23:5
+  --> $DIR/ambiguous-4-extern.rs:25:5
    |
 LL |     id();
    |     ^^ ambiguous name
@@ -18,18 +18,50 @@ LL |     id();
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `id` could refer to the function imported here
-  --> $DIR/ambiguous-4-extern.rs:10:9
+  --> $DIR/ambiguous-4-extern.rs:12:9
    |
 LL | pub use evp::*;
    |         ^^^^^^
    = help: consider adding an explicit import of `id` to disambiguate
 note: `id` could also refer to the function imported here
-  --> $DIR/ambiguous-4-extern.rs:11:9
+  --> $DIR/ambiguous-4-extern.rs:13:9
    |
 LL | pub use handwritten::*;
    |         ^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `id` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+note: the lint level is defined here
+  --> $DIR/ambiguous-4-extern.rs:4:9
+   |
+LL | #![warn(ambiguous_glob_imports)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: 2 warnings emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: `id` is ambiguous
+  --> $DIR/ambiguous-4-extern.rs:25:5
+   |
+LL |     id();
+   |     ^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `id` could refer to the function imported here
+  --> $DIR/ambiguous-4-extern.rs:12:9
+   |
+LL | pub use evp::*;
+   |         ^^^^^^
+   = help: consider adding an explicit import of `id` to disambiguate
+note: `id` could also refer to the function imported here
+  --> $DIR/ambiguous-4-extern.rs:13:9
+   |
+LL | pub use handwritten::*;
+   |         ^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `id` to disambiguate
+note: the lint level is defined here
+  --> $DIR/ambiguous-4-extern.rs:4:9
+   |
+LL | #![warn(ambiguous_glob_imports)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/imports/ambiguous-4.rs b/tests/ui/imports/ambiguous-4.rs
index fcb7b5c6671..3a9a14bfb52 100644
--- a/tests/ui/imports/ambiguous-4.rs
+++ b/tests/ui/imports/ambiguous-4.rs
@@ -1,4 +1,4 @@
-//@ build-pass
+//@ check-pass
 //@ aux-build: ../ambiguous-4-extern.rs
 
 extern crate ambiguous_4_extern;
diff --git a/tests/ui/imports/ambiguous-5.rs b/tests/ui/imports/ambiguous-5.rs
index 28447e10d1b..8f89c966d4a 100644
--- a/tests/ui/imports/ambiguous-5.rs
+++ b/tests/ui/imports/ambiguous-5.rs
@@ -1,4 +1,3 @@
-//@ check-pass
 // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296
 
 mod a {
@@ -11,7 +10,7 @@ mod gpos {
     use super::gsubgpos::*;
     use super::*;
     struct MarkRecord(Class);
-    //~^ WARNING `Class` is ambiguous
+    //~^ ERROR`Class` is ambiguous
     //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
 
diff --git a/tests/ui/imports/ambiguous-5.stderr b/tests/ui/imports/ambiguous-5.stderr
index 4bc35f86d3a..41c15809351 100644
--- a/tests/ui/imports/ambiguous-5.stderr
+++ b/tests/ui/imports/ambiguous-5.stderr
@@ -1,5 +1,5 @@
-warning: `Class` is ambiguous
-  --> $DIR/ambiguous-5.rs:13:23
+error: `Class` is ambiguous
+  --> $DIR/ambiguous-5.rs:12:23
    |
 LL |     struct MarkRecord(Class);
    |                       ^^^^^ ambiguous name
@@ -8,18 +8,42 @@ LL |     struct MarkRecord(Class);
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `Class` could refer to the struct imported here
-  --> $DIR/ambiguous-5.rs:12:9
+  --> $DIR/ambiguous-5.rs:11:9
    |
 LL |     use super::*;
    |         ^^^^^^^^
    = help: consider adding an explicit import of `Class` to disambiguate
 note: `Class` could also refer to the struct imported here
-  --> $DIR/ambiguous-5.rs:11:9
+  --> $DIR/ambiguous-5.rs:10:9
    |
 LL |     use super::gsubgpos::*;
    |         ^^^^^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `Class` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
+error: aborting due to 1 previous error
 
-warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+error: `Class` is ambiguous
+  --> $DIR/ambiguous-5.rs:12:23
+   |
+LL |     struct MarkRecord(Class);
+   |                       ^^^^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `Class` could refer to the struct imported here
+  --> $DIR/ambiguous-5.rs:11:9
+   |
+LL |     use super::*;
+   |         ^^^^^^^^
+   = help: consider adding an explicit import of `Class` to disambiguate
+note: `Class` could also refer to the struct imported here
+  --> $DIR/ambiguous-5.rs:10:9
+   |
+LL |     use super::gsubgpos::*;
+   |         ^^^^^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `Class` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/ambiguous-6.rs b/tests/ui/imports/ambiguous-6.rs
index 955cdc3854f..1c6e3437716 100644
--- a/tests/ui/imports/ambiguous-6.rs
+++ b/tests/ui/imports/ambiguous-6.rs
@@ -1,11 +1,10 @@
-//@ check-pass
 //@ edition: 2021
 // https://github.com/rust-lang/rust/issues/112713
 
 pub fn foo() -> u32 {
     use sub::*;
     C
-    //~^ WARNING `C` is ambiguous
+    //~^ ERROR `C` is ambiguous
     //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
 
diff --git a/tests/ui/imports/ambiguous-6.stderr b/tests/ui/imports/ambiguous-6.stderr
index d7871a0b8cb..d988126dbfb 100644
--- a/tests/ui/imports/ambiguous-6.stderr
+++ b/tests/ui/imports/ambiguous-6.stderr
@@ -1,5 +1,5 @@
-warning: `C` is ambiguous
-  --> $DIR/ambiguous-6.rs:7:5
+error: `C` is ambiguous
+  --> $DIR/ambiguous-6.rs:6:5
    |
 LL |     C
    |     ^ ambiguous name
@@ -8,18 +8,42 @@ LL |     C
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `C` could refer to the constant imported here
-  --> $DIR/ambiguous-6.rs:16:13
+  --> $DIR/ambiguous-6.rs:15:13
    |
 LL |     pub use mod1::*;
    |             ^^^^^^^
    = help: consider adding an explicit import of `C` to disambiguate
 note: `C` could also refer to the constant imported here
-  --> $DIR/ambiguous-6.rs:17:13
+  --> $DIR/ambiguous-6.rs:16:13
    |
 LL |     pub use mod2::*;
    |             ^^^^^^^
    = help: consider adding an explicit import of `C` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
+error: aborting due to 1 previous error
 
-warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+error: `C` is ambiguous
+  --> $DIR/ambiguous-6.rs:6:5
+   |
+LL |     C
+   |     ^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `C` could refer to the constant imported here
+  --> $DIR/ambiguous-6.rs:15:13
+   |
+LL |     pub use mod1::*;
+   |             ^^^^^^^
+   = help: consider adding an explicit import of `C` to disambiguate
+note: `C` could also refer to the constant imported here
+  --> $DIR/ambiguous-6.rs:16:13
+   |
+LL |     pub use mod2::*;
+   |             ^^^^^^^
+   = help: consider adding an explicit import of `C` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/ambiguous-9.rs b/tests/ui/imports/ambiguous-9.rs
index 97321512df0..c10b1268060 100644
--- a/tests/ui/imports/ambiguous-9.rs
+++ b/tests/ui/imports/ambiguous-9.rs
@@ -1,4 +1,3 @@
-//@ check-pass
 // https://github.com/rust-lang/rust/pull/113099#issuecomment-1638206152
 
 pub mod dsl {
@@ -22,8 +21,8 @@ use prelude::*;
 
 fn main() {
     date_range();
-    //~^ WARNING `date_range` is ambiguous
+    //~^ ERROR `date_range` is ambiguous
     //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-    //~| WARNING `date_range` is ambiguous
+    //~| ERROR `date_range` is ambiguous
     //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
diff --git a/tests/ui/imports/ambiguous-9.stderr b/tests/ui/imports/ambiguous-9.stderr
index 6c7d79174da..1c4768da827 100644
--- a/tests/ui/imports/ambiguous-9.stderr
+++ b/tests/ui/imports/ambiguous-9.stderr
@@ -1,5 +1,5 @@
 warning: ambiguous glob re-exports
-  --> $DIR/ambiguous-9.rs:8:13
+  --> $DIR/ambiguous-9.rs:7:13
    |
 LL |     pub use self::range::*;
    |             ^^^^^^^^^^^^^^ the name `date_range` in the value namespace is first re-exported here
@@ -8,8 +8,8 @@ LL |     use super::prelude::*;
    |
    = note: `#[warn(ambiguous_glob_reexports)]` on by default
 
-warning: `date_range` is ambiguous
-  --> $DIR/ambiguous-9.rs:24:5
+error: `date_range` is ambiguous
+  --> $DIR/ambiguous-9.rs:23:5
    |
 LL |     date_range();
    |     ^^^^^^^^^^ ambiguous name
@@ -18,29 +18,29 @@ LL |     date_range();
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `date_range` could refer to the function imported here
-  --> $DIR/ambiguous-9.rs:8:13
+  --> $DIR/ambiguous-9.rs:7:13
    |
 LL |     pub use self::range::*;
    |             ^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `date_range` to disambiguate
 note: `date_range` could also refer to the function imported here
-  --> $DIR/ambiguous-9.rs:9:9
+  --> $DIR/ambiguous-9.rs:8:9
    |
 LL |     use super::prelude::*;
    |         ^^^^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `date_range` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
 warning: ambiguous glob re-exports
-  --> $DIR/ambiguous-9.rs:16:13
+  --> $DIR/ambiguous-9.rs:15:13
    |
 LL |     pub use self::t::*;
    |             ^^^^^^^^^^ the name `date_range` in the value namespace is first re-exported here
 LL |     pub use super::dsl::*;
    |             ------------- but the name `date_range` in the value namespace is also re-exported here
 
-warning: `date_range` is ambiguous
-  --> $DIR/ambiguous-9.rs:24:5
+error: `date_range` is ambiguous
+  --> $DIR/ambiguous-9.rs:23:5
    |
 LL |     date_range();
    |     ^^^^^^^^^^ ambiguous name
@@ -49,17 +49,65 @@ LL |     date_range();
    = note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
    = note: ambiguous because of multiple glob imports of a name in the same module
 note: `date_range` could refer to the function imported here
-  --> $DIR/ambiguous-9.rs:20:5
+  --> $DIR/ambiguous-9.rs:19:5
    |
 LL | use dsl::*;
    |     ^^^^^^
    = help: consider adding an explicit import of `date_range` to disambiguate
 note: `date_range` could also refer to the function imported here
-  --> $DIR/ambiguous-9.rs:21:5
+  --> $DIR/ambiguous-9.rs:20:5
    |
 LL | use prelude::*;
    |     ^^^^^^^^^^
    = help: consider adding an explicit import of `date_range` to disambiguate
 
-warning: 4 warnings emitted
+error: aborting due to 2 previous errors; 2 warnings emitted
+
+Future incompatibility report: Future breakage diagnostic:
+error: `date_range` is ambiguous
+  --> $DIR/ambiguous-9.rs:23:5
+   |
+LL |     date_range();
+   |     ^^^^^^^^^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `date_range` could refer to the function imported here
+  --> $DIR/ambiguous-9.rs:7:13
+   |
+LL |     pub use self::range::*;
+   |             ^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `date_range` to disambiguate
+note: `date_range` could also refer to the function imported here
+  --> $DIR/ambiguous-9.rs:8:9
+   |
+LL |     use super::prelude::*;
+   |         ^^^^^^^^^^^^^^^^^
+   = help: consider adding an explicit import of `date_range` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
+Future breakage diagnostic:
+error: `date_range` is ambiguous
+  --> $DIR/ambiguous-9.rs:23:5
+   |
+LL |     date_range();
+   |     ^^^^^^^^^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `date_range` could refer to the function imported here
+  --> $DIR/ambiguous-9.rs:19:5
+   |
+LL | use dsl::*;
+   |     ^^^^^^
+   = help: consider adding an explicit import of `date_range` to disambiguate
+note: `date_range` could also refer to the function imported here
+  --> $DIR/ambiguous-9.rs:20:5
+   |
+LL | use prelude::*;
+   |     ^^^^^^^^^^
+   = help: consider adding an explicit import of `date_range` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
diff --git a/tests/ui/imports/duplicate.rs b/tests/ui/imports/duplicate.rs
index 69ec82aafbd..0a652889ca8 100644
--- a/tests/ui/imports/duplicate.rs
+++ b/tests/ui/imports/duplicate.rs
@@ -34,7 +34,7 @@ fn main() {
     e::foo();
     f::foo(); //~ ERROR `foo` is ambiguous
     g::foo();
-    //~^ WARNING `foo` is ambiguous
+    //~^ ERROR `foo` is ambiguous
     //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
 
diff --git a/tests/ui/imports/duplicate.stderr b/tests/ui/imports/duplicate.stderr
index f7dc7312b9d..ef987d07c04 100644
--- a/tests/ui/imports/duplicate.stderr
+++ b/tests/ui/imports/duplicate.stderr
@@ -68,7 +68,7 @@ LL |     use self::m2::*;
    |         ^^^^^^^^^^^
    = help: consider adding an explicit import of `foo` to disambiguate
 
-warning: `foo` is ambiguous
+error: `foo` is ambiguous
   --> $DIR/duplicate.rs:36:8
    |
 LL |     g::foo();
@@ -89,9 +89,33 @@ note: `foo` could also refer to the function imported here
 LL |     pub use crate::b::*;
    |             ^^^^^^^^^^^
    = help: consider adding an explicit import of `foo` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0252, E0659.
 For more information about an error, try `rustc --explain E0252`.
+Future incompatibility report: Future breakage diagnostic:
+error: `foo` is ambiguous
+  --> $DIR/duplicate.rs:36:8
+   |
+LL |     g::foo();
+   |        ^^^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `foo` could refer to the function imported here
+  --> $DIR/duplicate.rs:24:13
+   |
+LL |     pub use crate::a::*;
+   |             ^^^^^^^^^^^
+   = help: consider adding an explicit import of `foo` to disambiguate
+note: `foo` could also refer to the function imported here
+  --> $DIR/duplicate.rs:25:13
+   |
+LL |     pub use crate::b::*;
+   |             ^^^^^^^^^^^
+   = help: consider adding an explicit import of `foo` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
diff --git a/tests/ui/imports/unresolved-seg-after-ambiguous.rs b/tests/ui/imports/unresolved-seg-after-ambiguous.rs
index dcabc528a85..67366deabaa 100644
--- a/tests/ui/imports/unresolved-seg-after-ambiguous.rs
+++ b/tests/ui/imports/unresolved-seg-after-ambiguous.rs
@@ -18,7 +18,7 @@ mod a {
 
 use self::a::E::in_exist;
 //~^ ERROR: unresolved import `self::a::E`
-//~| WARNING: `E` is ambiguous
+//~| ERROR: `E` is ambiguous
 //~| WARNING: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 fn main() {}
diff --git a/tests/ui/imports/unresolved-seg-after-ambiguous.stderr b/tests/ui/imports/unresolved-seg-after-ambiguous.stderr
index 9e0efd4a75f..3b50ae32683 100644
--- a/tests/ui/imports/unresolved-seg-after-ambiguous.stderr
+++ b/tests/ui/imports/unresolved-seg-after-ambiguous.stderr
@@ -4,7 +4,7 @@ error[E0432]: unresolved import `self::a::E`
 LL | use self::a::E::in_exist;
    |              ^ `E` is a struct, not a module
 
-warning: `E` is ambiguous
+error: `E` is ambiguous
   --> $DIR/unresolved-seg-after-ambiguous.rs:19:14
    |
 LL | use self::a::E::in_exist;
@@ -25,8 +25,32 @@ note: `E` could also refer to the struct imported here
 LL |         pub use self::d::*;
    |                 ^^^^^^^^^^
    = help: consider adding an explicit import of `E` to disambiguate
-   = note: `#[warn(ambiguous_glob_imports)]` on by default
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0432`.
+Future incompatibility report: Future breakage diagnostic:
+error: `E` is ambiguous
+  --> $DIR/unresolved-seg-after-ambiguous.rs:19:14
+   |
+LL | use self::a::E::in_exist;
+   |              ^ ambiguous name
+   |
+   = 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
+   = note: ambiguous because of multiple glob imports of a name in the same module
+note: `E` could refer to the struct imported here
+  --> $DIR/unresolved-seg-after-ambiguous.rs:13:17
+   |
+LL |         pub use self::c::*;
+   |                 ^^^^^^^^^^
+   = help: consider adding an explicit import of `E` to disambiguate
+note: `E` could also refer to the struct imported here
+  --> $DIR/unresolved-seg-after-ambiguous.rs:12:17
+   |
+LL |         pub use self::d::*;
+   |                 ^^^^^^^^^^
+   = help: consider adding an explicit import of `E` to disambiguate
+   = note: `#[deny(ambiguous_glob_imports)]` on by default
+
diff --git a/tests/ui/linking/link-self-contained-consistency.rs b/tests/ui/linking/link-self-contained-consistency.rs
index 08227433891..e3944fc0360 100644
--- a/tests/ui/linking/link-self-contained-consistency.rs
+++ b/tests/ui/linking/link-self-contained-consistency.rs
@@ -1,7 +1,6 @@
 // Checks that self-contained linking components cannot be both enabled and disabled at the same
 // time on the CLI.
 
-//@ check-fail
 //@ revisions: one many
 //@ [one] compile-flags: -Clink-self-contained=-linker -Clink-self-contained=+linker -Zunstable-options
 //@ [many] compile-flags: -Clink-self-contained=+linker,+crto -Clink-self-contained=-linker,-crto -Zunstable-options
diff --git a/tests/ui/linking/link-self-contained-linker-disallowed.rs b/tests/ui/linking/link-self-contained-linker-disallowed.rs
new file mode 100644
index 00000000000..f076eb2017a
--- /dev/null
+++ b/tests/ui/linking/link-self-contained-linker-disallowed.rs
@@ -0,0 +1,18 @@
+// Check that only `-C link-self-contained=-linker` is stable on x64 linux. Any other value or
+// target, needs `-Z unstable-options`.
+
+// ignore-tidy-linelength
+
+//@ revisions: unstable_target_positive unstable_target_negative unstable_positive
+//@ [unstable_target_negative] compile-flags: --target=x86_64-unknown-linux-musl -C link-self-contained=-linker --crate-type=rlib
+//@ [unstable_target_negative] needs-llvm-components: x86
+//@ [unstable_target_positive] compile-flags: --target=x86_64-unknown-linux-musl -C link-self-contained=+linker --crate-type=rlib
+//@ [unstable_target_positive] needs-llvm-components: x86
+//@ [unstable_positive] compile-flags: --target=x86_64-unknown-linux-gnu -C link-self-contained=+linker --crate-type=rlib
+//@ [unstable_positive] needs-llvm-components: x86
+
+#![feature(no_core)]
+#![no_core]
+
+//[unstable_target_negative]~? ERROR `-C link-self-contained=-linker` is unstable on the `x86_64-unknown-linux-musl` target
+//[unstable_target_positive,unstable_positive]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable
diff --git a/tests/ui/linking/link-self-contained-linker-disallowed.unstable_positive.stderr b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_positive.stderr
new file mode 100644
index 00000000000..4eb0ff04b65
--- /dev/null
+++ b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_positive.stderr
@@ -0,0 +1,2 @@
+error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values
+
diff --git a/tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_negative.stderr b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_negative.stderr
new file mode 100644
index 00000000000..8bf71941c44
--- /dev/null
+++ b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_negative.stderr
@@ -0,0 +1,2 @@
+error: `-C link-self-contained=-linker` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target
+
diff --git a/tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_positive.stderr b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_positive.stderr
new file mode 100644
index 00000000000..4eb0ff04b65
--- /dev/null
+++ b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_positive.stderr
@@ -0,0 +1,2 @@
+error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values
+
diff --git a/tests/ui/linking/link-self-contained-unstable.crto.stderr b/tests/ui/linking/link-self-contained-unstable.crto.stderr
new file mode 100644
index 00000000000..4eb0ff04b65
--- /dev/null
+++ b/tests/ui/linking/link-self-contained-unstable.crto.stderr
@@ -0,0 +1,2 @@
+error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values
+
diff --git a/tests/ui/linking/link-self-contained-unstable.libc.stderr b/tests/ui/linking/link-self-contained-unstable.libc.stderr
new file mode 100644
index 00000000000..4eb0ff04b65
--- /dev/null
+++ b/tests/ui/linking/link-self-contained-unstable.libc.stderr
@@ -0,0 +1,2 @@
+error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values
+
diff --git a/tests/ui/linking/link-self-contained-unstable.mingw.stderr b/tests/ui/linking/link-self-contained-unstable.mingw.stderr
new file mode 100644
index 00000000000..4eb0ff04b65
--- /dev/null
+++ b/tests/ui/linking/link-self-contained-unstable.mingw.stderr
@@ -0,0 +1,2 @@
+error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values
+
diff --git a/tests/ui/linking/link-self-contained-unstable.rs b/tests/ui/linking/link-self-contained-unstable.rs
new file mode 100644
index 00000000000..10c895909d5
--- /dev/null
+++ b/tests/ui/linking/link-self-contained-unstable.rs
@@ -0,0 +1,13 @@
+// Checks that values for `-Clink-self-contained` other than the blanket enable/disable and
+// `-linker` require `-Zunstable-options`.
+
+//@ revisions: crto libc unwind sanitizers mingw
+//@ [crto] compile-flags: -Clink-self-contained=+crto
+//@ [libc] compile-flags: -Clink-self-contained=-libc
+//@ [unwind] compile-flags: -Clink-self-contained=+unwind
+//@ [sanitizers] compile-flags: -Clink-self-contained=-sanitizers
+//@ [mingw] compile-flags: -Clink-self-contained=+mingw
+
+fn main() {}
+
+//~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable
diff --git a/tests/ui/linking/link-self-contained-unstable.sanitizers.stderr b/tests/ui/linking/link-self-contained-unstable.sanitizers.stderr
new file mode 100644
index 00000000000..4eb0ff04b65
--- /dev/null
+++ b/tests/ui/linking/link-self-contained-unstable.sanitizers.stderr
@@ -0,0 +1,2 @@
+error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values
+
diff --git a/tests/ui/linking/link-self-contained-unstable.unwind.stderr b/tests/ui/linking/link-self-contained-unstable.unwind.stderr
new file mode 100644
index 00000000000..4eb0ff04b65
--- /dev/null
+++ b/tests/ui/linking/link-self-contained-unstable.unwind.stderr
@@ -0,0 +1,2 @@
+error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values
+
diff --git a/tests/ui/linking/linker-features-lld-disallowed.rs b/tests/ui/linking/linker-features-lld-disallowed.rs
new file mode 100644
index 00000000000..9b8fa2b11e6
--- /dev/null
+++ b/tests/ui/linking/linker-features-lld-disallowed.rs
@@ -0,0 +1,19 @@
+// Check that only `-C linker-features=-lld` is stable on x64 linux. Any other value or target,
+// needs `-Z unstable-options`.
+
+// ignore-tidy-linelength
+
+//@ revisions: unstable_target_positive unstable_target_negative unstable_positive
+//@ [unstable_target_negative] compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=-lld --crate-type=rlib
+//@ [unstable_target_negative] needs-llvm-components: x86
+//@ [unstable_target_positive] compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=+lld --crate-type=rlib
+//@ [unstable_target_positive] needs-llvm-components: x86
+//@ [unstable_positive] compile-flags: --target=x86_64-unknown-linux-gnu -C linker-features=+lld --crate-type=rlib
+//@ [unstable_positive] needs-llvm-components: x86
+
+
+#![feature(no_core)]
+#![no_core]
+
+//[unstable_target_negative]~? ERROR `-C linker-features=-lld` is unstable on the `x86_64-unknown-linux-musl` target
+//[unstable_target_positive,unstable_positive]~? ERROR `-C linker-features=+lld` is unstable, and also requires the `-Z unstable-options`
diff --git a/tests/ui/linking/linker-features-lld-disallowed.unstable_positive.stderr b/tests/ui/linking/linker-features-lld-disallowed.unstable_positive.stderr
new file mode 100644
index 00000000000..09e7e4975c4
--- /dev/null
+++ b/tests/ui/linking/linker-features-lld-disallowed.unstable_positive.stderr
@@ -0,0 +1,2 @@
+error: `-C linker-features=+lld` is unstable, and also requires the `-Z unstable-options` flag to be used
+
diff --git a/tests/ui/linking/linker-features-lld-disallowed.unstable_target_negative.stderr b/tests/ui/linking/linker-features-lld-disallowed.unstable_target_negative.stderr
new file mode 100644
index 00000000000..205082b0726
--- /dev/null
+++ b/tests/ui/linking/linker-features-lld-disallowed.unstable_target_negative.stderr
@@ -0,0 +1,2 @@
+error: `-C linker-features=-lld` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target
+
diff --git a/tests/ui/linking/linker-features-lld-disallowed.unstable_target_positive.stderr b/tests/ui/linking/linker-features-lld-disallowed.unstable_target_positive.stderr
new file mode 100644
index 00000000000..09e7e4975c4
--- /dev/null
+++ b/tests/ui/linking/linker-features-lld-disallowed.unstable_target_positive.stderr
@@ -0,0 +1,2 @@
+error: `-C linker-features=+lld` is unstable, and also requires the `-Z unstable-options` flag to be used
+
diff --git a/tests/ui/linking/linker-features-malformed.invalid_modifier.stderr b/tests/ui/linking/linker-features-malformed.invalid_modifier.stderr
index 909b277089f..d9ed65ad3e2 100644
--- a/tests/ui/linking/linker-features-malformed.invalid_modifier.stderr
+++ b/tests/ui/linking/linker-features-malformed.invalid_modifier.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `*lld` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
+error: incorrect value `*lld` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
 
diff --git a/tests/ui/linking/linker-features-malformed.invalid_separator.stderr b/tests/ui/linking/linker-features-malformed.invalid_separator.stderr
index 0f84898a774..e950d8f3e8f 100644
--- a/tests/ui/linking/linker-features-malformed.invalid_separator.stderr
+++ b/tests/ui/linking/linker-features-malformed.invalid_separator.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `-lld@+lld` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
+error: incorrect value `-lld@+lld` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
 
diff --git a/tests/ui/linking/linker-features-malformed.no_value.stderr b/tests/ui/linking/linker-features-malformed.no_value.stderr
index e93a4e79bb1..e03d3b34bb1 100644
--- a/tests/ui/linking/linker-features-malformed.no_value.stderr
+++ b/tests/ui/linking/linker-features-malformed.no_value.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
+error: incorrect value `` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
 
diff --git a/tests/ui/linking/linker-features-malformed.rs b/tests/ui/linking/linker-features-malformed.rs
index 0bdcfa39920..627b8e68920 100644
--- a/tests/ui/linking/linker-features-malformed.rs
+++ b/tests/ui/linking/linker-features-malformed.rs
@@ -1,27 +1,27 @@
-//! Check that malformed `-Zlinker-features` flags are properly rejected.
+//! Check that malformed `-Clinker-features` flags are properly rejected.
 
 //@ revisions: no_value
-//@[no_value] compile-flags: -Zlinker-features=
-//[no_value]~? ERROR incorrect value `` for unstable option `linker-features`
+//@[no_value] compile-flags: -Clinker-features=
+//[no_value]~? ERROR incorrect value `` for codegen option `linker-features`
 
 //@ revisions: invalid_modifier
-//@[invalid_modifier] compile-flags: -Zlinker-features=*lld
-//[invalid_modifier]~? ERROR incorrect value `*lld` for unstable option `linker-features`
+//@[invalid_modifier] compile-flags: -Clinker-features=*lld
+//[invalid_modifier]~? ERROR incorrect value `*lld` for codegen option `linker-features`
 
 //@ revisions: unknown_value
-//@[unknown_value] compile-flags: -Zlinker-features=unknown
-//[unknown_value]~? ERROR incorrect value `unknown` for unstable option `linker-features`
+//@[unknown_value] compile-flags: -Clinker-features=unknown
+//[unknown_value]~? ERROR incorrect value `unknown` for codegen option `linker-features`
 
 //@ revisions: unknown_modifier_value
-//@[unknown_modifier_value] compile-flags: -Zlinker-features=-unknown
-//[unknown_modifier_value]~? ERROR incorrect value `-unknown` for unstable option `linker-features`
+//@[unknown_modifier_value] compile-flags: -Clinker-features=-unknown
+//[unknown_modifier_value]~? ERROR incorrect value `-unknown` for codegen option `linker-features`
 
 //@ revisions: unknown_boolean
-//@[unknown_boolean] compile-flags: -Zlinker-features=maybe
-//[unknown_boolean]~? ERROR incorrect value `maybe` for unstable option `linker-features`
+//@[unknown_boolean] compile-flags: -Clinker-features=maybe
+//[unknown_boolean]~? ERROR incorrect value `maybe` for codegen option `linker-features`
 
 //@ revisions: invalid_separator
-//@[invalid_separator] compile-flags: -Zlinker-features=-lld@+lld
-//[invalid_separator]~? ERROR incorrect value `-lld@+lld` for unstable option `linker-features`
+//@[invalid_separator] compile-flags: -Clinker-features=-lld@+lld
+//[invalid_separator]~? ERROR incorrect value `-lld@+lld` for codegen option `linker-features`
 
 fn main() {}
diff --git a/tests/ui/linking/linker-features-malformed.unknown_boolean.stderr b/tests/ui/linking/linker-features-malformed.unknown_boolean.stderr
index 865738d0ccc..d82c2ea04b4 100644
--- a/tests/ui/linking/linker-features-malformed.unknown_boolean.stderr
+++ b/tests/ui/linking/linker-features-malformed.unknown_boolean.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `maybe` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
+error: incorrect value `maybe` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
 
diff --git a/tests/ui/linking/linker-features-malformed.unknown_modifier_value.stderr b/tests/ui/linking/linker-features-malformed.unknown_modifier_value.stderr
index 03b9620ca26..59366e28e44 100644
--- a/tests/ui/linking/linker-features-malformed.unknown_modifier_value.stderr
+++ b/tests/ui/linking/linker-features-malformed.unknown_modifier_value.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `-unknown` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
+error: incorrect value `-unknown` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
 
diff --git a/tests/ui/linking/linker-features-malformed.unknown_value.stderr b/tests/ui/linking/linker-features-malformed.unknown_value.stderr
index 566632a3df3..e8f6d5e637c 100644
--- a/tests/ui/linking/linker-features-malformed.unknown_value.stderr
+++ b/tests/ui/linking/linker-features-malformed.unknown_value.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `unknown` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
+error: incorrect value `unknown` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
 
diff --git a/tests/ui/linking/linker-features-unstable-cc.rs b/tests/ui/linking/linker-features-unstable-cc.rs
new file mode 100644
index 00000000000..38103c81060
--- /dev/null
+++ b/tests/ui/linking/linker-features-unstable-cc.rs
@@ -0,0 +1,13 @@
+// Check that only `-C linker-features=-lld` is stable on x64 linux, and that other linker
+// features require using `-Z unstable-options`.
+//
+// Note that, currently, only `lld` is parsed on the CLI, but that other linker features can exist
+// internally (`cc`).
+//
+//@ compile-flags: --target=x86_64-unknown-linux-gnu -C linker-features=+cc --crate-type=rlib
+//@ needs-llvm-components: x86
+
+#![feature(no_core)]
+#![no_core]
+
+//~? ERROR incorrect value `+cc` for codegen option `linker-features`
diff --git a/tests/ui/linking/linker-features-unstable-cc.stderr b/tests/ui/linking/linker-features-unstable-cc.stderr
new file mode 100644
index 00000000000..a69b4198160
--- /dev/null
+++ b/tests/ui/linking/linker-features-unstable-cc.stderr
@@ -0,0 +1,2 @@
+error: incorrect value `+cc` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected
+
diff --git a/tests/ui/lint/dead-code/unused-struct-derive-default.rs b/tests/ui/lint/dead-code/unused-struct-derive-default.rs
index f20b7cb66ee..bfbdf57b0dc 100644
--- a/tests/ui/lint/dead-code/unused-struct-derive-default.rs
+++ b/tests/ui/lint/dead-code/unused-struct-derive-default.rs
@@ -1,4 +1,4 @@
-#![deny(dead_code)]
+#![deny(dead_code)] //~ NOTE the lint level is defined here
 
 #[derive(Default)]
 struct T; //~ ERROR struct `T` is never constructed
@@ -7,7 +7,7 @@ struct T; //~ ERROR struct `T` is never constructed
 struct Used;
 
 #[derive(Default)]
-enum E {
+enum E { //~ NOTE variant in this enum
     #[default]
     A,
     B, //~ ERROR variant `B` is never constructed
diff --git a/tests/ui/lint/unused/closure-body-issue-136741.fixed b/tests/ui/lint/unused/closure-body-issue-136741.fixed
new file mode 100644
index 00000000000..2ded52544b9
--- /dev/null
+++ b/tests/ui/lint/unused/closure-body-issue-136741.fixed
@@ -0,0 +1,36 @@
+//@ run-rustfix
+// ignore-tidy-linelength
+#![deny(unused_parens)]
+#![deny(unused_braces)]
+
+fn long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces()
+{}
+
+fn func(f: impl FnOnce()) {
+    f()
+}
+
+pub fn main() {
+    let _closure = |x: i32, y: i32| { x * (x + (y * 2)) };
+    let _ = || 0 == 0; //~ ERROR unnecessary parentheses around closure body
+    let _ = (0..).find(|n| n % 2 == 0); //~ ERROR unnecessary parentheses around closure body
+    let _ = (0..).find(|n| {n % 2 == 0});
+
+    // multiple lines of code will not lint with braces
+    let _ = (0..).find(|n| {
+        n % 2 == 0
+    });
+
+    // multiple lines of code will lint with parentheses
+    let _ = (0..).find(|n| n % 2 == 0);
+
+    let _ = || {
+        _ = 0;
+        0 == 0 //~ ERROR unnecessary parentheses around block return value
+    };
+
+    // long expressions will not lint with braces
+    func(|| {
+        long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces()
+    })
+}
diff --git a/tests/ui/lint/unused/closure-body-issue-136741.rs b/tests/ui/lint/unused/closure-body-issue-136741.rs
new file mode 100644
index 00000000000..4eac981ec2e
--- /dev/null
+++ b/tests/ui/lint/unused/closure-body-issue-136741.rs
@@ -0,0 +1,38 @@
+//@ run-rustfix
+// ignore-tidy-linelength
+#![deny(unused_parens)]
+#![deny(unused_braces)]
+
+fn long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces()
+{}
+
+fn func(f: impl FnOnce()) {
+    f()
+}
+
+pub fn main() {
+    let _closure = |x: i32, y: i32| { x * (x + (y * 2)) };
+    let _ = || (0 == 0); //~ ERROR unnecessary parentheses around closure body
+    let _ = (0..).find(|n| (n % 2 == 0)); //~ ERROR unnecessary parentheses around closure body
+    let _ = (0..).find(|n| {n % 2 == 0});
+
+    // multiple lines of code will not lint with braces
+    let _ = (0..).find(|n| {
+        n % 2 == 0
+    });
+
+    // multiple lines of code will lint with parentheses
+    let _ = (0..).find(|n| ( //~ ERROR unnecessary parentheses around closure body
+        n % 2 == 0
+    ));
+
+    let _ = || {
+        _ = 0;
+        (0 == 0) //~ ERROR unnecessary parentheses around block return value
+    };
+
+    // long expressions will not lint with braces
+    func(|| {
+        long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces_long_expr_that_does_not_require_braces()
+    })
+}
diff --git a/tests/ui/lint/unused/closure-body-issue-136741.stderr b/tests/ui/lint/unused/closure-body-issue-136741.stderr
new file mode 100644
index 00000000000..2ea872c08c7
--- /dev/null
+++ b/tests/ui/lint/unused/closure-body-issue-136741.stderr
@@ -0,0 +1,62 @@
+error: unnecessary parentheses around closure body
+  --> $DIR/closure-body-issue-136741.rs:15:16
+   |
+LL |     let _ = || (0 == 0);
+   |                ^      ^
+   |
+note: the lint level is defined here
+  --> $DIR/closure-body-issue-136741.rs:3:9
+   |
+LL | #![deny(unused_parens)]
+   |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let _ = || (0 == 0);
+LL +     let _ = || 0 == 0;
+   |
+
+error: unnecessary parentheses around closure body
+  --> $DIR/closure-body-issue-136741.rs:16:28
+   |
+LL |     let _ = (0..).find(|n| (n % 2 == 0));
+   |                            ^          ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = (0..).find(|n| (n % 2 == 0));
+LL +     let _ = (0..).find(|n| n % 2 == 0);
+   |
+
+error: unnecessary parentheses around closure body
+  --> $DIR/closure-body-issue-136741.rs:25:28
+   |
+LL |        let _ = (0..).find(|n| (
+   |  _____________________________^
+LL | |          n % 2 == 0
+   | | ________^__________^
+   | ||________|
+   |  |
+LL |  |     ));
+   |  |_____^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = (0..).find(|n| (
+LL -         n % 2 == 0
+LL +     let _ = (0..).find(|n| n % 2 == 0);
+   |
+
+error: unnecessary parentheses around block return value
+  --> $DIR/closure-body-issue-136741.rs:31:9
+   |
+LL |         (0 == 0)
+   |         ^      ^
+   |
+help: remove these parentheses
+   |
+LL -         (0 == 0)
+LL +         0 == 0
+   |
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/paren-span.rs b/tests/ui/macros/macro-paren-span-diagnostic.rs
index c8cb63d5190..cbcb0231e4e 100644
--- a/tests/ui/paren-span.rs
+++ b/tests/ui/macros/macro-paren-span-diagnostic.rs
@@ -1,5 +1,6 @@
-// Be smart about span of parenthesized expression in macro.
+//! Check that error spans in parenthesized macro expressions point to the call site.
 
+#[rustfmt::skip]
 macro_rules! paren {
     ($e:expr) => (($e))
     //            ^^^^ do not highlight here
@@ -7,8 +8,9 @@ macro_rules! paren {
 
 mod m {
     pub struct S {
-        x: i32
+        x: i32,
     }
+
     pub fn make() -> S {
         S { x: 0 }
     }
diff --git a/tests/ui/paren-span.stderr b/tests/ui/macros/macro-paren-span-diagnostic.stderr
index da2f57033a4..ede6ff51c71 100644
--- a/tests/ui/paren-span.stderr
+++ b/tests/ui/macros/macro-paren-span-diagnostic.stderr
@@ -1,5 +1,5 @@
 error[E0616]: field `x` of struct `S` is private
-  --> $DIR/paren-span.rs:19:14
+  --> $DIR/macro-paren-span-diagnostic.rs:21:14
    |
 LL |     paren!(s.x);
    |              ^ private field
diff --git a/tests/ui/macros/metavar-expressions/syntax-errors.rs b/tests/ui/macros/metavar-expressions/syntax-errors.rs
index 8fc76a74baa..585ea4d5979 100644
--- a/tests/ui/macros/metavar-expressions/syntax-errors.rs
+++ b/tests/ui/macros/metavar-expressions/syntax-errors.rs
@@ -30,7 +30,7 @@ macro_rules! metavar_with_literal_suffix {
 
 macro_rules! mve_without_parens {
     ( $( $i:ident ),* ) => { ${ count } };
-    //~^ ERROR meta-variable expression parameter must be wrapped in parentheses
+    //~^ ERROR expected `(`
 }
 
 #[rustfmt::skip]
@@ -45,9 +45,14 @@ macro_rules! open_brackets_with_lit {
      //~^ ERROR expected identifier
  }
 
+macro_rules! mvs_missing_paren {
+    ( $( $i:ident ),* ) => { ${ count $i ($i) } };
+    //~^ ERROR expected `(`
+}
+
 macro_rules! mve_wrong_delim {
     ( $( $i:ident ),* ) => { ${ count{i} } };
-    //~^ ERROR meta-variable expression parameter must be wrapped in parentheses
+    //~^ ERROR expected `(`
 }
 
 macro_rules! invalid_metavar {
@@ -64,28 +69,30 @@ macro_rules! open_brackets_with_group {
 macro_rules! extra_garbage_after_metavar {
     ( $( $i:ident ),* ) => {
         ${count() a b c}
-        //~^ ERROR unexpected token: a
+        //~^ ERROR unexpected trailing tokens
         ${count($i a b c)}
-        //~^ ERROR unexpected token: a
+        //~^ ERROR unexpected trailing tokens
         ${count($i, 1 a b c)}
-        //~^ ERROR unexpected token: a
+        //~^ ERROR unexpected trailing tokens
         ${count($i) a b c}
-        //~^ ERROR unexpected token: a
+        //~^ ERROR unexpected trailing tokens
 
         ${ignore($i) a b c}
-        //~^ ERROR unexpected token: a
+        //~^ ERROR unexpected trailing tokens
         ${ignore($i a b c)}
-        //~^ ERROR unexpected token: a
+        //~^ ERROR unexpected trailing tokens
 
         ${index() a b c}
-        //~^ ERROR unexpected token: a
+        //~^ ERROR unexpected trailing tokens
         ${index(1 a b c)}
-        //~^ ERROR unexpected token: a
+        //~^ ERROR unexpected trailing tokens
 
         ${index() a b c}
-        //~^ ERROR unexpected token: a
+        //~^ ERROR unexpected trailing tokens
         ${index(1 a b c)}
-        //~^ ERROR unexpected token: a
+        //~^ ERROR unexpected trailing tokens
+        ${index(1, a b c)}
+        //~^ ERROR unexpected trailing tokens
     };
 }
 
@@ -111,7 +118,7 @@ macro_rules! unknown_ignore_ident {
 
 macro_rules! unknown_metavar {
     ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
-    //~^ ERROR unrecognized meta-variable expression
+    //~^ ERROR unrecognized metavariable expression
 }
 
 fn main() {}
diff --git a/tests/ui/macros/metavar-expressions/syntax-errors.stderr b/tests/ui/macros/metavar-expressions/syntax-errors.stderr
index 20d2358facc..bf1c7673a6c 100644
--- a/tests/ui/macros/metavar-expressions/syntax-errors.stderr
+++ b/tests/ui/macros/metavar-expressions/syntax-errors.stderr
@@ -40,167 +40,165 @@ error: only unsuffixes integer literals are supported in meta-variable expressio
 LL |     ( $( $i:ident ),* ) => { ${ index(1u32) } };
    |                                 ^^^^^
 
-error: meta-variable expression parameter must be wrapped in parentheses
+error: expected `(`
   --> $DIR/syntax-errors.rs:32:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ count } };
-   |                                 ^^^^^
+   |                                 ^^^^^- help: try adding parentheses: `( /* ... */ )`
+   |                                 |
+   |                                 for this this metavariable expression
+   |
+   = note: metavariable expressions use function-like parentheses syntax
 
-error: meta-variable expression parameter must be wrapped in parentheses
+error: expected `(`
   --> $DIR/syntax-errors.rs:49:33
    |
+LL |     ( $( $i:ident ),* ) => { ${ count $i ($i) } };
+   |                                 ^^^^^ - unexpected token
+   |                                 |
+   |                                 for this this metavariable expression
+   |
+   = note: metavariable expressions use function-like parentheses syntax
+
+error: expected `(`
+  --> $DIR/syntax-errors.rs:54:33
+   |
 LL |     ( $( $i:ident ),* ) => { ${ count{i} } };
-   |                                 ^^^^^
+   |                                 ^^^^^ for this this metavariable expression
+   |
+   = note: metavariable expressions use function-like parentheses syntax
 
 error: expected identifier, found `123`
-  --> $DIR/syntax-errors.rs:54:23
+  --> $DIR/syntax-errors.rs:59:23
    |
 LL |     () => { ${ignore($123)} }
    |                       ^^^ help: try removing `123`
 
-error: unexpected token: a
-  --> $DIR/syntax-errors.rs:66:19
-   |
-LL |         ${count() a b c}
-   |                   ^
-   |
-note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:66:19
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:71:19
    |
 LL |         ${count() a b c}
-   |                   ^
+   |           -----   ^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
 
-error: unexpected token: a
-  --> $DIR/syntax-errors.rs:68:20
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:73:20
    |
 LL |         ${count($i a b c)}
-   |                    ^
-   |
-note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:68:20
+   |           -----    ^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
    |
-LL |         ${count($i a b c)}
-   |                    ^
+   = note: the `count` metavariable expression takes between 1 and 2 arguments
 
-error: unexpected token: a
-  --> $DIR/syntax-errors.rs:70:23
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:75:23
    |
 LL |         ${count($i, 1 a b c)}
-   |                       ^
+   |           -----       ^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
    |
-note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:70:23
-   |
-LL |         ${count($i, 1 a b c)}
-   |                       ^
+   = note: the `count` metavariable expression takes between 1 and 2 arguments
 
-error: unexpected token: a
-  --> $DIR/syntax-errors.rs:72:21
-   |
-LL |         ${count($i) a b c}
-   |                     ^
-   |
-note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:72:21
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:77:21
    |
 LL |         ${count($i) a b c}
-   |                     ^
+   |           -----     ^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
 
-error: unexpected token: a
-  --> $DIR/syntax-errors.rs:75:22
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:80:22
    |
 LL |         ${ignore($i) a b c}
-   |                      ^
-   |
-note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:75:22
-   |
-LL |         ${ignore($i) a b c}
-   |                      ^
+   |           ------     ^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
 
-error: unexpected token: a
-  --> $DIR/syntax-errors.rs:77:21
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:82:21
    |
 LL |         ${ignore($i a b c)}
-   |                     ^
+   |           ------    ^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
    |
-note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:77:21
-   |
-LL |         ${ignore($i a b c)}
-   |                     ^
+   = note: the `ignore` metavariable expression takes a single argument
 
-error: unexpected token: a
-  --> $DIR/syntax-errors.rs:80:19
-   |
-LL |         ${index() a b c}
-   |                   ^
-   |
-note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:80:19
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:85:19
    |
 LL |         ${index() a b c}
-   |                   ^
+   |           -----   ^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
 
-error: unexpected token: a
-  --> $DIR/syntax-errors.rs:82:19
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:87:19
    |
 LL |         ${index(1 a b c)}
-   |                   ^
-   |
-note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:82:19
+   |           -----   ^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
    |
-LL |         ${index(1 a b c)}
-   |                   ^
+   = note: the `index` metavariable expression takes between 0 and 1 arguments
 
-error: unexpected token: a
-  --> $DIR/syntax-errors.rs:85:19
-   |
-LL |         ${index() a b c}
-   |                   ^
-   |
-note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:85:19
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:90:19
    |
 LL |         ${index() a b c}
-   |                   ^
+   |           -----   ^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
 
-error: unexpected token: a
-  --> $DIR/syntax-errors.rs:87:19
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:92:19
    |
 LL |         ${index(1 a b c)}
-   |                   ^
+   |           -----   ^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
    |
-note: meta-variable expression must not have trailing tokens
-  --> $DIR/syntax-errors.rs:87:19
+   = note: the `index` metavariable expression takes between 0 and 1 arguments
+
+error: unexpected trailing tokens
+  --> $DIR/syntax-errors.rs:94:18
    |
-LL |         ${index(1 a b c)}
-   |                   ^
+LL |         ${index(1, a b c)}
+   |           -----  ^^^^^^^ help: try removing these tokens
+   |           |
+   |           for this metavariable expression
+   |
+   = note: the `index` metavariable expression takes between 0 and 1 arguments
 
 error: meta-variable expression depth must be a literal
-  --> $DIR/syntax-errors.rs:94:33
+  --> $DIR/syntax-errors.rs:101:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ index(IDX) } };
    |                                 ^^^^^
 
 error: meta-variables within meta-variable expressions must be referenced using a dollar sign
-  --> $DIR/syntax-errors.rs:100:11
+  --> $DIR/syntax-errors.rs:107:11
    |
 LL |         ${count(foo)}
    |           ^^^^^
 
 error: meta-variables within meta-variable expressions must be referenced using a dollar sign
-  --> $DIR/syntax-errors.rs:107:11
+  --> $DIR/syntax-errors.rs:114:11
    |
 LL |         ${ignore(bar)}
    |           ^^^^^^
 
-error: unrecognized meta-variable expression
-  --> $DIR/syntax-errors.rs:113:33
+error: unrecognized metavariable expression
+  --> $DIR/syntax-errors.rs:120:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
-   |                                 ^^^^^^^^^^^^^^ help: supported expressions are count, ignore, index and len
+   |                                 ^^^^^^^^^^^^^^ not a valid metavariable expression
+   |
+   = note: valid metavariable expressions are `count`, `ignore`, `index`, `len`, and `concat`
 
 error: expected identifier or string literal
   --> $DIR/syntax-errors.rs:38:14
@@ -215,10 +213,10 @@ LL |      () => { ${ "hi" } };
    |                 ^^^^ help: try removing `"hi"`
 
 error: expected identifier or string literal
-  --> $DIR/syntax-errors.rs:60:33
+  --> $DIR/syntax-errors.rs:65:33
    |
 LL |     ( $( $i:ident ),* ) => { ${ {} } };
    |                                 ^^
 
-error: aborting due to 25 previous errors
+error: aborting due to 27 previous errors
 
diff --git a/tests/ui/mir/enum/convert_non_enum_break.rs b/tests/ui/mir/enum/convert_non_integer_break.rs
index de062c39907..29795190bf6 100644
--- a/tests/ui/mir/enum/convert_non_enum_break.rs
+++ b/tests/ui/mir/enum/convert_non_integer_break.rs
@@ -1,6 +1,6 @@
 //@ run-fail
 //@ compile-flags: -C debug-assertions
-//@ error-pattern: trying to construct an enum from an invalid value 0x10000
+//@ error-pattern: trying to construct an enum from an invalid value
 
 #[allow(dead_code)]
 #[repr(u32)]
@@ -11,10 +11,9 @@ enum Foo {
 
 #[allow(dead_code)]
 struct Bar {
-    a: u16,
-    b: u16,
+    a: u32,
 }
 
 fn main() {
-    let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 0, b: 1 }) };
+    let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 3 }) };
 }
diff --git a/tests/ui/mir/enum/convert_non_enum_niche_break.rs b/tests/ui/mir/enum/convert_non_integer_niche_break.rs
index 9ff4849c5b1..9ff4849c5b1 100644
--- a/tests/ui/mir/enum/convert_non_enum_niche_break.rs
+++ b/tests/ui/mir/enum/convert_non_integer_niche_break.rs
diff --git a/tests/ui/mir/enum/convert_non_enum_niche_ok.rs b/tests/ui/mir/enum/convert_non_integer_niche_ok.rs
index 24027da5458..24027da5458 100644
--- a/tests/ui/mir/enum/convert_non_enum_niche_ok.rs
+++ b/tests/ui/mir/enum/convert_non_integer_niche_ok.rs
diff --git a/tests/ui/mir/enum/convert_non_enum_ok.rs b/tests/ui/mir/enum/convert_non_integer_ok.rs
index 37fc64342ca..c9831531386 100644
--- a/tests/ui/mir/enum/convert_non_enum_ok.rs
+++ b/tests/ui/mir/enum/convert_non_integer_ok.rs
@@ -10,11 +10,10 @@ enum Foo {
 
 #[allow(dead_code)]
 struct Bar {
-    a: u16,
-    b: u16,
+    a: u32,
 }
 
 fn main() {
-    let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 0, b: 0 }) };
-    let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 1, b: 0 }) };
+    let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 0 }) };
+    let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 1 }) };
 }
diff --git a/tests/ui/mir/enum/niche_option_tuple_break.rs b/tests/ui/mir/enum/niche_option_tuple_break.rs
index 43eef3a4cc5..affdc4784a3 100644
--- a/tests/ui/mir/enum/niche_option_tuple_break.rs
+++ b/tests/ui/mir/enum/niche_option_tuple_break.rs
@@ -1,8 +1,9 @@
 //@ run-fail
 //@ compile-flags: -C debug-assertions
-//@ error-pattern: trying to construct an enum from an invalid value 0x3
+//@ error-pattern: trying to construct an enum from an invalid value
 
 #[allow(dead_code)]
+#[repr(u32)]
 enum Foo {
     A,
     B,
@@ -10,11 +11,11 @@ enum Foo {
 
 #[allow(dead_code)]
 struct Bar {
-    a: usize,
-    b: usize,
+    a: u32,
+    b: u32,
 }
 
 fn main() {
-    let _val: Option<(usize, Foo)> =
-        unsafe { std::mem::transmute::<_, Option<(usize, Foo)>>(Bar { a: 3, b: 3 }) };
+    let _val: Option<(u32, Foo)> =
+        unsafe { std::mem::transmute::<_, Option<(u32, Foo)>>(Bar { a: 3, b: 3 }) };
 }
diff --git a/tests/ui/mir/enum/with_niche_int_break.rs b/tests/ui/mir/enum/with_niche_int_break.rs
index 0ec60a33564..6a97eaa8f4f 100644
--- a/tests/ui/mir/enum/with_niche_int_break.rs
+++ b/tests/ui/mir/enum/with_niche_int_break.rs
@@ -1,6 +1,6 @@
 //@ run-fail
 //@ compile-flags: -C debug-assertions
-//@ error-pattern: trying to construct an enum from an invalid value 0x4
+//@ error-pattern: trying to construct an enum from an invalid value
 
 #[allow(dead_code)]
 #[repr(u16)]
@@ -17,5 +17,5 @@ enum Nested {
 }
 
 fn main() {
-    let _val: Nested = unsafe { std::mem::transmute::<u32, Nested>(4) };
+    let _val: Nested = unsafe { std::mem::transmute::<u32, Nested>(u32::MAX) };
 }
diff --git a/tests/ui/out-pointer-aliasing.rs b/tests/ui/out-pointer-aliasing.rs
deleted file mode 100644
index 0dfaa19fadb..00000000000
--- a/tests/ui/out-pointer-aliasing.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-//@ run-pass
-
-#[derive(Copy, Clone)]
-pub struct Foo {
-    f1: isize,
-    _f2: isize,
-}
-
-#[inline(never)]
-pub fn foo(f: &mut Foo) -> Foo {
-    let ret = *f;
-    f.f1 = 0;
-    ret
-}
-
-pub fn main() {
-    let mut f = Foo {
-        f1: 8,
-        _f2: 9,
-    };
-    f = foo(&mut f);
-    assert_eq!(f.f1, 8);
-}
diff --git a/tests/ui/over-constrained-vregs.rs b/tests/ui/over-constrained-vregs.rs
deleted file mode 100644
index 016a667e937..00000000000
--- a/tests/ui/over-constrained-vregs.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ run-pass
-
-#![allow(unused_must_use)]
-// Regression test for issue #152.
-pub fn main() {
-    let mut b: usize = 1_usize;
-    while b < std::mem::size_of::<usize>() {
-        0_usize << b;
-        b <<= 1_usize;
-        println!("{}", b);
-    }
-}
diff --git a/tests/ui/panic_implementation-closures.rs b/tests/ui/panic_implementation-closures.rs
deleted file mode 100644
index b161859bf9c..00000000000
--- a/tests/ui/panic_implementation-closures.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ build-pass (FIXME(62277): could be check-pass?)
-
-#![crate_type = "rlib"]
-#![no_std]
-
-#[panic_handler]
-pub fn panic_fmt(_: &::core::panic::PanicInfo) -> ! {
-    |x: u8| x;
-    loop {}
-}
diff --git a/tests/ui/panic-while-printing.rs b/tests/ui/panics/panic-during-display-formatting.rs
index 6505a69fef7..a307ee49385 100644
--- a/tests/ui/panic-while-printing.rs
+++ b/tests/ui/panics/panic-during-display-formatting.rs
@@ -1,3 +1,5 @@
+//! Check that panics in `Display::fmt` during printing are properly handled.
+
 //@ run-pass
 //@ needs-unwind
 
@@ -18,8 +20,10 @@ impl Display for A {
 
 fn main() {
     set_output_capture(Some(Arc::new(Mutex::new(Vec::new()))));
-    assert!(std::panic::catch_unwind(|| {
-        eprintln!("{}", A);
-    })
-    .is_err());
+    assert!(
+        std::panic::catch_unwind(|| {
+            eprintln!("{}", A);
+        })
+        .is_err()
+    );
 }
diff --git a/tests/ui/panics/panic-handler-closures.rs b/tests/ui/panics/panic-handler-closures.rs
new file mode 100644
index 00000000000..27fea925720
--- /dev/null
+++ b/tests/ui/panics/panic-handler-closures.rs
@@ -0,0 +1,12 @@
+//! Check that closures can be used inside `#[panic_handler]` functions.
+
+//@ check-pass
+
+#![crate_type = "rlib"]
+#![no_std]
+
+#[panic_handler]
+pub fn panicfmt(_: &::core::panic::PanicInfo) -> ! {
+    |x: u8| x;
+    loop {}
+}
diff --git a/tests/ui/parser/ufcs-return-unused-parens.fixed b/tests/ui/parser/ufcs-return-unused-parens.fixed
new file mode 100644
index 00000000000..811a853b769
--- /dev/null
+++ b/tests/ui/parser/ufcs-return-unused-parens.fixed
@@ -0,0 +1,20 @@
+//! Check that UFCS syntax works correctly in return statements
+//! without requiring workaround parentheses.
+//!
+//! Regression test for <https://github.com/rust-lang/rust/issues/37765>.
+
+//@ run-pass
+//@ run-rustfix
+
+#![allow(dead_code)]
+#![warn(unused_parens)]
+
+fn with_parens<T: ToString>(arg: T) -> String {
+    return <T as ToString>::to_string(&arg); //~ WARN unnecessary parentheses around `return` value
+}
+
+fn no_parens<T: ToString>(arg: T) -> String {
+    return <T as ToString>::to_string(&arg);
+}
+
+fn main() {}
diff --git a/tests/ui/parser/ufcs-return-unused-parens.rs b/tests/ui/parser/ufcs-return-unused-parens.rs
new file mode 100644
index 00000000000..6ea69ef9a26
--- /dev/null
+++ b/tests/ui/parser/ufcs-return-unused-parens.rs
@@ -0,0 +1,20 @@
+//! Check that UFCS syntax works correctly in return statements
+//! without requiring workaround parentheses.
+//!
+//! Regression test for <https://github.com/rust-lang/rust/issues/37765>.
+
+//@ run-pass
+//@ run-rustfix
+
+#![allow(dead_code)]
+#![warn(unused_parens)]
+
+fn with_parens<T: ToString>(arg: T) -> String {
+    return (<T as ToString>::to_string(&arg)); //~ WARN unnecessary parentheses around `return` value
+}
+
+fn no_parens<T: ToString>(arg: T) -> String {
+    return <T as ToString>::to_string(&arg);
+}
+
+fn main() {}
diff --git a/tests/ui/path-lookahead.stderr b/tests/ui/parser/ufcs-return-unused-parens.stderr
index 2cc786fd947..6c09e98e7b1 100644
--- a/tests/ui/path-lookahead.stderr
+++ b/tests/ui/parser/ufcs-return-unused-parens.stderr
@@ -1,11 +1,11 @@
 warning: unnecessary parentheses around `return` value
-  --> $DIR/path-lookahead.rs:10:12
+  --> $DIR/ufcs-return-unused-parens.rs:13:12
    |
 LL |     return (<T as ToString>::to_string(&arg));
    |            ^                                ^
    |
 note: the lint level is defined here
-  --> $DIR/path-lookahead.rs:5:9
+  --> $DIR/ufcs-return-unused-parens.rs:10:9
    |
 LL | #![warn(unused_parens)]
    |         ^^^^^^^^^^^^^
diff --git a/tests/ui/path-lookahead.fixed b/tests/ui/path-lookahead.fixed
deleted file mode 100644
index 440b22edd7d..00000000000
--- a/tests/ui/path-lookahead.fixed
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ run-pass
-//@ run-rustfix
-
-#![allow(dead_code)]
-#![warn(unused_parens)]
-
-// Parser test for #37765
-
-fn with_parens<T: ToString>(arg: T) -> String {
-    return <T as ToString>::to_string(&arg); //~WARN unnecessary parentheses around `return` value
-}
-
-fn no_parens<T: ToString>(arg: T) -> String {
-    return <T as ToString>::to_string(&arg);
-}
-
-fn main() {}
diff --git a/tests/ui/path-lookahead.rs b/tests/ui/path-lookahead.rs
deleted file mode 100644
index 7eaacd6bba7..00000000000
--- a/tests/ui/path-lookahead.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ run-pass
-//@ run-rustfix
-
-#![allow(dead_code)]
-#![warn(unused_parens)]
-
-// Parser test for #37765
-
-fn with_parens<T: ToString>(arg: T) -> String {
-    return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
-}
-
-fn no_parens<T: ToString>(arg: T) -> String {
-    return <T as ToString>::to_string(&arg);
-}
-
-fn main() {}
diff --git a/tests/ui/pattern/box-pattern-constructor-mismatch.rs b/tests/ui/pattern/box-pattern-constructor-mismatch.rs
new file mode 100644
index 00000000000..8f0a19d7407
--- /dev/null
+++ b/tests/ui/pattern/box-pattern-constructor-mismatch.rs
@@ -0,0 +1,11 @@
+//! Test that `box _` patterns and `Box { .. }` patterns can't be used to match on the same place.
+//! This is required for the current implementation of exhaustiveness analysis for deref patterns.
+
+#![feature(box_patterns)]
+
+fn main() {
+    match Box::new(0) {
+        box _ => {} //~ ERROR mix of deref patterns and normal constructors
+        Box { .. } => {}
+    }
+}
diff --git a/tests/ui/pattern/box-pattern-constructor-mismatch.stderr b/tests/ui/pattern/box-pattern-constructor-mismatch.stderr
new file mode 100644
index 00000000000..489eefe0d21
--- /dev/null
+++ b/tests/ui/pattern/box-pattern-constructor-mismatch.stderr
@@ -0,0 +1,10 @@
+error: mix of deref patterns and normal constructors
+  --> $DIR/box-pattern-constructor-mismatch.rs:8:9
+   |
+LL |         box _ => {}
+   |         ^^^^^ matches on the result of dereferencing `Box<i32>`
+LL |         Box { .. } => {}
+   |         ^^^^^^^^^^ matches directly on `Box<i32>`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/proc-macro/auxiliary/mixed-site-span.rs b/tests/ui/proc-macro/auxiliary/mixed-site-span.rs
index d837c88c955..18df712debc 100644
--- a/tests/ui/proc-macro/auxiliary/mixed-site-span.rs
+++ b/tests/ui/proc-macro/auxiliary/mixed-site-span.rs
@@ -3,33 +3,89 @@
 extern crate proc_macro;
 use proc_macro::*;
 
+
+#[proc_macro]
+pub fn proc_macro_item(input: TokenStream) -> TokenStream {
+    input
+}
+
+#[proc_macro]
+pub fn proc_macro_rules(_input: TokenStream) -> TokenStream {
+    let id = |s| TokenTree::from(Ident::new(s, Span::mixed_site()));
+    let item_def = id("ItemDef");
+    let local_def = id("local_def");
+    let item_use = id("ItemUse");
+    let local_use = id("local_use");
+    let mut single_quote = Punct::new('\'', Spacing::Joint);
+    single_quote.set_span(Span::mixed_site());
+    let label_use: TokenStream = [
+        TokenTree::from(single_quote),
+        id("label_use"),
+    ].iter().cloned().collect();
+    let dollar_crate = id("$crate");
+    quote!(
+        use $dollar_crate::proc_macro_item as _; // OK
+        type A = $dollar_crate::ItemUse; // ERROR
+
+        struct $item_def;
+        let $local_def = 0;
+
+        $item_use; // OK
+        $local_use; // ERROR
+        break $label_use; // ERROR
+    )
+}
+
+#[proc_macro]
+pub fn with_crate(input: TokenStream) -> TokenStream {
+    let mut input = input.into_iter();
+    let TokenTree::Ident(mut krate) = input.next().unwrap() else { panic!("missing $crate") };
+    let TokenTree::Ident(span) = input.next().unwrap() else { panic!("missing span") };
+    let TokenTree::Ident(ident) = input.next().unwrap() else { panic!("missing ident") };
+
+    match (krate.to_string().as_str(), span.to_string().as_str()) {
+        ("$crate", "input") => {},
+        (_, "input") => krate = Ident::new("$crate", krate.span()),
+
+        ("$crate", "mixed") => krate.set_span(Span::mixed_site()),
+        (_, "mixed") => krate = Ident::new("$crate", Span::mixed_site()),
+
+        ("$crate", "call") => krate.set_span(Span::call_site()),
+        (_, "call") => krate = Ident::new("$crate", Span::call_site()),
+
+        (_, x) => panic!("bad span {}", x),
+    }
+
+    quote!(use $krate::$ident as _;)
+}
+
 #[proc_macro]
-pub fn proc_macro_rules(input: TokenStream) -> TokenStream {
-    if input.is_empty() {
-        let id = |s| TokenTree::from(Ident::new(s, Span::mixed_site()));
-        let item_def = id("ItemDef");
-        let local_def = id("local_def");
-        let item_use = id("ItemUse");
-        let local_use = id("local_use");
-        let mut single_quote = Punct::new('\'', Spacing::Joint);
-        single_quote.set_span(Span::mixed_site());
-        let label_use: TokenStream = [
-            TokenTree::from(single_quote),
-            id("label_use"),
-        ].iter().cloned().collect();
-        quote!(
-            struct $item_def;
-            let $local_def = 0;
-
-            $item_use; // OK
-            $local_use; // ERROR
-            break $label_use; // ERROR
-        )
-    } else {
-        let mut dollar_crate = input.into_iter().next().unwrap();
-        dollar_crate.set_span(Span::mixed_site());
-        quote!(
-            type A = $dollar_crate::ItemUse;
-        )
+pub fn declare_macro(input: TokenStream) -> TokenStream {
+    let mut input = input.into_iter();
+    let TokenTree::Ident(mut krate) = input.next().unwrap() else { panic!("missing $crate") };
+    let TokenTree::Ident(span) = input.next().unwrap() else { panic!("missing span") };
+    let TokenTree::Ident(ident) = input.next().unwrap() else { panic!("missing ident") };
+
+
+    match (krate.to_string().as_str(), span.to_string().as_str()) {
+        ("$crate", "input") => {},
+        (_, "input") => krate = Ident::new("$crate", krate.span()),
+
+        ("$crate", "mixed") => krate.set_span(Span::mixed_site()),
+        (_, "mixed") => krate = Ident::new("$crate", Span::mixed_site()),
+
+        ("$crate", "call") => krate.set_span(Span::call_site()),
+        (_, "call") => krate = Ident::new("$crate", Span::call_site()),
+
+        (_, x) => panic!("bad span {}", x),
     }
+
+    quote!(
+        #[macro_export]
+        macro_rules! $ident {
+            ($$i:ident) => {
+                use $krate::$$i as _;
+            };
+        }
+    )
 }
diff --git a/tests/ui/proc-macro/auxiliary/token-site-span.rs b/tests/ui/proc-macro/auxiliary/token-site-span.rs
new file mode 100644
index 00000000000..39ad8368a50
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/token-site-span.rs
@@ -0,0 +1,30 @@
+// Testing token span hygiene.
+
+//@ proc-macro: mixed-site-span.rs
+
+extern crate mixed_site_span;
+
+use mixed_site_span::declare_macro;
+
+pub struct TokenItem;
+
+#[macro_export]
+macro_rules! invoke_with_crate {
+    ($s:ident $i:ident) => { with_crate!{$crate $s $i} };
+}
+
+#[macro_export]
+macro_rules! invoke_with_ident {
+    ($s:ident $i:ident) => { with_crate!{krate $s $i} };
+    ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} };
+}
+
+macro_rules! local {() => {
+    declare_macro!{$crate input use_input_crate}
+    declare_macro!{$crate mixed use_mixed_crate}
+    declare_macro!{$crate call use_call_crate}
+}}
+local!{}
+declare_macro!{krate input use_input_krate}
+declare_macro!{krate mixed use_mixed_krate}
+declare_macro!{krate call use_call_krate}
diff --git a/tests/ui/proc-macro/mixed-site-span.rs b/tests/ui/proc-macro/mixed-site-span.rs
index 2b5d9757043..442b440c121 100644
--- a/tests/ui/proc-macro/mixed-site-span.rs
+++ b/tests/ui/proc-macro/mixed-site-span.rs
@@ -1,24 +1,174 @@
 // Proc macros using `mixed_site` spans exhibit usual properties of `macro_rules` hygiene.
 
+//@ aux-build: token-site-span.rs
 //@ proc-macro: mixed-site-span.rs
 
-#[macro_use]
 extern crate mixed_site_span;
+extern crate token_site_span;
 
-struct ItemUse;
+use mixed_site_span::{proc_macro_rules, with_crate};
+use token_site_span::{
+    invoke_with_crate, invoke_with_ident,
+    use_input_crate, use_mixed_crate, use_call_crate,
+    use_input_krate, use_mixed_krate, use_call_krate,
+};
+
+pub struct ItemUse;
 
 fn main() {
     'label_use: loop {
         let local_use = 1;
         proc_macro_rules!();
-        //~^ ERROR use of undeclared label `'label_use`
+        //~^ ERROR cannot find type `ItemUse` in crate `$crate`
+        //~| ERROR use of undeclared label `'label_use`
         //~| ERROR cannot find value `local_use` in this scope
         ItemDef; // OK
         local_def; //~ ERROR cannot find value `local_def` in this scope
     }
 }
 
-macro_rules! pass_dollar_crate {
-    () => (proc_macro_rules!($crate);) //~ ERROR cannot find type `ItemUse` in crate `$crate`
-}
-pass_dollar_crate!();
+// Successful resolutions of `mixed_site_span::proc_macro_item`
+const _: () = {
+    invoke_with_crate!{mixed proc_macro_item}
+    invoke_with_ident!{mixed proc_macro_item}
+    invoke_with_ident!{krate mixed proc_macro_item}
+    with_crate!{krate mixed proc_macro_item}
+
+    macro_rules! test {() => {
+        invoke_with_ident!{$crate mixed proc_macro_item}
+        with_crate!{$crate mixed proc_macro_item}
+    }}
+    test!();
+};
+
+// Failed resolutions of `proc_macro_item`
+const _: () = {
+    // token_site_span::proc_macro_item
+    invoke_with_crate!{input proc_macro_item}            //~ ERROR unresolved import `$crate`
+    invoke_with_ident!{input proc_macro_item}            //~ ERROR unresolved import `$crate`
+    invoke_with_crate!{call proc_macro_item}             //~ ERROR unresolved import `$crate`
+    invoke_with_ident!{call proc_macro_item}             //~ ERROR unresolved import `$crate`
+    invoke_with_ident!{hello call proc_macro_item}       //~ ERROR unresolved import `$crate`
+
+    // crate::proc_macro_item
+    invoke_with_ident!{krate input proc_macro_item}      //~ ERROR unresolved import `$crate::proc_macro_item`
+    with_crate!{krate input proc_macro_item}             //~ ERROR unresolved import `$crate::proc_macro_item`
+    with_crate!{krate call proc_macro_item}              //~ ERROR unresolved import `$crate`
+
+    macro_rules! test {() => {
+        // crate::proc_macro_item
+        invoke_with_ident!{$crate input proc_macro_item} //~ ERROR unresolved import `$crate`
+        with_crate!{$crate input proc_macro_item}        //~ ERROR unresolved import `$crate`
+        with_crate!{$crate call proc_macro_item}         //~ ERROR unresolved import `$crate`
+
+        // token_site_span::proc_macro_item
+        invoke_with_ident!{$crate call proc_macro_item}  //~ ERROR unresolved import `$crate`
+    }}
+    test!();
+};
+
+// Successful resolutions of `token_site_span::TokenItem`
+const _: () = {
+    invoke_with_crate!{input TokenItem}
+    invoke_with_ident!{input TokenItem}
+    invoke_with_crate!{call TokenItem}
+    invoke_with_ident!{call TokenItem}
+    invoke_with_ident!{hello call TokenItem}
+
+    macro_rules! test {() => {
+        invoke_with_ident!{$crate call TokenItem}
+    }}
+    test!();
+};
+
+// Failed resolutions of `TokenItem`
+const _: () = {
+    // crate::TokenItem
+    invoke_with_ident!{krate input TokenItem}       //~ ERROR unresolved import `$crate::TokenItem`
+    with_crate!{krate input TokenItem}              //~ ERROR unresolved import `$crate::TokenItem`
+    with_crate!{krate call TokenItem}               //~ ERROR unresolved import `$crate`
+
+    // mixed_site_span::TokenItem
+    invoke_with_crate!{mixed TokenItem}             //~ ERROR unresolved import `$crate`
+    invoke_with_ident!{mixed TokenItem}             //~ ERROR unresolved import `$crate`
+    invoke_with_ident!{krate mixed TokenItem}       //~ ERROR unresolved import `$crate`
+    with_crate!{krate mixed TokenItem}              //~ ERROR unresolved import `$crate`
+
+    macro_rules! test {() => {
+        // crate::TokenItem
+        invoke_with_ident!{$crate input TokenItem}  //~ ERROR unresolved import `$crate`
+        with_crate!{$crate input TokenItem}         //~ ERROR unresolved import `$crate`
+        with_crate!{$crate call TokenItem}          //~ ERROR unresolved import `$crate`
+
+        // mixed_site_span::TokenItem
+        invoke_with_ident!{$crate mixed TokenItem}  //~ ERROR unresolved import `$crate`
+        with_crate!{$crate mixed TokenItem}         //~ ERROR unresolved import `$crate`
+
+    }}
+    test!();
+};
+
+
+// Successful resolutions of `crate::ItemUse`
+const _: () = {
+    invoke_with_ident!{krate input ItemUse}
+    with_crate!{krate input ItemUse}
+    with_crate!{krate call ItemUse}
+
+    macro_rules! test {() => {
+        invoke_with_ident!{$crate input ItemUse}
+        with_crate!{$crate input ItemUse}
+        with_crate!{$crate call ItemUse}
+    }}
+    test!();
+};
+
+// Failed resolutions of `ItemUse`
+const _: () = {
+    // token_site_span::ItemUse
+    invoke_with_crate!{input ItemUse}            //~ ERROR unresolved import `$crate`
+    invoke_with_ident!{input ItemUse}            //~ ERROR unresolved import `$crate`
+
+    // mixed_site_span::ItemUse
+    invoke_with_crate!{mixed ItemUse}            //~ ERROR unresolved import `$crate`
+    invoke_with_ident!{mixed ItemUse}            //~ ERROR unresolved import `$crate`
+    invoke_with_ident!{krate mixed ItemUse}      //~ ERROR unresolved import `$crate`
+    with_crate!{krate mixed ItemUse}             //~ ERROR unresolved import `$crate`
+
+    invoke_with_crate!{call ItemUse}             //~ ERROR unresolved import `$crate`
+    invoke_with_ident!{call ItemUse}             //~ ERROR unresolved import `$crate`
+    invoke_with_ident!{hello call ItemUse}       //~ ERROR unresolved import `$crate`
+
+    macro_rules! test {() => {
+        invoke_with_ident!{$crate mixed ItemUse} //~ ERROR unresolved import `$crate`
+        with_crate!{$crate mixed ItemUse}        //~ ERROR unresolved import `$crate`
+
+        invoke_with_ident!{$crate call ItemUse}  //~ ERROR unresolved import `$crate`
+    }}
+    test!();
+};
+
+
+// Only mixed should see mixed_site_span::proc_macro_item
+use_input_crate!{proc_macro_item}   //~ ERROR unresolved import `$crate`
+use_input_krate!{proc_macro_item}   //~ ERROR unresolved import `$crate`
+use_mixed_crate!{proc_macro_item}
+use_mixed_krate!{proc_macro_item}
+use_call_crate!{proc_macro_item}    //~ ERROR unresolved import `$crate`
+use_call_krate!{proc_macro_item}    //~ ERROR unresolved import `$crate`
+
+// Only mixed should fail to see token_site_span::TokenItem
+use_input_crate!{TokenItem}
+use_input_krate!{TokenItem}
+use_mixed_crate!{TokenItem}         //~ ERROR unresolved import `$crate`
+use_mixed_krate!{TokenItem}         //~ ERROR unresolved import `$crate`
+use_call_crate!{TokenItem}
+use_call_krate!{TokenItem}
+
+// Everything should fail to see crate::ItemUse
+use_input_crate!{ItemUse}           //~ ERROR unresolved import `$crate`
+use_input_krate!{ItemUse}           //~ ERROR unresolved import `$crate`
+use_mixed_crate!{ItemUse}           //~ ERROR unresolved import `$crate`
+use_mixed_krate!{ItemUse}           //~ ERROR unresolved import `$crate`
+use_call_crate!{ItemUse}            //~ ERROR unresolved import `$crate`
+use_call_krate!{ItemUse}            //~ ERROR unresolved import `$crate`
diff --git a/tests/ui/proc-macro/mixed-site-span.stderr b/tests/ui/proc-macro/mixed-site-span.stderr
index 13786080124..d62031a853c 100644
--- a/tests/ui/proc-macro/mixed-site-span.stderr
+++ b/tests/ui/proc-macro/mixed-site-span.stderr
@@ -1,13 +1,595 @@
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:47:5
+   |
+LL |     invoke_with_crate!{input proc_macro_item}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:48:5
+   |
+LL |     invoke_with_ident!{input proc_macro_item}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:49:5
+   |
+LL |     invoke_with_crate!{call proc_macro_item}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:50:5
+   |
+LL |     invoke_with_ident!{call proc_macro_item}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:51:5
+   |
+LL |     invoke_with_ident!{hello call proc_macro_item}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate::proc_macro_item`
+  --> $DIR/mixed-site-span.rs:54:5
+   |
+LL |     invoke_with_ident!{krate input proc_macro_item}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |     |                              |
+   |     |                              help: a similar name exists in the module: `proc_macro_rules`
+   |     no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate::proc_macro_item`
+  --> $DIR/mixed-site-span.rs:55:5
+   |
+LL |     with_crate!{krate input proc_macro_item}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |     |                       |
+   |     |                       help: a similar name exists in the module: `proc_macro_rules`
+   |     no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:56:5
+   |
+LL |     with_crate!{krate call proc_macro_item}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |     |                      |
+   |     |                      help: a similar name exists in the module: `proc_macro_rules`
+   |     no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:60:28
+   |
+LL |         invoke_with_ident!{$crate input proc_macro_item}
+   |                            ^^^^^^       --------------- help: a similar name exists in the module: `proc_macro_rules`
+   |                            |
+   |                            no `proc_macro_item` in the root
+...
+LL |     test!();
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:61:21
+   |
+LL |         with_crate!{$crate input proc_macro_item}
+   |                     ^^^^^^       --------------- help: a similar name exists in the module: `proc_macro_rules`
+   |                     |
+   |                     no `proc_macro_item` in the root
+...
+LL |     test!();
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:62:9
+   |
+LL |         with_crate!{$crate call proc_macro_item}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |         |                       |
+   |         |                       help: a similar name exists in the module: `proc_macro_rules`
+   |         no `proc_macro_item` in the root
+...
+LL |     test!();
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:67:5
+   |
+LL |     test!();
+   |     ^^^^^^^ no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate::TokenItem`
+  --> $DIR/mixed-site-span.rs:87:5
+   |
+LL |     invoke_with_ident!{krate input TokenItem}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/mixed-site-span.rs:59:34
+   |
+LL |     quote!(use $krate::$ident as token_site_span::TokenItem as _;)
+   |                                  +++++++++++++++++++++++++++++
+
+error[E0432]: unresolved import `$crate::TokenItem`
+  --> $DIR/mixed-site-span.rs:88:5
+   |
+LL |     with_crate!{krate input TokenItem}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+   |
+   = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/mixed-site-span.rs:59:34
+   |
+LL |     quote!(use $krate::$ident as token_site_span::TokenItem as _;)
+   |                                  +++++++++++++++++++++++++++++
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:89:5
+   |
+LL |     with_crate!{krate call TokenItem}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+   |
+   = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+   |
+LL -     with_crate!{krate call TokenItem}
+LL +     token_site_span::TokenItem as _
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:92:5
+   |
+LL |     invoke_with_crate!{mixed TokenItem}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:13:30
+   |
+LL -     ($s:ident $i:ident) => { with_crate!{$crate $s $i} };
+LL +     ($s:ident $i:ident) => { token_site_span::TokenItem as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:93:5
+   |
+LL |     invoke_with_ident!{mixed TokenItem}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:18:30
+   |
+LL -     ($s:ident $i:ident) => { with_crate!{krate $s $i} };
+LL +     ($s:ident $i:ident) => { token_site_span::TokenItem as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:94:5
+   |
+LL |     invoke_with_ident!{krate mixed TokenItem}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:19:39
+   |
+LL -     ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} };
+LL +     ($m:ident $s:ident $i:ident) => { token_site_span::TokenItem as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:95:5
+   |
+LL |     with_crate!{krate mixed TokenItem}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+   |
+   = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+   |
+LL -     with_crate!{krate mixed TokenItem}
+LL +     token_site_span::TokenItem as _
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:99:28
+   |
+LL |         invoke_with_ident!{$crate input TokenItem}
+   |                            ^^^^^^ no `TokenItem` in the root
+...
+LL |     test!();
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+   |
+LL -         invoke_with_ident!{$crate input TokenItem}
+LL +         invoke_with_ident!{token_site_span::TokenItem as _ input TokenItem}
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:100:21
+   |
+LL |         with_crate!{$crate input TokenItem}
+   |                     ^^^^^^ no `TokenItem` in the root
+...
+LL |     test!();
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+   |
+LL -         with_crate!{$crate input TokenItem}
+LL +         with_crate!{token_site_span::TokenItem as _ input TokenItem}
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:101:9
+   |
+LL |         with_crate!{$crate call TokenItem}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+...
+LL |     test!();
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+   |
+LL -         with_crate!{$crate call TokenItem}
+LL +         token_site_span::TokenItem as _
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:108:5
+   |
+LL |     test!();
+   |     ^^^^^^^ no `TokenItem` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:19:39
+   |
+LL -     ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} };
+LL +     ($m:ident $s:ident $i:ident) => { token_site_span::TokenItem as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:105:9
+   |
+LL |         with_crate!{$crate mixed TokenItem}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+...
+LL |     test!();
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+   |
+LL -         with_crate!{$crate mixed TokenItem}
+LL +         token_site_span::TokenItem as _
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:129:5
+   |
+LL |     invoke_with_crate!{input ItemUse}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:13:42
+   |
+LL -     ($s:ident $i:ident) => { with_crate!{$crate $s $i} };
+LL +     ($s:ident $i:ident) => { with_crate!{ItemUse as _ $s $i} };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:130:5
+   |
+LL |     invoke_with_ident!{input ItemUse}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:18:42
+   |
+LL -     ($s:ident $i:ident) => { with_crate!{krate $s $i} };
+LL +     ($s:ident $i:ident) => { with_crate!{ItemUse as _ $s $i} };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:133:5
+   |
+LL |     invoke_with_crate!{mixed ItemUse}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:13:30
+   |
+LL -     ($s:ident $i:ident) => { with_crate!{$crate $s $i} };
+LL +     ($s:ident $i:ident) => { ItemUse as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:134:5
+   |
+LL |     invoke_with_ident!{mixed ItemUse}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:18:30
+   |
+LL -     ($s:ident $i:ident) => { with_crate!{krate $s $i} };
+LL +     ($s:ident $i:ident) => { ItemUse as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:135:5
+   |
+LL |     invoke_with_ident!{krate mixed ItemUse}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:19:39
+   |
+LL -     ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} };
+LL +     ($m:ident $s:ident $i:ident) => { ItemUse as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:136:5
+   |
+LL |     with_crate!{krate mixed ItemUse}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+   |
+LL -     with_crate!{krate mixed ItemUse}
+LL +     ItemUse as _
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:138:5
+   |
+LL |     invoke_with_crate!{call ItemUse}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:13:30
+   |
+LL -     ($s:ident $i:ident) => { with_crate!{$crate $s $i} };
+LL +     ($s:ident $i:ident) => { ItemUse as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:139:5
+   |
+LL |     invoke_with_ident!{call ItemUse}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:18:30
+   |
+LL -     ($s:ident $i:ident) => { with_crate!{krate $s $i} };
+LL +     ($s:ident $i:ident) => { ItemUse as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:140:5
+   |
+LL |     invoke_with_ident!{hello call ItemUse}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:19:39
+   |
+LL -     ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} };
+LL +     ($m:ident $s:ident $i:ident) => { ItemUse as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:148:5
+   |
+LL |     test!();
+   |     ^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:19:39
+   |
+LL -     ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} };
+LL +     ($m:ident $s:ident $i:ident) => { ItemUse as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:144:9
+   |
+LL |         with_crate!{$crate mixed ItemUse}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+...
+LL |     test!();
+   |     ------- in this macro invocation
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+   |
+LL -         with_crate!{$crate mixed ItemUse}
+LL +         ItemUse as _
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:148:5
+   |
+LL |     test!();
+   |     ^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:19:39
+   |
+LL -     ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} };
+LL +     ($m:ident $s:ident $i:ident) => { ItemUse as _ };
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:153:1
+   |
+LL | use_input_crate!{proc_macro_item}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `use_input_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:154:1
+   |
+LL | use_input_krate!{proc_macro_item}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `use_input_krate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:157:1
+   |
+LL | use_call_crate!{proc_macro_item}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `use_call_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:158:1
+   |
+LL | use_call_krate!{proc_macro_item}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root
+   |
+   = note: this error originates in the macro `use_call_krate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:163:1
+   |
+LL | use_mixed_crate!{TokenItem}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+   |
+   = note: this error originates in the macro `use_mixed_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:24:5
+   |
+LL -     declare_macro!{$crate mixed use_mixed_crate}
+LL +     token_site_span::TokenItem as _
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:164:1
+   |
+LL | use_mixed_krate!{TokenItem}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
+   |
+   = note: this error originates in the macro `use_mixed_krate` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct instead
+  --> $DIR/auxiliary/token-site-span.rs:29:1
+   |
+LL - declare_macro!{krate mixed use_mixed_krate}
+LL + token_site_span::TokenItem as _
+   |
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:169:1
+   |
+LL | use_input_crate!{ItemUse}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `use_input_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:170:1
+   |
+LL | use_input_krate!{ItemUse}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `use_input_krate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:171:1
+   |
+LL | use_mixed_crate!{ItemUse}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `use_mixed_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:172:1
+   |
+LL | use_mixed_krate!{ItemUse}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `use_mixed_krate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:173:1
+   |
+LL | use_call_crate!{ItemUse}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `use_call_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0432]: unresolved import `$crate`
+  --> $DIR/mixed-site-span.rs:174:1
+   |
+LL | use_call_krate!{ItemUse}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
+   |
+   = note: this error originates in the macro `use_call_krate` (in Nightly builds, run with -Z macro-backtrace for more info)
+
 error[E0426]: use of undeclared label `'label_use`
-  --> $DIR/mixed-site-span.rs:13:9
+  --> $DIR/mixed-site-span.rs:21:9
    |
 LL |         proc_macro_rules!();
    |         ^^^^^^^^^^^^^^^^^^^ undeclared label `'label_use`
    |
    = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info)
 
+error[E0412]: cannot find type `ItemUse` in crate `$crate`
+  --> $DIR/mixed-site-span.rs:21:9
+   |
+LL |         proc_macro_rules!();
+   |         ^^^^^^^^^^^^^^^^^^^ not found in `$crate`
+   |
+   = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider importing this struct
+   |
+LL + use ItemUse;
+   |
+
 error[E0425]: cannot find value `local_use` in this scope
-  --> $DIR/mixed-site-span.rs:13:9
+  --> $DIR/mixed-site-span.rs:21:9
    |
 LL |         proc_macro_rules!();
    |         ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def`
@@ -15,20 +597,12 @@ LL |         proc_macro_rules!();
    = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0425]: cannot find value `local_def` in this scope
-  --> $DIR/mixed-site-span.rs:17:9
+  --> $DIR/mixed-site-span.rs:26:9
    |
 LL |         local_def;
    |         ^^^^^^^^^ help: a local variable with a similar name exists: `local_use`
 
-error[E0412]: cannot find type `ItemUse` in crate `$crate`
-  --> $DIR/mixed-site-span.rs:24:1
-   |
-LL | pass_dollar_crate!();
-   | ^^^^^^^^^^^^^^^^^^^^ not found in `$crate`
-   |
-   = note: this error originates in the macro `proc_macro_rules` which comes from the expansion of the macro `pass_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 4 previous errors
+error: aborting due to 52 previous errors
 
-Some errors have detailed explanations: E0412, E0425, E0426.
+Some errors have detailed explanations: E0412, E0425, E0426, E0432.
 For more information about an error, try `rustc --explain E0412`.
diff --git a/tests/ui/resolve/false-self-in-macro-issue-143134.rs b/tests/ui/resolve/false-self-in-macro-issue-143134.rs
new file mode 100644
index 00000000000..0983b8b3dc3
--- /dev/null
+++ b/tests/ui/resolve/false-self-in-macro-issue-143134.rs
@@ -0,0 +1,10 @@
+trait T {
+    fn f(self);
+  }
+  impl T for () {
+    fn f(self) {
+        let self = (); //~ ERROR expected unit struct, unit variant or constant, found local variable `self`
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/resolve/false-self-in-macro-issue-143134.stderr b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr
new file mode 100644
index 00000000000..48c979575ea
--- /dev/null
+++ b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr
@@ -0,0 +1,9 @@
+error[E0424]: expected unit struct, unit variant or constant, found local variable `self`
+  --> $DIR/false-self-in-macro-issue-143134.rs:6:13
+   |
+LL |         let self = ();
+   |             ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0424`.
diff --git a/tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs b/tests/ui/resolve/suggestions/auxiliary/suggest-constructor-cycle-error.rs
index 8de68c38bc3..8de68c38bc3 100644
--- a/tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs
+++ b/tests/ui/resolve/suggestions/auxiliary/suggest-constructor-cycle-error.rs
diff --git a/tests/ui/resolve/suggest-builder-fn.rs b/tests/ui/resolve/suggestions/suggest-builder-fn.rs
index 959675ef2c9..959675ef2c9 100644
--- a/tests/ui/resolve/suggest-builder-fn.rs
+++ b/tests/ui/resolve/suggestions/suggest-builder-fn.rs
diff --git a/tests/ui/resolve/suggest-builder-fn.stderr b/tests/ui/resolve/suggestions/suggest-builder-fn.stderr
index 9c5eed35ccf..9c5eed35ccf 100644
--- a/tests/ui/resolve/suggest-builder-fn.stderr
+++ b/tests/ui/resolve/suggestions/suggest-builder-fn.stderr
diff --git a/tests/ui/resolve/suggest-constructor-cycle-error.rs b/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.rs
index c23d6788eef..c23d6788eef 100644
--- a/tests/ui/resolve/suggest-constructor-cycle-error.rs
+++ b/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.rs
diff --git a/tests/ui/resolve/suggest-constructor-cycle-error.stderr b/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.stderr
index c6ec2465a43..c6ec2465a43 100644
--- a/tests/ui/resolve/suggest-constructor-cycle-error.stderr
+++ b/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.stderr
diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed
index 607c9af4927..607c9af4927 100644
--- a/tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed
+++ b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed
diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.rs b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs
index 6cc53fb1086..6cc53fb1086 100644
--- a/tests/ui/resolve/suggest-import-without-clobbering-attrs.rs
+++ b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs
diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.stderr
index de65d695dd2..de65d695dd2 100644
--- a/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr
+++ b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.stderr
diff --git a/tests/ui/resolve/suggest-path-for-tuple-struct.rs b/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.rs
index c8bc3e79fe2..c8bc3e79fe2 100644
--- a/tests/ui/resolve/suggest-path-for-tuple-struct.rs
+++ b/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.rs
diff --git a/tests/ui/resolve/suggest-path-for-tuple-struct.stderr b/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.stderr
index 68a5b550978..68a5b550978 100644
--- a/tests/ui/resolve/suggest-path-for-tuple-struct.stderr
+++ b/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.stderr
diff --git a/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.rs b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.rs
index d5d6b13d62c..d5d6b13d62c 100644
--- a/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.rs
+++ b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.rs
diff --git a/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr
index 5db943cd10d..5db943cd10d 100644
--- a/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
+++ b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr
diff --git a/tests/ui/specialization/const_trait_impl.rs b/tests/ui/specialization/const_trait_impl.rs
index 2df92dfad3b..e917263d193 100644
--- a/tests/ui/specialization/const_trait_impl.rs
+++ b/tests/ui/specialization/const_trait_impl.rs
@@ -2,6 +2,8 @@
 
 #![feature(const_trait_impl, min_specialization, rustc_attrs)]
 
+use std::fmt::Debug;
+
 #[rustc_specialization_trait]
 #[const_trait]
 pub unsafe trait Sup {
@@ -31,19 +33,19 @@ pub trait A {
     fn a() -> u32;
 }
 
-impl<T: [const] Default> const A for T {
+impl<T: [const] Debug> const A for T {
     default fn a() -> u32 {
         2
     }
 }
 
-impl<T: [const] Default + [const] Sup> const A for T {
+impl<T: [const] Debug + [const] Sup> const A for T {
     default fn a() -> u32 {
         3
     }
 }
 
-impl<T: [const] Default + [const] Sub> const A for T {
+impl<T: [const] Debug + [const] Sub> const A for T {
     fn a() -> u32 {
         T::foo()
     }
diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr
index ea3ec16ac1e..b9c768812c8 100644
--- a/tests/ui/specialization/const_trait_impl.stderr
+++ b/tests/ui/specialization/const_trait_impl.stderr
@@ -1,58 +1,58 @@
 error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const_trait_impl.rs:34:9
+  --> $DIR/const_trait_impl.rs:36:9
    |
-LL | impl<T: [const] Default> const A for T {
-   |         ^^^^^^^ can't be applied to `Default`
+LL | impl<T: [const] Debug> const A for T {
+   |         ^^^^^^^ can't be applied to `Debug`
    |
-note: `Default` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/default.rs:LL:COL
+note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
+  --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
 
 error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const_trait_impl.rs:40:9
+  --> $DIR/const_trait_impl.rs:42:9
    |
-LL | impl<T: [const] Default + [const] Sup> const A for T {
-   |         ^^^^^^^ can't be applied to `Default`
+LL | impl<T: [const] Debug + [const] Sup> const A for T {
+   |         ^^^^^^^ can't be applied to `Debug`
    |
-note: `Default` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/default.rs:LL:COL
+note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
+  --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
 
 error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const_trait_impl.rs:46:9
+  --> $DIR/const_trait_impl.rs:48:9
    |
-LL | impl<T: [const] Default + [const] Sub> const A for T {
-   |         ^^^^^^^ can't be applied to `Default`
+LL | impl<T: [const] Debug + [const] Sub> const A for T {
+   |         ^^^^^^^ can't be applied to `Debug`
    |
-note: `Default` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/default.rs:LL:COL
+note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
+  --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
 
 error: `[const]` can only be applied to `#[const_trait]` traits
-  --> $DIR/const_trait_impl.rs:40:9
+  --> $DIR/const_trait_impl.rs:42:9
    |
-LL | impl<T: [const] Default + [const] Sup> const A for T {
-   |         ^^^^^^^ can't be applied to `Default`
+LL | impl<T: [const] Debug + [const] Sup> const A for T {
+   |         ^^^^^^^ can't be applied to `Debug`
    |
-note: `Default` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/default.rs:LL:COL
+note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
+  --> $SRC_DIR/core/src/fmt/mod.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_trait_impl.rs:34:9
+  --> $DIR/const_trait_impl.rs:36:9
    |
-LL | impl<T: [const] Default> const A for T {
-   |         ^^^^^^^ can't be applied to `Default`
+LL | impl<T: [const] Debug> const A for T {
+   |         ^^^^^^^ can't be applied to `Debug`
    |
-note: `Default` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/default.rs:LL:COL
+note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
+  --> $SRC_DIR/core/src/fmt/mod.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_trait_impl.rs:46:9
+  --> $DIR/const_trait_impl.rs:48:9
    |
-LL | impl<T: [const] Default + [const] Sub> const A for T {
-   |         ^^^^^^^ can't be applied to `Default`
+LL | impl<T: [const] Debug + [const] Sub> const A for T {
+   |         ^^^^^^^ can't be applied to `Debug`
    |
-note: `Default` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
-  --> $SRC_DIR/core/src/default.rs:LL:COL
+note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]`
+  --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: aborting due to 6 previous errors
diff --git a/tests/ui/suggestions/suggest-remove-refs-6.rs b/tests/ui/suggestions/suggest-remove-refs-6.rs
new file mode 100644
index 00000000000..0d06aed4806
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-refs-6.rs
@@ -0,0 +1,12 @@
+// Regression test for #143523.
+
+trait Trait {}
+
+impl Trait for Vec<i32> {}
+
+fn foo(_: impl Trait) {}
+
+fn main() {
+    foo(&mut vec![1]);
+    //~^ ERROR the trait bound `&mut Vec<{integer}>: Trait` is not satisfied
+}
diff --git a/tests/ui/suggestions/suggest-remove-refs-6.stderr b/tests/ui/suggestions/suggest-remove-refs-6.stderr
new file mode 100644
index 00000000000..bdc5a8a9049
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-refs-6.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `&mut Vec<{integer}>: Trait` is not satisfied
+  --> $DIR/suggest-remove-refs-6.rs:10:9
+   |
+LL |     foo(&mut vec![1]);
+   |     --- ^^^^^^^^^^^^ the trait `Trait` is not implemented for `&mut Vec<{integer}>`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `foo`
+  --> $DIR/suggest-remove-refs-6.rs:7:16
+   |
+LL | fn foo(_: impl Trait) {}
+   |                ^^^^^ required by this bound in `foo`
+help: consider removing the leading `&`-reference
+   |
+LL -     foo(&mut vec![1]);
+LL +     foo(vec![1]);
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const-traits-alloc.rs b/tests/ui/traits/const-traits/const-traits-alloc.rs
new file mode 100644
index 00000000000..07725ef02f1
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-traits-alloc.rs
@@ -0,0 +1,9 @@
+//@ run-pass
+#![feature(const_trait_impl, const_default)]
+#![allow(dead_code)]
+// alloc::string
+const STRING: String = Default::default();
+// alloc::vec
+const VEC: Vec<()> = Default::default();
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const-traits-core.rs b/tests/ui/traits/const-traits/const-traits-core.rs
new file mode 100644
index 00000000000..6df53daae13
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-traits-core.rs
@@ -0,0 +1,46 @@
+//@ run-pass
+#![feature(
+    const_trait_impl, const_default, ptr_alignment_type, ascii_char, f16, f128, sync_unsafe_cell,
+)]
+#![allow(dead_code)]
+// core::default
+const UNIT: () = Default::default();
+const BOOL: bool = Default::default();
+const CHAR: char = Default::default();
+const ASCII_CHAR: std::ascii::Char = Default::default();
+const USIZE: usize = Default::default();
+const U8: u8 = Default::default();
+const U16: u16 = Default::default();
+const U32: u32 = Default::default();
+const U64: u64 = Default::default();
+const U128: u128 = Default::default();
+const I8: i8 = Default::default();
+const I16: i16 = Default::default();
+const I32: i32 = Default::default();
+const I64: i64 = Default::default();
+const I128: i128 = Default::default();
+const F16: f16 = Default::default();
+const F32: f32 = Default::default();
+const F64: f64 = Default::default();
+const F128: f128 = Default::default();
+// core::marker
+const PHANTOM: std::marker::PhantomData<()> = Default::default();
+// core::option
+const OPT: Option<i32> = Default::default();
+// core::iter::sources::empty
+const EMPTY: std::iter::Empty<()> = Default::default();
+// core::ptr::alignment
+const ALIGNMENT: std::ptr::Alignment = Default::default();
+// core::slice
+const SLICE: &[()] = Default::default();
+const MUT_SLICE: &mut [()] = Default::default();
+// core::str
+const STR: &str = Default::default();
+const MUT_STR: &mut str = Default::default();
+// core::cell
+const CELL: std::cell::Cell<()> = Default::default();
+const REF_CELL: std::cell::RefCell<()> = Default::default();
+const UNSAFE_CELL: std::cell::UnsafeCell<()> = Default::default();
+const SYNC_UNSAFE_CELL: std::cell::SyncUnsafeCell<()> = Default::default();
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs b/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs
index a772d69c9e2..04fea1189ae 100644
--- a/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs
@@ -1,5 +1,6 @@
-#[derive_const(Default)] //~ ERROR use of unstable library feature
-//~^ ERROR const `impl` for trait `Default` which is not marked with `#[const_trait]`
+#[derive_const(Debug)] //~ ERROR use of unstable library feature
+//~^ ERROR const `impl` for trait `Debug` which is not marked with `#[const_trait]`
+//~| ERROR cannot call non-const method
 pub struct S;
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr
index 202210a2e65..5bde358001c 100644
--- a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr
@@ -1,21 +1,30 @@
 error[E0658]: use of unstable library feature `derive_const`
   --> $DIR/derive-const-gate.rs:1:3
    |
-LL | #[derive_const(Default)]
+LL | #[derive_const(Debug)]
    |   ^^^^^^^^^^^^
    |
    = help: add `#![feature(derive_const)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
+error: const `impl` for trait `Debug` which is not marked with `#[const_trait]`
   --> $DIR/derive-const-gate.rs:1:16
    |
-LL | #[derive_const(Default)]
-   |                ^^^^^^^ this trait is not `const`
+LL | #[derive_const(Debug)]
+   |                ^^^^^ this trait is not `const`
    |
    = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
    = note: adding a non-const method body in the future would be a breaking change
 
-error: aborting due to 2 previous errors
+error[E0015]: cannot call non-const method `Formatter::<'_>::write_str` in constant functions
+  --> $DIR/derive-const-gate.rs:1:16
+   |
+LL | #[derive_const(Debug)]
+   |                ^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0015, E0658.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs
index 7bda7117a47..0bc25ce5f65 100644
--- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs
@@ -3,11 +3,13 @@
 
 pub struct A;
 
-impl Default for A {
-    fn default() -> A { A }
+impl std::fmt::Debug for A {
+    fn fmt(&self, _: &mut std::fmt::Formatter<'_>)  -> Result<(), std::fmt::Error> {
+        panic!()
+    }
 }
 
-#[derive_const(Default)]
+#[derive_const(Debug)]
 pub struct S(A);
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr
index 27f4bcf46ef..c0bd360ebe5 100644
--- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr
@@ -1,19 +1,17 @@
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-non-const-type.rs:10:16
+error: const `impl` for trait `Debug` which is not marked with `#[const_trait]`
+  --> $DIR/derive-const-non-const-type.rs:12:16
    |
-LL | #[derive_const(Default)]
-   |                ^^^^^^^ this trait is not `const`
+LL | #[derive_const(Debug)]
+   |                ^^^^^ this trait is not `const`
    |
    = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
    = note: adding a non-const method body in the future would be a breaking change
 
-error[E0015]: cannot call non-const associated function `<A as Default>::default` in constant functions
-  --> $DIR/derive-const-non-const-type.rs:11:14
+error[E0015]: cannot call non-const method `Formatter::<'_>::debug_tuple_field1_finish` in constant functions
+  --> $DIR/derive-const-non-const-type.rs:12:16
    |
-LL | #[derive_const(Default)]
-   |                ------- in this derive macro expansion
-LL | pub struct S(A);
-   |              ^
+LL | #[derive_const(Debug)]
+   |                ^^^^^
    |
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-use.rs b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
index 1e447147213..1a3012de06f 100644
--- a/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
@@ -1,6 +1,6 @@
 //@ known-bug: #110395
 
-#![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
+#![feature(const_trait_impl, const_default, const_cmp, derive_const)]
 
 pub struct A;
 
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
index ce61eb9a1ab..4ea11a0c7ed 100644
--- a/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
@@ -1,27 +1,3 @@
-error[E0635]: unknown feature `const_default_impls`
-  --> $DIR/derive-const-use.rs:3:41
-   |
-LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
-   |                                         ^^^^^^^^^^^^^^^^^^^
-
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:7:12
-   |
-LL | impl const Default for A {
-   |            ^^^^^^^ this trait is not `const`
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:15:16
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                ^^^^^^^ this trait is not `const`
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error[E0277]: the trait bound `(): [const] PartialEq` is not satisfied
   --> $DIR/derive-const-use.rs:16:14
    |
@@ -30,35 +6,6 @@ LL | #[derive_const(Default, PartialEq)]
 LL | pub struct S((), A);
    |              ^^
 
-error[E0015]: cannot call non-const associated function `<S as Default>::default` in constants
-  --> $DIR/derive-const-use.rs:18:35
-   |
-LL | const _: () = assert!(S((), A) == S::default());
-   |                                   ^^^^^^^^^^^^
-   |
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const associated function `<() as Default>::default` in constant functions
-  --> $DIR/derive-const-use.rs:16:14
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                ------- in this derive macro expansion
-LL | pub struct S((), A);
-   |              ^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const associated function `<A as Default>::default` in constant functions
-  --> $DIR/derive-const-use.rs:16:18
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                ------- in this derive macro expansion
-LL | pub struct S((), A);
-   |                  ^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 7 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0015, E0277, E0635.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/std-impl-gate.gated.stderr b/tests/ui/traits/const-traits/std-impl-gate.gated.stderr
deleted file mode 100644
index a78cf8ce61e..00000000000
--- a/tests/ui/traits/const-traits/std-impl-gate.gated.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0635]: unknown feature `const_default_impls`
-  --> $DIR/std-impl-gate.rs:6:46
-   |
-LL | #![cfg_attr(gated, feature(const_trait_impl, const_default_impls))]
-   |                                              ^^^^^^^^^^^^^^^^^^^
-
-error[E0015]: cannot call non-const associated function `<Vec<usize> as Default>::default` in constant functions
-  --> $DIR/std-impl-gate.rs:13:5
-   |
-LL |     Default::default()
-   |     ^^^^^^^^^^^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0015, E0635.
-For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/std-impl-gate.rs b/tests/ui/traits/const-traits/std-impl-gate.rs
index 84091931997..d29bccf17c9 100644
--- a/tests/ui/traits/const-traits/std-impl-gate.rs
+++ b/tests/ui/traits/const-traits/std-impl-gate.rs
@@ -1,9 +1,9 @@
 // This tests feature gates for const impls in the standard library.
 
 //@ revisions: stock gated
-//@[gated] known-bug: #110395
+//@[gated] run-pass
 
-#![cfg_attr(gated, feature(const_trait_impl, const_default_impls))]
+#![cfg_attr(gated, feature(const_trait_impl, const_default))]
 
 fn non_const_context() -> Vec<usize> {
     Default::default()
@@ -11,7 +11,8 @@ fn non_const_context() -> Vec<usize> {
 
 const fn const_context() -> Vec<usize> {
     Default::default()
-    //[stock]~^ ERROR cannot call non-const associated function
+    //[stock]~^ ERROR cannot call conditionally-const associated function
+    //[stock]~| ERROR `Default` is not yet stable as a const trait
 }
 
 fn main() {
diff --git a/tests/ui/traits/const-traits/std-impl-gate.stock.stderr b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr
index 8728f652ef9..1fa71e41a98 100644
--- a/tests/ui/traits/const-traits/std-impl-gate.stock.stderr
+++ b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr
@@ -1,11 +1,25 @@
-error[E0015]: cannot call non-const associated function `<Vec<usize> as Default>::default` in constant functions
+error[E0658]: cannot call conditionally-const associated function `<Vec<usize> as Default>::default` in constant functions
   --> $DIR/std-impl-gate.rs:13:5
    |
 LL |     Default::default()
    |     ^^^^^^^^^^^^^^^^^^
    |
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 1 previous error
+error: `Default` is not yet stable as a const trait
+  --> $DIR/std-impl-gate.rs:13:5
+   |
+LL |     Default::default()
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+help: add `#![feature(const_default)]` to the crate attributes to enable
+   |
+LL + #![feature(const_default)]
+   |
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs
new file mode 100644
index 00000000000..ad313823fe4
--- /dev/null
+++ b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs
@@ -0,0 +1,18 @@
+// Regression test for #143481, where we were calling `predicates_of` on
+// a Crate HIR node because we were using a dummy obligation cause's body id
+// without checking that it was meaningful first.
+
+trait Role {
+    type Inner;
+}
+struct HandshakeCallback<C>(C);
+impl<C: Clone> Role for HandshakeCallback {
+    //~^ ERROR missing generics
+    type Inner = usize;
+}
+struct Handshake<R: Role>(R::Inner);
+fn accept() -> Handshake<HandshakeCallback<()>> {
+    todo!()
+}
+
+fn main() {}
diff --git a/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr
new file mode 100644
index 00000000000..17ace03e891
--- /dev/null
+++ b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for struct `HandshakeCallback`
+  --> $DIR/ambiguity-in-dropck-err-reporting.rs:9:25
+   |
+LL | impl<C: Clone> Role for HandshakeCallback {
+   |                         ^^^^^^^^^^^^^^^^^ expected 1 generic argument
+   |
+note: struct defined here, with 1 generic parameter: `C`
+  --> $DIR/ambiguity-in-dropck-err-reporting.rs:8:8
+   |
+LL | struct HandshakeCallback<C>(C);
+   |        ^^^^^^^^^^^^^^^^^ -
+help: add missing generic argument
+   |
+LL | impl<C: Clone> Role for HandshakeCallback<C> {
+   |                                          +++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/partialeq_help.rs b/tests/ui/traits/partialeq-ref-mismatch-diagnostic.rs
index 34b88b8a866..26ef8050b87 100644
--- a/tests/ui/partialeq_help.rs
+++ b/tests/ui/traits/partialeq-ref-mismatch-diagnostic.rs
@@ -1,8 +1,10 @@
+//! Check diagnostic messages for `PartialEq` trait bound mismatches between `&T` and `T`.
+
 fn foo<T: PartialEq>(a: &T, b: T) {
     a == b; //~ ERROR E0277
 }
 
-fn foo2<T: PartialEq>(a: &T, b: T) where {
+fn foo2<T: PartialEq>(a: &T, b: T) {
     a == b; //~ ERROR E0277
 }
 
diff --git a/tests/ui/partialeq_help.stderr b/tests/ui/traits/partialeq-ref-mismatch-diagnostic.stderr
index f5de1308e87..4cbd31656dc 100644
--- a/tests/ui/partialeq_help.stderr
+++ b/tests/ui/traits/partialeq-ref-mismatch-diagnostic.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `&T` with `T`
-  --> $DIR/partialeq_help.rs:2:7
+  --> $DIR/partialeq-ref-mismatch-diagnostic.rs:4:7
    |
 LL |     a == b;
    |       ^^ no implementation for `&T == T`
@@ -15,7 +15,7 @@ LL | fn foo<T: PartialEq>(a: &T, b: T) where &T: PartialEq<T> {
    |                                   ++++++++++++++++++++++
 
 error[E0277]: can't compare `&T` with `T`
-  --> $DIR/partialeq_help.rs:6:7
+  --> $DIR/partialeq-ref-mismatch-diagnostic.rs:8:7
    |
 LL |     a == b;
    |       ^^ no implementation for `&T == T`
@@ -25,10 +25,10 @@ help: consider dereferencing here
    |
 LL |     *a == b;
    |     +
-help: consider extending the `where` clause, but there might be an alternative better way to express this requirement
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
    |
 LL | fn foo2<T: PartialEq>(a: &T, b: T) where &T: PartialEq<T> {
-   |                                          ++++++++++++++++
+   |                                    ++++++++++++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/triagebot.toml b/triagebot.toml
index 4e3dff219f1..9f8ea2dad52 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -535,6 +535,9 @@ trigger_files = [
 [autolabel."S-waiting-on-review"]
 new_pr = true
 
+[autolabel."S-waiting-on-author"]
+new_draft = true
+
 [autolabel."needs-triage"]
 new_issue = true
 exclude_labels = [
@@ -931,6 +934,15 @@ instead.
 """
 cc = ["@tgross35"]
 
+[mentions."library/stdarch"]
+message = """
+`stdarch` is developed in its own repository. If possible, consider \
+making this change to \
+[rust-lang/stdarch](https://github.com/rust-lang/stdarch) \
+instead.
+"""
+cc = ["@Amanieu", "@folkertdev", "@sayantn"]
+
 [mentions."library/core/src/intrinsics/simd.rs"]
 message = """
 Some changes occurred to the platform-builtins intrinsics. Make sure the
@@ -1080,6 +1092,10 @@ cc = ["@jieyouxu"]
 message = "The list of allowed third-party dependencies may have been modified! You must ensure that any new dependencies have compatible licenses before merging."
 cc = ["@davidtwco", "@wesleywiser"]
 
+[mentions."src/tools/tidy/src/ext_tool_checks.rs"]
+message = "`tidy` extra checks were modified."
+cc = ["@lolbinarycat"]
+
 [mentions."src/bootstrap/src/core/config"]
 message = """
 This PR modifies `src/bootstrap/src/core/config`.